CFolderDialog - 选择文件夹






4.95/5 (87投票s)
CFolderDialog 类允许您将文件夹选择对话框添加到您的应用程序中。
引言
正如我在另一篇文章“CIconDialog - 选择图标”中提到的,在开发一个向导应用程序时,我需要一个对话框来从可执行文件中选择图标,另一个对话框用于在多个可执行文件中选择文件夹,但在 MFC 中没有找到任何相关内容。因此,编写了 CFolderDialog。它封装了 ::SHBrowseForFolder API。
示例用法

CFolderDialog 派生自 CCommonDialog,其行为类似于任何通用对话框。请参阅示例用法
//... #ifndef __FOLDERDLG_H__ #include "FolderDlg.h" #endif // ... void CSomeDialog::OnSomeHandler( void ) { m_strFolderPath = _T( "d:\\Windows" ); // Just for sample m_strDisplayName.Empty(); CFolderDialog dlg( _T( "Dialog Title" ), m_strFolderPath, this ); if( dlg.DoModal() == IDOK ) { m_strFolderPath = dlg.GetFolderPath(); m_strDisplayName = dlg.GetFolderDisplayName(); // Use folder path and display name here ... } } //

有关更多信息,请参阅演示项目源代码。
设置根文件夹
您还可以设置对话框的根文件夹,指定开始浏览的根文件夹位置。只有指定的文件夹及其在命名空间层次结构中的任何子文件夹才会出现在对话框中。

请参阅示例用法
//... #ifndef __FOLDERDLG_H__ #include "FolderDlg.h" #endif // ... void CSomeDialog::OnSomeHandler( void ) { CFolderDialog dlg( _T( "Root folder is C:\" ), NULL, this ); dlg.SetRootFolder( _T( "C:\\" ); if( dlg.DoModal() == IDOK ) { // ... } } //

感谢 Eckhard Schwabe 和 Jose Insa 提供的这个示例。
自定义过滤
在 Microsoft® Windows® XP/2003 或更高版本上,您可以对对话框的内容进行自定义过滤。

要创建自定义过滤器,请遵循以下步骤
- 在 CFolderDialog构造函数的uFlags成员中设置BIF_NEWDIALOGSTYLE标志。在派生类中重写OnIUnknown虚成员函数。在OnIUnknown中,函数的pIUnknown参数将包含指向IUnknown实例的指针。在该IUnknown上调用QueryInterface以获取指向IFolderFilterSite的指针。
- 创建一个实现 IFolderFilter的对象 - 从中派生一个类,该类实现IUnknown的所有基本纯虚成员函数,并实现执行过滤的IFolderFilterSite::ShouldShow和IFolderFilterSite::GetEnumFlags函数。
- 调用 IFolderFilterSite::SetFilter(您在步骤 1 中获得的指针),将指向您的自定义IFolderFilter派生类的指针传递给它。然后可以使用IFolderFilterSite::ShouldShow和IFolderFilterSite::GetEnumFlags方法来包含和排除树中的项目。
- 一旦过滤器创建,就不再需要 IFolderFilterSite接口。如果您不再需要它,请调用IFolderFilterSite::Release。

我添加了一个自定义过滤示例(请看图片,对话框中只显示树中的“JPG/GIF/BMP”文件)。感谢 Arik Poznanski 的文章 “C# 和 Shell,第一部分”。有关更多信息,请参阅源代码。
类成员
基类
- CCommonDialog
数据成员
- m_bi- Windows- BROWSEINFO结构。提供对基本文件夹对话框参数的访问。
- m_szFolPath- 包含通过对话框选择的文件夹的路径。
- m_szSelPath- 包含对话框打开时最初选择的文件夹路径。
然后,当你开始迭代 2(这是构建迭代的开始)时,你可能想要复制测试用例并将它们重新分类到迭代 2。这还允许对测试用例进行粒度跟踪,并允许你说某个测试用例在一个迭代中是准备好的,但在另一个迭代中不是。同样,如何做到这一点取决于你以及你希望如何报告。 “场景”部分提供了更多细节。
构造一个 CFolderDialog 对象
CFolderDialog( IN LPCTSTR pszTitle = NULL, IN LPCTSTR pszSelPath = 
      NULL, IN CWnd* pWndParent = NULL, IN UINT uFlags = BIF_RETURNONLYFSDIRS )
- pszTitle- 在对话框顶部显示的标题。
- pszSelPath- 对话框打开时最初选择的文件夹路径。
- pWndParent- 指向文件对话框对象的父窗口或所有者窗口的指针。
- uFlags- 一个或多个标志的组合,允许您自定义对话框。有关更多信息,请参阅平台 SDK 中的- BROWSEINFO结构。
操作
- DoModal( void )显示浏览文件夹对话框并允许用户进行选择。
- SetSelectedFolder( IN LPCTSTR pszPath )- 设置对话框打开时最初选择的文件夹路径。
- SetRootFolder( IN LPCTSTR pszPath )- 设置要显示的根文件夹路径。如果- pszPath为- NULL,则根文件夹将被移除。
- GetRootFolder( IN OUT LPTSTR pszPath )- 获取对话框的根文件夹。- pszPath缓冲区的大小必须至少为- MAX_PATH个字符。
- GetSelectedFolder( void ) const- 获取对话框打开时最初选择的文件夹路径。
- GetFolderPath( void )const- 检索打开的文件夹的路径。
- GetFolderDisplayName( void )const- 检索当前打开的文件夹的显示名称。
- GetFolderImageIndex( void )const- 获取与所选文件夹关联的图像。图像以系统图像列表的索引形式指定。
- GetBI( void )- 检索- CFolderDialog对象的- BROWSEINFO结构。
- GetBI( void )const- 检索- CFolderDialog对象的- BROWSEINFO结构。
可重写函数
- OnInitialized( void )- 当浏览对话框完成初始化时调用。
- OnSelChanged( IN LPITEMIDLIST pItemIDList )- 当浏览对话框选择改变时调用。
- OnValidateFailed( IN LPCTSTR pszPath )- 当用户在浏览对话框的编辑框(如果有)中输入无效名称时调用。返回零以允许对话框关闭,或返回非零以保持对话框打开。
Microsoft® Windows® XP/2003 或更高版本
- OnIUnknown( IN IUnknown* pIUnknown )- 为客户端提供- IUnknown接口,用于使用- IFolderFilterSite和- IFolderFilter对话框内容进行自定义过滤。
只能从 可重写函数 中调用的函数
- EnableOK( IN BOOL bEnable = TRUE )- 启用或禁用浏览对话框的“确定”按钮。
- SetSelection( IN LPITEMIDLIST pItemIDList )- 选择指定的文件夹。
- SetSelection( IN LPCTSTR pszPath )- 选择指定的文件夹。
- SetStatusText( IN LPCTSTR pszText )- 设置对话框状态文本。
Shell 版本 5.0 或更高版本
- SetExpanded( IN LPITEMIDLIST pItemIDList )- 指定要在对话框中展开的路径。
- SetExpanded( IN LPCTSTR pszPath )- 指定要在对话框中展开的路径。
- SetOKText( IN LPCTSTR pszText )- 设置对话框“确定”按钮文本。
注释
如果您将此项目转换为 VC 7.0 或更高版本,请不要忘记将 shlwapi.dll 添加到延迟加载 DLL 列表中,因为它使用了 shlwapi.dll 5.0 的 ::StrRetToStr 函数。转到“[项目属性]>[配置属性]>[链接器]>[输入]”,然后将“shlwapi.dll;”添加到“[延迟加载 DLLs]”列表中。VC 6.0 项目使用“/DelayLoad”链接器选项来实现此目的,该选项在 VC 7.0 或更高版本中不受支持。
版本历史
- 2002年3月27日 
- 发布文章。
 
- 2003年3月30日 
- 部分代码更改。
- 添加了旧平台 SDK 中缺少的新标志定义。
- 添加了对 MFC 6.0 和 7.0 的支持。
- 为 Microsoft® Windows® XP 文件夹过滤添加了 OnIUnknown处理程序。
- 添加了 SetExpanded、SetOKText和GetSelectedFolder函数。
 
- 2003年5月30日 
- 添加了 OnSelChanged的默认实现。
 
- 添加了 
- 2003年7月14日 
- 为 Microsoft® Windows® XP/2003 或更高版本添加了自定义过滤示例。
- 将 SetExpanded和SetOKText设置为noinline。
 
- 2004年1月7日 
- 添加了 SetRootFolder和GetRootFolder函数。
- 更改了 IFolderFilter实现。
 
- 添加了 
- 2005年2月15日 
- DoModal中有一个小错误修复,感谢 WindSeven。
 


