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;
};
在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;
};
相关文章推荐
- MFC消息处理与SDK消息处理
- MFC与SDK中的重画问题 。。WM_PAINT消息的处理
- MFC消息处理与SDK消息处理
- MFC与SDK中的重画问题 。。WM_PAINT消息的处理
- 【VC编程】笔记3---使用Win32SDK编程,模仿MFC的消息映射处理机制
- SDK对消息的处理过程和MFC消息映射及MFC中类产的对象与窗口
- MFC与SDK中的重画问题 。。WM_PAINT消息的处理
- MFC消息结构和消息处理
- MFC对消息处理的封装
- Win32 SDK基础(10)—— 几种常见的Windows消息处理
- MFC的消息处理机制由两部分组成:CCmdTarget类和消息映射表。
- MFC消息处理函数是怎么映射的
- 使用VS2012 MFC自定义消息时,处理函数不能返回void类型。
- MFC程序的消息处理顺序
- MFC消息处理顺序
- MFC之按键消息(长按处理)
- MFC的来龙去脉-----消息循环,找处理场所
- 使用SDK实现MFC模式的处理方法(一)
- MFC消息处理笔记
- MFC之处理消息映射的步骤...