首先,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