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?
Taken from this newsgroup post:
You can use SHBrowseForFolder(...), it takes BROWSEINFO as parameter;
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 );
//......
}
SHBrowseForFolder returns the folder's PIDL and its display name, to get the full path from PIDL, call 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):
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();
}
}
精彩评论