分析與理解訊息反射機制 (轉)
分析與理解訊息反射機制 (轉)[@more@]鄭力群
前言:
我曾寫過一篇文章對通知訊息WM_NOTIFY進行分析,訊息反射是MFC中對通知訊息的處理方式,兩者之間關係十分緊密,因此,我寫了這篇文章,希望能夠描繪出通知訊息的完整印象。
訊息反射的基礎知識
1、訊息反射解釋:
父視窗將控制子視窗發給它的通知訊息,首先反射回子視窗進行處理(即給控制子視窗一個機會,讓控制子視窗處理此訊息),這樣通知訊息就有機會能被子視窗自身進行處理。
2、MFC中引入訊息反射的原因:
在的訊息處理中,控制子視窗的發給其父視窗的通知訊息只能由其父視窗進行處理,這使得控制子視窗的自身能動性大大降低(你想,它連改變自己的背景色,處理一個自身滾動問題都要其父視窗來完成),為了解決這個問題,在MFC中引入了反射訊息“Reflect Message”的概念,進行訊息反射,可以使得控制子視窗能夠自行處理與自身相關的一些訊息,增強了封裝性,從而提高了控制子視窗的可重用性。
訊息反射的處理流程(不考慮OLE控制)
一、訊息反射處理流程圖:
1、父視窗收到控制子視窗發來的通知訊息後,它的虛CWnd::OnNotify.
CWnd::OnNotify()主體部分:
{
if (ReflectLastMsg(hWndCtrl, pResult)) //此時,hWndCtrl,為傳送視窗,即子視窗的視窗控制程式碼
return TRUE; // 子視窗已處理了此訊息
AFX_NOTIFY notify;
notify.pResult = pResult;
notify.pNMHDR = pNMHDR;
return OnCmdMsg(nID, MAKELONG(nCode, WM_NOTIFY), ¬ify, NULL);
}
分析:首先,呼叫ReflectLastMsg(hCtrlChildWnd,...)給子視窗一個自身處理的機會,將訊息反射給子視窗處理,函式返回TRUE,表明子視窗處理了此訊息。反之,表示子視窗未處理此訊息,此時,呼叫OnCmdMsg(...)由父視窗進行通常的處理。
2、ReflectLastMsg中:
主要是呼叫傳送視窗的SendChildNotifyLastMsg(...)。
3、SendChildNotifyLastMsg 中:
呼叫傳送視窗的虛擬函式OnChildNotify函式,進行處理。 如果沒有處理,則呼叫ReflectChildNotify(...)函式進行標準的反射訊息的訊息對映處理。
二、訊息處理
方式1:
由上述處理流程可以看出來,子視窗要想自身處理此訊息,過載子視窗的OnChildNotify虛擬函式應該是很容易想到的方式。
注意:MFC中對各個子控制元件視窗一般都已經過載了OnChildNotify函式,它對應呼叫類的虛擬函式進行處理,所以,你過載對應的虛擬函式即可,如下例:
BOOL CStatarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,LRESULT* pResult)
{
if (message != WM_DRAWITEM) //對應不同的控制,會有不同的有特殊處理要求的訊息。
return CWnd::OnChildNotify(message, wParam, lParam, pResult);
...
...
DrawItem((LPDRAWITEMSTRUCT)lParam);
return TRUE;
}
virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
void CStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT)
{
ASSERT(FALSE); // must overr for self draw status bars
}
你過載CSTatusBarCtrl類的DrawItem虛擬函式,即可實現對反射訊息WM_DRAWITEM的處理。
方式2:
從方式1可以看出,如果你不在被過載的OnChildNotify中對訊息進行處理,函式會呼叫CWnd::OnChildNotify,它呼叫ReflectChildNotify函式進行標準的處理。
1、增加反射訊息的對映入口。
2、增加對應的訊息處理函式。
注意:可以使用MFC的ClassWizard作上述動作,在ClassWizard中,可處理的反射訊息以一個"="號以示區別。返回值為TRUE,表示控制元件視窗已處理此反射訊息,為FALSE,表示控制元件子視窗未處理此反射訊息。
結語:
訊息反射不是很難的概念。它僅出現在MFC中;它的用意是方便控制子視窗的重用;對某些通知訊息你可以過載對應的虛擬函式(WM_DRAWITEM...)進行處理;對其它你可以使用標準的訊息反射對映進行處理。限於篇幅,一些細節問題,請閱讀MFC中對應的。
/recommend.">
前言:
我曾寫過一篇文章對通知訊息WM_NOTIFY進行分析,訊息反射是MFC中對通知訊息的處理方式,兩者之間關係十分緊密,因此,我寫了這篇文章,希望能夠描繪出通知訊息的完整印象。
訊息反射的基礎知識
1、訊息反射解釋:
父視窗將控制子視窗發給它的通知訊息,首先反射回子視窗進行處理(即給控制子視窗一個機會,讓控制子視窗處理此訊息),這樣通知訊息就有機會能被子視窗自身進行處理。
2、MFC中引入訊息反射的原因:
在的訊息處理中,控制子視窗的發給其父視窗的通知訊息只能由其父視窗進行處理,這使得控制子視窗的自身能動性大大降低(你想,它連改變自己的背景色,處理一個自身滾動問題都要其父視窗來完成),為了解決這個問題,在MFC中引入了反射訊息“Reflect Message”的概念,進行訊息反射,可以使得控制子視窗能夠自行處理與自身相關的一些訊息,增強了封裝性,從而提高了控制子視窗的可重用性。
訊息反射的處理流程(不考慮OLE控制)
一、訊息反射處理流程圖:
1、父視窗收到控制子視窗發來的通知訊息後,它的虛CWnd::OnNotify.
CWnd::OnNotify()主體部分:
{
if (ReflectLastMsg(hWndCtrl, pResult)) //此時,hWndCtrl,為傳送視窗,即子視窗的視窗控制程式碼
return TRUE; // 子視窗已處理了此訊息
AFX_NOTIFY notify;
notify.pResult = pResult;
notify.pNMHDR = pNMHDR;
return OnCmdMsg(nID, MAKELONG(nCode, WM_NOTIFY), ¬ify, NULL);
}
分析:首先,呼叫ReflectLastMsg(hCtrlChildWnd,...)給子視窗一個自身處理的機會,將訊息反射給子視窗處理,函式返回TRUE,表明子視窗處理了此訊息。反之,表示子視窗未處理此訊息,此時,呼叫OnCmdMsg(...)由父視窗進行通常的處理。
2、ReflectLastMsg中:
主要是呼叫傳送視窗的SendChildNotifyLastMsg(...)。
3、SendChildNotifyLastMsg 中:
呼叫傳送視窗的虛擬函式OnChildNotify函式,進行處理。 如果沒有處理,則呼叫ReflectChildNotify(...)函式進行標準的反射訊息的訊息對映處理。
二、訊息處理
方式1:
由上述處理流程可以看出來,子視窗要想自身處理此訊息,過載子視窗的OnChildNotify虛擬函式應該是很容易想到的方式。
注意:MFC中對各個子控制元件視窗一般都已經過載了OnChildNotify函式,它對應呼叫類的虛擬函式進行處理,所以,你過載對應的虛擬函式即可,如下例:
BOOL CStatarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,LRESULT* pResult)
{
if (message != WM_DRAWITEM) //對應不同的控制,會有不同的有特殊處理要求的訊息。
return CWnd::OnChildNotify(message, wParam, lParam, pResult);
...
...
DrawItem((LPDRAWITEMSTRUCT)lParam);
return TRUE;
}
virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
void CStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT)
{
ASSERT(FALSE); // must overr for self draw status bars
}
你過載CSTatusBarCtrl類的DrawItem虛擬函式,即可實現對反射訊息WM_DRAWITEM的處理。
方式2:
從方式1可以看出,如果你不在被過載的OnChildNotify中對訊息進行處理,函式會呼叫CWnd::OnChildNotify,它呼叫ReflectChildNotify函式進行標準的處理。
1、增加反射訊息的對映入口。
2、增加對應的訊息處理函式。
注意:可以使用MFC的ClassWizard作上述動作,在ClassWizard中,可處理的反射訊息以一個"="號以示區別。返回值為TRUE,表示控制元件視窗已處理此反射訊息,為FALSE,表示控制元件子視窗未處理此反射訊息。
結語:
訊息反射不是很難的概念。它僅出現在MFC中;它的用意是方便控制子視窗的重用;對某些通知訊息你可以過載對應的虛擬函式(WM_DRAWITEM...)進行處理;對其它你可以使用標準的訊息反射對映進行處理。限於篇幅,一些細節問題,請閱讀MFC中對應的。
/recommend.">
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993635/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 理解 Android 訊息機制Android
- 深入理解Android訊息機制Android
- 深入理解windows 訊息機制Windows
- 訊息機制篇——初識訊息與訊息佇列佇列
- 反射機制的簡答理解反射
- iOS 訊息轉發機制Demo解析iOS
- java基礎:深入理解Class物件與反射機制Java物件反射
- iOS進階之訊息轉發機制iOS
- 原始碼分析:Android訊息處理機制原始碼Android
- 深入理解Android非同步訊息處理機制Android非同步
- Java註解與反射機制Java反射
- 類載入機制與反射反射
- Android訊息機制HandlerAndroid
- android訊息機制—HandlerAndroid
- Android 之訊息機制Android
- Runtime 從NullSafe原始碼看訊息轉發 機制Null原始碼
- Runtime底層原理探究(一) --- 訊息轉發機制(快速轉發)
- iOS探索 動態方法解析和訊息轉發機制iOS
- Rabbitmq可靠訊息投遞,訊息確認機制MQ
- Android非同步訊息機制Android非同步
- 重拾 ObjC 訊息機制OBJ
- flutter 訊息傳遞機制Flutter
- RabbitMQ 訊息確認機制MQ
- 簡析Windows訊息機制Windows
- Handler訊息傳遞機制
- Android訊息機制Handler用法Android
- Kafka 訊息儲存機制Kafka
- Java反射機制Java反射
- iOS:利用訊息轉發機制實現多播委託iOS
- 你需要理解的 Java 反射機制知識總結Java反射
- Android的Handler訊息機制 解析Android
- MFC學習(四) 訊息機制
- Android Handler 訊息機制詳述Android
- 【RocketMQ】訊息的刷盤機制MQ
- RabbitMQ訊息佇列(九):Publisher的訊息確認機制MQ佇列
- Java - 反射機制與工廠設計模式Java反射設計模式
- Java - 反射機制與單例設計模式Java反射單例設計模式
- Java進階 | 泛型機制與反射原理Java泛型反射
- 用程式碼理解 ObjC 中的傳送訊息和訊息轉發OBJ