MFC消息映射的來龍去脈
2011-08-16 04:42
447 查看
CWinApp::CWinApp(LPCTSTR lpszAppName) { ...... pThreadState->m_pCurrentWinThread = this; ...... } _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ...... // App global initializations (rare) if (pApp != NULL && !pApp->InitApplication()) goto InitFailure; // Perform specific initializations if (!pThread->InitInstance()) { goto InitFailure; } nReturnCode = pThread->Run(); ...... return nReturnCode; } BOOL CWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { ...... return CreateEx(0, lpszClassName, lpszWindowName, dwStyle | WS_CHILD, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pParentWnd->GetSafeHwnd(), (HMENU)nID, (LPVOID)pContext); } BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam) { CREATESTRUCT cs; cs.dwExStyle = dwExStyle; cs.lpszClass = lpszClassName; cs.lpszName = lpszWindowName; cs.style = dwStyle; cs.x = x; cs.y = y; cs.cx = nWidth; cs.cy = nHeight; cs.hwndParent = hWndParent; cs.hMenu = nIDorHMenu; cs.hInstance = AfxGetInstanceHandle(); cs.lpCreateParams = lpParam; if (!PreCreateWindow(cs)) { PostNcDestroy(); return FALSE; } AfxHookWindowCreate(this); HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams); ...... return TRUE; } BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs) { if (cs.lpszClass == NULL) { // make sure the default window class is registered VERIFY(AfxDeferRegisterClass(AFX_WND_REG)); // no WNDCLASS provided - use child window default ASSERT(cs.style & WS_CHILD); cs.lpszClass = _afxWnd; } return TRUE; } #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister) { // mask off all classes that are already registered AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); fToRegister &= ~pModuleState->m_fRegisteredClasses; if (fToRegister == 0) return TRUE; LONG fRegisteredClasses = 0; // common initialization WNDCLASS wndcls; memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults wndcls.lpfnWndProc = DefWindowProc; wndcls.hInstance = AfxGetInstanceHandle(); wndcls.hCursor = afxData.hcurArrow; INITCOMMONCONTROLSEX init; init.dwSize = sizeof(init); // work to register classes as specified by fToRegister, populate fRegisteredClasses as we go if (fToRegister & AFX_WND_REG) { // Child windows - no brush, no icon, safest default class styles wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wndcls.lpszClassName = _afxWnd; if (AfxRegisterClass(&wndcls)) fRegisteredClasses |= AFX_WND_REG; } ...... // save new state of registered controls pModuleState->m_fRegisteredClasses |= fRegisteredClasses; // special case for all common controls registered, turn on AFX_WNDCOMMCTLS_REG if ((pModuleState->m_fRegisteredClasses & AFX_WIN95CTLS_MASK) == AFX_WIN95CTLS_MASK) { pModuleState->m_fRegisteredClasses |= AFX_WNDCOMMCTLS_REG; fRegisteredClasses |= AFX_WNDCOMMCTLS_REG; } // must have registered at least as mamy classes as requested return (fToRegister & fRegisteredClasses) == fToRegister; } BOOL AFXAPI AfxRegisterClass(WNDCLASS* lpWndClass) { WNDCLASS wndcls; if (GetClassInfo(lpWndClass->hInstance, lpWndClass->lpszClassName, &wndcls)) { // class already registered return TRUE; } if (!::RegisterClass(lpWndClass)) { TRACE1("Can't register window class named %s\n", lpWndClass->lpszClassName); return FALSE; } ...... return TRUE; } void AFXAPI AfxHookWindowCreate(CWnd* pWnd) { _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData(); if (pThreadState->m_pWndInit == pWnd) return; if (pThreadState->m_hHookOldCbtFilter == NULL) { pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT, _AfxCbtFilterHook, NULL, ::GetCurrentThreadId()); if (pThreadState->m_hHookOldCbtFilter == NULL) AfxThrowMemoryException(); } ASSERT(pThreadState->m_hHookOldCbtFilter != NULL); ASSERT(pWnd != NULL); ASSERT(pWnd->m_hWnd == NULL); // only do once ASSERT(pThreadState->m_pWndInit == NULL); // hook not already in progress pThreadState->m_pWndInit = pWnd; } _AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam) { ...... CWnd* pWndInit = pThreadState->m_pWndInit; BOOL bContextIsDLL = afxContextIsDLL; if (pWndInit != NULL || (!(lpcs->style & WS_CHILD) && !bContextIsDLL)) { ...... ASSERT(wParam != NULL); // should be non-NULL HWND HWND hWnd = (HWND)wParam; WNDPROC oldWndProc; if (pWndInit != NULL) { // the window should not be in the permanent map at this time ASSERT(CWnd::FromHandlePermanent(hWnd) == NULL); // connect the HWND to pWndInit... pWndInit->Attach(hWnd); // allow other subclassing to occur first pWndInit->PreSubclassWindow(); WNDPROC *pOldWndProc = pWndInit->GetSuperWndProcAddr(); ASSERT(pOldWndProc != NULL); { // subclass the window with standard AfxWndProc WNDPROC afxWndProc = AfxGetAfxWndProc(); oldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)afxWndProc); ASSERT(oldWndProc != NULL); if (oldWndProc != afxWndProc) *pOldWndProc = oldWndProc; } pThreadState->m_pWndInit = NULL; } ...... } ...... return lResult; } BOOL CWnd::Attach(HWND hWndNew) { ASSERT(m_hWnd == NULL); // only attach once, detach on destroy ASSERT(FromHandlePermanent(hWndNew) == NULL); // must not already be in permanent map if (hWndNew == NULL) return FALSE; CHandleMap* pMap = afxMapHWND(TRUE); // create map if not exist ASSERT(pMap != NULL); pMap->SetPermanent(m_hWnd = hWndNew, this); ...... return TRUE; } 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); ASSERT(pWnd != NULL); ASSERT(pWnd->m_hWnd == hWnd); if (pWnd == NULL || pWnd->m_hWnd != hWnd) return ::DefWindowProc(hWnd, nMsg, wParam, lParam); return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam); } LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg, WPARAM wParam = 0, LPARAM lParam = 0) { ...... // Catch exceptions thrown outside the scope of a callback // in debug builds and warn the user. LRESULT lResult; TRY { ...... // delegate to object's WindowProc lResult = pWnd->WindowProc(nMsg, wParam, lParam); ...... } CATCH_ALL(e) { ...... } END_CATCH_ALL pThreadState->m_lastSentMsg = oldState; return lResult; } 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; }
相关文章推荐
- MFC再学习(二)消息映射
- MFC 消息映射与配对函数~小结
- MFC消息映射的实现(转)
- MFC消息映射与消息传递内幕
- 孙鑫VC++讲座笔记-(4)MFC消息映射机制的剖析(修订版)
- MFC六大关键技术之(五)(六)——消息映射与命令传递
- MFC_OnSize_改变窗口大小(WM_SIZE消息映射)
- MFC六大核心机制之五、六:消息映射和命令传递
- 谈谈MFC中的消息映射
- (zz)MFC消息映射BEGIN_MESSAGE_MAP()
- 发送消息 MFC 消息映射
- MFC学习笔记2_消息映射
- MFC框架及消息映射
- MFC的消息映射有什么作用
- MFC单文档程序添加消息映射和消息响应函数的问题
- MFC消息映射与命令传递
- MFC里ON_COMMAND_RANGE消息映射的ID问题
- MFC消息映射与命令传递
- MFC消息映射-小白理解(4)
- MFC在VS2008中如何手动添加消息映射