windows 如何从 SHBrowseForFolder 函数获取完整路径?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1953339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:37:57  来源:igfitidea点击:

How to get full path from SHBrowseForFolder function?

c++cwindows

提问by winlin

I'm using SHBrowseForFolder and SHGetPathFromIDList functions to get the selected folder path by user. However this method does not return the drive path of the full path. How to additionally get that information too?

我正在使用 SHBrowseForFolder 和 SHGetPathFromIDList 函数来获取用户选择的文件夹路径。但是,此方法不会返回完整路径的驱动器路径。如何另外获取该信息?

回答by GalacticJello

Taken from this newsgroup post:

取自此新闻组帖子

You can use SHBrowseForFolder(...), it takes BROWSEINFO as parameter;

您可以使用 SHBrowseForFolder(...),它以 BROWSEINFO 作为参数;

TCHAR szDir[MAX_PATH];
BROWSEINFO bInfo;
bInfo.hwndOwner = Owner window
bInfo.pidlRoot = NULL; 
bInfo.pszDisplayName = szDir; // Address of a buffer to receive the display name of the folder selected by the user
bInfo.lpszTitle = "Please, select a folder"; // Title of the dialog
bInfo.ulFlags = 0 ;
bInfo.lpfn = NULL;
bInfo.lParam = 0;
bInfo.iImage = -1;

LPITEMIDLIST lpItem = SHBrowseForFolder( &bInfo);
if( lpItem != NULL )
{
  SHGetPathFromIDList(lpItem, szDir );
  //......
}

SHBrowseForFolderreturns the folder's PIDL and its display name, to get the full path from PIDL, call SHGetPathFromIDList

SHBrowseForFolder返回文件夹的 PIDL 及其显示名称,要从 PIDL 中获取完整路径,请调用SHGetPathFromIDList

EDIT:The OP seems to be having trouble getting it to work, so here is some working C# code (you should be able to translate it to whatever language, the APIs are the same):

编辑:OP 似乎无法让它工作,所以这里有一些可用的 C# 代码(你应该能够将它翻译成任何语言,API 是相同的):

class SHGetPath
{
    [DllImport("shell32.dll")]
    static extern IntPtr SHBrowseForFolder(ref BROWSEINFO lpbi);

    [DllImport("shell32.dll")]
    public static extern Int32 SHGetPathFromIDList(
    IntPtr pidl, StringBuilder pszPath);

    public delegate int BrowseCallBackProc(IntPtr hwnd, int msg, IntPtr lp, IntPtr wp);
    struct BROWSEINFO 
    {
        public IntPtr hwndOwner;
        public IntPtr pidlRoot;
        public string pszDisplayName;
        public string lpszTitle;
        public uint ulFlags;
        public BrowseCallBackProc lpfn;
        public IntPtr lParam;
        public int iImage;
    }

    public SHGetPath()
    {
        Console.WriteLine(SelectFolder("Hello World", "C:\"));
    }

    public string SelectFolder(string caption, string initialPath)
    {
        StringBuilder sb = new StringBuilder(256);
        IntPtr pidl = IntPtr.Zero;
        BROWSEINFO bi;
        bi.hwndOwner = Process.GetCurrentProcess().MainWindowHandle; ;
        bi.pidlRoot = IntPtr.Zero;
        bi.pszDisplayName = initialPath;
        bi.lpszTitle = caption;
        bi.ulFlags = 0; // BIF_NEWDIALOGSTYLE | BIF_SHAREABLE;
        bi.lpfn = null; // new BrowseCallBackProc(OnBrowseEvent);
        bi.lParam = IntPtr.Zero;
        bi.iImage = 0;

        try
        {
            pidl = SHBrowseForFolder(ref bi);
            if (0 == SHGetPathFromIDList(pidl, sb))
            {
                return null;
            }
        }
        finally
        {
            // Caller is responsible for freeing this memory.
            Marshal.FreeCoTaskMem(pidl);
        }
        return sb.ToString();
    }
}