【项目界面】MFC框架程序总体剖析

MFC框架程序剖析

在理解MFC框架之前,首先要明白C++中的继承、封装、多态。
多态成立三个条件:
1 子类要继承父类
2 子类重载父类的虚函数
3 父类指针指向子类对象

MFC框架把main函数封装在了里面


WINDOWS程序是与传统的DOS程序截然不同的两种程序设计方式,它是由事件驱动的,在应用程序展示给客户的UI (User In⁃terface 用户界面)中提供了各式各样的可视对象,用户可以根据需要,对这些可视对象进行操作,通过鼠标或者键盘的操作,产生了操作系统能感知的事件,在这样的事件发生之后,操作系统向应用程序中的特定对象发送消息,然后这些对象调用相应的函数处理过程来完成用户所要的需求。
WINDOWS 应用程序是建立在对象的基础之上的。程序中所包含的所有可以操作的可视化组建本质上也是一个对象,用户通过鼠标或者键盘对这些可视化的组建进行操作,之后消息驱动模式去调用这些组件内部可以使用的方法。用户通过外部输入进行操作的同时产生了各种不同类型的事件,这些事件又经过操作系统的分配,被相应的对象进行处理,这就是WINDOWS程序运行的的本质。下图就是对WINDOWS程序的运行原理的简要说明。

1 WINDOWS应用程序基本特点

在这里插入图片描述
WINDOWS系统的本质是一个消息驱动的操作系统,那么消息的定义是什么呢,从以下的几个方面,可以对消息有一个初步的了解。
1)消息组成部分:消息是由两部分组成的,它们分别是消息的名称(UINT)和参数(WPARAM,LPARM)。当用户点击鼠标或者通过键盘输入信息时,操作系统会捕捉到这一事件,同时发送消息到特定的窗口。例如当用户通过键盘输入字符“z”的时候,就会有WM_CHAR消息就会被发送,此时用户输入的具体是哪个字符则由WPARAM和LPARAM两个参数来确定。用户在使用系统提供的消息的同时也可以根据自己的需要定义消息,以便通过自定义的消息发送和接收数据。
2)消息传递的目标:每个消息必须由一个窗口来接收,否则会被系统默认的处理。每个窗口都有一个后台的消息处理函数,称之为窗口过程,它的作用是对传递过来的进行整理,处理那些和自己有关的消息,屏蔽掉无关的消息。例如(如果对鼠标左键单击事件进行处理,那么就必须增加针对WM_LBUTTONDOWN消息的处理函数,同样如果对鼠标右键单击事件进行处理,那么就必须增加针对WM_RBUTTONDOWN消息的处理函数,以便处理用户的需求。
3)未处理的消息:在用户的操作过程中会产生很过的消息,其中有些消息是需要我们处理的,然后大部分的消息是我们不关心的,这时WINDOWS操作系统就会调用默认的串口过程来处理这些我们未处理的消息。WINDOWS的这种默认处理机制,大大的缩短了程序员的开发时间,我们只要把精力集中在我们关注的消息上就可以,其余的都可以交给系统默认处理。
4)窗口句柄:窗口句柄类似于C++中的指针,系统通过句柄来识别每个不同的窗口,用户通过操作触发事件进而又操作系统转发消息,这是必须为每一个窗口分配一个句柄,用来辨明窗口的身份,以便接受消息,保证了每一个消息能够被相应的窗口接受,之后再调用该窗口的窗口过程处理。如果有两个窗口,窗口A,窗口B,共用一个窗口过程时,如果在窗口A上单击了鼠标,怎会通过窗口A的句柄发送给窗口A而不是窗口B。

2 消息传递过程

消息到产生之后是如何被相应的窗口过程相应的呢,下面我们来了解一下相应的过程,其中有大致分为5个步骤:

  1. 用户通过外部设备进行了输入或者窗口的状态发生改变导致了事件的产生。
  2. 操作系统捕捉到这个事件,并把其转化为相应的消息,之后放入到消息队列中等候处理。
  3. 应用程序从消息队列中接收到这个消息。
  4. 应用程序根据消息中的标识句柄把消息传递给相应的窗口,并交由该窗口的窗口过程进行处理。
  5. 窗口过程响应这个消息并进行处理。
    其中第3步和第4步构成了应用程序消息循环的主题。消息循环机制是WINDOWS应用程序中最重要的机制,因为消息循环机制能够把用户的操作和消息的响应结合起来。消息循环机制的主要作用就是从已经消息队列中找到已经产生的消息,然后根据消息句柄发送给相应的窗口进行处理。如果消息队列中没有已经生产的消息,那么操作系统就允许其他应用程序处理它们的消息。

3 MFC主要类库分析

Windows操作系统最方便之处就是良好的用户接口,它为用户提供了丰富的图形化界面,这个图像化界面的本质就是消息处理机制驱动的,所以说消息处理机制是WINDOWS编程的核心,只有详细的了解了这个机制,才彻底了解WINDOWS编程。
VC++编程环境提供了一套MFC AppWizard应用向导,可以不用编写代码的情况下建立一个简单的WINDOWS应用程序,下面就以这个简单的应用程序为模板,简单分析一下生成对象之间的关系。
在这里插入图片描述
CMyApp类:类CmyApp的对象就代表了一个应用程序应用程序启动:用户运行该应用程序时,Windows会自动调用应用程序框架内部WinMain函数,CMyApp类它的父类是MFC中的CWINAPP类。这个类包含了其他CWINAPP类中的构造函数,同时还包含了一个重要的成员函数INITINSTANCE(),在WINDOWS操作系统中同一个程序可以在内存中存在很多的实例,例如我们可以开启多个QQ应用程序,,函数INITINSTANCE 的作用就是在每一个实例产生的时候,完成一些初始化的工作。
CMainFrame类:类CMainFrame它的父类是MFC 中的CFremeWnd类,所以它也是一个框架窗口。CMainFrame是类CMyview的父类,换句话说CMyview类的对象显示在主框架窗口的客户区中。在类CMainFrame中,系统已经从类CFremeWnd 那里继承了处理窗口的一般事件的WINDOWS 消息,比如改变窗口的大小,窗口最小化等等的成员函数,因此编程的时候程序员不需要再关心此类消息的处理。当然,如果用户确实需要多这写默认的成员函数进行修改的时候,我们也可以在类CMainFrame中添加相应的函数,之后重载就可以了。
CMyView 类与CMyDoc类:CMyView 类和CMyDoc 类是两个结合在一起的类,下面的框图可以说明文档与视窗的关系。
在这里插入图片描述
在这个框图当中,文档是由文档模板对象生成的,并由应用程序对象管理,而用户则是通过与文档相联系的视窗对象来存储、管理应用程序的数据,用户与文档之间的交互则是通过与文档相关联的视窗对象来进行的。
在这个框图结构当中,文档的产生是由文档模板对象决定的,生成之后的文档交由应用程序对象管理,而用户对数据的更新,删除,修改等操作都是通过文档窗口对应的对象来完成的,用户与文档之间的交互则是通过与文档窗口对象的对象来进行的。
在每一个新的文档生成的时候,MFC总会为其生成一个框架窗口,并且在这个框架窗口中生成一个用户的视窗窗口作为它的子窗口。用户视窗的作用就是监听用户的鼠标,键盘等输入设备的操作,一旦有事件产生,就生成消息并传递到消息队列中,完成消息循环以达到文档对象处理的目的。

4 windows窗口创建过程

WINDOWS 应用程序分单文档界面SDI 和多文档界面MDI 两种,在单文档界面中,文档窗口与主框架窗口是同一概念。而这
时的视窗对象则是显示在文档窗口的客户区当中,此时文档窗口是主框架窗口,即类CMainFrame 的对象。
在了解了WINDOWS程序的运行原理以及MFC程序的四个基本对象之后,我们来一起分析一下WINDOWS窗口程序的创建流程。
1)CXXApp中的全局变量定义(在WinMain()函数之前定义的全局变量)CXXApp theApp;
2)调用CXXApp构造函数(创建一个类,它首先会调用自己的构造函数)CXXApp ::CXXApp(){}
3)进入Winmain函数(_tWinMain为宏,值为WinMain)
4)完成初始化工作:包括窗口类注册、窗口产生、显示和更新
pThread->InitInstance()
对于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口
① 注册窗口类
AfxEndDeferRegisterClass ()(相当于SDK里面的RegisterClass()函数)
②创建窗口
CMainFrame::PreCreateWindow()//反复调用一次用来修改窗口属性
CFrameWnd::Create()
③消息循环
PumpMessage()
结合了以上的各个内容,我们对WINDOWS应用程序有了一个基本的理解,在基于WINDOWS开发应用程序的时候MFC框架为我们提供了快捷有效的编程方式,类似于我们常见的填空题项一样,MFC框架为我们提供了应用程序建立所需要的主体代码,其中包含应用程序外观框架,应用程序消息处理机制框架等,这样就大大的加快了程序开发的过程,程序开发者可以主要的精力投入多商业逻辑的开发中,而不是在苦苦的在底层代码中挣扎,缩短了开发的周期,有效的提高了程序开发的效率。

刘红, 校云芳. MFC框架程序剖析[J]. 电脑知识与技术, 2012(12):99-101.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章