为了操练更多 CFolderDialog 的高级特性,我写了一个测试程序 FolderPick。它有两个运行文件夹对话框的命令。一个显示“旧式”对话框;另一个显示新式对话框。新式样(BIF_NEWDIALOGSTYLE)创建一个更大的,可变大小的对话框,对应的按钮是“Make
New Folder”——如果你指定 BIF_EDITBOX——则有一个编辑框,用户可以敲入文件夹的名字。其它标志还有 BIF_BROWSEFORCOMPUTER,用于显示计算机,BIF_BROWSEFORPRINTER
用于打印机。BIF_RETURNONLYFSDIRS 告诉 Windows 仅返回文件系统目录,而非伪文件夹,如网络邻居,BIF_STATUSTEXT
创建一个状态窗口,你可以设置其文本。(新式对话框不支持 BIF_STATUSTEXT)。完整的标志清单请参考 BROWSEINFO 文档。 逆@风@者
FolderPick 派生一个新类,CMyFolderDialog,重写了 nInitialized 和 OnValidateFailed。当该对话框被初始化时,FolderPick
设置状态文本并将 OK 按钮的名字改为“Choose Me!”:
void CMyFolderDialog::OnInitialized()
{
SetStatusText(_T("Nice day, isn''t it?"));
SetOKText(L"Choose Me!");
}
这里有两件事情需要注意。第一,CFolderDialog 有包装器,SetStatusText 和 SetOKText,用于文件夹对话框消息 BFFM_SETSTATUSTEXT and BFFM_SETOKTEXT。如果你用
C 编程,你要调用 ::SendMessage;但 CFolderDialog 调用包装器既可。唯一的警告是你只能从通虚拟知消息处理函数(OnInitialized,OnSelChanged
等)中调用这些包装器,因为 m_hWnd 仅在文件夹对话框真正运行的时候才有效,调用 BrowseForFolder
之前或之后则不然。当其回调第一次收到通知消息时,CFolderDialog 在内部子类化文件夹对话框。第二,某些 BFFM_ 消息需要
Unicode 串,而不是 LPCTSTRs。这就是为何代码段中“Choose Me!”使用的是宽字符串的原因(带前缀 L)。
如果你试图用 C 编写 SHBrowseForFolder 程序,Microsoft 的文档有两个小错误,我必须在此指出来。文档中说 BFFM_SETOKTEXT
使用的字符串是在 WPARAM 中传递的,但实际上却是在 LPARAM 中。文档还说 BFFM_SETSELECTION 需要 Unicode
字符串,但 BFFM_SETSELECTION 的处理函数 A 和 W两个版本都有。所以你可以在其中使用 LPCTSTR。
如果你在新式样对话框中使用 BIF_EDITBOX,Windows
将显示一个编辑框,用户可以在其中敲入文件夹名。如果用户敲入非法数据,Windows 将用 BFFM_VALIDATEFAILED 调用浏览过程。CFolderDialog
会调用 OnValidateFailed 来处理它。FolderPick 该写了 OnValidateFailed 以显示如 Figure 4
所示的出错信息框。
BOOL CMyFolderDialog::OnValidateFailed(LPCTSTR lpsz)
{
MessageBox(...);
return TRUE; // don''t dismiss dialog
}

Figure 4 FolderPick 的出错框
SHBrowseForFolder
支持的另一个很酷的特性是过滤器定制。它能让你以项目为单位控制在文件夹对话框中显示那些项。使用回调时,这种机制冗长而繁琐。你必须得实现 COM
接口,IFolderFilter,它有两个方法:GetEnumFlags 和 ShouldShow。当文件夹对话框向你的回调发送 BFFM_IUNKNOWN
时,你必须要用 QueryInterface 查询为 IFolderFilterSite 而传递的 IUnknown,然后用你的 IFolderFilter
调用 IFolderFilterSite::SetFilter。现在文件夹对话框调用你的 IFolderFilter::ShouldShow
来过滤每一项,当不再需要 IFolderFilterSite 时必须对之进行 Release 操作。
自然,我将所有这些细节都作了封装。为了使用定制的过滤器,你只需以 bFilter=TRUE 调用 BrowseForFolder
既可,并改写两个虚函数:OnGetEnumFlags 和 OnShouldShow。不需要再处理 COM 的细节——QueryInterface
或 IFolderFilter。
本文章更多内容:<<上一页 - 1 - 2 - 3 - 4 - 下一页>> |