OnCmdMsg 是 MFC 框架用来在窗口间分发消息用的
2013-03-15 10:53
381 查看
首先,OnCommand( )是在CWnd类中的,而OnCmdMsg( )是在CCmdTarget类中的。你如果看了MFC的类的继承图的话,你就会知道CWnd是从CCmdTarget类中继承的。下面是从MFC的源码中取出的片断,其中不难看到CWnd中的OnCommand( )调用了OnCmdMsg( );
/////////////////////////////////////////////////////////////////////////////
// CWnd command handling
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
// return TRUE if command invocation was attempted
{
UINT nID = LOWORD(wParam);
HWND hWndCtrl = (HWND)lParam;
int nCode = HIWORD(wParam);
// default routing for command messages (through closure table)
if (hWndCtrl == NULL)
{
// zero IDs for normal commands are not allowed
if (nID == 0)
return FALSE;
// make sure command has not become disabled before routing
CTestCmdUI state;
state.m_nID = nID;
OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);
if (!state.m_bEnabled)
{
TRACE1("Warning: not executing disabled command %d\n", nID);
return TRUE;
}
// menu or accelerator
nCode = CN_COMMAND;
}
else
{
// control notification
ASSERT(nID == 0 || ::IsWindow(hWndCtrl));
if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)
return TRUE; // locked out - ignore control notification
// reflect notification to child window control
if (ReflectLastMsg(hWndCtrl))
return TRUE; // eaten by child
// zero IDs for normal commands are not allowed
if (nID == 0)
return FALSE;
}
#ifdef _DEBUG
if (nCode < 0 && nCode != (int)0x8000)
TRACE1("Implementation Warning: control notification = $%X.\n",
nCode);
#endif
return OnCmdMsg(nID, nCode, NULL, NULL);
}
其次,我的理解是,OnCommand( )主要是用来处理消息(控件,菜单,加速键)的;而OnCmdMsg( )主要是用来处理消息的路由的。路由就是各个类处理消息的顺序,在MFC中,标准的路由如下:(摘自MSDN)
Standard Command Route
When an object of this type receives a command . . . It gives itself and other command-target objects a chance to handle the command in this order:
MDI frame window
(CMDIFrameWnd)
1、Active CMDIChildWnd
2、This frame window
3、Application (CWinApp object)
Document frame window
(CFrameWnd, CMDIChildWnd)
1、Active view
2、This frame window
3、Application (CWinApp object)
View
1、This view
2、Document attached to the view
Document
1、This document
2、Document template attached to the document
Dialog box
1、This dialog box
2、Window that owns the dialog box
3、Application (CWinApp object)
下面这个例子也是摘自MSDN, 它重新定义了MFC的标准路由。
// This example illustrates extending the framework's standard command
// route from the view to objects managed by the view. This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits "shapes".
BOOL CMyView::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// Extend the framework's command route from the view to
// the application-specific CMyShape that is currently selected
// in the view. m_pActiveShape is NULL if no shape object
// is currently selected in the view.
if ((m_pActiveShape != NULL)
&& m_pActiveShape->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// If the object(s) in the extended command route don't handle
// the command, then let the base class OnCmdMsg handle it.
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
// The command handler for ID_SHAPE_COLOR (menu command to change
// the color of the currently selected shape) was added to
// the message map of CMyShape (note, not CMyView) using ClassWizard.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL. It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
//{{AFX_MSG_MAP(CMyShape)
ON_COMMAND(ID_SHAPE_COLOR, OnShapeColor)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
http://bbs.csdn.net/topics/23919
/////////////////////////////////////////////////////////////////////////////
// CWnd command handling
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
// return TRUE if command invocation was attempted
{
UINT nID = LOWORD(wParam);
HWND hWndCtrl = (HWND)lParam;
int nCode = HIWORD(wParam);
// default routing for command messages (through closure table)
if (hWndCtrl == NULL)
{
// zero IDs for normal commands are not allowed
if (nID == 0)
return FALSE;
// make sure command has not become disabled before routing
CTestCmdUI state;
state.m_nID = nID;
OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);
if (!state.m_bEnabled)
{
TRACE1("Warning: not executing disabled command %d\n", nID);
return TRUE;
}
// menu or accelerator
nCode = CN_COMMAND;
}
else
{
// control notification
ASSERT(nID == 0 || ::IsWindow(hWndCtrl));
if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)
return TRUE; // locked out - ignore control notification
// reflect notification to child window control
if (ReflectLastMsg(hWndCtrl))
return TRUE; // eaten by child
// zero IDs for normal commands are not allowed
if (nID == 0)
return FALSE;
}
#ifdef _DEBUG
if (nCode < 0 && nCode != (int)0x8000)
TRACE1("Implementation Warning: control notification = $%X.\n",
nCode);
#endif
return OnCmdMsg(nID, nCode, NULL, NULL);
}
其次,我的理解是,OnCommand( )主要是用来处理消息(控件,菜单,加速键)的;而OnCmdMsg( )主要是用来处理消息的路由的。路由就是各个类处理消息的顺序,在MFC中,标准的路由如下:(摘自MSDN)
Standard Command Route
When an object of this type receives a command . . . It gives itself and other command-target objects a chance to handle the command in this order:
MDI frame window
(CMDIFrameWnd)
1、Active CMDIChildWnd
2、This frame window
3、Application (CWinApp object)
Document frame window
(CFrameWnd, CMDIChildWnd)
1、Active view
2、This frame window
3、Application (CWinApp object)
View
1、This view
2、Document attached to the view
Document
1、This document
2、Document template attached to the document
Dialog box
1、This dialog box
2、Window that owns the dialog box
3、Application (CWinApp object)
下面这个例子也是摘自MSDN, 它重新定义了MFC的标准路由。
// This example illustrates extending the framework's standard command
// route from the view to objects managed by the view. This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits "shapes".
BOOL CMyView::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// Extend the framework's command route from the view to
// the application-specific CMyShape that is currently selected
// in the view. m_pActiveShape is NULL if no shape object
// is currently selected in the view.
if ((m_pActiveShape != NULL)
&& m_pActiveShape->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// If the object(s) in the extended command route don't handle
// the command, then let the base class OnCmdMsg handle it.
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
// The command handler for ID_SHAPE_COLOR (menu command to change
// the color of the currently selected shape) was added to
// the message map of CMyShape (note, not CMyView) using ClassWizard.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL. It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
//{{AFX_MSG_MAP(CMyShape)
ON_COMMAND(ID_SHAPE_COLOR, OnShapeColor)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
http://bbs.csdn.net/topics/23919
相关文章推荐
- MFC----文档 视图 框架窗口间的关系 和消息传送规律
- 模拟MFC和WTL对Windows窗口框架消息映射机制的封装代码
- MFC 文档 视图 框架窗口间的关系 和消息传送规律
- c++控制台(非窗口,非MFC框架)里线程如何通过自定义消息通信
- MFC 文档 视图 框架窗口间的关系 和消息传送规律
- VC 2010 + MFC + MDI多文档视图框架:视图框架窗口激活的消息通知
- MFC之消息传递(A->B->C, C为主窗口且没有启动)
- MFC自定义控件如何向父窗口发送自定义消息
- MFC关于遍历同一个应用程序打开的多个窗口并发送消息
- MFC窗口消息
- MFC中非MDI子框架窗口
- MFC单文档框架编程(二): SDI框架下的消息处理
- MFC 向指定窗口发送自定义消息
- MFC学习笔记之二----------MFC框架程序及消息映射
- VS2013/MFC编程入门之三十八(文档、视图和框架:分割窗口)
- MFC应用程序中处理消息的顺序,创建窗口的过程关闭窗口的顺序(非模态窗口),打开模式对话框的函数调用顺序
- VS2013MFC单文档工程学习笔记六 - 窗口的常用消息事件
- MFC窗口的消息响应顺序
- MFC窗口变化消息( OnSize、OnSizing和OnGetMinMaxInfo)
- 深入解析Windows窗口创建和消息分发