LRESULT CALLBACK CSubclassWnd::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { CSubclassWnd* pThis = (CSubclassWnd*)hWnd; // set a ptr to this message and save the old value MSG msg = { pThis->m_hWnd, message, wParam, lParam, 0, { 0, 0 } }; // check to see if this is a reflected message and adjust accordingly MSGREFLECTSTRUCT* rs = 0; if (message == WM_REFLECT) { rs = (MSGREFLECTSTRUCT*)lParam; ASSERT(rs); msg.message = rs->message; msg.wParam = rs->wParam; msg.lParam = rs->lParam; } // save the message information and set the new current const MSG* pOldMsg = pThis->m_pCurrentMsg; pThis->m_pCurrentMsg = &msg; // pass to the message map to process LRESULT lRes; BOOL bRet = pThis->ProcessWindowMessage(msg.message, msg.wParam, msg.lParam, lRes); // if this is a reflected message let parent know if it was handled if (rs) rs->bHandled = bRet; // restore saved value for the current message pThis->m_pCurrentMsg = pOldMsg; // do the default processing if message was not handled // note that we need to use the original values, so that reflected // messages can properly set the 'bHandled' flag. if (!bRet) lRes = pThis->DefWindowProc(message, wParam, lParam); if (message == WM_NCDESTROY) { // unsubclass, if needed pThis->UnsubclassWindow(); // clean up after window is destroyed pThis->OnFinalMessage(); } return lRes; }
static LRESULT CALLBACK SubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lr; CSubclassWnd *pSubClass = NULL; if(CSubclassWnd::m_SubclassWndMap.Lookup(hWnd, pSubClass) && pSubClass != NULL) { lr = pSubClass->WindowProc(uMsg, wParam, lParam); } else { lr = ::DefWindowProc(hWnd, uMsg, wParam, lParam); } return lr; }
////////////////// // Subclassed window proc for message hooks. Replaces AfxWndProc (or whatever // else was there before.) // LRESULT CALLBACK HookWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { #ifdef _USRDLL // If this is a DLL, need to set up MFC state AFX_MANAGE_STATE(AfxGetStaticModuleState()); #endif // Set up MFC message state just in case anyone wants it // This is just like AfxCallWindowProc, but we can't use that because // a CSubclassWnd is not a CWnd. // MSG& curMsg = AfxGetThreadState()->m_lastSentMsg; MSG oldMsg = curMsg; // save for nesting curMsg.hwnd = hwnd; curMsg.message = msg; curMsg.wParam = wp; curMsg.lParam = lp; // Get hook object for this window. Get from hook map CSubclassWnd* pSubclassWnd = theHookMap.Lookup(hwnd); ASSERT(pSubclassWnd); LRESULT lr; if (msg==WM_NCDESTROY) { // Window is being destroyed: unhook all hooks (for this window) // and pass msg to orginal window proc // WNDPROC wndproc = pSubclassWnd->m_pOldWndProc; theHookMap.RemoveAll(hwnd); lr = ::CallWindowProc(wndproc, hwnd, msg, wp, lp); } else { // pass to msg hook lr = pSubclassWnd->WindowProc(msg, wp, lp); } curMsg = oldMsg; // pop state return lr; }
////////////////// // Remove all the hooks for a window // void CSubclassWndMap::RemoveAll(HWND hwnd) { CSubclassWnd* pSubclassWnd; while ((pSubclassWnd = Lookup(hwnd))!=NULL) pSubclassWnd->HookWindow((HWND)NULL); // (unhook) }