您的位置:首页 > 其它

MFC消息处理与SDK消息处理

2009-01-01 00:38 323 查看
在MFC类实现中,采用消息映射实现对消息的响应,从而改变了在SDK中的循环结构,使得消息的流转更加隐蔽。
在SDK中有分三部分构成:

WNDCLASS wnd;
wnd.lpfnWndProc = WndProc ; // 首先将回调函数设置好

SDK循环结构,进行消息循环
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DisptachMessage(&msg);
}
而在另一处有回调函数的实现:
LPRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE: ... break;
case WM_PAINT: ... break;
case WM_LBUTTONDOWN: ... break;
case WM_LBUTTONUP:... break;
case WM_MOUSEMOVE:... break;
case WM_CHAR: ... break;
case WM_TIMER: ... break;
case WM_CLOSE: ... break;
case WM_DESTROYS: ... break;
case WM_QUIT: ... break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_XXX: break;
default: break;
}
break;
default: break;
}
DefWindowProc(hWnd,msg,wParam,lParam);
}

消息映射中为:
在MFC类定义结构中申明一个语句:
DECLARE_MESSAGE_MAP()
然后在全局空间实现中出现使用如下语句进行消息映射:
BEGIN_DECLARE
ON_WM_LBUTTONDOWM()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_PAINT()

ON_COMMAND(ID,lpFunc)
END_DECALRE

在类成员函数的实现中,将上面的消息映射函数进行实现。常用命令有固定的消息名称:
ON_WM_LBUTTONDOWN()映射函数为ONLBUTTONDOWN()函数,ON_WM_LBUTTONUP映射函数为LBUTTONUP()函数,ON_WM_MOUSEMOVE()映射函数为ONMOUSEMOVE()函数,ON_WM_PAINT()映射函数为ONPAINT()函数,而ON_COMMAND中的映射函数即为lpFunc函数。

情况下,消息映射声明不通过手工进行修改,而是在ClassWizard中进行修改,这样修改,可以避免因为手工修改时遗漏某个部分或者是输入时出现的一些小bug。

MFC的消息流转为从当前类APP流转到CWndApp,再流转到CWndThread类,在流转到CCmdTarget类,当CCmdTarget类中消息还不符合时,在流转到CWndThread中进行消息匹配。

虽然MFC消息比较难以理解,以及消息相对比较复杂,但是MFC消息函数的出现,使得对每个消息的实现变得很独立,比SDK中一连串的消息判断要清晰明白的多。

深入浅出中将MFC中消息映射设置成这么一个结构:
struct AFX_MSGMAP
{
AFX_MSGMAP* pBaseMessageMap;
AFX_MSGMAP_ENTRY* lpEntries;
};
struct AFX_MSGMAP_ENTRY // MFC 4.0 format
{
UINT nMessage; // windows message
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT nSig; // signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};
typedef void (CCmdTarget::*AFX_PMSG)(void);
#define DECLARE_MESSAGE_MAP() /
static AFX_MSGMAP_ENTRY _messageEntries[]; /
static AFX_MSGMAP messageMap; /
virtual AFX_MSGMAP* GetMessageMap() const;
其中的AFX_MSGMAP_ENTRY 又是另一个数据结构:
其中的AFX_PMSG 定义为函数指针:
然后我们定义一个宏:
#define DECLARE_MESSAGE_MAP() /
static AFX_MSGMAP_ENTRY _messageEntries[]; /
static AFX_MSGMAP messageMap; /
这个数据结构的填充有三个宏来实现:
#define BEGIN_MESSAGE_MAP(theClass, baseClass) /
AFX_MSGMAP* theClass::GetMessageMap() const /
{ return &theClass::messageMap; } /
AFX_MSGMAP theClass::messageMap = /
{ &(baseClass::messageMap), /
(AFX_MSGMAP_ENTRY*) &(theClass::_messageEntries) }; /
AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /
{
#define ON_COMMAND(id, memberFxn) /
{ WM_COMMAND, 0, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)memberFxn },
#define END_MESSAGE_MAP() /
{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } /
rtual AFX_MSGMAP* GetMessageMap() const;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: