I have this call:
oShell.BrowseForFolder(Me.hwnd, "Select path:", 0, "C:\dir\")
This opens a standard file browser dialog with "C:\dir\" as root.
My problem is that you can not browse above the root folder. (as specified in doc http://msdn.microsoft.com/en-us/library/bb774065(v=vs.85).aspx)
Any suggestions on oppening this dialog with a selected path and full browsing posibility?
Thanks
The way to do this involves calling the underlying API, SHBrowseForFolder()
.
Since you want the entire shell namespace to be available you need to pass NULL
as pidlRoot
. In order to select your desired folder you will need to provide a callback in lpfn
. Make this callback respond to BFFM_INITIALIZED
by setting the selected folder. This selection is performed by sending the BFFM_SETSELECTION
message to the dialog's window handle (passed to the callback function).
No code because I don't have VB6, but hopefully this outline of the method is enough to get you on your way.
Karl E Peterson's excellent website contains a sample which demonstrates the API call SHBrowseForFolder
with a callback, as in David Heffernan's answer.
The KeyStuff project
Look at MFolderBrowse.bas
, routine BrowseForFolderByPIDL
which passes a callback function BrowseCallbackProc
.
Try the old CCRP project. It has a nicely done implementation of the Browse dialog. I used it in several of my projects and it has properties to address the issue you are having.
Here a code ready for copy and paste in a C++ class:
// 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);
}