消息映射

在wincore.cpp中

 1LRESULT CALLBACK
 2AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
 3{
 4 // special message which identifies the window as using AfxWndProc
 5 if (nMsg == WM_QUERYAFXWNDPROC)
 6  return 1;
 7
 8 // all other messages route through message map
 9 CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);//句柄转化为wnd对象
10 ASSERT(pWnd != NULL);
11 ASSERT(pWnd->m_hWnd == hWnd);
12 return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
13}

14

最后转到afxCallWndProc()

 1LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg,
 2 WPARAM wParam = 0, LPARAM lParam = 0)
 3{
 4 _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
 5 MSG oldState = pThreadState->m_lastSentMsg;   // save for nesting
 6 pThreadState->m_lastSentMsg.hwnd = hWnd;
 7 pThreadState->m_lastSentMsg.message = nMsg;
 8 pThreadState->m_lastSentMsg.wParam = wParam;
 9 pThreadState->m_lastSentMsg.lParam = lParam;
10
11#ifdef _DEBUG
12 if (afxTraceFlags & traceWinMsg)
13  _AfxTraceMsg(_T("WndProc"), &pThreadState->m_lastSentMsg);
14#endif
15
16 // Catch exceptions thrown outside the scope of a callback
17 // in debug builds and warn the user.
18 LRESULT lResult;
19 TRY
20 {
21#ifndef _AFX_NO_OCC_SUPPORT
22  // special case for WM_DESTROY
23  if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))
24   pWnd->m_pCtrlCont->OnUIActivate(NULL);
25#endif
26
27  // special case for WM_INITDIALOG
28  CRect rectOld;
29  DWORD dwStyle = 0;
30  if (nMsg == WM_INITDIALOG)
31   _AfxPreInitDialog(pWnd, &rectOld, &dwStyle);
32
33  // delegate to object's WindowProc
34  lResult = pWnd->WindowProc(nMsg, wParam, lParam);
35
36  // more special case for WM_INITDIALOG
37  if (nMsg == WM_INITDIALOG)
38   _AfxPostInitDialog(pWnd, rectOld, dwStyle);
39 }

40 CATCH_ALL(e)
41 {
42  lResult = AfxGetThread()->ProcessWndProcException(e, &pThreadState->m_lastSentMsg);
43  TRACE1("Warning: Uncaught exception in WindowProc (returning %ld).\n",
44   lResult);
45  DELETE_EXCEPTION(e);
46 }

47 END_CATCH_ALL
48
49 pThreadState->m_lastSentMsg = oldState;
50 return lResult;
51}

52
53

再转到 WndProc中:
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,如果找不到处理函数
再到DefWindowProc中

BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
 LRESULT lResult = 0;

 // special case for commands
 if (message == WM_COMMAND)
 {
  if (OnCommand(wParam, lParam))
  {
   lResult = 1;
   goto LReturnTrue;
  }
  return FALSE;
 }

 // special case for notifies
 if (message == WM_NOTIFY)
 {
  NMHDR* pNMHDR = (NMHDR*)lParam;
  if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))
   goto LReturnTrue;
  return FALSE;
 }

 // special case for activation
 if (message == WM_ACTIVATE)
  _AfxHandleActivate(this, wParam, CWnd::FromHandle((HWND)lParam));

 // special case for set cursor HTERROR
 if (message == WM_SETCURSOR &&
  _AfxHandleSetCursor(this, (short)LOWORD(lParam), HIWORD(lParam)))
 {
  lResult = 1;
  goto LReturnTrue;
 }

 const AFX_MSGMAP* pMessageMap; pMessageMap = GetMessageMap();
 UINT iHash; iHash = (LOWORD((DWORD)pMessageMap) ^ message) & (iHashMax-1);
 AfxLockGlobals(CRIT_WINMSGCACHE);
 AFX_MSG_CACHE* pMsgCache; pMsgCache = &_afxMsgCache[iHash];
 const AFX_MSGMAP_ENTRY* lpEntry;
 if (message == pMsgCache->nMsg && pMessageMap == pMsgCache->pMessageMap)
 {
  // cache hit
  lpEntry = pMsgCache->lpEntry;
  AfxUnlockGlobals(CRIT_WINMSGCACHE);
  if (lpEntry == NULL)
   return FALSE;

  // cache hit, and it needs to be handled
  if (message < 0xC000)
   goto LDispatch;
  else
   goto LDispatchRegistered;
 }
 else
 {
  // not in cache, look for it
  pMsgCache->nMsg = message;
  pMsgCache->pMessageMap = pMessageMap;

#ifdef _AFXDLL
  for (/* pMessageMap already init'ed */; pMessageMap != NULL;
   pMessageMap = (*pMessageMap->pfnGetBaseMap)())
#else
  for (/* pMessageMap already init'ed */; pMessageMap != NULL;
   pMessageMap = pMessageMap->pBaseMap)
#endif
  {
   // Note: catch not so common but fatal mistake!!
   //      BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd)
#ifdef _AFXDLL
   ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
#else
   ASSERT(pMessageMap != pMessageMap->pBaseMap);
#endif

   if (message < 0xC000)
   {
    // constant window message
    if ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,
     message, 0, 0)) != NULL)
    {
     pMsgCache->lpEntry = lpEntry;
     AfxUnlockGlobals(CRIT_WINMSGCACHE);
     goto LDispatch;
    }
   }
   else
   {
    // registered windows message
    lpEntry = pMessageMap->lpEntries;
    while ((lpEntry = AfxFindMessageEntry(lpEntry, 0xC000, 0, 0)) != NULL)
    {
     UINT* pnID = (UINT*)(lpEntry->nSig);
     ASSERT(*pnID >= 0xC000 || *pnID == 0);
      // must be successfully registered
     if (*pnID == message)
     {
      pMsgCache->lpEntry = lpEntry;
      AfxUnlockGlobals(CRIT_WINMSGCACHE);
      goto LDispatchRegistered;
     }
     lpEntry++;      // keep looking past this one
    }
   }
  }

  pMsgCache->lpEntry = NULL;
  AfxUnlockGlobals(CRIT_WINMSGCACHE);
  return FALSE;
 }
 ASSERT(FALSE);      // not reached

LDispatch:
 ASSERT(message < 0xC000);
 union MessageMapFunctions mmf;
 mmf.pfn = lpEntry->pfn;

 // if we've got WM_SETTINGCHANGE / WM_WININICHANGE, we need to
 // decide if we're going to call OnWinIniChange() or OnSettingChange()

 int nSig;
 nSig = lpEntry->nSig;
 if (lpEntry->nID == WM_SETTINGCHANGE)
 {
  DWORD dwVersion = GetVersion();
  if (LOBYTE(LOWORD(dwVersion)) >= 4)
   nSig = AfxSig_vws;
  else
   nSig = AfxSig_vs;
 }

 switch (nSig)
 {
 default:
  ASSERT(FALSE);
  break;

 case AfxSig_bD:
  lResult = (this->*mmf.pfn_bD)(CDC::FromHandle((HDC)wParam));
  break;

 case AfxSig_bb:     // AfxSig_bb, AfxSig_bw, AfxSig_bh
  lResult = (this->*mmf.pfn_bb)((BOOL)wParam);
  break;

 case AfxSig_bWww:   // really AfxSig_bWiw
  lResult = (this->*mmf.pfn_bWww)(CWnd::FromHandle((HWND)wParam),
   (short)LOWORD(lParam), HIWORD(lParam));
  break;

 case AfxSig_bWCDS:
  lResult = (this->*mmf.pfn_bWCDS)(CWnd::FromHandle((HWND)wParam),
   (COPYDATASTRUCT*)lParam);
  break;

 case AfxSig_bHELPINFO:
  lResult = (this->*mmf.pfn_bHELPINFO)((HELPINFO*)lParam);
  break;

 case AfxSig_hDWw:
  {
   // special case for OnCtlColor to avoid too many temporary objects
   ASSERT(message == WM_CTLCOLOR);
   AFX_CTLCOLOR* pCtl = (AFX_CTLCOLOR*)lParam;
   CDC dcTemp; dcTemp.m_hDC = pCtl->hDC;
   CWnd wndTemp; wndTemp.m_hWnd = pCtl->hWnd;
   UINT nCtlType = pCtl->nCtlType;
   // if not coming from a permanent window, use stack temporary
   CWnd* pWnd = CWnd::FromHandlePermanent(wndTemp.m_hWnd);
   if (pWnd == NULL)
   {
#ifndef _AFX_NO_OCC_SUPPORT
    // determine the site of the OLE control if it is one
    COleControlSite* pSite;
    if (m_pCtrlCont != NULL && (pSite = (COleControlSite*)
     m_pCtrlCont->m_siteMap.GetValueAt(wndTemp.m_hWnd)) != NULL)
    {
     wndTemp.m_pCtrlSite = pSite;
    }
#endif
    pWnd = &wndTemp;
   }
   HBRUSH hbr = (this->*mmf.pfn_hDWw)(&dcTemp, pWnd, nCtlType);
   // fast detach of temporary objects
   dcTemp.m_hDC = NULL;
   wndTemp.m_hWnd = NULL;
   lResult = (LRESULT)hbr;
  }
  break;

 case AfxSig_hDw:
  {
   // special case for CtlColor to avoid too many temporary objects
   ASSERT(message == WM_REFLECT_BASE+WM_CTLCOLOR);
   AFX_CTLCOLOR* pCtl = (AFX_CTLCOLOR*)lParam;
   CDC dcTemp; dcTemp.m_hDC = pCtl->hDC;
   UINT nCtlType = pCtl->nCtlType;
   HBRUSH hbr = (this->*mmf.pfn_hDw)(&dcTemp, nCtlType);
   // fast detach of temporary objects
   dcTemp.m_hDC = NULL;
   lResult = (LRESULT)hbr;
  }
  break;

 case AfxSig_iwWw:
  lResult = (this->*mmf.pfn_iwWw)(LOWORD(wParam),
   CWnd::FromHandle((HWND)lParam), HIWORD(wParam));
  break;

 case AfxSig_iww:
  lResult = (this->*mmf.pfn_iww)(LOWORD(wParam), HIWORD(wParam));
  break;

 case AfxSig_iWww:   // really AfxSig_iWiw
  lResult = (this->*mmf.pfn_iWww)(CWnd::FromHandle((HWND)wParam),
   (short)LOWORD(lParam), HIWORD(lParam));
  break;

 case AfxSig_is:
  lResult = (this->*mmf.pfn_is)((LPTSTR)lParam);
  break;

 case AfxSig_lwl:
  lResult = (this->*mmf.pfn_lwl)(wParam, lParam);
  break;

 case AfxSig_lwwM:
  lResult = (this->*mmf.pfn_lwwM)((UINT)LOWORD(wParam),
   (UINT)HIWORD(wParam), (CMenu*)CMenu::FromHandle((HMENU)lParam));
  break;

 case AfxSig_vv:
  (this->*mmf.pfn_vv)();
  break;

 case AfxSig_vw: // AfxSig_vb, AfxSig_vh
  (this->*mmf.pfn_vw)(wParam);
  break;

 case AfxSig_vww:
  (this->*mmf.pfn_vww)((UINT)wParam, (UINT)lParam);
  break;

 case AfxSig_vvii:
  (this->*mmf.pfn_vvii)((short)LOWORD(lParam), (short)HIWORD(lParam));
  break;

 case AfxSig_vwww:
  (this->*mmf.pfn_vwww)(wParam, LOWORD(lParam), HIWORD(lParam));
  break;

 case AfxSig_vwii:
  (this->*mmf.pfn_vwii)(wParam, LOWORD(lParam), HIWORD(lParam));
  break;

 case AfxSig_vwl:
  (this->*mmf.pfn_vwl)(wParam, lParam);
  break;

 case AfxSig_vbWW:
  (this->*mmf.pfn_vbWW)(m_hWnd == (HWND)lParam,
   CWnd::FromHandle((HWND)lParam),
   CWnd::FromHandle((HWND)wParam));
  break;

 case AfxSig_vD:
  (this->*mmf.pfn_vD)(CDC::FromHandle((HDC)wParam));
  break;

 case AfxSig_vM:
  (this->*mmf.pfn_vM)(CMenu::FromHandle((HMENU)wParam));
  break;

 case AfxSig_vMwb:
  (this->*mmf.pfn_vMwb)(CMenu::FromHandle((HMENU)wParam),
   LOWORD(lParam), (BOOL)HIWORD(lParam));
  break;

 case AfxSig_vW:
  (this->*mmf.pfn_vW)(CWnd::FromHandle((HWND)wParam));
  break;

 case AfxSig_vW2:
  (this->*mmf.pfn_vW)(CWnd::FromHandle((HWND)lParam));
  break;

 case AfxSig_vWww:
  (this->*mmf.pfn_vWww)(CWnd::FromHandle((HWND)wParam), LOWORD(lParam),
   HIWORD(lParam));
  break;

 case AfxSig_vWp:
  {
   CPoint point((DWORD)lParam);
   (this->*mmf.pfn_vWp)(CWnd::FromHandle((HWND)wParam), point);
  }
  break;

 case AfxSig_vWh:
  (this->*mmf.pfn_vWh)(CWnd::FromHandle((HWND)wParam),
    (HANDLE)lParam);
  break;

 case AfxSig_vwW:
  (this->*mmf.pfn_vwW)(wParam, CWnd::FromHandle((HWND)lParam));
  break;

 case AfxSig_vwWb:
  (this->*mmf.pfn_vwWb)((UINT)(LOWORD(wParam)),
   CWnd::FromHandle((HWND)lParam), (BOOL)HIWORD(wParam));
  break;

 case AfxSig_vwwW:
 case AfxSig_vwwx:
  {
   // special case for WM_VSCROLL and WM_HSCROLL
   ASSERT(message == WM_VSCROLL || message == WM_HSCROLL ||
    message == WM_VSCROLL+WM_REFLECT_BASE || message == WM_HSCROLL+WM_REFLECT_BASE);
   int nScrollCode = (short)LOWORD(wParam);
   int nPos = (short)HIWORD(wParam);
   if (lpEntry->nSig == AfxSig_vwwW)
    (this->*mmf.pfn_vwwW)(nScrollCode, nPos,
     CWnd::FromHandle((HWND)lParam));
   else
    (this->*mmf.pfn_vwwx)(nScrollCode, nPos);
  }
  break;

 case AfxSig_vs:
  (this->*mmf.pfn_vs)((LPTSTR)lParam);
  break;

 case AfxSig_vws:
  (this->*mmf.pfn_vws)((UINT) wParam, (LPCTSTR)lParam);
  break;

 case AfxSig_vOWNER:
  (this->*mmf.pfn_vOWNER)((int)wParam, (LPTSTR)lParam);
  lResult = TRUE;
  break;

 case AfxSig_iis:
  lResult = (this->*mmf.pfn_iis)((int)wParam, (LPTSTR)lParam);
  break;

 case AfxSig_wp:
  {
   CPoint point((DWORD)lParam);
   lResult = (this->*mmf.pfn_wp)(point);
  }
  break;

 case AfxSig_wv: // AfxSig_bv, AfxSig_wv
  lResult = (this->*mmf.pfn_wv)();
  break;

 case AfxSig_vCALC:
  (this->*mmf.pfn_vCALC)((BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam);
  break;

 case AfxSig_vPOS:
  (this->*mmf.pfn_vPOS)((WINDOWPOS*)lParam);
  break;

 case AfxSig_vwwh:
  (this->*mmf.pfn_vwwh)(LOWORD(wParam), HIWORD(wParam), (HANDLE)lParam);
  break;

 case AfxSig_vwp:
  {
   CPoint point((DWORD)lParam);
   (this->*mmf.pfn_vwp)(wParam, point);
   break;
  }
 case AfxSig_vwSIZING:
  (this->*mmf.pfn_vwl)(wParam, lParam);
  lResult = TRUE;
  break;

 case AfxSig_bwsp:
  lResult = (this->*mmf.pfn_bwsp)(LOWORD(wParam), (short) HIWORD(wParam),
   CPoint(LOWORD(lParam), HIWORD(lParam)));
  if (!lResult)
   return FALSE;
 }
 goto LReturnTrue;

LDispatchRegistered:    // for registered windows messages
 ASSERT(message >= 0xC000);
 mmf.pfn = lpEntry->pfn;
 lResult = (this->*mmf.pfn_lwl)(wParam, lParam);

LReturnTrue:
 if (pResult != NULL)
  *pResult = lResult;
 return TRUE;
}

LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
 if (m_pfnSuper != NULL)
  return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);

 WNDPROC pfnWndProc;
 if ((pfnWndProc = *GetSuperWndProcAddr()) == NULL)
  return ::DefWindowProc(m_hWnd, nMsg, wParam, lParam);
 else
  return ::CallWindowProc(pfnWndProc, m_hWnd, nMsg, wParam, lParam);
}



 


posted @ 2007-10-17 15:52  yfcomeon  阅读(719)  评论(0编辑  收藏  举报