在开发向导类型的应用程序时,经常需要提供一个对话框让用户选择图标或者文件夹。在MFC中,虽然提供了选择图标的对话框,但是并没有直接提供选择文件夹的对话框。因此,本文将介绍如何使用CFolderDialog类来实现这一功能。CFolderDialog类封装了Windows的SHBrowseForFolder API,使得在MFC应用程序中实现文件夹选择对话框变得简单。
示例用法
CFolderDialog类是从CCommonDialog类派生出来的,使用起来就像任何常见的对话框一样。以下是如何使用CFolderDialog类的示例代码:
#ifndef __FOLDERDLG_H__
#include "FolderDlg.h"
#endif
void CSomeDialog::OnSomeHandler(void) {
m_strFolderPath = _T("d:\\Windows");
// 仅为示例
m_strDisplayName.Empty();
CFolderDialog dlg(_T("Dialog Title"), m_strFolderPath, this);
if (dlg.DoModal() == IDOK) {
m_strFolderPath = dlg.GetFolderPath();
m_strDisplayName = dlg.GetFolderDisplayName();
// 在这里使用文件夹路径和显示名称...
}
}
更多示例请查看演示项目的源代码。
设置根文件夹
还可以设置对话框的根文件夹,指定从哪个位置开始浏览。只有指定的文件夹及其子文件夹才会出现在对话框中。以下是如何设置根文件夹的示例代码:
#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的对象——从它派生一个类,实现所有基本的纯虚成员函数,并实现IFolderFilterSite::ShouldShow和IFolderFilterSite::GetEnumFlags函数,进行过滤。
- 调用IFolderFilterSite::SetFilter(在步骤1中获得的指针),传递一个指向自定义IFolderFilter派生类的指针。
- IFolderFilterSite::ShouldShow和IFolderFilterSite::GetEnumFlags方法可以用来包含和排除树中的项。
- 一旦创建了过滤器,就不再需要IFolderFilterSite接口了。如果没有进一步的用途,请调用IFolderFilterSite::Release。
添加了一个自定义过滤的示例(请看图片,对话框只显示"JPG/GIF/BMP"文件)。感谢Arik Poznanski的文章"C# does Shell, Part 1"。更多信息,请查看源代码。
类成员
- Base Class: CCommonDialog
- Data Members:
- m_bi - Windows BROWSEINFO结构体。提供对基本文件夹对话框参数的访问。
- m_szFolPath - 包含对话框中选择的文件夹路径。
- m_szSelPath - 包含对话框打开时最初选择的文件夹路径。
- Construction: 构造CFolderDialog对象。
- Operations:
- 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结构体。
- Overridables:
- OnInitialized(void) - 当浏览对话框完成初始化时调用。
- OnSelChanged(IN LPITEMIDLIST pItemIDList) - 当浏览对话框的选择更改时调用。
- OnValidateFailed(IN LPCTSTR pszPath) - 当用户在浏览对话框的编辑框(如果有)中输入无效名称时调用。返回零以允许关闭对话框,或返回非零值以保持对话框打开。
- Microsoft® Windows® XP/2003或更高版本: OnIUnknown(IN IUnknown* pIUnknown) - 提供IUnknown接口给客户端,用于使用IFolderFilterSite和IFolderFilter对对话框内容进行自定义过滤。
- Functions, that are valid to be called only from Overridables:
- EnableOK(IN BOOL bEnable = TRUE) - 启用或禁用浏览对话框的OK按钮。
- SetSelection(IN LPITEMIDLIST pItemIDList) - 选择指定的文件夹。
- SetSelection(IN LPCTSTR pszPath) - 选择指定的文件夹。
- SetStatusText(IN LPCTSTR pszText) - 设置对话框的状态文本。
- Shell version 5.0或更高版本: SetExpanded(IN LPITEMIDLIST pItemIDList) - 指定在对话框中展开的路径。
- SetExpanded(IN LPCTSTR pszPath) - 指定在对话框中展开的路径。
- SetOKText(IN LPCTSTR pszText) - 设置对话框"OK"按钮的文本。