下面的例子中返回路径,如果没有选,返回"",选择了路径,则返回选择的路径。
char *GetPath(HWND hWnd,char *pBuffer)
{
BROWSEINFO bf;
LPITEMIDLIST lpitem;
memset(&bf,0,sizeof BROWSEINFO);
bf.hwndOwner=hWnd;
bf.lpszTitle="选择路径";
bf.ulFlags=BIF_RETURNONLYFSDIRS; //属性你可自己选择
lpitem=SHBrowseForFolder(&bf);
if(lpitem==NULL) //如果没有选择路径则返回 0
return "";
//如果选择了路径则复制路径,返回路径长度
SHGetPathFromIDList(lpitem,pBuffer);
return pBuffer;
}
下面我们来解释一下这个函数用到的一些值的含义。
1. BROWSEINFO
它是一个结构, 原型是
typedef struct _browseinfo {
HWND hwndOwner; // 弹出的dialog的父窗体的句柄
LPCITEMIDLIST pidlRoot; // 指向一个ITEMIDLIST的指针,我们会在后边介绍ITEMIDLIST结构,可空
LPSTR pszDisplayName; // 指向一个buffer,这个buffer用来存放用户选中的目录,buffer的size为MAX_PATH
LPCSTR lpszTitle; //指向一个非空的string,用来显示树目录之上的指示信息
UINT ulFlags; // 指出了显示的文件夹的类型
BFFCALLBACK lpfn; //简单的记为NULL
LPARAM lParam; // 当lpfn不为空时,把dialogbox的值传给回调函数lpfn
int iImage; // 系统的图标list的索引,当用户选中目录的时候,得到这个索引
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
ulFlags的可能取值为:
BIF_BROWSEFORCOMPUTER ——只返回"我的电脑",当选中"我的电脑"之外的目录时,OK键为灰色
BIF_BROWSEFORPRINTER ——只返回"打印机",当选中"打印机"之外的目录时,OK键为灰色
BIF_DONTGOBELOWDOMAIN ——不包括"网上邻居"
BIF_RETURNFSANCESTORS ——只返回"我的文件",当选中"我的文件"之外的目录时,OK键为灰色
BIF_RETURNONLYFSDIRS ——同上
BIF_STATUSTEXT ——Includes a status area in the dialog box. The callback can set the status text by sending messages to the dialog box.
2. ITEMIDLIST
是一个结构,指明了默认浏览的根文件夹的位置,可以为空,那样的话,默认为桌面文件夹的文件目录.
原型为
typedef struct _ITEMIDLIST
{
SHITEMID mkid; // list of item identifers
} ITEMIDLIST, * LPITEMIDLIST;
typedef const ITEMIDLIST * LPCITEMIDLIST;
3. SHGetPathFromIDList函数
原型是
WINSHELLAPI BOOL WINAPI SHGetPathFromIDList(
LPCITEMIDLIST pidl,
LPSTR pszPath
);
反正记住配套使用就行了,哈哈~~
如果是在bcb环境中使用,那么如果提示不能识别BROWSEINFO,则需加入头文件#i nclude <ShellAPI.h>
,然后在对应的.cpp的include之前#define NO_WIN32_LEAN_AND_MEAN
另一解析:
LPITEMIDLIST Dir2Pidl(AnsiString &str) short int __fastcall SelectDir(HANDLE HDL, AnsiString &S) void __fastcall TForm1::Button3Click(TObject *Sender) |
总结:
显示一个用于选择文件夹的对话框.
语法
PIDLIST_ABSOLUTE SHBrowseForFolder(
LPBROWSEINFO lpbi
);
参数
lpbi
[in] 一个指向BROWSEINFO结构的指针,该指针包含了文件夹选择对话框显示的信息。
返回值
Returns a pointer to an item identifier list (PIDL) that specifies the location of the selected folder relative to the root of the namespace. If the user chooses the Cancel button in the dialog box, the return value is NULL.
It is possible that the PIDL returned is that of a folder shortcut rather than a folder. For a full discussion of this case, see the Remarks section.
===========================我的源码======================================================
CString CDlgLocalConfig::GetDirectoryPath()
{
LPITEMIDLIST pidlRoot=NULL;
SHGetSpecialFolderLocation(m_hWnd,CSIDL_DRIVES,&pidlRoot);
BROWSEINFO bi; //必须传入的参数,下面就是这个结构的参数的初始化
CString strDisplayName; //用来得到,你选择的活页夹路径,相当于提供一个缓冲区
bi.hwndOwner=GetSafeHwnd(); //得到父窗口Handle值
bi.pidlRoot=pidlRoot; //这个变量就是我们在上面得到的.
bi.pszDisplayName=strDisplayName.GetBuffer(MAX_PATH+1); //得到缓冲区指针
char szLan[32] = {0};
g_StringLanType(szLan, "文件夹", "Directory");
bi.lpszTitle=szLan; //设置标题
bi.ulFlags=BIF_RETURNONLYFSDIRS; //设置标志
bi.lpfn=NULL;
bi.lParam=0;
bi.iImage=0; //上面这个是一些无关的参数的设置,最好设置起来,
LPITEMIDLIST lpIDList= SHBrowseForFolder(&bi); //打开对话框
strDisplayName.ReleaseBuffer(); //和上面的GetBuffer()相对应
char pPath[MAX_PATH];
CString Str;
if (lpIDList)
{
SHGetPathFromIDList (lpIDList, pPath);
Str=pPath;
}
return Str;
}
SHGetPathFromIDList
功能是把项目标志符列表转换为文件系统路径:
BOOL SHGetPathFromIDList(
LPCITEMIDLIST pidl,
LPSTR pszPath
);
参数:
pidl---相对 namespace 的根指定一个文件或目录地点的一张项目标识符表的地址 ( 桌面 ) ;
pszPath---接收文件系统路径的缓冲地址,大小至少是MAX_PATH的字符长度