CTreePropSheet - 类似于 Netscape/Visual Studio .NET 的首选项对话框






4.94/5 (140投票s)
2003年2月26日
8分钟阅读

1087333

12458
此框架引入了一个属性表,它基于原始的 Windows 属性表(继承自 CPropertySheet),但使用树形控件来浏览页面,而不是选项卡控件。
Content
引言
使用 Windows 提供的普通属性表对用户来说很困难,尤其是当属性表包含很多页面时。在这种情况下,大多数属性表会提供多行选项卡,每次点击不在最底层的那一行的一个选项卡时,行顺序都会改变。在其他情况下,属性表可能只提供单行选项卡,您可以通过微小的箭头按钮滚动浏览。这两种解决方案对用户来说都不够方便。
这是什么?
这就是 CTreePropSheet 的用武之地:这个属性表不使用选项卡,而是提供一个树形控件,允许用户选择属性表的页面。这还允许开发人员对多个页面进行分组。一个组将显示给用户为一个带有子项(组的页面)的树项。
这种概念已经被几个产品用于设置首选项。最著名的可能是 Netscape/Mozilla 和 Visual Studio .NET。
为什么要再来一个?
已经有一些类实现了类似的对话框(例如,请参阅 SAPrefs - 类似于 Netscape 的首选项对话框)。但 CTreePropSheet 是一个特殊的实现:它不从头开始实现一个新的首选项对话框,而是基于原始的 Windows 属性表,这带来了许多优势。
- 基于经过充分测试的代码
- 我们免费获得了原始属性表的 所有功能
- 通过其 HPROPSHEETPAGE 句柄添加页面,这对于提供插件机制的应用程序很有用。
- 最重要的是:它继承自 CPropertySheet 类,并使用 CPropertyPage 对象作为页面,因此您可以使用您常用的代码,只需进行最少的更改。
特点
由于 CTreePropSheet 基于原始属性表,因此您将获得此通用对话框提供的所有功能,包括:
- 自动调整大小以适应最大的页面
- 支持“确定”、“取消”、“应用”和“帮助”按钮
- 页面图标
此外,CTreePropSheet 还引入了以下功能:
- 将页面分组到逻辑类别中
- 根页面的默认文本
- 根页面和子页面的默认图标
- 一些辅助函数,使设置页面图标更容易
- 自定义外观和风格的可能性
- 完全支持 Windows XP 主题(在带主题和不带主题的系统上看起来都不错)
使用 CTreePropSheet
本节将不描述所有基本内容,因为您可以在 MFC 文档的 CPropertySheet 描述中找到这些内容。本节将只描述高级功能。这也是功能性的教程式描述。还提供了 完整参考。
使用 CTreePropSheet 的第一步与使用 MFC 类 CPropertySheet 相同。
- 创建一些 CPropertyPage(或派生类)对象,并修改它们的名称以将它们分组(见下文)。
- 创建一个 CTreePropSheet 对象。
- 使用 CTreePropSheet::AddPage() 方法将 CPropertyPage 对象添加到 CTreePropSheet 对象。
- 使用 自定义 部分描述的方法修改属性表的样式。
- 调用 CTreePropSheet::DoModal() 以模态对话框形式显示属性表,或调用 CTreePropSheet::Create() 以获取非模态属性表。
如果您只想修改现有应用程序,使其使用 CTreePropSheet 类而不是 CPropertySheetClass,请按照以下步骤操作:
- 将所有 CPropertySheet 的出现替换为 CTreePropSheet。
- 更改页面的名称,以将它们分组(见下文)。
就是这样!
要将页面分组到类别中,您只需更改属性页的名称(窗口标题)。标题现在不仅应该包含页面的名称,还应该指定 CTreePropSheet 的页面树中的页面的 *路径*。字符串“::”在此处用作路径分隔符。例如,上面页面顶部的截图所示的示例应用程序有五个页面,它们被命名为:
- Server::Outgoing
- Server::Incoming
- Message Format::View
- Message Format::Composition
- 外观
根项“Server”和“Message Format”以及相关的页面是由 CTreePropSheet 类自动生成的,如果您不显式添加具有这些路径的页面。您可以使用 CTreePropSheet::SetEmptyPageText() 方法设置应为这些隐式根页面显示的文本。
要获取包含字符串“::”的可见名称的页面,您只需在双冒号前加上反斜杠(“\\::”)。
自定义 CTreePropSheet
本节简要概述了更改 CTreePropSheet 外观的可能性。
基础
以下方法提供了简单修改 CTreePropSheet 外观的可能性。您将在 参考 中找到每个方法的完整描述。
SetTreeViewMode()
- 更改以下设置(仅在创建窗口之前):
- 在经典选项卡和树形视图模式之间切换
- 在树形视图模式下启用/禁用页面标题
- 在树形视图模式下启用/禁用页面树中的页面图标
SetTreeWidth()
- 设置树形控件的宽度。默认值为 150 像素。
SetEmptyPageText()
- 指定在空页面上显示的文本。空页面是为树中的根项隐式创建的页面。
SetEmptyTextFormat()
- 指定与 DrawText() 一起使用的标志,用于在空页面上绘制文本(主要与对齐相关的部分)。
SetTreeDefaultImages()
- 指定用于页面和空页面的图像,这些页面没有显式定义的图像。仅在启用了图像时才相关。
GetPageTreeControl()
- 在对话框创建后(即在 OnInitDialog() 中)提供对树形控件的直接访问,允许您更改树形控件的样式。
- SetPageIcon() 和 DestroyPageIcon()
- 静态辅助函数,用于定义页面的图标并在不再需要时销毁它们。
高级
CTreePropSheet 类还提供了几种高级自定义机制,可以通过重写虚方法来实现。
页面框架和标题
从屏幕截图中可以看到,CTreePropSheet 已经支持 Windows XP 主题,这对于属性页面的背景和框架尤为重要:在非主题系统(如 Windows 2000)或禁用主题时,属性页面通常的绘制方式与属性表背景不同。这需要属性表在页面周围绘制一个框架。这个框架通常由选项卡控件提供,但由于我们不使用选项卡控件,因此在需要时必须自己绘制框架。
这个框架由 CPropPageFrame 派生类的对象绘制,该对象在 CTreePropSheet::CreatePageFrame() 中创建。此方法的默认实现会创建一个 CPropPageFrameDefault 对象,该对象会检测是否启用了主题,并使用 Windows XP 主题库(如果需要)执行相应的绘制。如果启用了页面标题(SetTreeViewMode()),该对象也负责绘制页面标题。
您可以通过重写 CTreePropSheet 的派生类中的 CreatePageFrame() 方法并创建自己的 CPropPageFrame 派生类的对象,来提供自己的框架和标题绘制机制。
页面树
通过使用 GetPageTreeControl() 方法获取指向 CTreeCtrl 的指针并修改其样式,可以对页面树进行大部分修改。如果您想注入自己的树形控件,可以在派生类中重写虚拟的 CreatePageTreeObject() 方法,并创建自己的类的对象而不是默认的 CTreeCtrl。
空页面消息
如果您想自定义由属性表生成的空页面消息,可以重写虚拟的 GenerateEmptyPageMessage() 方法。
参考
您将在源代码的头文件中找到完整的 CTreePropSheet 框架的参考。您可以使用帮助提取工具 doxygen 从源文件生成 HTML、HtmlHelp 或 LaTeX 文档(以及相应的 PDF 文档)。
要求
它应该可以在 Windows 95 或更高版本以及 Windows NT 4.0 或更高版本上运行,尽管我只在 Windows 98、Windows 2000 和 Windows XP 上进行过测试。
如果您在列出的一个或多个平台上发现问题,请告知我。
编译需要 Visual C++ 6.0 或 7.0 以及 2002 年 5 月的 Platform SDK。(如果您没有安装此 SDK,可以取消注释掉 PropPageFrameDefault.cpp 文件中 XPSUPPORT 宏(第 30 行)然后它也应该可以工作。)
Unicode 支持
虽然我没有测试过,但没有理由不支持 Unicode。
实现细节
实现方面没什么大不了的。最有趣的部分在 WM_INITDIALOG 处理程序 (OnInitDialog) 中完成。该方法会隐藏选项卡控件,水平调整属性表的大小以腾出页面树的空间,将所有现有项目移到属性表的右侧,然后在左侧创建树形控件。
其余的实现很简单。只需查看代码。如果您有任何问题,请将其发布到本文的评论部分。
修订历史
2003/02/26 |
|
2003/02/27 |
|
2003/03/03 |
|