我有这个电话:
oShell.BrowseForFolder(Me.hwnd, "Select path:", 0, "C:\dir\")
这将打开一个以“C:\dir\”为根的标准文件浏览器对话框。我的问题是您无法浏览根文件夹上方。(如文档http://msdn.microsoft.com/en-us/library/bb774065(v=vs.85).aspx中所述)
关于使用选定路径和完整浏览可能性打开此对话框的任何建议?
谢谢
我有这个电话:
oShell.BrowseForFolder(Me.hwnd, "Select path:", 0, "C:\dir\")
这将打开一个以“C:\dir\”为根的标准文件浏览器对话框。我的问题是您无法浏览根文件夹上方。(如文档http://msdn.microsoft.com/en-us/library/bb774065(v=vs.85).aspx中所述)
关于使用选定路径和完整浏览可能性打开此对话框的任何建议?
谢谢
执行此操作的方法涉及调用底层 API SHBrowseForFolder()
,.
由于您希望整个 shell 命名空间可用,因此您需要传递NULL
为pidlRoot
. 为了选择您想要的文件夹,您需要在lpfn
. BFFM_INITIALIZED
通过设置所选文件夹来响应此回调。此选择是通过将BFFM_SETSELECTION
消息发送到对话框的窗口句柄(传递给回调函数)来执行的。
没有代码,因为我没有 VB6,但希望这个方法大纲足以让你上路。
Karl E Peterson 的优秀网站包含一个示例,该示例演示了SHBrowseForFolder
带有回调的 API 调用,如 David Heffernan 的回答。
看MFolderBrowse.bas
,例程BrowseForFolderByPIDL
传递了一个回调函数BrowseCallbackProc
。
试试旧的CCRP项目。它很好地实现了浏览对话框。我在我的几个项目中使用了它,它具有解决您遇到的问题的属性。
这是一个准备好复制并粘贴到 C++ 类中的代码:
// static
int CALLBACK Func::FolderBrowserCallback(HWND h_Dlg, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED)
{
// Requires Windows XP or higher
SendMessageW(h_Dlg, BFFM_SETEXPANDED, TRUE, lpData);
}
return 0;
}
// returns an empty string u16_PathOut if an error occurrs or if the user cancels the dialog
void Func::GetOpenFolder(HWND h_Owner,
const WCHAR* u16_Title, // IN: Title at the top of dialog
int s32_CsidlRoot, // IN: Root folder for treeview (CSIDL_DRIVES -> My Computer)
const WCHAR* u16_Preselect, // IN: NULL or the folder to be preselected and expanded
WCHAR* u16_PathOut) // OUT: selected path
{
u16_PathOut[0] = 0;
// CoInitialize(NULL);
// InitCommonControls();
ITEMIDLIST* pk_RootPIDL = NULL; // NULL -> Root = Desktop
SHGetSpecialFolderLocation(h_Owner, s32_CsidlRoot, &pk_RootPIDL);
BROWSEINFOW k_Info = {0};
k_Info.hwndOwner = h_Owner;
k_Info.pidlRoot = pk_RootPIDL;
k_Info.lpszTitle = u16_Title;
k_Info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
if (u16_Preselect)
{
k_Info.lpfn = FolderBrowserCallback;
k_Info.lParam = (LPARAM)u16_Preselect;
}
// DO NOT DISABLE Wow64FsRedirection HERE !!
LPITEMIDLIST pk_IDlist = SHBrowseForFolderW(&k_Info);
if (pk_IDlist)
{
SHGetPathFromIDListW(pk_IDlist, u16_PathOut);
CoTaskMemFree(pk_IDlist);
}
CoTaskMemFree(pk_RootPIDL);
}