我正在使用SHBrowseForFolder和新的对话框样式,它为您提供了“创建新文件夹”按钮
我在Windows XP中遇到了一些问题。
行为是这样的:
1)首先,当我调用对话框时,行为是正常的(即,它正在选择当前文件夹。但是 焦点不在树项上(变暗)。
如果单击“使用此状态创建新文件夹”按钮,则会创建一个新文件夹,但该文件夹未处于选中状态 状态(即,当我们创建一个新文件夹时,它允许您重命名选择文件夹 项目和编辑框)。
如果我选择目录(即,将焦点设置为项目),然后单击新文件夹创建文件夹 处于选定状态。 (在Windows 8,Windows 7和Windows Vista中它工作正常) 任何人都遇到了这个问题。
有没有解决方案?
bool GetFolder(std::string& folderpath, const char* szCaption = NULL, HWND hOwner = NULL)
{ bool retVal = false;
// The BROWSEINFO struct tells the shell
// how it should display the dialog.
BROWSEINFO bi;
memset(&bi, 0, sizeof(bi));
bi.ulFlags = BIF_NEWDIALOGSTYLE|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
bi.hwndOwner = hOwner;
bi.lpszTitle = szCaption;
// must call this if using BIF_USENEWUI
::OleInitialize(NULL);
// Show the dialog and get the itemIDList for the selected folder.
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
if(pIDL != NULL)
{
// Create a buffer to store the path, then get the path.
char buffer[_MAX_PATH] = {'\0'};
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
{
// Set the string value.
folderpath = "";
retVal = true;
}
// free the item id list
CoTaskMemFree(pIDL);
}
::OleUninitialize();
return retVal;
}
答案 0 :(得分:0)
这似乎是Windows XP中的一个错误。
尝试以下代码。这可能不是您想要的,它会自动扩展默认文件夹,但至少会导致或多或少的正确行为。我在Windows XP和Windows 7上测试过它。在Windows的更高版本中,这可能无法按预期工作,因此您可能应该检查您是否在XP下运行并且只有在XP下运行时才会这样做。
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM pData)
{
if (uMsg == BFFM_INITIALIZED)
{
HWND hchild = GetWindow(hWnd, GW_CHILD) ;
while (hchild != NULL)
{
TCHAR classname[200] ;
GetClassName(hchild, classname, 200) ;
if (lstrcmp(classname, "SHBrowseForFolder ShellNameSpace Control") == 0)
{
// hchild is the handle to the ShellName Space Control
HWND hlistctrl = GetWindow(hchild, GW_CHILD) ;
do
{
// browse through all controls of the ShellnameSpace control
GetClassName(hlistctrl, classname, 200) ;
if (lstrcmp(classname, "SysTreeView32") == 0)
break ; // we've got the list control
hlistctrl = GetWindow(hlistctrl, GW_HWNDNEXT) ;
} while (hlistctrl != NULL) ;
if (hlistctrl != NULL)
{
// get the handle to the selected item
HTREEITEM ht = (HTREEITEM)::SendMessage(hlistctrl, TVM_GETNEXTITEM, TVGN_CARET, 0) ;
if (ht != NULL)
{
// expand the selected item
::SendMessage(hlistctrl, TVM_EXPAND, TVE_EXPAND, (LPARAM)ht) ;
}
}
}
hchild = GetWindow(hchild, GW_HWNDNEXT) ;
}
}
return 0;
}
bool GetFolder(CString& folderpath, const char* szCaption, HWND hOwner)
{
bool retVal = false;
// how it should display the dialog.
BROWSEINFO bi;
memset(&bi, 0, sizeof(bi));
bi.ulFlags = BIF_NEWDIALOGSTYLE|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
bi.lpfn = BrowseCallbackProc ;
bi.hwndOwner = hOwner;
bi.lpszTitle = szCaption;
// must call this if using BIF_USENEWUI
::OleInitialize(NULL);
// Show the dialog and get the itemIDList for the selected folder.
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
if (pIDL != NULL)
{
// Create a buffer to store the path, then get the path.
char buffer[_MAX_PATH] = {'\0'};
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
{
// Set the string value.
folderpath = buffer;
retVal = true;
}
// free the item id list
CoTaskMemFree(pIDL);
}
::OleUninitialize();
return retVal;
}
另一种解决方案是使用BFFM_SETEXPANDED消息,如下所示。在此示例中,“C:”文件夹自动展开,然后“新建文件夹”按钮的行为正确。
int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM pData)
{
if (uMsg == BFFM_INITIALIZED)
{
::SendMessage(hWnd, BFFM_SETEXPANDED, TRUE, (LPARAM)L"C:\\") ;
}
return 0;
}