
使用SHBrowseForFolder函数打开文件目录对话框
自从第一份工作辞职以来,我已经在MFC上工作了三年以上. 我真的忘记了Microsoft的Windows桌面开发. 这次我收到了一个任务,需要开发一个小工具. 尽管任务很小,但是我遇到了一个小问题,即如何打开文件目录对话框. 尽管我通过Internet找到了解决方案,但是Internet上有太多文章太耗时,因此我花一点时间来总结一下. 尽管它简单易用,但无需过多扩展,只需标记一下您自己即可.
关于SHBrowseForFolder函数和简单易用
要打开文件目录对话框,我发现的方法是使用SHBrowseForFolder函数. 此函数的原型是LPITEMIDLISTSHBrowseForFolder(LPBROWSEINFO lpbi). 该函数很简单,只是一个返回值和一个参数. 参数简单列出如下
typedef struct _browseinfo {
HWNDhwndOwner; //父窗口句柄
LPCITEMIDLISTpidlRoot; //要显示的文件目录对话框的根目录
LPTSTR pszDisplayName; //缓冲区以保存选定的文件夹路径
LPCTSTRlpszTitle; //在对话框的左上方显示标题
UINTulFlags; //用于指定对话框外观和功能的标志
BFFCALLBACKlpfn; //处理事件的回调函数
LPARAMlParam; //应用程序传递给回调函数的参数
intiImage; //文件夹对话框的图片索引
} BROWSEINFO,* PBROWSEINFO,* LPBROWSEINFO
通常,可以将父窗口句柄(hwndOwner)和根(pidlRoot)设置为Null,pszDisplayName设置MAX_PATH大小缓冲区,与显示相关的参数是对话框提示标题(lpszTitle),样式(ulFlags),设置对话框默认路径(lpfn和lParam)的操作,以及显示在对话框任务栏上的图标(iImage).
由于返回值LPITEMIDLIST是指向ITEMIDLIST的指针,因此该ITEMIDLIST与WindowsShell中有关管理对象(例如文件,网络上的计算机,控制面板程序,回收站等)的知识点有关. WindowsShell旨在识别每个特定对象对象使用ITEMID来唯一标识和区分它们,而ITEMIDLIST是完整的对象路径. 显然,此功能可用于浏览非文件对象,例如局域网中的计算机等. 这里LPITEMIDLIST返回的对象路径是文件夹的路径. Windows提供了一个函数BOOLSHGetPathFromIDList(LPCITEMIDLIST pidl,LPSTRpszPath)来实现从属对象. 路径被转换为文件夹路径.
此处应注意,此返回值是通过调用IMallocInterface分配的,该函数不负责释放内存操作,因此在使用此返回值之后,我们必须通过IMallocInterface释放内存.
最简单的代码在下面给出
BROWSEINFObi;
charBuffer [MAX_PATH];
//初始化入口参数bi的初始化
bi.hwndOwner = NULL;

bi.pidlRoot = NULL; //初始化指定的根目录并不容易
bi.pszDisplayName =缓冲区; //如果此参数为NULLfly文件怎么打开,则无法显示该对话框
bi.lpszTitle =“选择Sis目标文件路径”;
bi.ulFlags = BIF_EDITBOX; //带有编辑框的样式
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = IDR_MAINFRAME;
//初始化输入参数bi的结束
LPITEMIDLISTpIDList = SHBrowseForFolder(&bi); //呼叫显示选择对话框
如果(pIDList)
{
SHGetPathFromIDList(pIDList,缓冲区);
//获取Buffer的文件夹路径
CStringm_cSisDes =缓冲区; //将路径保存在CString对象中
}
UpdateData(FALSE);
//已使用的可用内存
IMalloc * imalloc = 0;
如果(成功(SHGetMalloc(&imalloc)))
{
imalloc->免费(pIDList);
imalloc->版本();

}
上面的代码可以显示最简单的浏览文件夹对话框fly文件怎么打开,并为我的计算机实际选择编辑框.
创建一个浏览文件夹对话框,该对话框可以创建一个新文件夹并指定所选的初始路径
由于在实践中我需要一个带有新文件夹功能并指定初始选定路径的浏览文件夹对话框,因此将此要求作为扩展应用程序使用. 因为对话框样式由ulFlags标记确定,所以系统头文件SHLOBJ.h中给出的对话框样式仅如下所示:
//浏览目录.
#define BIF_RETURNONLYFSDIRS0x0001 //用于查找文件夹以开始文档搜索
#define BIF_DONTGOBELOWDOMAIN0x0002 //用于启动查找计算机
#define BIF_STATUSTEXT0x0004
#define BIF_RETURNFSANCESTORS0x0008
#define BIF_EDITBOX0x0010
#define BIF_VALIDATE0x0020 //坚持有效的结果(或取消)
#define BIF_BROWSEFORCOMPUTER0x1000 //浏览计算机.
#define BIF_BROWSEFORPRINTER0x2000 //浏览打印机
#define BIF_BROWSEINCLUDEFILES 0x4000 //浏览所有内容
没有符合我需求的风格. 我通过csdn发现,实际上有一个样式值0x40支持创建新文件夹的功能. 通常,网络上的宏是BIF_NEWDIALOGSTYLE和BIF_USENEWUI. 由于我们不知道哪个特定的头文件,因此您可以自己在代码中定义这两个宏,如下所示
#define BIF_NEWDIALOGSTYLE0x40
#define BIF_USENEWUI(BIF_NEWDIALOGSTYLE | BIF_EDITBOX)
这样,解决了第一个问题,因此如何使对话框具有最初选择的文件夹路径. 起初,我考虑过pidlRoot,但结果是鼻子灰白了. 原始文件夹路径是最初设置的. 它是通过魔术回调函数实现的. 换句话说,就像调用CDialog :: DoModal()函数一样,调用SHBrowseForFolder. 该对话框中类似操作的具体实现是lpfn. 实现了该回调函数.
下面给出了此简单扩展的代码
#define BIF_NEWDIALOGSTYLE0x40
intCALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAMlParam,LPARAM lpData)
{

如果(uMsg == BFFM_INITIALIZED)
{
SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);
}
return0;
}
voidCSisAppendMidDlg :: OnButtonSisdes()
{
// TODO: 在此处添加您的控制通知处理程序代码
BROWSEINFObi;
charBuffer [MAX_PATH];
//初始化入口参数bi的初始化
bi.hwndOwner = NULL;
bi.pidlRoot = NULL; //初始化指定的根目录并不容易
bi.pszDisplayName =缓冲区; //如果此参数为NULL,则无法显示该对话框
bi.lpszTitle =“选择Sis目标文件路径”;
bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE;
CFileFindfinder;
if(finder.FindFile(m_cSisDes)== FALSE)
{
bi.lParam = 0;
bi.lpfn = NULL;

}
其他
{
bi.lParam =(long)(m_cSisDes.GetBuffer(m_cSisDes.GetLength())); //初始化路径,格式为(_T(“ c: \\ Symbian”));
bi.lpfn = BrowseCallbackProc;
}
finder.Close();
bi.iImage = IDR_MAINFRAME;
//初始化输入参数bi的结束
LPITEMIDLISTpIDList = SHBrowseForFolder(&bi); //呼叫显示选择对话框
如果(pIDList)
{
SHGetPathFromIDList(pIDList,缓冲区);
//获取Buffer的文件夹路径
m_cSisDes =缓冲区; //将路径保存在CString对象中
}
UpdateData(FALSE);
//已使用的可用内存
IMalloc * imalloc = 0;
如果(成功(SHGetMalloc(&imalloc)))
{
imalloc->免费(pIDList);
imalloc->版本();
}
}
好的,仅此而已. 由于许多伟大的神灵需要进一步扩展,因此只需遵循以下思路即可. 毕竟,我到了这一点,哈哈.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-150048-1.html
看到你那批样子
玩它一玩