【摘要】:创建一个工程名为“dyn”的SDI程序,用于了解动态创建的原理和使用方法,如图13-18所示。4)根据宏定义原型,翻译CMainFrame类声明动态创建宏的结果如下。6)再打开CMainFrame的源文件查看,在开头部分可以看到执行动态创建的宏,如图13-21所示。#define RUNTIME_CLASS11)再次翻译CMainFrame类执行动态创建宏的结果如下。12)所有MFC类的动态创建宏内,都隐藏了两个成员函数和一个静态成员变量,如图13-22所示。图13-24 添加工具栏按钮消息映射函数15)编写代码,测试动态创建函数CRuntimeClass::CreateObject。
凡是包含DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE两个宏的MFC类或派生类,都是支持动态创建的类,例如,框架类、视图类还有文档类等。
创建一个工程名为“dyn”的SDI程序,用于了解动态创建的原理和使用方法,如图13-18所示。
图13-18 创建文档视图架构的程序
1)打开CMainFrame类的头文件查看,首先看到的就是用于支持动态创建的宏,如图13-19所示。
2)选中DECLARE_DYNCREATE,再查看宏定义原型,如图13-20所示。
图13-19 查看宏定义
图13-20 创建浏览信息文件
3)在需要重建浏览信息的对话框中,单击“Yes”按钮后进入宏定义的头文件。
4)根据宏定义原型,翻译CMainFrame类声明动态创建宏的结果如下。
5)对DECLARE_DYNAMIC宏再次翻译的结果如下。
6)再打开CMainFrame的源文件查看,在开头部分可以看到执行动态创建的宏,如图13-21所示。
图13-21 查看宏定义
7)选中IMPLEMENT_DYNCREATE宏名称,通过菜单命令或者快捷键<F12>查看宏定义原型。
8)根据宏定义原型,翻译CMainFrame类执行动态创建宏的结果如下。
9)对IMPLEMENT_RUNTIMECLASS宏再次翻译的结果如下。
(www.chuimin.cn)
10)查看RUNTIME_CLASS宏定义原型,并去除无用代码AFX_COMDAT和AFX_DATADEF。
#define RUNTIME_CLASS(class_name)((CRuntimeClass*)(&class_name::class##class_name))
11)再次翻译CMainFrame类执行动态创建宏的结果如下。
12)所有MFC类的动态创建宏内,都隐藏了两个成员函数和一个静态成员变量,如图13-22所示。
图13-22 翻译后的动态创建宏定义代码
13)在资源视图中添加工具栏按钮,用于测试动态创建,如图13-23所示。
图13-23 编辑工具栏资源
14)在App类中添加测试按钮的消息映射函数,如图13-24所示。
图13-24 添加工具栏按钮消息映射函数
15)编写代码,测试动态创建函数CRuntimeClass::CreateObject。
16)编译并运行,测试代码。
在以上的翻译过程,有两个不常见的宏定义方式。在C语言标准中定义了#和##两种操作,#用来把参数转换成字符串,##则用来把前后两个参数连接在一起。例如,#define#x表示"x",#define#abc表示"abc";#define x##y表示xy,#define abc##xyz表示abcxyz。
17)分析CRuntimeClass结构体成员构成并对应赋值。
18)查看基于文档模板架构的InitInstance主体代码。
19)分析以上代码。
CSingleDocTemplate类的构造函数中,除指定资源标志IDR_MAINFRAME外,主要代入三个运行时类型名用于系统在内部创建这三个类的对象。在执行ProcessShellCommand函数时,系统内部动态创建了主框架类的对象,并将其存储于theApp.m_pMainWnd成员变量中。
相关推荐