我们都知道MFC的窗口例程都是 AfxWndProc,下面就来分析是怎样实现的。
我们在wnd的Create函数或者dialog的DoModel函数里面都会看到一个函数:AfxHookWindowCreate(this);
在这个函数里面最重要的一句语句是:
::SetWindowsHookEx(WH_CBT, _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());
- void AFXAPI AfxHookWindowCreate(CWnd* pWnd)
- {
- _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();//看下面的说明
- if (pThreadState->m_pWndInit == pWnd)
- return;
- if (pThreadState->m_hHookOldCbtFilter == NULL)
- {//可以看出,这if之后进来一次,可以调用多次。
- pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT,
- _AfxCbtFilterHook, NULL, ::GetCurrentThreadId());
- if (pThreadState->m_hHookOldCbtFilter == NULL)
- AfxThrowMemoryException();
- }
- //···
- pThreadState->m_pWndInit = pWnd;
- }
SetWindowsHookEx函数的作用是:给线程安装一个WH_CBT钩子,当激活,创建,销毁··一个窗口的时候回先调用这个钩子函数通知我们。也就是在线程创建窗口时,在窗口接收第一个消息之前会调用我们 _AfxCbtFilterHook 这个函数。
然后 _AfxCbtFilterHook 这个函数把 原来旧的窗口程序换成了 AfxWndProc。 这个钩子保证窗口在收到第一个消息前执行,也就保证了第一条消息的正确处理。