MDI应用程序的构成

本文来自编程入门网:http://www.bianceng.cn/Programming/vc/201003/16098_2.htm

 

本节解释一个典型的MDI应用程序的构成。

用AppWizard产生一个MDI工程t(无OLE等支持),AppWizard创建了一系列文件,构成了一个应用程序框架。这些文件分四类:头文件(.h),实现文件(.cpp),资源文件(.rc),模块定义文件(.def),等。

构成应用程序的对象

图1-1解释了该应用程序的结构,箭头表示信息流向。


从CWinApp、CDocument、CView、CMDIFrameWnd、CMDIChildWnd类对应地派生出CTApp、CTDoc、CTView、CMainFrame、CChildFrame五个类,这五个类的实例分别是应用程序对象、文档对象、视对象、主框架窗口对象和文档边框窗口对象。主框架窗口包含了视窗口、工具条和状态栏。对这些类或者对象解释如下。

(1)应用程序

应用程序类派生于CWinApp。基于框架的应用程序必须有且只有一个应用程序对象,它负责应用程序的初始化、运行和结束。

(2)边框窗口

如果是SDI应用程序,从CFrameWnd类派生边框窗口类,边框窗口的客户子窗口(MDIClient)直接包含视窗口;如果是MDI应用程序,从CMDIFrameWnd类派生边框窗口类,边框窗口的客户子窗口(MDIClient)直接包含文档边框窗口。

如果要支持工具条、状态栏,则派生的边框窗口类还要添加CToolBar和CStatusBar类型的成员变量,以及在一个OnCreate消息处理函数中初始化这两个控制窗口。

边框窗口用来管理文档边框窗口、视窗口、工具条、菜单、加速键等,协调半模式状态(如上下文的帮助(SHIFT+F1模式)和打印预览)。

(3)文档边框窗口

文档边框窗口类从CMDIChildWnd类派生,MDI应用程序使用文档边框窗口来包含视窗口。

(4)文档

文档类从CDocument类派生,用来管理数据,数据的变化、存取都是通过文档实现的。视窗口通过文档对象来访问和更新数据。

(5)视

视类从CView或它的派生类派生。视和文档联系在一起,在文档和用户之间起中介作用,即视在屏幕上显示文档的内容,并把用户输入转换成对文档的操作。

(6)文档模板

文档模板类一般不需要派生。MDI应用程序使用多文档模板类CMultiDocTemplate;SDI应用程序使用单文档模板类CSingleDocTemplate。

应用程序通过文档模板类对象来管理上述对象(应用程序对象、文档对象、主边框窗口对象、文档边框窗口对象、视对象)的创建。

 

构成应用程序的对象之间的关系


这里,用图的形式可直观地表示所涉及的MFC类的继承或者派生关系,如图1-2所示意。

图1-2所示的类都是从CObject类派生出来的;所有处理消息的类都是从CCmdTarget类派生的。如果是多文档应用程序,文档模板使用CMultiDocTemplae,主框架窗口从CMdiFarmeWnd派生,它包含工具条、状态栏和文档框架窗口。文档框架窗口从CMdiChildWnd派生,文档框架窗口包含视,视从CView或其派生类派生。

 

构成应用程序的文件

通过上述分析,可知AppWizard产生的MDI框架程序的内容,所定义和实现的类。下面,从文件的角度来考察AppWizard生成了哪些源码文件,这些文件的作用是什么。表1-1列出了AppWizard所生成的头文件,表1-2列出了了AppWizard所生成的实现文件及其对头文件的包含关系。

表1-1 AppWizard所生成的头文件

头文件 用途
stdafx.h 标准AFX头文件
resource.h 定义了各种资源ID
t.h #include "resource.h"
定义了从CWinApp派生的应用程序对象CTApp

childfrm.h 定义了从CMDIChildWnd派生的文档框架窗口对象CTChildFrame
mainfrm.h 定义了从CMDIFrameWnd派生的框架窗口对象CMainFrame
tdoc.h 定义了从CDocument派生的文档对象CTDoc
tview.h 定义了从CView派生的视图对象CTView

表1-2 AppWizard所生成的实现文件

实现文件 所包含的头文件 实现的内容和功能
stdafx.cpp #include "stdafx.h" 用来产生预编译的类型信息。
t.cpp # include "stdafx.h"
# include "t.h"
# include "MainFrm.h"
# include "childfrm.h"
#include "tdoc.h"
#include "tview.h" 定义CTApp的实现,并定义CTApp类型的全局变量theApp。
childfrm.cpp #inlcude "stdafx.h"
#include "t.h"
#include “childfrm.h” 实现了类CChildFrame
childfrm.cpp #inlcude "stdafx.h"
#include "t.h"
#include "childfrm.h" 实现了类CMainFrame
tdoc.cpp # include "stdafx.h"
# include "t.h"
# include "tdoc.h" 实现了类CTDoc
tview.cpp # include "stdafx.h"
# include "t.h"
# include "tdoc.h"
# include "tview.h" 实现了类CTview

从表1-2中的包含关系一栏可以看出:

CTApp 的实现用到所有的用户定义对象,包含了他们的定义;CView 的实现用到CTdoc;其他对象的实现只涉及自己的定义;

当然,如果增加其他操作,引用其他对象,则要包含相应的类的定义文件。

 

对预编译头文件说明如下:

所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。

预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。

编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。

因此,所有的CPP实现文件第一条语句都是:#include "stdafx.h"。

另外,每一个实现文件CPP都包含了如下语句:

#ifdef _DEBUG

#undef THIS_FILE

static char BASED_CODE THIS_FILE[] = __FILE__;

#endif

这是表示,如果生成调试版本,要指示当前文件的名称。__FILE__是一个宏,在编译器编译过程中给它赋值为当前正在编译的文件名称。

 

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