MFC窗口过程函数之偷梁换柱

来源:互联网 发布:linux下lnmp环境搭建 编辑:程序博客网 时间:2024/05/19 16:47

前阵子看MFC的时候,看到MFC窗口的过程函数竟是默认的DefWindowProc,可实际调试程序时却发现实际调试跟踪程序时发现实际的窗口过程函数却变成了AfxWndProcBase了。这是咋回事呢?!

后来分析了一下代码,原来是被Hook函数给偷梁换柱了,呵呵,不多说了,直接上代码了。

// Wincore.cppLPCTSTR AFXAPI AfxRegisterWndClass(UINT nClassStyle,HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon){// ... wndcls.style = nClassStyle;wndcls.lpfnWndProc = DefWindowProc;// ...if (!AfxRegisterClass(&wndcls))AfxThrowResourceException();return lpszName;}

我在这看见的过程函数明明就是DefWindowProc嘛,怎么后来会变成AfxWinProcBase了呢?

原来窗口产生之前又偷梁换柱掉了。

下面展示下这个过程。

// wincore.cppBOOL 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;// ...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);// ...}void AFXAPI AfxHookWindowCreate(CWnd* pWnd){// ...if (pThreadState->m_hHookOldCbtFilter == NULL){pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT,_AfxCbtFilterHook, NULL, ::GetCurrentThreadId());if (pThreadState->m_hHookOldCbtFilter == NULL)AfxThrowMemoryException();}// ...}_AfxCbtFilterHook是过回调函数,安装Hook后,窗口做任何操作前,必须先调用此函数。LRESULT CALLBACK_AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam){...WNDPROC afxWndProc = AfxGetAfxWndProc();oldWndProc = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC,(DWORD)afxWndProc);...}WNDPROC AFXAPI AfxGetAfxWndProc(){...return AfxGetModuleState()->m_pfnAfxWndProc;...}


总之到这里过程函数就变成了AfxWndProcBase了,因为m_pfnAfxWndProc是个函数指针,里面中放得就是AfxWndProcBase的函数地址。具体的细节又涉及Module的初始化,哈哈,小文篇幅有限,这里就不展开去了。

所以不必奇怪,是Hook函数完成了偷梁换柱的行当,害得我跟踪了好久^_^。 

参考资料:《深入浅出MFC[侯捷,华东理工简体版]