1、 SHBrowseForFolder函数(SHBrowseForFolder function)
最简单的方式是使用SHBrowseForFolder函数。它的参数只有一个结构体BROWSEINFO。定义在头文件shlobj.h中。成员变量有:hwndOwner:浏览文件夹对话框的父窗体句柄;pidlRoot:ITEMIDLIST结构的地址,包含浏览时的初始根目录。当设置为NULL时根目录为桌面。pszDisplayName:用来保存用户选中的目录字符串的内存地址。该缓冲区的大小缺省是定义的MAX_PATH常量宏。lpszTitle:该浏览文件夹对话框对话框的显示文本,用来提示该浏览文件夹对话框的功能、作用和目的。ulFlags:该标志位描述了对话框的选项。在新升级的版本中,针对windows vista及以上版本,添加了新的对话框形式及功能,包括新建文件夹等等。lpfn:应用程序定义的浏览对话框回调函数的地址。当对话框中的事件发生时,该对话框将调用回调函数。可以为NULL。lParam:对话框传递给回调函数的一个参数指针。iImage:与选中目录相关的图像。该图像将被指定为系统图像列表中的索引值。
一个简单地例子:
//旧版的对话框
void__fastcall TForm::Button1Click(TObject *Sender)
{
BROWSEINFO bi;
char SelectedDir[MAX_PATH];
char *p1 = SelectedDir;
LPITEMIDLIST ItemID;
memset(p1, 0, MAX_PATH);
memset(&bi, 0, sizeof(BROWSEINFO));
bi.hwndOwner = Application->Handle;
bi.pszDisplayName = p1;//FolderName.c_str();
bi.lpszTitle = "请选择源目录";
bi.ulFlags=BIF_RETURNONLYFSDIRS ;
bi.lpfn = NULL;
bi.lParam = 0;
ItemID = SHBrowseForFolder(&bi); // 调用函数,打开目录选择对话框
if(ItemID)
{
SHGetPathFromIDList(ItemID, p1); // 获取所选目录的全名
Edit1->Text = SelectedDir;
GlobalFree(ItemID); // 释放
}
}
//新版对话框
void__fastcall TForm::Button2Click(TObject *Sender)
{
BROWSEINFO bi;
...
bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS| BIF_NEWDIALOGSTYLE ;
...
}.
2、 IFileOpen接口
在MSDN中介绍SHBrowseForFolder函数时提到:
For Windows Vista or later, it is recommended that you useIFileDialog with the FOS_PICKFOLDERS option rather than the SHBrowseForFolderfunction. This uses the Open Files dialog in pick folders mode and is thepreferred implementation.
据此,我们尝试使用IFileDialog接口来制作对话框。
IFileDialog 接口继承IModalWindow.接口,因此可以使用Show方法来显示对话框。IFileDialog接口有一个方法是SetOptions,用来控制对话框的形式,其中的FOS_PICKFOLDERS (0x00000020)用来设置对话框选择文件夹而不是文件。
例子:
void__fastcall TForm3::Button5Click(TObject *Sender)
{
//需要头文件#include<ShObjIdl.h>
IFileOpenDialog *pFileOpen;
HRESULThr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,__uuidof(IFileOpenDialog), reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr)) {
hr =pFileOpen->SetOptions(FOS_PICKFOLDERS);//浏览文件夹模式
if (SUCCEEDED(hr)) {
hr =pFileOpen->Show(Application->Handle);
if (SUCCEEDED(hr)) {
IShellItem *psiResult;
hr =pFileOpen->GetResult(&psiResult);
if (SUCCEEDED(hr))
{
PWSTRpszFilePath = NULL;
hr =psiResult->GetDisplayName(SIGDN_FILESYSPATH,&pszFilePath);
if(SUCCEEDED(hr))Edit1->Text = pszFilePath;
psiResult->Release();
}
}
}
pFileOpen->Release();
}
pFileOpen->Release();
}
参考:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762115(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205(v=vs.85).aspx
http://baike.baidu.com/view/1977841.htm
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775966(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761832(v=vs.85).aspx