• 深入浅出MFC——MFC六大关键技术仿真(二)


    1. 仿真MFC目的:以MFC为例,学习application framework的内部运行。MFC六大关键技术

      (1)MFC程序的初始化过程

      (2)RTTI(Runtime Type Information)运行时类型识别

      (3)Dynamic Creation 动态创建

      (4)Persistence 永久保存

      (5)Message Mapping 消息映射

      (6)Message Routing 消息传递(回溯)

    2. MFC数个最重要的类的层次结构

    3. 以下范例展示了类层次及其成员(对于那些“除了构造函数与析构函数之外没有其他成员”的类就不展开):

    注:

      (1)从上图可以看到,theApp是一个全局对象(同时也是静态对象),上一篇说过,全局对象的构造函数将更早于main。换句话说,你所看到的执行结果中的那些构造函数输出操作全都是在main函数之前完成的。main函数调用全局函数AfxGetApp以取得theApp的对象指针。这完全是仿真MFC程序的手法。

      (2)InitApplicationInitInstance是MFC的CWinApp的两个虚函数。前者负责“每一个程序只做一次”的操作,后者负责“每一个例程都得做一次”的操作。

    4. RTTI(运行时类型识别):构建类别型录网与CRuntimeClass。类库的设计者一定要在类构建起来的时候,记录必要的信息,以建立型录。型录中的类信息,最好以链表方式连接起来。我们的“类别型录”的链表元素将以CRuntimeClass描述之

      (1)CRuntimeClass内容如下:

      (2)DECLARE_DYNAMIC宏:为了神不知鬼不觉把CRuntimeClass对象塞到类之中,并声明一个可以抓到该对象地址的函数。

       (3)IMPLEMENT_DYNAMIC宏:类别型录(也就是各个CRuntimeClass对象)的内容指定以及连接工作也神不知鬼不觉加入。

    :AFX_CLASSINIT结构体,会导致在宏"IMPLEMENT_DYNAMIC"中创建一个名字为"_init_##class_name"的对象。

      (4)示范例子: 

     

    5. 动态创建:要根据一个类名称让程序产生一个对象,我们需要把类的大小记录在类别型录中,把建构函数(注意,这里并非指C++构造函数,而是指即将出现的CRuntimeClass::CreateObject)也记录在类别型录中。当程序在执行期间获得一个类名称,它就可以在“类别型录网”中找出对应的元素,然后调用其建构函数(这里并非指C++构造函数),产生出对象。

      (1)CRuntimeClass修改如下:

     

      (2)为了适应CRuntimeClass中新增的成员变量,我们再添两个宏:DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE.如下:

      (3)示范例子:

      (4)图示如下:

    6. Persistence(永久保存)机制:MFC有一套Serialize机制,目的在于把文件名的选择、文件的开关、缓冲区的建立、数据的读写、提取运算符(>>)和插入运算符(<<)的重载、对象的动态创建等都包装起来。最主要的是执行数据的读写和对象的动态创建;动态创建如上所述,接下来便是数据的读写(本小节不对serialization进行仿真,原因在于很多东西需要仿真:CFile、CArchive、CObject、CDWordArray、CRect、CPoint、运算符重载、serialize函数……,所以,persistence机制直接使用MFC讲解,详见XXXXXX):

      (1)DECLARE_SERIAL/IMPLEMENT_SERIAL:将<<和>>两个运算符重载,还要让Serialize函数神不知鬼不觉地放入类声明之中。类之所以能够进行文件读写操作,前提是拥有动态创建的能力。如下:

      (2)为了在每一个对象被处理(读或写)之前,能够处理琐屑的工作,诸如判断是否第一次出现、记录版本号码、记录文件名等工作,CRuntimeClass需要两个函数Load和Store

      (3)Load和Store函数实现类似如下:

      (4)为了让整个Serialization机制运气起来,我们在自定义类的时候,加上这样的宏声明,然后实现serialize函数:

    7. Message Mapping(消息映射):把消息和其处理程序关联起来。是将消息于表格中的元素比较,然后调用对应的处理程序。

      (1)准备必要的数据结构:

      (2)定义DECLARE_MESSAGE_MAP:

      (3)定义宏填塞数据结构:

      (4)示范例子:

    图示表示为:

    注意:CObject并不属于消息传递网的一分子;(抽象基类)。CWinThread并不属于消息传递网的一分子;(多线程)。

      (5)图示消息传递网:

    8. Command Routing(命令传递):命令传递提供消息横流的机会;上面消息映射表能很简单的实现消息从子类流向父类(纵向流动),但作为application framework的重要结构之一的document/view,也具有处理消息的能力,所以,我们应该提供消息横流的机会。MFC对于消息循环的规定是:

      (1)示范例子:新增成员函数:(参见《深入浅出MFC》第三章)

      (2)下图所示命令传递过程中的函数调用次序:

    ------------------------------------------------------------------------------------------------------------------------------------

    8. MFC重要的开发工具:

    9. 强大的资源编辑器:

      (1)Icon编辑器

      (2)Cursor编辑器

      (3)Bitmap编辑器

      (4)工具栏(Toolbar)编辑器

      (5)VERSIONINFO资源编辑器

      (6)字符串表格(String Table)编辑器

      (7)菜单(menu)编辑器

      (8)加速键(Accelerator)编辑器

      (9)对话框(Dialog)编辑器

     ------------------------------------------------------------------------------------------------------------------------------------

    10. 什么是Application Framework?

    11. Microsoft Foundation Classes(MFC):

    12. 纵览MFC:

    13. Windows API classes:

    14. Application framework classes:

    15. AFX全局函数:

    16. MFC宏(macros):

    17. MFC数据类型(data types)——定义于WINDEF.H

  • 相关阅读:
    Java学习之路(三)--Thinking in Java
    Java学习之路(二)--Thinking in Java
    Java学习之路(一)--Thinking in Java
    ES6中y修饰符合u修饰符
    map数据结构
    Set数据结构
    不确定参数的处理
    函数参数的默认值
    class基础语法
    生成新数组的方法和在数组中查找
  • 原文地址:https://www.cnblogs.com/yyxt/p/4847485.html
Copyright © 2020-2023  润新知