MFC--------------------------------------------------------------------------------- /*** for (pMessageMap = GetMessageMap(); pMessageMap->pfnGetBaseMap != NULL; pMessageMap = (*pMessageMap->pfnGetBaseMap)()) { // Note: catches BEGIN_MESSAGE_MAP(CMyClass, CMyClass)! ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)()); lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID); if (lpEntry != NULL) { // found it #ifdef _DEBUG if (nCode == CN_COMMAND) TRACE(traceCmdRouting, 1, "SENDING command id 0x%04X to %hs target.\n", nID, GetRuntimeClass()->m_lpszClassName); else if (nCode > CN_COMMAND) TRACE(traceCmdRouting, 1, "SENDING control notification %d from control id 0x%04X to %hs window.\n", nCode, nID, GetRuntimeClass()->m_lpszClassName); #endif //_DEBUG return _AfxDispatchCmdMsg(this, nID, nCode, lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo); } } //MFC 窗口处理消息 // The WndProc for all CWnd's and derived classes //一般子类化 LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { // special message which identifies the window as using AfxWndProc if (nMsg == WM_QUERYAFXWNDPROC) return 1; // all other messages route through message map CWnd* pWnd = CWnd::FromHandlePermanent(hWnd); //通过HWND 获取到CWnd 这个c++对象,对于windows界面编程 ASSERT(pWnd != NULL); //这个HWND是非常有用的。 ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd); if (pWnd == NULL || pWnd->m_hWnd != hWnd) return ::DefWindowProc(hWnd, nMsg, wParam, lParam); //如果CWnd不合法,就丢给系统去处理吧 return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam); } ///////////////////////////////////////////////////////////////////////////// // Official way to send message to a CWnd LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg, WPARAM wParam = 0, LPARAM lParam = 0) { _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); //这个一看就跟线程有关。 看代码保存信息 MSG oldState = pThreadState->m_lastSentMsg; // save for nesting pThreadState->m_lastSentMsg.hwnd = hWnd; pThreadState->m_lastSentMsg.message = nMsg; pThreadState->m_lastSentMsg.wParam = wParam; pThreadState->m_lastSentMsg.lParam = lParam; #ifdef _DEBUG _AfxTraceMsg(_T("WndProc"), &pThreadState->m_lastSentMsg); #endif // Catch exceptions thrown outside the scope of a callback // in debug builds and warn the user. LRESULT lResult; TRY { // special case for WM_DESTROY if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL)) pWnd->m_pCtrlCont->OnUIActivate(NULL); // special case for WM_INITDIALOG CRect rectOld; DWORD dwStyle = 0; if (nMsg == WM_INITDIALOG) _AfxPreInitDialog(pWnd, &rectOld, &dwStyle); //真正进入c++ Cwnd里面的消息处理函数,这个MFC已经写好了,一般我们用DirectUI时候其实也有这样的。 //可以重载,一般来说除非特殊处理,才重载这个消息处理函数,而且处理,我们一般都会调用父类的这个消息处理, //因为这里是框架,你打乱框架会出现很多错误,你要保存消息正确流向和处理。 // delegate to object's WindowProc lResult = pWnd->WindowProc(nMsg, wParam, lParam); // more special case for WM_INITDIALOG if (nMsg == WM_INITDIALOG) _AfxPostInitDialog(pWnd, rectOld, dwStyle); } CATCH_ALL(e) { lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg); TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n", lResult); DELETE_EXCEPTION(e); } END_CATCH_ALL pThreadState->m_lastSentMsg = oldState; return lResult; } //现在进入c++ CWnd消息处理函数里面去了。 ///////////////////////////////////////////////////////////////////////////// // main WindowProc implementation //这个重载意义不大, 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; } BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) { LRESULT lResult = 0; union MessageMapFunctions mmf; mmf.pfn = 0; CInternalGlobalLock winMsgLock; // 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; } // special case for windows that contain windowless ActiveX controls BOOL bHandled; bHandled = FALSE; if ((m_pCtrlCont != NULL) && (m_pCtrlCont->m_nWindowlessControls > 0)) { if (((message >= WM_MOUSEFIRST) && (message <= AFX_WM_MOUSELAST)) || ((message >= WM_KEYFIRST) && (message <= WM_IME_KEYLAST)) || ((message >= WM_IME_SETCONTEXT) && (message <= WM_IME_KEYUP))) { bHandled = m_pCtrlCont->HandleWindowlessMessage(message, wParam, lParam, &lResult); } } if (bHandled) { goto LReturnTrue; } switch (message) { case WM_SIZE: { CHwndRenderTarget* pRenderTarget = LockRenderTarget(); if (pRenderTarget != NULL && pRenderTarget->IsValid()) { pRenderTarget->Resize(CD2DSizeU(UINT32(LOWORD(lParam)), UINT32(HIWORD(lParam)))); RedrawWindow(); } UnlockRenderTarget(); } break; case WM_PAINT: if (DoD2DPaint()) { lResult = 1; goto LReturnTrue; } break; case WM_ERASEBKGND: { CHwndRenderTarget* pRenderTarget = LockRenderTarget(); BOOL fValid = (pRenderTarget != NULL) && pRenderTarget->IsValid(); UnlockRenderTarget(); if (fValid) { lResult = 1; goto LReturnTrue; } } break; } //总算进入我们前面用宏定义消息处理了 //自己的类获取自己类的消息MAP //注意GetMessageMap 是虚函数哦, /************************************************************************************* //看这个宏定义,所以先获取是子类消息的map(数组)。 #define DECLARE_MESSAGE_MAP() protected: static const AFX_MSGMAP* PASCAL GetThisMessageMap(); virtual const AFX_MSGMAP* GetMessageMap() const; **************************************************************************/ const AFX_MSGMAP* pMessageMap; pMessageMap = GetMessageMap(); UINT iHash; iHash = (LOWORD((DWORD_PTR)pMessageMap) ^ message) & (iHashMax-1); winMsgLock.Lock(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; winMsgLock.Unlock(); 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; for (/* pMessageMap already init'ed */; pMessageMap->pfnGetBaseMap != NULL; pMessageMap = (*pMessageMap->pfnGetBaseMap)()) //如果自己这个c++ 类 没有处理这个消息,老子就去老爸那里看有没有 { // Note: catch not so common but fatal mistake!! // BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd) ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)()); //我查了一下资料 //用户自定义的消息, 对于其范围有如下规定: //WM_USER: 0x0400-0x7FFF (ex. WM_USER+10) //WM_APP(winver> 4.0): 0x8000-0xBFFF (ex.WM_APP+4) //RegisterWindowMessage: 0xC000-0xFFFF //这么做加快消息查找吧。 if (message < 0xC000) { // constant window message if ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, message, 0, 0)) != NULL) { pMsgCache->lpEntry = lpEntry; //缓存保存 winMsgLock.Unlock(); 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; winMsgLock.Unlock(); goto LDispatchRegistered; //跳到自己注册window消息那里去处理。。。 } lpEntry++; // keep looking past this one } } } pMsgCache->lpEntry = NULL; winMsgLock.Unlock(); return FALSE; } LDispatch: ASSERT(message < 0xC000); mmf.pfn = lpEntry->pfn; switch (lpEntry->nSig) //根据不同的函数签名,把函数指针转换对应的类型 { default: ASSERT(FALSE); break; case AfxSig_l_p: { CPoint point(lParam); lResult = (this->*mmf.pfn_l_p)(point); break; } case AfxSig_b_D_v: lResult = (this->*mmf.pfn_b_D)(CDC::FromHandle(reinterpret_cast<HDC>(wParam))); break; case AfxSig_l_D_u: lResult = (this->*mmf.pfn_l_D_u)(CDC::FromHandle(reinterpret_cast<HDC>(wParam)), (UINT)lParam); break; case AfxSig_b_b_v: lResult = (this->*mmf.pfn_b_b)(static_cast<BOOL>(wParam)); break; case AfxSig_b_u_v: lResult = (this->*mmf.pfn_b_u)(static_cast<UINT>(wParam)); break; case AfxSig_b_h_v: lResult = (this->*mmf.pfn_b_h)(reinterpret_cast<HANDLE>(wParam)); break; case AfxSig_i_u_v: lResult = (this->*mmf.pfn_i_u)(static_cast<UINT>(wParam)); break; case AfxSig_C_v_v: lResult = reinterpret_cast<LRESULT>((this->*mmf.pfn_C_v)()); break; case AfxSig_v_u_W: (this->*mmf.pfn_v_u_W)(static_cast<UINT>(wParam), CWnd::FromHandle(reinterpret_cast<HWND>(lParam))); break; case AfxSig_u_u_v: lResult = (this->*mmf.pfn_u_u)(static_cast<UINT>(wParam)); break; case AfxSig_b_v_v: lResult = (this->*mmf.pfn_b_v)(); break; case AfxSig_b_W_uu: lResult = (this->*mmf.pfn_b_W_u_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), LOWORD(lParam), HIWORD(lParam)); break; case AfxSig_b_W_COPYDATASTRUCT: lResult = (this->*mmf.pfn_b_W_COPYDATASTRUCT)( CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), reinterpret_cast<COPYDATASTRUCT*>(lParam)); break; case AfxSig_b_v_HELPINFO: lResult = (this->*mmf.pfn_b_HELPINFO)(reinterpret_cast<LPHELPINFO>(lParam)); break; case AfxSig_CTLCOLOR: { // special case for OnCtlColor to avoid too many temporary objects ASSERT(message == WM_CTLCOLOR); AFX_CTLCOLOR* pCtl = reinterpret_cast<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) { // 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; } pWnd = &wndTemp; } HBRUSH hbr = (this->*mmf.pfn_B_D_W_u)(&dcTemp, pWnd, nCtlType); // fast detach of temporary objects dcTemp.m_hDC = NULL; wndTemp.m_hWnd = NULL; lResult = reinterpret_cast<LRESULT>(hbr); } break; case AfxSig_CTLCOLOR_REFLECT: { // special case for CtlColor to avoid too many temporary objects ASSERT(message == WM_REFLECT_BASE+WM_CTLCOLOR); AFX_CTLCOLOR* pCtl = reinterpret_cast<AFX_CTLCOLOR*>(lParam); CDC dcTemp; dcTemp.m_hDC = pCtl->hDC; UINT nCtlType = pCtl->nCtlType; HBRUSH hbr = (this->*mmf.pfn_B_D_u)(&dcTemp, nCtlType); // fast detach of temporary objects dcTemp.m_hDC = NULL; lResult = reinterpret_cast<LRESULT>(hbr); } break; case AfxSig_i_u_W_u: lResult = (this->*mmf.pfn_i_u_W_u)(LOWORD(wParam), CWnd::FromHandle(reinterpret_cast<HWND>(lParam)), HIWORD(wParam)); break; case AfxSig_i_uu_v: lResult = (this->*mmf.pfn_i_u_u)(LOWORD(wParam), HIWORD(wParam)); break; case AfxSig_i_W_uu: lResult = (this->*mmf.pfn_i_W_u_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), LOWORD(lParam), HIWORD(lParam)); break; case AfxSig_i_v_s: lResult = (this->*mmf.pfn_i_s)(reinterpret_cast<LPTSTR>(lParam)); break; case AfxSig_i_v_S: lResult = (this->*mmf.pfn_i_S)(reinterpret_cast<LPCTSTR>(lParam)); break; case AfxSig_v_F_b: (this->*mmf.pfn_v_F_b)(CFont::FromHandle(reinterpret_cast<HFONT>(wParam)), (BOOL)LOWORD(lParam)); break; case AfxSig_h_v_v: { HANDLE handle = (this->*mmf.pfn_h_v)(); lResult = reinterpret_cast<LRESULT>(handle); } break; case AfxSig_h_b_h: { HANDLE handle = (this->*mmf.pfn_h_b_h)(static_cast<BOOL>(wParam), reinterpret_cast<HANDLE>(lParam)); lResult = reinterpret_cast<LRESULT>(handle); } break; case AfxSig_h_h_h: { HANDLE handle = (this->*mmf.pfn_h_h_h)(reinterpret_cast<HANDLE>(wParam), reinterpret_cast<HANDLE>(lParam)); lResult = reinterpret_cast<LRESULT>(handle); } break; case AfxSig_l_w_l: lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam); break; case AfxSig_l_uu_M: lResult = (this->*mmf.pfn_l_u_u_M)(LOWORD(wParam), HIWORD(wParam), CMenu::FromHandle(reinterpret_cast<HMENU>(lParam))); break; case AfxSig_v_b_h: (this->*mmf.pfn_v_b_h)(static_cast<BOOL>(wParam), reinterpret_cast<HANDLE>(lParam)); break; case AfxSig_v_h_v: (this->*mmf.pfn_v_h)(reinterpret_cast<HANDLE>(wParam)); break; case AfxSig_v_h_h: (this->*mmf.pfn_v_h_h)(reinterpret_cast<HANDLE>(wParam), reinterpret_cast<HANDLE>(lParam)); break; case AfxSig_v_v_v: (this->*mmf.pfn_v_v)(); break; case AfxSig_v_u_v: (this->*mmf.pfn_v_u)(static_cast<UINT>(wParam)); break; case AfxSig_v_up_v: (this->*mmf.pfn_v_up)(static_cast<UINT_PTR>(wParam)); break; case AfxSig_v_u_u: (this->*mmf.pfn_v_u_u)(static_cast<UINT>(wParam), static_cast<UINT>(lParam)); break; case AfxSig_v_uu_v: (this->*mmf.pfn_v_u_u)(LOWORD(wParam), HIWORD(wParam)); break; case AfxSig_v_v_ii: (this->*mmf.pfn_v_i_i)(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case AfxSig_v_u_uu: (this->*mmf.pfn_v_u_u_u)(static_cast<UINT>(wParam), LOWORD(lParam), HIWORD(lParam)); break; case AfxSig_v_u_ii: (this->*mmf.pfn_v_u_i_i)(static_cast<UINT>(wParam), LOWORD(lParam), HIWORD(lParam)); break; case AfxSig_v_w_l: (this->*mmf.pfn_v_w_l)(wParam, lParam); break; case AfxSig_MDIACTIVATE: (this->*mmf.pfn_v_b_W_W)(m_hWnd == reinterpret_cast<HWND>(lParam), CWnd::FromHandle(reinterpret_cast<HWND>(lParam)), CWnd::FromHandle(reinterpret_cast<HWND>(wParam))); break; case AfxSig_MDINext: (this->*mmf.pfn_v_W_b)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), static_cast<BOOL>(lParam)); break; case AfxSig_v_D_v: (this->*mmf.pfn_v_D)(CDC::FromHandle(reinterpret_cast<HDC>(wParam))); break; case AfxSig_v_M_v: (this->*mmf.pfn_v_M)(CMenu::FromHandle(reinterpret_cast<HMENU>(wParam))); break; case AfxSig_v_M_ub: (this->*mmf.pfn_v_M_u_b)(CMenu::FromHandle(reinterpret_cast<HMENU>(wParam)), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case AfxSig_v_W_v: (this->*mmf.pfn_v_W)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam))); break; case AfxSig_v_v_W: (this->*mmf.pfn_v_W)(CWnd::FromHandle(reinterpret_cast<HWND>(lParam))); break; case AfxSig_v_W_uu: (this->*mmf.pfn_v_W_u_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), LOWORD(lParam), HIWORD(lParam)); break; case AfxSig_v_W_p: { CPoint point(lParam); (this->*mmf.pfn_v_W_p)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), point); } break; case AfxSig_v_W_h: (this->*mmf.pfn_v_W_h)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), reinterpret_cast<HANDLE>(lParam)); break; case AfxSig_ACTIVATE: (this->*mmf.pfn_v_u_W_b)(LOWORD(wParam), CWnd::FromHandle(reinterpret_cast<HWND>(lParam)), HIWORD(wParam)); break; case AfxSig_SCROLL: case AfxSig_SCROLL_REFLECT: { // 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_SCROLL) (this->*mmf.pfn_v_u_u_W)(nScrollCode, nPos, CWnd::FromHandle(reinterpret_cast<HWND>(lParam))); else (this->*mmf.pfn_v_u_u)(nScrollCode, nPos); } break; case AfxSig_v_v_s: (this->*mmf.pfn_v_s)(reinterpret_cast<LPTSTR>(lParam)); break; case AfxSig_v_u_cs: (this->*mmf.pfn_v_u_cs)(static_cast<UINT>(wParam), reinterpret_cast<LPCTSTR>(lParam)); break; case AfxSig_OWNERDRAW: (this->*mmf.pfn_v_i_s)(static_cast<int>(wParam), reinterpret_cast<LPTSTR>(lParam)); lResult = TRUE; break; case AfxSig_i_i_s: lResult = (this->*mmf.pfn_i_i_s)(static_cast<int>(wParam), reinterpret_cast<LPTSTR>(lParam)); break; case AfxSig_u_v_p: { CPoint point(lParam); lResult = (this->*mmf.pfn_u_p)(point); } break; case AfxSig_u_v_v: lResult = (this->*mmf.pfn_u_v)(); break; case AfxSig_v_b_NCCALCSIZEPARAMS: (this->*mmf.pfn_v_b_NCCALCSIZEPARAMS)(static_cast<BOOL>(wParam), reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam)); break; case AfxSig_v_v_WINDOWPOS: (this->*mmf.pfn_v_v_WINDOWPOS)(reinterpret_cast<WINDOWPOS*>(lParam)); break; case AfxSig_v_uu_M: (this->*mmf.pfn_v_u_u_M)(LOWORD(wParam), HIWORD(wParam), reinterpret_cast<HMENU>(lParam)); break; case AfxSig_v_u_p: { CPoint point(lParam); (this->*mmf.pfn_v_u_p)(static_cast<UINT>(wParam), point); } break; case AfxSig_SIZING: (this->*mmf.pfn_v_u_pr)(static_cast<UINT>(wParam), reinterpret_cast<LPRECT>(lParam)); lResult = TRUE; break; case AfxSig_MOUSEWHEEL: lResult = (this->*mmf.pfn_b_u_s_p)(LOWORD(wParam), (short)HIWORD(wParam), CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); if (!lResult) return FALSE; break; case AfxSig_MOUSEHWHEEL: (this->*mmf.pfn_MOUSEHWHEEL)(LOWORD(wParam), (short)HIWORD(wParam), CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); break; case AfxSig_l: lResult = (this->*mmf.pfn_l_v)(); if (lResult != 0) return FALSE; break; case AfxSig_u_W_u: lResult = (this->*mmf.pfn_u_W_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), static_cast<UINT>(lParam)); break; case AfxSig_v_u_M: (this->*mmf.pfn_v_u_M)(static_cast<UINT>(wParam), CMenu::FromHandle(reinterpret_cast<HMENU>(lParam))); break; case AfxSig_u_u_M: lResult = (this->*mmf.pfn_u_u_M)(static_cast<UINT>(wParam), CMenu::FromHandle(reinterpret_cast<HMENU>(lParam))); break; case AfxSig_u_v_MENUGETOBJECTINFO: lResult = (this->*mmf.pfn_u_v_MENUGETOBJECTINFO)(reinterpret_cast<MENUGETOBJECTINFO*>(lParam)); break; case AfxSig_v_M_u: (this->*mmf.pfn_v_M_u)(CMenu::FromHandle(reinterpret_cast<HMENU>(wParam)), static_cast<UINT>(lParam)); break; case AfxSig_v_u_LPMDINEXTMENU: (this->*mmf.pfn_v_u_LPMDINEXTMENU)(static_cast<UINT>(wParam), reinterpret_cast<LPMDINEXTMENU>(lParam)); break; case AfxSig_APPCOMMAND: (this->*mmf.pfn_APPCOMMAND)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), static_cast<UINT>(GET_APPCOMMAND_LPARAM(lParam)), static_cast<UINT>(GET_DEVICE_LPARAM(lParam)), static_cast<UINT>(GET_KEYSTATE_LPARAM(lParam))); lResult = TRUE; break; case AfxSig_RAWINPUT: (this->*mmf.pfn_RAWINPUT)(static_cast<UINT>(GET_RAWINPUT_CODE_WPARAM(wParam)), reinterpret_cast<HRAWINPUT>(lParam)); break; case AfxSig_u_u_u: lResult = (this->*mmf.pfn_u_u_u)(static_cast<UINT>(wParam), static_cast<UINT>(lParam)); break; case AfxSig_u_u_l: lResult = (this->*mmf.pfn_u_u_l)(static_cast<UINT>(wParam), lParam); break; case AfxSig_MOUSE_XBUTTON: (this->*mmf.pfn_MOUSE_XBUTTON)(static_cast<UINT>(GET_KEYSTATE_WPARAM(wParam)), static_cast<UINT>(GET_XBUTTON_WPARAM(wParam)), CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); lResult = TRUE; break; case AfxSig_MOUSE_NCXBUTTON: (this->*mmf.pfn_MOUSE_NCXBUTTON)(static_cast<short>(GET_NCHITTEST_WPARAM(wParam)), static_cast<UINT>(GET_XBUTTON_WPARAM(wParam)), CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); lResult = TRUE; break; case AfxSig_INPUTLANGCHANGE: (this->*mmf.pfn_INPUTLANGCHANGE)(static_cast<UINT>(wParam), static_cast<UINT>(lParam)); lResult = TRUE; break; case AfxSig_INPUTDEVICECHANGE: (this->*mmf.pfn_INPUTDEVICECHANGE)(LOWORD(wParam), reinterpret_cast<HANDLE>(lParam)); break; case AfxSig_v_u_hkl: (this->*mmf.pfn_v_u_h)(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam)); break; case AfxSig_b_v_ii: lResult = (this->*mmf.pfn_b_v_ii)(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; } goto LReturnTrue; LDispatchRegistered: // for registered windows messages ASSERT(message >= 0xC000); ASSERT(sizeof(mmf) == sizeof(mmf.pfn)); mmf.pfn = lpEntry->pfn; lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam); LReturnTrue: if (pResult != NULL) *pResult = lResult; return TRUE; } 现在进入对应---》Hwnd 转换成对应的过程 ----------->CWnd自己有一个内存的表,一般界面库是绑定this在窗口到数据里面,这样就不用查询 表了。自己保存这个表的话就同步,如果窗口很多查询估计有一点消耗。但估计对性能影响不大。 其实很多界面库其实也差不多做法,对于消息处理封装。 //其实MFC代码有很多历史的包袱在里面,既要封装windows的基本的API 就要封装com, 一些插件。 对象没有很好抽离出来,加上很多新手直接跳过WIN32 SDK开发直接用MFC开发,搞死个人啊。。。。。。。 MFC 不仅仅是界面库的东西。 目前MFC 这种UI开发思想就是 所有一切(控件)都是窗口,因为每个窗口都有自己消息循环,而MFC(window) 关系联系太过简单, 导致很多操作很麻烦,而且对于自定义贴图那些显得麻烦。我做自定义CBtn自绘按钮时候,贴入透明图片,必须要刷新父窗口指定位置,才能刷掉原来东西,不然就会绘图重叠,我想这个问题大家都会遇到过。window 控件在支持自绘显得很麻烦。用过directui 开发就知道,那种感觉。 最近对UI做的比较多一些,很多东西都在脑海出现。感慨很多。window界面开发感觉会越来越来浏览器开发。发现很多技术在很久以前都出现了,比喻浏览器这种界面开发,现在directui无非只是简单模拟而已。 菜鸟一些小小的感概而已,只是随便总结一下而已。
原文地址:http://blog.csdn.net/littlefishvc/article/details/43704957