消息映射
一:为什么用消息映射
为了解决传统窗口函数的缺点,MFC引入了消息映射的概念。消息映射实际上是采用一张表(消息映射表),将消息标识和消息处理函数存储在其中,当调用窗口函数处理消息时,窗口函数搜索消息映射表,就可以调用消息映射表中对应消息的消息处理函数。
MFC就采用了上述的消息映射机制·它提供了一个消息映射的基类CCmdTarget,在CCmdTarget类中提供了一个消息映射表,以后与消息有关的类都应是CCmdTarget的派生类。这样,基类的消息映射表就可以与派生类的消息映射表连接起来。消息处理可以按着从派生类到基类的顺序搜索消息映射表。
二:消息映射表:
为了构建消息映射表,MFC的设计者们提供了两个数据结构AFX_MSGMAP_ENTRY和AFX_MSGMAP。
AFX_MSGMAP_ENTRY结构定义如下:
struct AFX_MSGMAP_ENTRY(静态数组_messageEntries[]的每个元素的类型)
{
UINT nMessage;
UINT nCode;
UINT nID;
UINT nLastID;
UINT_PTR nSig;
AFX_PMSG pfn;
};
参数说明
nMessage:表示消息标识。
nCode:控制代码或WMNOTIFY通知代码。
nID:控件ID,如果是窗口消息,nID为0。
nLastID:表示一定范围的命令中的最后一个命令或控件ID,用于将一组命令映射到同一个消息处理函数中。
nSig:消息处理函数的类型。
pfn:表示消息处理的地址(指针)。
pfn所表示的函数原型如下:
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
在AFX_MSGMAP_ENTRY结构中,对于每一个消息nMessage,都有对应的消息处理函数pfn。对于不同的消息,其消息处理函数的参数个数、参数类型一般也不会相同·而在AFX_MSGMAP_ENTRY结构中,则定义了统一的消息处理函数pfn.在MFC内部定义了一个用于转换消息处理函数的联合体MessageMapFuncuons,该结构定义如下:
union MessageMapFunctions
{
AFX_PMSG pfn;
void (AFX_MSG_CALL CCmdTarget::*pfnCmd_v_v)();
BOOL (AFX_MSG_CALL CCmdTarget::*pfnCmd_b_v)();
void (AFX_MSG_CALL CCmdTarget::*pfnCmd_v_u)(UINT);
BOOL (AFX_MSG_CALL CCmdTarget::*pfnCmd_b_u)(UINT);
.......//此处省略代码
};
其中,pfn对应于AFX_MSGMAP_ENTRY结构的pfn成员·该联合体的作用是将统一的消息处理函数的指针转换为特定的形式·分析下面代码:
union MessageMapFunctions mmf;
mmf.pfn = lpEntry->pfn;
switch (lpEntry->nSig)
{
default:
ASSERT(FALSE);
break;
case AfxSig_l_p:
{
CPoint point(lParam);
lResult = (