使用一个CWnd空闲池创建一个动态用户界面
2007-10-04 20:11:32 来源:WEB开发网对话框示例是相当简单的,它展示了如何动态地创建一个UI。然而,为了证明资源使用方面从空闲池机制获得的好处,我们需要一个在运行时从容器添加或移除CWndControl实例的方法。最好的说明就是使用一个控件被分成小组(但是一次只有一组控件可以被显示)场景,并且分组的选择这里有一个机制(比如使用一个树视图或一个标签控件)。最后,我添加了另一个层的类:它实现包含可以通过XML被定义的内容的一个“控件窗体”。我用这一组类的主要目的是展示给一个非常特别的UI场景所带来的资源节约。下面简要描述一下控件皮肤类:
CTreeWnd: 一个树控件的CWnd包装类。用来实现在控件窗体中的树视图;
CListWnd: 一个列表控件的CWnd包装类。用来在控件窗体中实现事件区域;
CControlDlg: 这就是使用CWndContainer实例的对话框类。它就是CWnd控件被创建、显示或隐藏所在的实际控件皮肤;
CMarkup: 来自Ben Bryant文章的XML 析构器类。这是一个易用的没有额外依赖的类,它只包括两个源文件(release 6.5 Lite version);
CControlGroup: 代表一个“控件组”,它与文件系统中的一个文件夹相似。一个控件组可以包含其它组,并且也可能包含控件(这里的控件就好像文件系统中的文件);
CControlXml: 这是一个使用CMarkup来解析XML文件和生成控件组和控件实例的XML引擎;
ControlWnd: 一个继承于CWnd的类,它实现一个包括一个左手边上的树视图、在右边的内容控件和一个小的来展示事件处理的事件窗体。这是TestFreePool 演示应用程序用到的顶层类。
TestFreePool应用程序
该演示项目(TestFreePool)是一个MDI应用程序,我是用Visual Studio开始生成的。该应用程序只允许你打开为MDI子窗体而定义UI内容的XML文件。在每个子窗体内部,你可以访问一个包含选项:"Show CWnd Count"的上下文菜单。这个功能计算窗体在CChildView实例层次上实际使用的CWnd对象(当做一个资源使用的粗略估计)。CChildView由Visual Studio生成并且它是以控件皮肤层整合MDI应用程序代码的基本点。下面的截屏显示了演示项目是如何构成的。
本文提供下载的zip文件包括TestFreePool应用程序的一个release版本。如果你希望自己创建演示项目,请注意由于许可限制的原因我已经从zip文件中剔除了两个源文件:Markup.h和Markup.cpp。请首先从CMarkup文章下载该源代码,并在使用Visual Studio生成解决方案之前将Markup.h和Markup.cpp文件置入 TestFreePool 项目文件夹中去。如果你使用VS 2005来转换并生成演示项目,你可能会因为Markup.cpp的 Line 725而碰到一个编译器错误C2440。为了解决之,你可以只添加一个适当的强制类型转换(_TCHAR *)(译注:即改为if ( (pFound=(_TCHAR *)_tcschr(pFind,cSource)) != NULL ) 就可)以避免这个错误。
下面的图展示了在演示应用程序中的每个MDI子窗体的窗体继承图表。
XML 文件
在TestFreePool文件夹中,有三个可以由演示应用程序打开的示例XML文件。下表描述了每个文件并且也给出了一个关于使用空闲池机制获得的资源节约指标(基于CWnd统计总数)。XML格式选择是相当武断的-它主要允许你定义每组可以包含零个或更多子组和零或更多控件的一个控件组层次。
Filename | Description | Maximum CWnd Count | Estimated CWnd count without using free pool |
Example1.xml | Displays each of the supported UI control types. | 30 | 41 |
Example2.xml | Displays 12 control groups, each containing 10 labels and 10 buttons. | 27 | 259 |
Example3.xml | Displays 3 pages from the VS 2005 Options dialog. | 30 | 48 |
注意为Example1.xml计算的CWnd最大数可能会随着你系统上配置的Internet Explorer而变化(因为其中一个支持控件是Microsoft WebBrowser2 ActiveX 控件)。下面是演示应用程序中载入Example2.xml文件时的截图。
总结
本文的目的是演示如何动态创建UI同时在特定场景下最小化资源使用。开发出的代码是为了阐明这个概念而不是为了一个一般的或完整的XML表格库,等等。比如,现在只有一些有限的控件和属性被支持,并且事件处理机制是非常简单的。加入XML支持是作为一个方便的说明和测试的方法和但不是我要本文要表达的重点。虽然如果你能将其改编以适应你自己的特定应用程序需要,源代码对你来说将可能更有用。比如,你可能想为更多的MFC控件或者甚至你自己的自定义控件添加支持。在演示项目文件夹中有一个文本文件,它概述了添加一个新的控件支持的步骤。
更多精彩
赞助商链接