MFC漫談(四)——消息的路由
有了消息映射表,如何利用呢?消息如何被分門別類的派發(fā)出去的?用最基本的一句話概述,鉤子函數(shù)起了很大作用。故事是這樣的,有些漫長,也需要些耐心。
MFC中消息分為3類:
?1. WM_COMMAND:所有的UI組件和加速鍵都會產(chǎn)生這種消息,所有派生于CCmdTarget的類都有能力處理該消息
?2. 標(biāo)準(zhǔn)消息:除WM_COMMAND之外的WM_xx消息都是標(biāo)準(zhǔn)消息,派生于CWnd的類都有能力處理該消息
?3. 控件通知消息:用于子窗口控件向父窗口發(fā)送的消息
在MFC的消息映射表的建立中,通過一組宏,你就可以讓自己的類先于父類處理某些Windows消息,這種行為很像虛函數(shù),只是我們重載的內(nèi)容不是虛函數(shù),而是消息。
推動消息的泵
第一階段 窗口過程
在產(chǎn)生一個窗口的時候,會調(diào)用CFrameWnd::Create,所有的故事也都從這里展開。下面的代碼為了簡潔,去掉了不相關(guān)的代碼
BOOL?CFrameWnd::Create(…)?
{
????
//
?…
????
if
?(
!
CreateEx(…))?
{
????????
//
?…
????}
????
//
?…
}
BOOL?CWnd::CreateEx(…)?
{
????
//
?…
????AfxHookWindowCreate(
this
);
????HWND?hWnd?
=
?::CreateWindowEx(…);
????
//
?…
}
void
?AFXAPI?AfxHookWindowCreate(CWnd
*
?pWnd)?
{
????
//
?…
????
if
?(pThreadState
->
m_hHookOldCbtFilter?
==
?NULL)?
{
????????pThreadState
->
m_hHookOldCbtFilter?
=
?::SetWindowsHookEx(WH_CBT,
????????_AfxCbtFilterHook,?NULL,?::GetCurrentThreadId());
????????
//
?…
????}
????
//
?…
????pThreadState
->
m_pWndInit?
=
?pWnd;
}
這樣,通過AfxHookWindowCreate,在當(dāng)前線程中安裝了一個鉤子,用來攔截和窗口相關(guān)的事件,每當(dāng):
1. 另一個窗口成為active;
2. 產(chǎn)生或摧毀一個窗口
3. Minimize或maximize一個窗口;
4. 移動或縮放一個窗口;
5. 完成一個來自系統(tǒng)菜單的命令;
6. 從系統(tǒng)隊(duì)列中取出一個消息;
時,都會先調(diào)用_AfxCbtFilterHook,接下來看看鉤子函數(shù)作了什么:
LRESULT?CALLBACK
_AfxCbtFilterHook(
int
?code,?WPARAM?wParam,?LPARAM?lParam)?
{
????
//
?…
????WNDPROC?afxWndProc?
=
?AfxGetAfxWndProc();
????oldWndProc?
=
?(WNDPROC)SetWindowLongPtr(hWnd,?GWLP_WNDPROC,(DWORD_PTR)afxWndProc);
????
//
?…
}
WNDPROC?AFXAPI?AfxGetAfxWndProc()?
{
????
//
?…
????
return
?
&
AfxWndProc;
}
這樣,_AfxCbtFilterHook的工作總結(jié)起來就是通過窗口子類化,把新建的窗口的窗口過程設(shè)置成AfxWndProc。
到這里,我們終于找到了窗口過程。
結(jié)論
CFrameWnd::Create創(chuàng)建窗口調(diào)用CWnd::CreateEx
CWnd::CreateEx調(diào)用AfxHookWindowCreate準(zhǔn)備為窗口設(shè)置鉤子
AfxHookWindowCreate調(diào)用::SetWindowHookEx為窗口設(shè)置了一個WH_CBT類型的鉤子來過濾消息,并把過濾函數(shù)設(shè)置成_AfxCbtFilterHook
_AfxCbtFilterHook通過窗口子類化設(shè)置窗口的窗口過程為AfxWndProc
這樣,通過::DispatchMessage發(fā)送給窗口的消息就會源源不斷地送到AfxWndProc中來,可以想到,AfxWndProc利用MFC的消息映射表,分門別類的對消息進(jìn)行分流。
(待續(xù)……)
posted on 2006-05-18 17:29 nacci 閱讀(3896) 評論(2) 編輯 收藏 引用 所屬分類: C++漫談

