消息的类中添加一些有关消息映射的内容和处理消息的成员函数。程序员将完成消
息处理函数,实现所希望的消息处理能力。
如果派生类要覆盖基类的消息处理函数,就用 ClassWizard 在派生类中添加一个
消息映射条目,用同样的原型定义一个函数,然后实现该函数。这个函数覆盖派生
类的任何基类的同名处理函数。
下面几节将分析 MFC 的消息机制的实现原理和消息处理的过程。为此,首先要
分析 ClassWizard 实现消息映射的内幕,然后讨论 MFC 的窗口过程,分析 MFC 窗
口过程是如何实现消息处理的。
消息映射的定义和实现
MFC 处理的三类消息
根据处理函数和处理过程的不同,MFC 主要处理三类消息:
Windows 消息,前缀以“WM_”打头,WM_COMMAND 例外。Windows 消息直
接送给 MFC 窗口过程处理,窗口过程调用对应的消息处理函数。一般,由窗口对象
来处理这类消息,也就是说,这类消息处理函数一般是 MFC 窗口类的成员函数。
控制通知消息,是控制子窗口送给父窗口的 WM_COMMAND 通知消息。窗口
过程调用对应的消息处理函数。一般,由窗口对象来处理这类消息,也就是说,这
类消息处理函数一般是 MFC 窗口类的成员函数。
需要指出的是,Win32 使用新的 WM_NOFITY 来处理复杂的通知消息。
WM_COMMAND 类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗 ID
和通知代码(wparam)。WM_NOTIFY 能传递任意复杂的信息。
命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的
WM_COMMAND 通知消息,属于应用程序自己定义的消息。通过消息映射机制,
MFC 框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,
如文档、窗口、应用程序、文档模板等对象。能处理消息映射的类必须从 CCmdTarget
类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。但是,要
知道怎么处理消息,首先要知道如何映射消息。
MFC 消息映射的实现方法
MFC 使用 ClassWizard 帮助实现消息映射,它在源码中添加一些消息映射的内
容,并声明和实现消息处理函数。现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息
映射的宏 DECLARE_MESSAGE_MAP。
在类的实现(实现文件)里,实现消息处理函数,并使用
IMPLEMENT_MESSAGE_MAP 宏实现消息映射。一般情况下,这些声明和实现是
由 MFC 的 ClassWizard 自动来维护的。看一个例子:
在AppWizard 产生的应用程序类的源码中,应用程序类的定义(头文件)包含
了类似如下的代码:
//{{AFX_MSG(CTttApp)
afx_msg void OnAppAbout();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
应用程序类的实现文件中包含了类似如下的代码:
BEGIN_MESSAGE_MAP(CTApp, CWinApp)
//{{AFX_MSG_MAP(CTttApp)