以Windows API开发程序,程序从进入点开始,然后产生窗口类别、窗口、取得消息、分辨消息,然后决定如何处理消息:

mfc开发参考手册(抽丝剥茧理解一个MFC)(1)

以MFC 开发程序开发工具会为你产生一个骨干程序,一般该有的各种接口一应俱全:

mfc开发参考手册(抽丝剥茧理解一个MFC)(2)

MFC就是用C 语言的类来封装Windows API:

mfc开发参考手册(抽丝剥茧理解一个MFC)(3)

SDK 程序设计的第一要务是了解最重要的数个API 函数的意义和用法, 像RegisterClass、CreateWindow、GetMessage、DispatchMessage,以及消息的获得与分配。MFC 程序设计的第一要务则是熟记MFC 的类别阶层架构,并清楚知晓其中几个一定会用到的类别。

mfc开发参考手册(抽丝剥茧理解一个MFC)(4)

一个"Hello MFC" 程序的两个类别在MFC 的地位如下图所示:

mfc开发参考手册(抽丝剥茧理解一个MFC)(5)

每一个MFC程序都想从MFC中衍生出适当的类别来用(不然又何必以MFC写程序呢),其中两个不可或缺的类别CWinApp和CFrameWnd在Hello程序中会表现出来。

MFC类别中某些函数一定得被应用程序改写(例如CWinApp::InitInstance)。

mfc开发参考手册(抽丝剥茧理解一个MFC)(6)

Hello 程序的基本文件架构。一般习惯为每个类别准备一个.H( 声明)和一个.CPP(实作)。

mfc开发参考手册(抽丝剥茧理解一个MFC)(7)

SDK 程序的WinMain 所完成的工作现

在由CWinApp 的三个函数完成:

virtual BOOL InitApplication(); virtual BOOL InitInstance(); virtual int Run();

mfc开发参考手册(抽丝剥茧理解一个MFC)(8)

CFrameWnd::Create 产生主窗口(并先注册窗口类别)

mfc开发参考手册(抽丝剥茧理解一个MFC)(9)

CWinApp::Run

mfc开发参考手册(抽丝剥茧理解一个MFC)(10)

把消息与处理函数串接在一起:Message Map 机制

mfc开发参考手册(抽丝剥茧理解一个MFC)(11)

MFC 应用程序代码一开始是一个衍生自CWinApp 的全域对象application object,然后是一个隐藏的WinMain 函数,调用application object 的InitInstance 函数,将程序初始化。初始化动作包括构造一个窗口对象(CFrameWnd 物件),而其构造式又调用CFrameWnd::Create 产生真正的窗口(并在产生之前要求MFC注册窗口类别)。窗口产生后WinMain 又调用Run 激活消息循环,将WM_COMMAND(IDM_ABOUT)和WM_PAINT 分别交给成员函数OnAbout 和OnPaint 处理。

MFC 应用程序的诞生:

■ Application object 产生,内存于是获得配置,初值亦设立了。

■ Afx WinMain 执行AfxWinInit,后者又调用AfxInitThread,把消息队列尽量加大。

■ Afx WinMain 执行InitApplication。这是CWinApp 的虚拟函数,但我们通常不改写它。

■ AfxWinMain 执行InitInstance。这是CWinApp 的虚拟函数,我们必须改写它。

■ CMyWinApp::InitInstance 'new' 一个CMyFrameWnd 对象。

■ CMyFrameWnd 构造式调用Create,产生主窗口。我们在Create 参数中指定的窗口类别是NULL, 于是MFC 根据窗口种类, 自行为我们注册一个名为"AfxFrameOrView42d" 的窗口类别。

■ 回到InitInstance 中继续执行ShowWindow,显示窗口。

■ 执行UpdateWindow,于是发出WM_PAINT。

■ 回到AfxWinMain,执行Run,进入消息循环。

MFC 应用程序开始运作:

■ 程序获得WM_PAINT 消息(藉由CWinApp::Run 中的::GetMessage 循环)。

■ WM_PAINT 经由::DispatchMessage 送到窗口函数CWnd::DefWindowProc 中。

■ CWnd::DefWindowProc 将消息绕行过消息映射表格(Message Map)。

■ 绕行过程中发现有吻合项目,于是调用项目中对应的函数。此函数是应用程序利用BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之间的宏设立起来的。

( 标准消息的处理例程亦有标准命名,例如WM_PAINT 必然由OnPaint 处理。)

MFC 应用程序的死亡:

■ 使用者选按【File/Close】,于是发出WM_CLOSE。

■ CMyFrameWnd 并没有设置WM_CLOSE 处理例程,于是交给预设之处理例程。

■ 预设函数对于WM_CLOSE 的处理方式是调用::DestroyWindow, 并因而发出WM_DESTROY。

■ 预设之WM_DESTROY 处理方式是调用::PostQuitMessage,因此发出WM_QUIT。

■ CWinApp::Run 收到WM_QUIT 后会结束其内部之消息循环, 然后调用ExitInstance,这是CWinApp 的一个虚拟函数。

■ 如果CMyWinApp 改写了ExitInstance , 那么CWinApp::Run 所调用的就是CMyWinApp::ExitInstance,否则就是CWinApp::ExitInstance。

■ 最后回到AfxWinMain,执行AfxWinTerm,结束程序。

附:VC中可调用的函数大致可分三类

1、类自己的函数,只对类自己的数据成员有作用。例如MFC中 MessageBox的原型,它是属于 CWnd 类的成员函数,只能在 CWnd 和CWnd的派生类的对象中调用;当然,也可以直接调用类中的其他成员函数;

2、AFX小组在设计Application Framworks 时设计的全局函数,多冠在Afx前缀,在包含了MFC库/框架的工程中可用。例如AfxMessageBox可在任何地方调用。

3、Windows API的全局函数。对所有Windows平台下的程序设计都可以调用,如Vb,Vc,Dephi等等。

参考:《深入浅出MFC》

-End-

,