3.2基于MFC的程序框架剖析
利用MFC AppWizard创建一个基于MFC的单文档界面(SDI)应用程序Test。
图 3.10
图3.10是MFC AppWizard帮助我们生成的代码。在Class View(类视图)标签页,可以看到图 3.10所示的五个类。在MFC中,类的命名都以字母“C“开头。
图 3.11 部分MFC类组织结构图
CWnd类封装了与窗口相关的操作。
3.2.1 MFC程序中的WinMain函数
在安装完Microsoft Visual Studio 6.0后,在安装目录下(C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC),微软提供了部分MFC源代码,可以跟踪这些源代码,来找出程序的运行脉络。
图 3.12 包含“WinMain”文字的搜索结果
WinMain函数在APPMODUL.CPP这个文件中。双击APPMODUL.CPP可在VC++环境中打开该文件。例 3-1所示是这段代码。
例 3-1
在WinMain函数中按下F9键设置一个断点,然后按下F5调试运行当前程序。可以看到程序确实运行到该断点处停了下来,如图3.13所示。说明Test这个MFC程序确实有WinMain函数,在程序编译链接时,WinMain函数就成为该程序的一部分。
图3.13 程序运行到 WinMain 断点处
在_tWinMain上单击鼠标右键,选择【Go To Definition Of _tWinMain】,光标就会定位到_tWinMain函数的定义处。如例3-2所示,发现_tWinMain实际上是一个宏,展开就是WinMain函数。
例3-2
1. theApp全局对象
双击Class View标签页中的CTestApp类,跳转到该类的头文件(Test.h)中。可以发现CTestApp派生于CWinApp类,后者表示应用程序类。
在Class View标签页中的打开CTestApp类前面的“+”符号,双击该类的构造函数,跳转到该类的源文件(Test.cpp)中。
通过设置断点发现程序执行的顺序依次是:theApp全局对象定义处、TestApp构造函数,然后才是WinMain函数。
应用程序的实例是由实例句柄(WinMain函数的参数是hInstance)来标识的。而对MFC程序来说,通过产生一个应用程序类的对象来惟一标识应用程序的实例。每一个MFC程序有且仅有一个从应用程序(CWinApp)派生的类。每一个MFC程序实例有且仅有一个该派生类的实例化对象,也就是theApp全局对象。
查看CWinApp类构造函数的定义。找到appcore.cpp源文件。
例 3-5
上述CWinApp的构造函数中有这样一名代码:
pModuleState->m_pCurrentWinApp = this;
根据C++继承性原理,这个this对象代表的是子类