090921(星期一):MFC消息路由6, Frame8代码分析,GetMessageMap获取了谁的Map
2009-09-22 00:28
453 查看
Monday, September 21, 2009
一、宏替换为代码进行调试
Frame8消息分发AfxWndProc(0, WM_CREATE, 0, 0, pMyFrame);
进入LRESULT CWnd::WindowProc(WM_CREATE, 0, 0)
之后:
// 调试跟不进去,模拟MFC都做成宏了。
// 消息映射的知识就在这儿了,可以参考0914的笔记。
// 获取消息映射指针
pMessageMap = GetMessageMap();
// 遍历消息
for (; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMessageMap)
{
lpEntry = pMessageMap->lpEntries;
printlpEntries(lpEntry);
}
return 0; // add by JJHou. if find, should call lpEntry->pfn,
// otherwise should call DefWindowProc.
上面的语句究竟是如何进行的,使用单步调试的方法加深印象。
1, 备份四个源文件
2, 将CMyFrameWnd类相关的宏使用代码替换
#define DECLARE_MESSAGE_MAP()
static AFX_MSGMAP_ENTRY _messageEntries[];
static AFX_MSGMAP messageMap;
virtual AFX_MSGMAP* GetMessageMap() const;
#define BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
{ return &CMyFrameWnd::messageMap; }
AFX_MSGMAP CMyFrameWnd::messageMap =
{
&(CFrameWnd::messageMap),
(AFX_MSGMAP_ENTRY*) &(CMyFrameWnd::_messageEntries)
};
AFX_MSGMAP_ENTRY CMyFrameWnd::_messageEntries[] =
{
ON_COMMAND(CMyFrameWndid, 0)
{ WM_COMMAND, 0, (WORD) CMyFrameWndid, (WORD) CMyFrameWndid, AfxSig_vv, (AFX_PMSG)memberFxn },
#define END_MESSAGE_MAP()
{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } };
3, 替换之后的代码
class CMyFrameWnd : public CFrameWnd
{
public:
CMyFrameWnd();
~CMyFrameWnd() {
}
// DECLARE_MESSAGE_MAP()
static AFX_MSGMAP_ENTRY _messageEntries[];
static AFX_MSGMAP messageMap;
virtual AFX_MSGMAP* GetMessageMap() const;
};
//BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
//ON_COMMAND(CMyFrameWndid, 0)
//END_MESSAGE_MAP()
AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
{ return &CMyFrameWnd::messageMap; }
AFX_MSGMAP CMyFrameWnd::messageMap =
{
&(CFrameWnd::messageMap),
(AFX_MSGMAP_ENTRY*) &(CMyFrameWnd::_messageEntries)
};
AFX_MSGMAP_ENTRY CMyFrameWnd::_messageEntries[] =
{
{ WM_COMMAND, 0, (WORD) CMyFrameWndid, (WORD) CMyFrameWndid, AfxSig_vv, (AFX_PMSG)0 },
{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
4、调试时就可以清楚的看见,this指针的类型是CMyFrameWnd,不是CFrameWnd,更不是CWnd。
消息栈:
AfxWndProc(0, WM_CREATE, 0, 0, pMyFrame);
return AfxCallWndProc(pMyFrame, 0, WM_CREATE, 0, 0);
LRESULT lResult = pMyFrame ->WindowProc(WM_CREATE, 0, 0);
WindowProc函数在被调用时,代码是CWnd中定义的函数代码:
LRESULT CWnd::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
AFX_MSGMAP* pMessageMap;
AFX_MSGMAP_ENTRY* lpEntry;
if (nMsg == WM_COMMAND) // special case for commands
{
if (OnCommand(wParam, lParam))
return 1L; // command handled
else
return (LRESULT)DefWindowProc(nMsg, wParam, lParam);
}
pMessageMap = GetMessageMap();
for (; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMessageMap)
{
lpEntry = pMessageMap->lpEntries;
printlpEntries(lpEntry);
}
return 0; // add by JJHou. if find, should call lpEntry->pfn,
// otherwise should call DefWindowProc.
}
但是this指针是指向CMyFrameWnd的。
至于pMyFrame在声名的时候是CFrameWnd类型,而this是指向CMyFrameWnd的这个问题,完全是和虚函数表现一致,尽管声名成CFrameWnd类型:
CFrameWnd* pMyFrame
但是系统非常清楚它的实际类型。
总之,在GetMessageMap时,获取的是
AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
{ return &CMyFrameWnd::messageMap; }
通过单步跟踪就看得更加真切了。
一、宏替换为代码进行调试
Frame8消息分发AfxWndProc(0, WM_CREATE, 0, 0, pMyFrame);
进入LRESULT CWnd::WindowProc(WM_CREATE, 0, 0)
之后:
// 调试跟不进去,模拟MFC都做成宏了。
// 消息映射的知识就在这儿了,可以参考0914的笔记。
// 获取消息映射指针
pMessageMap = GetMessageMap();
// 遍历消息
for (; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMessageMap)
{
lpEntry = pMessageMap->lpEntries;
printlpEntries(lpEntry);
}
return 0; // add by JJHou. if find, should call lpEntry->pfn,
// otherwise should call DefWindowProc.
上面的语句究竟是如何进行的,使用单步调试的方法加深印象。
1, 备份四个源文件
2, 将CMyFrameWnd类相关的宏使用代码替换
#define DECLARE_MESSAGE_MAP()
static AFX_MSGMAP_ENTRY _messageEntries[];
static AFX_MSGMAP messageMap;
virtual AFX_MSGMAP* GetMessageMap() const;
#define BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
{ return &CMyFrameWnd::messageMap; }
AFX_MSGMAP CMyFrameWnd::messageMap =
{
&(CFrameWnd::messageMap),
(AFX_MSGMAP_ENTRY*) &(CMyFrameWnd::_messageEntries)
};
AFX_MSGMAP_ENTRY CMyFrameWnd::_messageEntries[] =
{
ON_COMMAND(CMyFrameWndid, 0)
{ WM_COMMAND, 0, (WORD) CMyFrameWndid, (WORD) CMyFrameWndid, AfxSig_vv, (AFX_PMSG)memberFxn },
#define END_MESSAGE_MAP()
{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } };
3, 替换之后的代码
class CMyFrameWnd : public CFrameWnd
{
public:
CMyFrameWnd();
~CMyFrameWnd() {
}
// DECLARE_MESSAGE_MAP()
static AFX_MSGMAP_ENTRY _messageEntries[];
static AFX_MSGMAP messageMap;
virtual AFX_MSGMAP* GetMessageMap() const;
};
//BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
//ON_COMMAND(CMyFrameWndid, 0)
//END_MESSAGE_MAP()
AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
{ return &CMyFrameWnd::messageMap; }
AFX_MSGMAP CMyFrameWnd::messageMap =
{
&(CFrameWnd::messageMap),
(AFX_MSGMAP_ENTRY*) &(CMyFrameWnd::_messageEntries)
};
AFX_MSGMAP_ENTRY CMyFrameWnd::_messageEntries[] =
{
{ WM_COMMAND, 0, (WORD) CMyFrameWndid, (WORD) CMyFrameWndid, AfxSig_vv, (AFX_PMSG)0 },
{ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
4、调试时就可以清楚的看见,this指针的类型是CMyFrameWnd,不是CFrameWnd,更不是CWnd。
消息栈:
AfxWndProc(0, WM_CREATE, 0, 0, pMyFrame);
return AfxCallWndProc(pMyFrame, 0, WM_CREATE, 0, 0);
LRESULT lResult = pMyFrame ->WindowProc(WM_CREATE, 0, 0);
WindowProc函数在被调用时,代码是CWnd中定义的函数代码:
LRESULT CWnd::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
AFX_MSGMAP* pMessageMap;
AFX_MSGMAP_ENTRY* lpEntry;
if (nMsg == WM_COMMAND) // special case for commands
{
if (OnCommand(wParam, lParam))
return 1L; // command handled
else
return (LRESULT)DefWindowProc(nMsg, wParam, lParam);
}
pMessageMap = GetMessageMap();
for (; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMessageMap)
{
lpEntry = pMessageMap->lpEntries;
printlpEntries(lpEntry);
}
return 0; // add by JJHou. if find, should call lpEntry->pfn,
// otherwise should call DefWindowProc.
}
但是this指针是指向CMyFrameWnd的。
至于pMyFrame在声名的时候是CFrameWnd类型,而this是指向CMyFrameWnd的这个问题,完全是和虚函数表现一致,尽管声名成CFrameWnd类型:
CFrameWnd* pMyFrame
但是系统非常清楚它的实际类型。
总之,在GetMessageMap时,获取的是
AFX_MSGMAP* CMyFrameWnd::GetMessageMap() const
{ return &CMyFrameWnd::messageMap; }
通过单步跟踪就看得更加真切了。
相关文章推荐
- 090919(星期六):MFC消息路由4, Frame8代码分析3CWinApp的聚合情况
- 090917(星期四):MFC消息路由2 , Frame8代码分析
- 090922(星期二):MFC消息路由7, Frame8代码分析,消息链表的访问
- 090918(星期五):MFC消息路由3, Frame8代码分析2
- 090920(星期天):MFC消息路由5, Frame8代码分析,消息处理
- 090923(星期三):MFC消息路由8, Frame8代码分析,ONCOMMAND消息的多线索流动
- 090924(星期四):MFC消息路由9, Frame8代码分析,最复杂的CMyFrameWnd之ONCOMMAND消息的多线索流动
- 090928(星期一):MFC消息路由,观察 控件消息的 处理
- Meandering Through the Maze of MFC Message and Command Routing MFC消息路由机制分析
- 分析:由 XToolTip类 联想到 WTL (MFC) 消息循环
- MFC获取win10平板右键菜单消息
- MFC中的CListCtrl添加右键菜单消息响应实例分析
- 090914(星期一):MFC消息映射1
- MFC消息路由
- Android获取Root权限之后的静默安装实现代码示例分析
- 从MFC消息映射宏分析MFC消息映射的实现
- 基于visual c++之windows核心编程代码分析(23)遍历驱动器并获取驱动器属性
- MFC文档视图(三):命令消息路由
- 基于Linux的消息队列及多线程编程实现的聊天室(二)代码分析
- 用MFC实现代码获取当前EXE 执行的绝对路径,用于扩展相对路径扩展,以及计算文件大小功能