WEB开发网
开发学院软件开发VC 计算MDI子窗口数,仅显示文件夹的打开对话框 阅读

计算MDI子窗口数,仅显示文件夹的打开对话框

 2006-07-19 11:29:33 来源:WEB开发网   
核心提示: BOOL CMyFolderDialog::OnValidateFailed(LPCTSTR lpsz){MessageBox(...);return TRUE; // don''t dismiss dialog}Figure 4 FolderPick 的出错框SHBrow
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。Figure 5 具体实现代码和 Figure 6。CFolderDialog 在内部实现了自己的 IFolderFilter,也就是调用对应的虚拟函数。CFolderDialog::OnIUnknown 使用了活动模板库(ATL)CComQIPtr 智能指针类,它使得 COM 编码轻而易举。

如果你决定用定制的过滤器,要小心,因为它改写了 BIF_RETURNONLYFSDIRS 这样的标志(只返回文件系统目录)。出于好玩,我决定当所选的项目不是文件系统目录时,通过手动禁用 OK 按钮,自己为 FolderPick 实现 BIF_RETURNONLYFSDIRS。为了检查文件系统对象,你要考虑适当的方式调用 IShellFolder::GetAttributesOf 并寻找 SFGAO_FILESYSTEM。但是当我尝试这样做的时候,“我的电脑”得到的是SFGAO_FILESYSTEM 属性,尽管它并非真正的文件系统目录!后来,我发现要想知道某个外壳对象是否为真正的文件或文件夹,唯一可靠的方法是调用 GetPathName 并检查串是否为空。在 CMyFolderDialog 中我就是这么做的,一旦碰到非文件夹则禁用 OK 按钮。具体细节请参考下载的源代码。

最后,为了帮助你理解来龙去脉,我对运行时的 CFolderDialog 进行了 TRACE 跟踪诊断。如图 Figure 6 所示。

Figure 6 TraceWin

你可以通过设置 CFolderDialog::bTRACE 全局变量对诊断进行开/关控制。当然,跟踪只能在调试模式进行。下载的代码中附带有 TraceWin 的免费拷贝,以便不用运行调试器就能察看诊断输出。

SHBrowseForFolder 还有许多标志和特性我没有发掘,但是不论你使用哪种特性,CFolderDialog 都能减轻你的工作负担并让你能用 MFC 的方式来编写使用 SHBrowseForFolder 的程序。

祝编程愉快!

您的提问和评论可发送到 Paul 的信箱:cppqa@microsoft.com

上一页  1 2 3 4 5 6 

Tags:计算 MDI 窗口

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接