C++ MFC程序框架结构解析(详细)
MFC主要框架解析
- 一、MFC应用程序类型
- 二、MFC类与重要概念
- 1.1 应用程序结构类
- 1.2 窗口支持类
- 1.3 重要概念解析
- 1.3.1 Document 与 View
- 1.3.2 Document Frame
- 1.3.3 Document Template
- 三、MFC运行流程图
- 四、MDI 多文档界面应用程序
- 1.1类框架图
- 1.2 应用程序展示图
- 1.3 初始化函数InitInstance关键位置解析
- 五、SDI 单文档界面应用程序
- 1.1类框架图
- 1.2 应用程序展示图
- 1.3 初始化函数InitInstance关键位置解析
一、MFC应用程序类型
MFC应用程序中的类至少包含一个CWinApp应用程序类和一个CFrameWnd窗口框架类,其有三种典型的应用程序:
- 基于对话框的应用程序:这类程序适合于文档较少而交互操作较多的应用场合,如 Windows 自带的计算器程序。
- 单文档界面( SDI )应用程序:这类程序一次只能打开一个文档,如 Windows 自带的 Notepad 程序。
- 多文档界面( MDI )应用程序:这类程序可以同时打开多个文档并进行处理,处理的过程中很容易地进行切换,如 Microsoft Word 。
注 :多文档界面程序不仅可以打开多个文档同时处理,也可以打开不同类型的文档进行处理
二、MFC类与重要概念
MFC类分为两种:
1、CObject基类的派生类,它们以层次结构的形式组织起来,几乎每个子层次结构都与一个具体的 Windows实体对应;
2、非 CObject 派生类,这些都是独立的类,如表示点的 CPoint 类,表示矩形的 CRect 类等;
本文章主要讲解CObject基类的派生类
1.1 应用程序结构类
应用程序结构类代表的是应用程序的基本元素,主要是CCmdTarget类与它的派生类。其中CWinApp类,负责整个程序的执行流程。
- CCmdTarget类:是MFC类库中消息映射体系的基类,继承于Cobject类。该类负责把消息命令传递给用户编写的消息响应函数,如果需要处理消息,则从CCmdTarget类中派生一个类出来,但很少从CCmdTarget类直接派生类出来用。
- CWinThread类:CWinThread类继承于CCmdTarget类。CWinThread类的对象代表应用程序内部运行的线程。运行的主线程通常由CwinApp类的派生类提供。并CWinThread类支持两种线程:工作线程和用户界面线程。工作线程不能够发送、接收消息,通常用于后台运行。用户界面线程能够发送和接收消息。
- CWinApp【应用程序类】:CWinApp类继承于CWinThread类,MFC创建的所有应用程序中,都包含一个继承于该类的应用程序子类。负责程序的初始化、运行及退出。
- CDocument【文档类】:CDocument类是继承于CCmdTarget类。提供了文档的基本功能,主要用于代表程序中的数据。
- CDocTemplate【文档模版类】:CDocTemplate类继承于CCmdTarget类。通常通过应用程序类的InitInstance函数来创建一或多个文档模版。
1.2 窗口支持类
窗口支持类包含了基于Windows应用程序的一些可视性元素,如窗口,对话框,控件等。窗口支持类中的所有类都是从CWnd类中派生的,包括CFrameWnd类,CDialog类,CView类等。关系如下所示。
- CWnd类:CWnd类继承于CCmdTarget类。CWnd类提供了MFC中所有窗口类的基本功能,以及处理一些系统消息。
- CFrameWnd【框架窗口类】:CFrameWnd类继承于CWnd类。它是框架窗口类,封装对各种框架窗口的操作。
- CView【视图窗口类】:CView类继承于CWnd类。CView视图类是应用程序框架窗口中的子窗口,视图是用户与文档交互的媒介,用户可以在视图窗口内输入文本,绘图等。
- CDialog【对话框类】:CDialog类继承于CWnd类。CDialog对话框类是在屏幕上显示的对话框的基类。CDialog类对象是对话框模版与一个CDialog派生类的组合,通过使用对话框编辑器创建对话框并存入资源之中,然后为对话框创建一个CDialog派生类。
- 各种各样的控件类:控件类很多种,基本上都继承自CWnd类。例如CButton类,CEdit类等。
1.3 重要概念解析
1.3.1 Document 与 View
用最简单的一句话描述, Document 就是文件的体, View 就是文件的面
CDocument类可理解为用于处理存放文件数据的类,CView 就是负责文件数据的显示窗口类。
1.3.2 Document Frame
初学者很容易疑惑的地方,已经有专门处理数据的类CDocument,也有显示数据的窗口类CView ,为什么还有一个CFrameWnd框架窗口类?
你可以这么来理解
View本身虽然已经是一个窗口类,其外围却必须再包装一个CFrameWnd框架窗口做为舞台。这样的切割其实是为了让 View 可以非常独立地放置于「 MDI 框架窗口」或「 SDI 框架窗口」或「 OLE 框架窗口」等各种应用之中。也可以说,CFrameWnd框架窗口是View窗口的一个容器。文件的内容、文件的表象、以及「容纳文件表象的外框窗口」三者是一体的,换言之,程序每打开一份文件,就应该产生三份对象:
- 一份Document 对象,
- 一份View 对象,
- 一份CFrameWnd对象(做为外框窗口)
1.3.3 Document Template
上面已经知道了一个份文件会产生三份对象,那么Document Template的意义就是作为文档模板,将上面的三个对象绑定起来统一进行管理,换言之,文档模版定义了框架,文档和视图三个类之间的关系。
三、MFC运行流程图
四、MDI 多文档界面应用程序
1.1类框架图
下图为MFC多文档应用程序包含的类,需要理解每个类存在的作用;
1.2 应用程序展示图
结合上面的MDI框架图跟下面的应用程序展示图进行理解。
1.3 初始化函数InitInstance关键位置解析
- 首先定义了一个CMultiDocTemplate多文档模板类对象;
- 用多文档模板类对象将文档类CXXXDoc、子框架窗口类 CChildFrame 、视图类CXXXView联系在一起;
- 调用AddDocTemplate函数将这一多文档模板对象加入到应用程序维护的文档模板列表中。
- 再新建初始化一个主框架窗口类CMainFrame。
如果想打开编辑不同类型的文件比如 .txt 跟 .bmp 文件,这里就需要创建两个不同的模板对象。
五、SDI 单文档界面应用程序
1.1类框架图
1.2 应用程序展示图
结合上面的SDI框架图与下面的应用程序展示图进行理解。
1.3 初始化函数InitInstance关键位置解析
- 定义了一个CSingleDocTemplate单文档模板类对象;
- 用单文档模板类对象将文档类CXXXDoc、主框架窗口类CMainFrame、视图类 CXXXView联系在一起;
- 调用AddDocTemplate函数将这一单文档模板对象加入到应用程序维护的文档模板列表中。
- 主框架窗口类CMainFrame在2中已经新建初始化了。