MFC相关

1、MFC程序的main函数封装在库中,MFC程序内没有main函数。

对于C和C++来讲,程序以main函数作为入口函数,整个程序都是从入口函数进入的。一般来说,main函数是C程序的入口点,WinMain是Windows程序的入口点。当系统监测到用户欲执行一个Windows程序时,调用加载器把程序加载,然后调用C  startup code,后者再调用WinMain,开始执行程序。WinMain的4个参数由操作系统传入。

但是MFC从表面上看是没有main函数的。那它的main函数是怎么样的呢?

具体来说呢,MFC的main函数是长这样的:

// export WinMain to force linkage to this module
extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine, int nCmdShow);
这就是MFC整个程序的main函数,也就是整个程序的入口。

它藏在哪里呢?它藏在MFC的源文件appmodul.cpp中。

那main函数与MFC程序是如何联系起来的呢?

根据C++的规则,全局变量是先于main函数执行的。而在MFC程序中,有一个全局的对象,如下所示:

extern CTestMFCApp theApp;
这个全局的对象是一个继承于CWinApp类的对象。当操作系统将程序加载并激活后,这个全局对象获得配置及初始化,因此它的构造函数也会运行,而先于main函数。因此可以认为,MFC开始的地方是CWinApp子类对象的初始化。甚至可以说,CWinApp在MFC中替代了WinMain在SDK中的地位,做了主要的工作,而main函数只是简单的调用一下CWinApp的方法。CWinApp主要通过以下3个函数来完成对程序的创建:

virtual BOOL InitApplication();	// 窗口的注册
virtual BOOL InitInstance();	// 窗口的创建
virtual int Run();		// 消息的分发

在全局对象theApp初始化结束后,开始运行AfxWinMain函数。AfxWinMain函数的主要框架为:

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	_In_ LPTSTR lpCmdLine, int nCmdShow)
{
	
	CWinThread* pThread = AfxGetThread();
	CWinApp* pApp = AfxGetApp();

	pApp->InitApplication();
		
	pThread->InitInstance();
	
	nReturnCode = pThread->Run();

	return nReturnCode;
}

先通过全局函数获得CWinApp和CWinThread全局对象的指针,因为调用main之前已经初始化了这两个类。CTestMFCApp初始化时也会初始化他的父类CWinApp,及父类的父类CWinThread。

而接下来就调用CWinApp的3个主要函数完成程序的创建。

因此总结一下,MFC程序的执行顺序是:

a)theApp全局对象定义处

b)XApp构造函数

c)WinMain函数

因此全局对象分配空间要先于main函数,theApp全局对象表示程序本身,类似于hInstance。

2、那么,MFC中默认类的关系为:

App类中InitInstance()驱动Doc,View,MainFrame。

3、MFC默认程序有2个窗口:

其一为MainFrame对象所代表的应用程序框架窗口;

其二为CXView对象所代表的视类窗口。

其中,第一类为第二类的父窗口。

4、MFC运行机制与Win32 SDK一致,流程都是:

设计窗口类——注册窗口类——创建窗口——显示&更新窗口——消息循环

5、MFC基本类的继承结构图:


6、MFC消息响应机制

MFC消息响应是可以由MFC类向导自动添加的。它会在以下3个地方添加内容。以绘制命令为例:

a)头文件中消息响应函数的声明

afx_msg void OnPaint();

b)源文件中的消息映射宏

ON_WM_PAINT();

所有这些消息映射的宏都位于一对宏之中:

BEGIN_MESSAGE_MAP(CXView, CView)
        ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CtobedeletedView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_PAINT()
END_MESSAGE_MAP()

c)源文件中的函数实现

void CXView::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
}

MFC没有采用虚函数进行消息响应,因为虚函数表太大。它采用消息映射方式,在每个类中定义一个消息——消息函数的静态对照表(消息映射表)。在处理消息时,搜索此表,调用消息函数。



注:

1、这篇文章的内容主要是对前段时间做项目时做的笔记的总结。笔记来源于当时查阅的博客。在写此篇文章时,为了将内容串联起来,参考了著名的《深入浅出MFC》。

2、MFC确实是很老了,也很难用,理应被替代。但是很多时候还是会用到。《深入浅出MFC》这本书挺不错的,可以详细了解Windows编程的各种机制。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值