#include
#include
#include
using namespace std;
string chooseFile(void) {
//用户选择的路径,可以是TCHAR szBuffer[MAX_PATH] = {0};然后再使用TCHAR 转char字符串,此处可以直接使用char数组类型
char dir[MAX_PATH];
BROWSEINFO bi;
ZeroMemory(&bi,sizeof(BROWSEINFO));
ITEMIDLIST *ppidl;
//设置根目录
SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &ppidl);
//常用有CSIDL_DESKTOP(桌面)CSIDL_PROGRAMS(开始菜单)CSIDL_MYMUSIC(我的音乐)CSIDL_DRIVES(盘符)
bi.hwndOwner = NULL; //父窗口句柄,通常通过AfxGetMainWnd()->GetSafeHwnd()函数获取安全的句柄。
bi.pidlRoot = ppidl; //文件夹的根目录,此处为桌面CSIDL_DESKTOP;
// pidlRoot:显示的文件目录对话框的根(Root),一般设置为NULL
bi.pszDisplayName = dir; //保存被选取的文件夹路径的缓冲区
bi.lpszTitle = NULL; //显示位于对话框左上部的标题。
bi.ulFlags = BIF_BROWSEINCLUDEFILES | BIF_EDITBOX ;//指定对话框的外观和功能的标志
// bi.ulFlags= BIF_NEWDIALOGSTYLE;
//获取程序路径
string defaultPath = "";
if ("" != beforeChooseFilePath) {
defaultPath = beforeChooseFilePath;
} else {
char buffer[MAX_PATH];
GetModuleFileName( NULL, buffer, MAX_PATH);
defaultPath = buffer;
if (defaultPath.find("\\") != string::npos) {
int lastIndex = defaultPath.find_last_of("\\");
defaultPath = defaultPath.substr(0, lastIndex);
}
}
//回调函数,设置默认打开文件夹路径
bi.lpfn = BrowseCallbackProc;
bi.lParam = (LPARAM) (defaultPath.data());
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
SHGetPathFromIDList(idl, dir);
if (idl && SHGetPathFromIDList(idl, dir)) {
string strDir = dir;
return strDir;
}
return "";
}
int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /*lParam*/,
LPARAM lpData) {
if (uMsg == BFFM_INITIALIZED) {
//(LPARAM)"D:\\remote"--指定初始目录 BFFM_SETSELECTION(指向目录)
SendMessage(hwnd, BFFM_SETSELECTION, (WPARAM) TRUE, (LPARAM) lpData);
}
return 0;
}
BROWSEINFO结构中包含有用户选中目录的重要信息。
typedef struct_browseinfo
{
HWND hwndOwner;
LPCITEMIDLIST pidlRoot;
LPSTR pszDisplayName;
LPCSTR lpszTitle;
UINT ulFlags;
BFFCALLBACK lpfn;
LPARAM lParam;
int iImage;
}BROWSEINFO,*PBROWSEINFO,*LPBROWSEINFO;
hwndOwner
类型:HWND
对话框的所有者窗口的句柄。
pidlRoot
类型: PCIDLIST_ABSOLUTE
一个 PIDL,指定要从中开始浏览的根文件夹的位置。 只有命名空间层次结构中的指定文件夹及其子文件夹才会显示在对话框中。 此成员可以为 NULL;在这种情况下,将使用默认位置。
pszDisplayName
类型: LPTSTR
指向缓冲区的指针,用于接收用户选择的文件夹的显示名称。 此缓冲区的大小假定为MAX_PATH字符。
lpszTitle
类型: LPCTSTR
指向对话框中树视图控件上方显示的空终止字符串的指针。 此字符串可用于指定用户的说明。
ulFlags
类型: UINT
指定对话框选项的标志。 此成员可以是 0 或以下值的组合。 版本号是指 SHBrowseForFolder 识别在更高版本中添加的标志所需的最低Shell32.dll版本。 有关详细信息,请参阅 Shell 和 Common Controls 版本 。
BIF_RETURNONLYFSDIRS (0x00000001)
0x00000001。 仅返回文件系统目录。 如果用户选择不属于文件系统的文件夹,则 “确定 ”按钮灰显。
注意 “ 确定 ”按钮仍为“\\server”项以及“\\server\share”和目录项启用。 但是,如果用户选择“\\server”项,将 SHBrowseForFolder 返回的 PIDL 传递给 SHGetPathFromIDList 失败。
BIF_DONTGOBELOWDOMAIN (0x00000002)
0x00000002。 不要在对话框的树视图控件中包含域级别下面的网络文件夹。
BIF_STATUSTEXT (0x00000004)
0x00000004。 在对话框中包括状态区域。 回调函数可以通过将消息发送到对话框来设置状态文本。 指定BIF_NEWDIALOGSTYLE时不支持此标志。
BIF_RETURNFSANCESTORS (0x00000008)
0x00000008。 仅返回文件系统上级。 上级是命名空间层次结构中根文件夹下的子文件夹。 如果用户选择不属于文件系统的根文件夹的上级文件夹,则 “确定 ”按钮灰显。
BIF_EDITBOX (0x00000010)
0x00000010。 版本 4.71。 在浏览对话框中包括一个编辑控件,该控件允许用户键入项的名称。
BIF_VALIDATE (0x00000020)
0x00000020。 版本 4.71。 如果用户在编辑框中键入无效的名称,则浏览对话框会使用BFFM_VALIDATEFAILED消息调用应用程序的 BrowseCallbackProc。 如果未指定BIF_EDITBOX,则忽略此标志。
BIF_NEWDIALOGSTYLE (0x00000040)
0x00000040。 版本 5.0。 使用新的用户界面。 设置此标志为用户提供可以调整大小的较大对话框。 该对话框具有多种新功能,包括:对话框中的拖放功能、重新排序、快捷菜单、新文件夹、删除和其他快捷菜单命令。
注意 如果 COM 通过 CoInitializeEx 初始化并设置了COINIT_MULTITHREADED标志,则如果传递BIF_NEWDIALOGSTYLE, SHBrowseForFolder 将失败。
BIF_BROWSEINCLUDEURLS (0x00000080)
0x00000080。 版本 5.0。 浏览对话框可以显示 URL。 还必须设置BIF_USENEWUI和BIF_BROWSEINCLUDEFILES标志。 如果未设置这三个标志中的任何一个,浏览器对话框将拒绝 URL。 即使设置了这些标志,浏览对话框也仅当包含所选项的文件夹支持 URL 时显示 URL。 当调用文件夹的 IShellFolder::GetAttributesOf 方法以请求所选项的属性时,该文件夹必须设置 SFGAO_FOLDER 属性标志。 否则,浏览对话框将不会显示 URL。
BIF_USENEWUI
版本 5.0。 使用新的用户界面,包括编辑框。 此标志等效于BIF_EDITBOX |BIF_NEWDIALOGSTYLE。
注意 如果 COM 通过 CoInitializeEx 初始化并设置了COINIT_MULTITHREADED标志,则如果传递BIF_USENEWUI, SHBrowseForFolder 将失败。
BIF_UAHINT (0x00000100)
0x00000100。 版本 6.0。 与BIF_NEWDIALOGSTYLE结合使用时,请将使用提示添加到对话框,代替编辑框。 BIF_EDITBOX重写此标志。
BIF_NONEWFOLDERBUTTON (0x00000200)
0x00000200。 版本 6.0。 不要在浏览对话框中包括 “新建文件夹 ”按钮。
BIF_NOTRANSLATETARGETS (0x00000400)
0x00000400。 版本 6.0。 当所选项是快捷方式时,返回快捷方式本身的 PIDL 而不是其目标。
BIF_BROWSEFORCOMPUTER (0x00001000)
0x00001000。 仅返回计算机。 如果用户选择计算机之外的任何内容,“确定”按钮就会变灰。
BIF_BROWSEFORPRINTER (0x00002000)
0x00002000。 仅允许选择打印机。 如果用户选择打印机之外的任何内容,“确定”按钮就会变灰。
在 Windows XP 和更高版本中,最佳做法是使用 Windows XP 样式对话框,将对话框的根设置为 打印机和传真 文件夹 (CSIDL_PRINTERS) 。
BIF_BROWSEINCLUDEFILES (0x00004000)
0x00004000。 版本 4.71。 “浏览”对话框显示文件和文件夹。
BIF_SHAREABLE (0x00008000)
0x00008000。 版本 5.0。 浏览对话框可以在远程系统上显示可共享资源。 这适用于希望在本地系统上公开远程共享的应用程序。 还必须设置BIF_NEWDIALOGSTYLE标志。
BIF_BROWSEFILEJUNCTIONS (0x00010000)
0x00010000。 Windows 7 及更高版本。 允许浏览具有.zip文件扩展名的文件夹交接点(如库或压缩文件)。
lpfn
类型: BFFCALLBACK
指向对话框在事件发生时调用的应用程序定义函数的指针。 有关详细信息,请参阅 BrowseCallbackProc 函数。 此成员可以为 NULL。
lParam
类型: LPARAM
对话框传递给回调函数的应用程序定义值(如果在 lpfn 中指定)。
iImage
类型: int
一个整数值,该值接收与所选文件夹关联的图像的索引,存储在系统映像列表中。
最低受支持的客户端 | Windows XP、Windows 7 [仅限桌面应用] |
最低受支持的服务器 | Windows 2000 Server [仅限桌面应用] |
标头 | shlobj_core.h (包括 Shlobj.h、Shlobj_core.h) |
指定一个应用程序定义的回调函数,用于向在调用SHBrowseForFolder时显示的Browse对话框发送消息,并从该对话框处理消息
typedef int ( CALLBACK *BrowseCallbackProc)( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData );
hwnd
类型:HWND
浏览对话框的窗口句柄。
uMsg
类型:UINT
生成消息的对话框事件。下列值之一。
BFFM_INITIALIZED
对话框已完成初始化。
BFFM_IUNKNOWN
对话框可使用IUnknown接口。
BFFM_SELCHANGED
对话框中的选择已更改。
BFFM_VALIDATEFAILED
用户在对话框的编辑框中输入了无效的名称。不存在的文件夹被认为是无效的名称。
lParam
类型:LPARAM
该值的含义取决于uMsg中指定的事件,如下所示:
uMsg | lParam |
---|---|
BFFM_INITIALIZED | 未使用,值为NULL。 |
BFFM_IUNKNOWN | 指向IUnknown接口的指针。 |
BFFM_SELCHANGED | 标识新选择项的PIDL。 |
BFFM_VALIDATEFAILED | 指向包含无效名称的字符串的指针。应用程序可以在错误对话框中使用此数据,通知用户该名称无效。 |
lpData
类型:LPARAM
一个应用程序定义的值,在调用SHBrowseForFolder时使用的BROWSEINFO结构的lParam成员中指定。
类型:int
返回0,除非bffm_validatfailed。对于该标志,返回0以取消对话框,或返回非0以保持对话框的显示。
要将BrowseCallbackProc附加到对话框,请在SHBrowseForFolder调用中使用的BROWSEINFO结构的lpfn成员中指定它的地址。
BrowseCallbackProc也可以通过SendMessage向对话框发送消息,来控制这些方面:
OK按钮启用/禁用
OK按钮文本
所选文件夹
扩展文件夹
状态文本
将SendMessage函数的Msg参数设置为以下值之一,为每种消息类型在wParam和lParam参数中提供附加信息
Msg | Meaning | wParam | lParam |
---|---|---|---|
BFFM_ENABLEOK | 启用或禁用对话框的OK按钮。 | Not used. | 若要启用,请设置为非零值。若要禁用,请设置为0。 |
BFFM_SETOKTEXT | Version 6.0 or later. Sets the text that is displayed on the dialog box's OK button.6.0或更高版本。设置对话框的OK按钮上显示的文本。 | Not used. | 指向包含所需文本的以空结束的Unicode字符串的指针。 |
BFFM_SETSELECTION | 指定要选择的文件夹的路径。路径可以指定为字符串或PIDL。 | TRUE表示使用字符串;FALSE表示使用PIDL。 | 指定路径的字符串或PIDL。 |
BFFM_SETEXPANDED | Version 6.0 or later. Specifies the path of a folder to expand in the Browse dialog box. The path can be specified as a Unicode string or a PIDL.6.0或更高版本。指定要在“浏览”对话框中展开的文件夹的路径。路径可以指定为Unicode字符串或PIDL。 | TRUE to use a string; FALSE to use a PIDL. | 指定路径的字符串或PIDL。 |
BFFM_SETSTATUSTEXT | 设置状态文本。将BrowseCallbackProc lpData参数设置为指向一个以空结束的字符串,其中包含所需的文本。 | Not used. | 指向包含所需文本的以空结束的字符串的指针。 |