当前位置:C++技术网 > 资讯 > MFC框架封装底层代码详细解析

MFC框架封装底层代码详细解析

更新时间:2015-12-01 20:57:42浏览次数:1+次

新建一个MFC工程,我们详细解析MFC框架的底层封装代码。

为了更好的学习和掌握基于MFC的程序,有必要对MFC的运行机制,以及封装原理有所了解。在win32的编程中,winmain函数是所有的win32程序的入口函数,就像DOS下的mian函数一样。MFC程序也一样,他也有一个WinMain函数,但这个WinMain函数是在程序编译链接时,由链接器将该函数链接到MFC程序中。
在安装完的VC6.0的目录下,目录里有部分原代码。在Microsoft Visual Stual\VC98\MFC\SRC,
你可以相应的源代码。下面我们就看看WinMain函数的代码文件,在VC98\MFC\SRC目录下的APPMODUL.CPP文件中,我们打开它就能看到:

extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPTSTR lpCmdLine, int nCmdShow)
{
	// call shared/exported WinMain
	return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
通常我们的理解当中,WinMain函数应该是程序的入口函数。也就是说,程序运行时首先应该调用WinMain函数。但是VC中,会首先调用CTextApp类的构造函数。因为,在编译器运行时,无论是全局变量还是全局对象,程序在运行时,在加载mian函数之前,就已经为全局变量或全局对象分配了空间。对一个全局变量来说,此时就会调用该对象的构造函数,构造该对象,并进行初始化操作。
在MFC程序中,程序先运行到唯一的全局变量theApp变量处,但是此时接下来调用的却不是theApp的构造函数,而是变量theApp所属类的基类CWinApp的构造函数,从而就把我们程序自己创建的类与Microsoft提供的基类关联起来了。CWinApp的构造函数完成程序运行时的一些初始化工作。
当程序调用了CWinApp类的构造函数,并执行了CTextApp类的构造函数,且产生了theApp对象之后,接下来就进入WinMain函数。根据之前的代码,可以看到WinMain函数实际上是通过AfxWinMain函数来完成它的功能。
Afx前缀的函数代表应用程序框架函数。应用程序框架实际上是一套辅助我们生成应用程序的框架模型。在MFC中,所有以Afx为前缀的函数都是全局函数,可以在程序的任何地方调用他们。
看看AfxWinMain函数的源文件:


AfxWinMain首先调用AfxGetThread函数获得一个CWinThread类型的指针,接着调用AfxGetApp函数获得一个CWinApp类型的指针,同时CWinApp派生于CWinThread。
在MFC的底层代码中,我们看下AfxGetThread函数的源代码:

因此在AfxWinMain函数中的pThread和pApp这两指针是一致的。
再回到AfxWinMain函数的源代码中,可以看到接下来的代码中,pThread和pApp调用了三个函数(加灰显示的代码行2,3,4三行)这三个函数就完成了win32程序所需要的几个步骤:设计窗口类,注册窗口类,创建窗口,显示窗口,更新窗口,消息循环,以及窗口过程函数。pApp首先调用InitInstance函数,在MFC程序中,可以发现从CWinApp派生的应用程序类App中也有一个InitInstance函数,其生命如下,
virtual Bool InitInstance();
根据类的多态性原理,可以知道AfxWinMain函数这里实际上调用的是子类的InitInstance函数。你可以在MFC程序中查看InitInstance函数源码。这也是这个函数为什么声明为虚函数的原因。