先上CWnd,WindowProc->OnWndMsg->OnDrawItem
WindowProc直接调用OnWndMsg
LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// OnWndMsg does most of the work, except for DefWindowProc call
LRESULT lResult = 0;
if (!OnWndMsg(message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;
}
OnWndMsg获得msg后通过检索MESSAGE_MAP获得函数地址进行处理
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
·
·
·
for (/* pMessageMap already init'ed */; pMessageMap->pfnGetBaseMap != NULL;//根据messageMap调用msg,包括WM_DRAWITEM
pMessageMap = (*pMessageMap->pfnGetBaseMap)())
{
// Note: catch not so common but fatal mistake!!
// BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd)
ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
if (message < 0xC000)
{
// constant window message
if ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,
message, 0, 0)) != NULL)
{
pMsgCache->lpEntry = lpEntry;
winMsgLock.Unlock();
goto LDispatch;
}
}
·
·
·
}
BEGIN_MESSAGE_MAP(CWnd, CCmdTarget)
ON_MESSAGE(WM_CTLCOLORSTATIC, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLOREDIT, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORBTN, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORLISTBOX, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORDLG, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORMSGBOX, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORSCROLLBAR, &CWnd::OnNTCtlColor)
ON_WM_SETFOCUS()
ON_WM_DRAWITEM()
ON_WM_MEASUREITEM()
ON_WM_CTLCOLOR()
ON_WM_COMPAREITEM()
ON_WM_ENTERIDLE()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_DELETEITEM()
ON_WM_CHARTOITEM()
ON_WM_VKEYTOITEM()
ON_WM_NCDESTROY()
ON_WM_PARENTNOTIFY()
ON_WM_SYSCOLORCHANGE()
ON_WM_DEVMODECHANGE()
ON_WM_HELPINFO()
ON_WM_SETTINGCHANGE()
ON_WM_DESTROY()
ON_MESSAGE(WM_ACTIVATETOPLEVEL, &CWnd::OnActivateTopLevel)
ON_WM_DISPLAYCHANGE()
ON_REGISTERED_MESSAGE(CWnd::m_nMsgDragList, &CWnd::OnDragList)
ON_MESSAGE(WM_GETOBJECT, &CWnd::OnGetObject)
ON_MESSAGE(WM_TOUCH, &CWnd::OnTouchMessage)
ON_MESSAGE(WM_TABLET_QUERYSYSTEMGESTURESTATUS, &CWnd::OnTabletQuerySystemGestureStatus)
ON_MESSAGE(WM_GESTURE, &CWnd::OnGesture)
END_MESSAGE_MAP()
OnDrawItem将lpDrawItemStruct传递给子控件
void CWnd::OnDrawItem(int /*nIDCtl*/, LPDRAWITEMSTRUCT lpDrawItemStruct)//获得WM_DRAWITEM并传递给子控件
{
if (lpDrawItemStruct->CtlType == ODT_MENU)
{
CMenu* pMenu = CMenu::FromHandlePermanent(
(HMENU)lpDrawItemStruct->hwndItem);
if (pMenu != NULL)
{
pMenu->DrawItem(lpDrawItemStruct);//如果是menu类型就调用子控件的DrawItem函数
return; // eat it
}
}
// reflect notification to child window control
if (ReflectLastMsg(lpDrawItemStruct->hwndItem))
return; // eat it
// not handled - do default
Default();
}
WindowProc直接调用OnWndMsg
LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// OnWndMsg does most of the work, except for DefWindowProc call
LRESULT lResult = 0;
if (!OnWndMsg(message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;
}
OnWndMsg获得msg后通过检索MESSAGE_MAP获得函数地址进行处理
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
·
·
·
for (/* pMessageMap already init'ed */; pMessageMap->pfnGetBaseMap != NULL;//根据messageMap调用msg,包括WM_DRAWITEM
pMessageMap = (*pMessageMap->pfnGetBaseMap)())
{
// Note: catch not so common but fatal mistake!!
// BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd)
ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
if (message < 0xC000)
{
// constant window message
if ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,
message, 0, 0)) != NULL)
{
pMsgCache->lpEntry = lpEntry;
winMsgLock.Unlock();
goto LDispatch;
}
}
·
·
·
}
BEGIN_MESSAGE_MAP(CWnd, CCmdTarget)
ON_MESSAGE(WM_CTLCOLORSTATIC, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLOREDIT, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORBTN, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORLISTBOX, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORDLG, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORMSGBOX, &CWnd::OnNTCtlColor)
ON_MESSAGE(WM_CTLCOLORSCROLLBAR, &CWnd::OnNTCtlColor)
ON_WM_SETFOCUS()
ON_WM_DRAWITEM()
ON_WM_MEASUREITEM()
ON_WM_CTLCOLOR()
ON_WM_COMPAREITEM()
ON_WM_ENTERIDLE()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_DELETEITEM()
ON_WM_CHARTOITEM()
ON_WM_VKEYTOITEM()
ON_WM_NCDESTROY()
ON_WM_PARENTNOTIFY()
ON_WM_SYSCOLORCHANGE()
ON_WM_DEVMODECHANGE()
ON_WM_HELPINFO()
ON_WM_SETTINGCHANGE()
ON_WM_DESTROY()
ON_MESSAGE(WM_ACTIVATETOPLEVEL, &CWnd::OnActivateTopLevel)
ON_WM_DISPLAYCHANGE()
ON_REGISTERED_MESSAGE(CWnd::m_nMsgDragList, &CWnd::OnDragList)
ON_MESSAGE(WM_GETOBJECT, &CWnd::OnGetObject)
ON_MESSAGE(WM_TOUCH, &CWnd::OnTouchMessage)
ON_MESSAGE(WM_TABLET_QUERYSYSTEMGESTURESTATUS, &CWnd::OnTabletQuerySystemGestureStatus)
ON_MESSAGE(WM_GESTURE, &CWnd::OnGesture)
END_MESSAGE_MAP()
OnDrawItem将lpDrawItemStruct传递给子控件
void CWnd::OnDrawItem(int /*nIDCtl*/, LPDRAWITEMSTRUCT lpDrawItemStruct)//获得WM_DRAWITEM并传递给子控件
{
if (lpDrawItemStruct->CtlType == ODT_MENU)
{
CMenu* pMenu = CMenu::FromHandlePermanent(
(HMENU)lpDrawItemStruct->hwndItem);
if (pMenu != NULL)
{
pMenu->DrawItem(lpDrawItemStruct);//如果是menu类型就调用子控件的DrawItem函数
return; // eat it
}
}
// reflect notification to child window control
if (ReflectLastMsg(lpDrawItemStruct->hwndItem))
return; // eat it
// not handled - do default
Default();
}