1.使用MFC AppWizard生成一个单文档应用程序框架。
(1)启动Visual Studio 6.0
(2) 文件->新建->项目->MFC AppWizard(exe)->输入项目名称MySDI
(3) Step1,选择Single Document。
(4) Step2~6,选择默认。
(5) F7,Build MySDI.exe即可运行。
2.MFC程序框架解析
(1)MFC AppWizard生成的工程框架如下图所示。
(2)让我们通过项目自述文件Readme.txt来看一看MySDI项目生成的文件类型及功能结构。
<1>框架窗口类实现文件
MainFrm.h, MainFrm.cpp
These files contain the frame class CMainFrame, which is derived from
CFrameWnd and controls all SDI frame features.
MainFrm.h和MainFrm.cpp 为框架窗口类实现文件
该组文件包含了窗口类CMainFrame的实现代码,它主要负责创建标题栏、菜单栏、工具栏和状态栏。它实现的窗口为应用程序的主窗口。
<2>文档类实现文件
MySDIDoc.h, MySDIDoc.cpp - the document
These files contain your CMySDIDoc class. Edit these files to
add your special document data and to implement file saving and loading
(via CMySDIDoc::Serialize).
MFCFrameDoc.h和MFCFrameDoc.cpp为文档类实现文件
它主要负责应用程序数据的保存和装载,实现文档的序列化功能。在多文档程序中,当用户执行File菜单中的New时,MFC应用程序框架会调用OnNewDocument()来新建文档。Serialize函数负责文档数据的磁盘读写操作。
<3>视图类实现文件
MySDIView.h, MySDIView.cpp - the view of the document
These files contain your CMySDIView class.
CMySDIView objects are used to view CMySDIDoc objects.
MySDIView.h, MySDIView.cpp为视图类实现文件
它主要负责客户区文档数据的显示,以及如何进行人机交互。视图对象是用来显示文档对象的内容的,函数GetDocument()用于获取当前文档对象的指针m_pDocument. 另外一个很重要的函数OnDraw负责将文档对象的数据显示输出到用户视图区。
<4>应用程序类实现文件
MySDI.h
This is the main header file for the application. It includes other
project specific headers (including Resource.h) and declares the
CMySDIApp application class.
MySDI.cpp
This is the main application source file that contains the application
class CMySDIApp.
MySDI.h和MySDI.cpp为应用程序类实现文件。
该组文件是应用程序的主函数文件,MFC应用程序的初始化、启动运行和结束都是由应用程序对象完成。
<5>资源头文件
Resource.h
This is the standard header file, which defines new resource IDs.
Microsoft Visual C++ reads and updates this file.
Resource.h为资源头文件
在项目中,资源通过资源标识符加以区别,通常将一个项目中所有的资源标识符放在头文件Resourde.h中定义。
<6>应用程序生成的资源文件
[1].资源文件
向导为项目Mysdi生成了资源文件MySDI.rc和MySDI.rc2。MySDI.rc是Visual C++生成的脚本文件,它使用标准的Windows资源定义语句,可通过资源编译器转换为二进制资源。一般利用资源编辑器对资源进行可视化编辑,也可通过Open命令以文本方式打开一个资源文件进行编辑。MySDI.rc2文件一般用于定义资源编辑器不能编辑的资源。
[2].图标文件
向导为项目Mysdi生成了应用程序的图标文件MySDI.ico。在Visual C++中,可利用图形编辑器编辑应用程序的图标。
[3].文档图标文件
向导为项目Mysdi生成了文档图标文件MySDIDoc.ico。文档图标一般用于多文档应用程序中,在程序MySDI中没有显示这个图标,但编程时用户可以利用相关函数来获取该图标资源并显示图标(ID为IDR_MYSDITYPE)。
[4].工具栏按钮位图文件
向导为项目MySDI生成了工具栏按钮的位图文件Toolbar.bmp,该位图是应用程序工具栏中所有按钮的图形表示。
<7>标准包含头文件
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named MySDI.pch and a precompiled types file named StdAfx.obj.
stdafx.h和stdafx.cpp,stdafx为Standard Application Framework X,stdafx.h为标准包含文件, stdafx.h和stdafx.cpp用来生成预编译文件。其机制如下:
Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程序也要花费相当长的时间来完成工作。由于每个.CPP文件都包含相同的include文件,为每个.CPP文件都重复处理这些文件就显得很傻了。 为避免这种浪费,AppWizard和VisualC++编译程序一起进行工作,如下所示:
◎AppWizard建立了文件stdafx.h,该文件包含了所有当前工程文件需要的MFCinclude文件。且这一文件可以随被选择的选项而变化。
◎AppWizard然后就建立stdafx.cpp。这个文件通常都是一样的。
◎然后AppWizard就建立起工程文件,这样第一个被编译的文件就是stdafx.cpp。
◎当VisualC++编译stdafx.cpp文件时,它将结果保存在一个名为stdafx.pch的文件里。(扩展名pch表示预编译头文件。)
◎当VisualC++编译随后的每个.cpp文件时(你可以打开下面的4个.CPP文件看到都#include<stdafx.h>),它阅读并使用它刚生成的.pch文件。VisualC++不再分析Windows include文件,除非你又编缉了stdafx.cpp或stdafx.h。
3.MFC的框架视图文档的关联
以下代码摘自BOOL CMySDIApp::InitInstance()// CMySDIApp initialization
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMySDIDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CMySDIView));
AddDocTemplate(pDocTemplate);
文档模版类CdocTemplate的构造函数如下:
CDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
文档模板对象创建后,调用CWinApp::AddDocTemplate来注册文档模板对象,用于链接文档、框架窗口和视图。
宏RUNTIME_CLASS(class_name):
返回参数class_name所指定类的静态成员变量class##class_name的指针,该指针指向一个CRuntimeClass结构。
运行时类型识别RTTI(Run Time Type Information)是指在程序运行时允许确定对象的类型。MFC扩充了一般C++中运行时类型识别的功能,当一个类支持MFC的运行时类型识别时,它允许程序获取对象的信息(如类名、所占存储空间大小及版本号等)和基类信息。关于运行时动态类型识别和动态创建请参考有关书籍。
4.MFC应用程序对象之间的关系
参考:
《Windows程序设计》王艳平&张铮
《VC++深入详解》 孙鑫
《跟我学Visual C++ 6 [Visual C++ 6 Programming Blue Book]》 Stephen D.Gilbert
《深入浅出MFC》 侯捷