上一节了解了大体流程,但是界面控件元素是如何被加载、解析、构建、管理、控件消息如何处理的呢?接下来我们将结合控件构造器进行分析;
CDialogBuilder:控件构造器,主要用以解析xml配置文件并以此创建相应控件及相关属性。
类成员数据:
m_xml:xml解析器,用以读取并解析xml配置文件;
m_pCallback:构造器回调函数,用以给予用户可以实现自定义的构造控件对象的方式;
m_pstrtype:以NULL为结束符的字符串,资源类型,参数含义同EnumResLangProc函数中的IPszType,字符串指定了那些被列举的语句资源的类型名;如:RT_ACCELERATOR、
RT_CURSOR、RT_VERSION等;
类成员函数:
Create:
重载了的Create函数,首先第一个函数Create(STRINGorID xml, LPCTSTR type, IDialogBuilderCallback* pCallback, CPaintManagerUI* pManager, CControlUI* pParent);
可以看到,此函数内部只是通过xml解析器分类别地方式加载XML文件,参数xml,可以为XML文件路径名、压缩包或是以'<'开始的字符串资源(XML文件内容)、资源ID,
若xml为空,则通过加载资源模块句柄或是可执行应用程序句柄资源模块中加载类型为type的资源;pCallback为构造器回调函数;pManager为绘制管理器对象,用以对解析构建的控件或资源的管理、绘制;
pParent:控件父窗口,用以作为解析构建后各控件的父窗口;
注意:内部xml解析器通过三种方式解析:一种解析以"<"开头的文件内容字符串Load,二种解析XML文件路径名LoadFromFile,三种解析以可执行应用程序或是dll资源内容加载LoadFromMem;
XML解析器后期将分析。
第二个Create函数,主要在第一个Create函数基础上,实现真正的解析、遍历、构建的过程;返回第一个构建的控件对象;
内部具体过程:
1. 获取到xml中root根节点;
2. 从根节点起,对根节点一般是Window节点下的子节点的兄弟节点遍历,找到诸如:Image、Font、Default等各节点的属性信息并添加到pManager中以便于以后显示、绘制需要;
3. 单独对节点Window解析,获取到本窗口的窗口信息、大小、背景、颜色、透明度等信息;
4. 调用私有成员函数_Parse,内部主要实现获取Window节点下的子节点Include、TreeNode、以及各种控件,遍历并创建相应控件和子控件;
5. 对于4中的Include节点,根据该节点的属性count和source以及传入的参数资源类型type,确定是文件或是资源再次分别调用Create两个重载函数创建子控件;
6. 对于4中的TreeNode节点,先获取设置该控件默认属性并应用和其他属性覆盖部分默认属性,此外再次通过_Parse解析其子节点及附加控件;
7. 对于4中无法识别的节点,一部分为用户通过CPaintManagerUI::GetPlugins()插件的方式创建该节点对象;或者是另一部分通过m_pCallback构造回调函数创建用户自定义类型对象,
剩余若不被处理,将被忽视;
8. 对于4中的其他控件,均是先获取设置该控件默认属性并应用和其他属性覆盖部分默认属性;所有控件、节点均会被添加到pManager中管理。
GetMarkup:获取内部解析器对象地址指针;
GetLastErrorMessage:获取xml解析最近错误信息;
GetLastErrorLocation:获取xml解析最近错误位置。
接下来将介绍其XML解析器CMarkup。