一、数据结构
VC中目录选择对话框使用如下函数打开:
PIDLIST_ABSOLUTE SHBrowseForFolder( LPBROWSEINFO lpbi );
其中,LPBROWSEINFO是一个结构:
typedef struct _browseinfo {
HWND hwndOwner;
PCIDLIST_ABSOLUTE pidlRoot;
LPTSTR pszDisplayName;
LPCTSTR lpszTitle;
UINT ulFlags;
BFFCALLBACK lpfn;
LPARAM lParam;
int iImage;
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
该结构参数的具体含义见MSDN。
二、使用方法:
BROWSEINFO bi;
WCHAR szPathName[MAX_PATH];
//初始化参数
SecureZeroMemory(&bi, sizeof(BROWSEINFO)); //清0
//bi.pidlRoot = ParsePidlFromPath("C://"); //设置选择的根目录,如“C://”则只能选C盘的目录
bi.hwndOwner = GetSafeHwnd(); //父窗口句柄
bi.pszDisplayName = szPathName; //保存路径的buffer
bi.lpszTitle = L"浏览文件夹"; //标题
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_VALIDATE; //对话框显示模式
//调用显示选择对话框
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if(pidl)
{
SHGetPathFromIDList(pidl, szPathName); //获取全路径
GetDlgItem(IDC_EDIT_INFO)->SetWindowText(szPathName);
//检查选择是否有错
CString szErrMsg;
if(_wchdir(szPathName)) //changing the current working directory.
{
switch(errno)
{
case ENOENT:
szErrMsg = "Unable to locate the directory: ";
szErrMsg += szPathName;
break;
case EINVAL:
szErrMsg = "Invalid buffer.";
break;
default:
szErrMsg = "Unknown error.";
}
}
MessageBox(szErrMsg, L"Error", MB_ICONERROR | MB_OK);
//释放内存
LPMALLOC pMalloc;
if(SUCCEEDED(SHGetMalloc(&pMalloc)))
{
pMalloc->Free(pidl);
pMalloc->Release();
}
}
三、限定目录
也就是限制用户只能从哪个目录下选择目录(子目录)。将二中如下语句注释去掉:
//bi.pidlRoot = ParsePidlFromPath("C://"); //设置选择的根目录,如“C://”则只能选C盘的目录
增加如下函数:
//文件目录转成LPITEMIDLIST
LPITEMIDLIST CTestToolsDlg::ParsePidlFromPath(LPCSTR lpszPath)
{
OLECHAR olePath[MAX_PATH];
LPSHELLFOLDER pDesktopFolder;
LPITEMIDLIST pidl;
ULONG ulEaten, ulAttribs;
HRESULT hres;
SHGetDesktopFolder(&pDesktopFolder);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, lpszPath, -1, olePath, sizeof(olePath));
hres = pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &ulEaten, &pidl, &ulAttribs);
hres = pDesktopFolder->Release();
if(FAILED(hres))
return NULL;
return pidl;
}
之所以使用该函数是因为BROWSEINFO结构的pidlRoot参数只支持LPITEMIDLIST,不支持字符串。
参考文献:
http://blogger.org.cn/blog/more.asp?name=joinclear&id=15268
http://www.anqn.com/dev/vc-c++/a/2005-08-31/a52730.shtml