在上面的例子中,CDerived从CBase中派生出来。CDerived类通过定义一个WM_LBUTTONDOWN消息处理函数来改变CBase类代表的窗口的功能。
这样,CBase类的消息映射定义了一个ProcessWindowMessage()函数,而CDerived类的消息映射也定义了一个ProcessWindowMessage()函数。
那么,我们在窗口处理函数逻辑中怎样把这两个类的ProcessWindowMessage()连起来呢?(想想为什么要连起来?)
在CDerived的消息映射中,有一个宏CHAIN_MSG_MAP()。它的作用就是把两个类对消息的处理连起来。
看一下这个宏的定义:
很简单,它仅仅调用了基类的ProcessWindowMessage()函数。
也就是说,CDerived类的ProcessWindowMessage()包含两部分,一部分是调用处理WM_LBUTTONDOWN的消息处理函数,该函数是该类的成员函数。第二部分是调用CBase类的ProcessWindowMessage()函数,该函数用于处理WM_DESTROY消息。
在后面对窗口函数的封装中,我们会知道,对于其他消息处理,CDerived会传递给缺省窗口函数。
派生和ALT_MSG_MAP()
如果我们希望在CBase类上再派生一个新的窗口类。该类除了要对WM_RBUTTONDOWN做不同的处理外,还希望CBase对WM_DESTROY消息的响应与前一个例子不同。比如希望能提示关闭窗口信息。
那怎么处理呢?ATL提供了一种机制,它由ALT_MSG_MAP()实现。它使得一个类的消息映射能处理多个Windows窗口类。
下面是具体的示例:
ALT_MSG_MAP()将消息映射分成两个部分。每个部分的消息映射都有一个ID。上面的消息映射的ID分别为0和100。
分析一下ALT_MSG_MAP():
很简单,它结束了前面的msgMapID的处理,开始进入另一个msgMapID的处理。
那么,在CDerived类的消息映射中,是怎样将两个类的ProcessWindowMessage()函数的逻辑连在一起的呢?
这里使用CHAIN_MSG_MAP_ALT()宏。它的具体定义如下:
不再分析其原理。请参考前面对CHAIN_MSG_MAP()宏的分析。
这样,CBase类的消息映射定义了一个ProcessWindowMessage()函数,而CDerived类的消息映射也定义了一个ProcessWindowMessage()函数。
那么,我们在窗口处理函数逻辑中怎样把这两个类的ProcessWindowMessage()连起来呢?(想想为什么要连起来?)
在CDerived的消息映射中,有一个宏CHAIN_MSG_MAP()。它的作用就是把两个类对消息的处理连起来。
看一下这个宏的定义:
#define CHAIN_MSG_MAP(theChainClass) /
{ /
if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) /
return TRUE; /
}
|
很简单,它仅仅调用了基类的ProcessWindowMessage()函数。
也就是说,CDerived类的ProcessWindowMessage()包含两部分,一部分是调用处理WM_LBUTTONDOWN的消息处理函数,该函数是该类的成员函数。第二部分是调用CBase类的ProcessWindowMessage()函数,该函数用于处理WM_DESTROY消息。
在后面对窗口函数的封装中,我们会知道,对于其他消息处理,CDerived会传递给缺省窗口函数。
派生和ALT_MSG_MAP()
如果我们希望在CBase类上再派生一个新的窗口类。该类除了要对WM_RBUTTONDOWN做不同的处理外,还希望CBase对WM_DESTROY消息的响应与前一个例子不同。比如希望能提示关闭窗口信息。
那怎么处理呢?ATL提供了一种机制,它由ALT_MSG_MAP()实现。它使得一个类的消息映射能处理多个Windows窗口类。
下面是具体的示例:
// in class CBase:
BEGIN_MSG_MAP( CBase )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy1 )
ALT_MSG_MAP( 100 )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy2 )
END_MSG_MAP()
|
ALT_MSG_MAP()将消息映射分成两个部分。每个部分的消息映射都有一个ID。上面的消息映射的ID分别为0和100。
分析一下ALT_MSG_MAP():
#define ALT_MSG_MAP(msgMapID) / break; / case msgMapID: |
很简单,它结束了前面的msgMapID的处理,开始进入另一个msgMapID的处理。
那么,在CDerived类的消息映射中,是怎样将两个类的ProcessWindowMessage()函数的逻辑连在一起的呢?
// in class CDerived:
BEGIN_MSG_MAP( CDerived )
CHAIN_MSG_MAP_ALT( CBase, 100 )
END_MSG_MAP()
|
这里使用CHAIN_MSG_MAP_ALT()宏。它的具体定义如下:
#define CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) /
{ /
if(theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult,
msgMapID)) /
return TRUE; /
}
|
不再分析其原理。请参考前面对CHAIN_MSG_MAP()宏的分析。
博客围绕Windows类的消息映射处理展开。介绍了CDerived类从CBase类派生后,通过CHAIN_MSG_MAP()宏将两个类的ProcessWindowMessage()函数连接以处理消息。还提及在派生新窗口类时,ATL的ALT_MSG_MAP()机制可使类的消息映射处理多个窗口类,用CHAIN_MSG_MAP_ALT()宏连接逻辑。
2383

被折叠的 条评论
为什么被折叠?



