MFC的訊息對映原理

2021-10-02 05:38:30 字數 2663 閱讀 9963

本文要求對c++語法比較熟悉(特別是虛函式的使用),若不熟悉建議參閱《c++語法詳解》一書,電子工業出版社出版

1、訊息對映:就是把指定的訊息交給指定的函式進行處理的方法,這樣就形成了乙個《訊息,處理函式》對。

2、本文有時會使用表示《訊息,處理函式》對。

一、共用體(union)的使用

1、共用體可以實現以下兩個功能(詳見示例說明)。

1)、呼叫函式時不需要知道函式的名稱(通過函式指標呼叫),以及確定呼叫該函式時需要傳遞什麼型別的形參(即可以確定函式原型)。

2)、在類繼承體系中實現類似虛函式的功能。

2、語法問題(指向類成員的指標):使用指向類成員的函式指標時,必須通過類的物件或指向類的指標間接使用,比如class a}; a m; a *pa=&m; void (a::*pf)()=&a::f; 則應這樣通過pf呼叫f,即(ma.*pf)()或(pa->*pf)();是正確的,但不能直接使用pf呼叫成員函式f,即(*pf)();或(a::*pf)();錯誤。

示例3.5:共用體的使用(以下示例為c++程式)

#include 「stdafx.h」 //對於c++程式,vc++編譯器必須包含此標頭檔案。

#include

using namespace std;

class b;

typedef void (b::*pf)();

class b; /因為un是共用體,因此其成員uf,pf_0,pf_1擁有相同的值,即他們都是指向同一位址的指標,但是三個函式指標的型別不一樣(即指向的函式的形參和返回型別不一樣)。/

void main()

//輸出fc,其原理同上。

#include 「stdafx.h」 //對於c++程式,vc++編譯器必須包含此標頭檔案。

#include

using namespace std;

class b;

typedef void (b::*pf)();

class b; /因為un是共用體,因此其成員uf,pf_0,pf_1擁有相同的值,即他們都是指向同一位址的指標,但是三個函式指標的型別不一樣(即指向的函式的形參和返回型別不一樣)。/

void main()

//輸出fc,其原理同上。

#include 「stdafx.h」 //對於c++程式,vc++編譯器必須包含此標頭檔案。

#include

using namespace std;

class b;

typedef void (b::*pf)();

class b; /因為un是共用體,因此其成員uf,pf_0,pf_1擁有相同的值,即他們都是指向同一位址的指標,但是三個函式指標的型別不一樣(即指向的函式的形參和返回型別不一樣)。/

void main()

//輸出fc,其原理同上。

按下滑鼠左鍵後彈出的訊息框如下圖(省略主視窗):

程式演算法步驟詳解:

1、使用setwindowlongptr函式重新設定mfc程式的過程函式。

2、把需要處理的《訊息,處理函式》對(即),抽像為乙個型別,假設使用結構體型別s進行表示,那麼每個結構體型別變數都會儲存有乙個相對應的。比如:

typedef void (*pf)();

struct s;

1)、msg表示需要處理的訊息。

2)、msgid用於標示該結構體變數的乙個id符號。該成員在本例無用處,但在後面會有用。

3)、pf表示用於處理訊息msg的處理函式。

4)、為什麼pf的型別是pf:因為訊息處理函式的原型並不是全部一致的,在進行訊息對映時應使用相同的函式原型形式(即pf的形式)以便對訊息處理函式進行統一管理,因此在使用訊息處理函式初始化該成員時需要把訊息處理函式強制轉換為pf型別。

3、建立乙個結構體型別s的陣列用於儲存不同的對,該陣列就是程式設計師把訊息指定給自定義函式進行處理的地方。比如:

lresult f1(wparam w, lparam l) //處理訊息的函式f1

lresult f(wparam w, lparam l) //處理訊息的函式f

const s ss=,, };

1)、陣列ss儲存有兩個對,即處理滑鼠左鍵按下訊息的和處理滑鼠右鍵按下訊息的。

2)、若程式設計師需要把其他訊息使用另外的函式進行處理,則只需把相應的《訊息,處理函式》對,新增到陣列ss中即可,這樣就實現了訊息的對映。

3)、完成以上步驟之後,則在過程函式中接收到需要處理的訊息時,只需呼叫「」中的處理函式f處理該訊息即可。問題的關鍵是怎樣呼叫「處理函式f」。

4、使用共用體間接呼叫訊息處理函式:

怎樣呼叫相關聯的訊息處理函式:因為mfc的原始碼實現的訊息對映是向程式設計師隱藏了的,那麼在呼叫訊息處理函式時,mfc原始碼肯定是不知道程式設計師自定義的「訊息處理函式」的名稱的,這就意味著,不能在原始碼中直接呼叫訊息處理函式,而只能間接的呼叫類似以上陣列ss中的結構體s中的成員pf,即只能這樣呼叫訊息處理函式ss[1].pf();但因為pf的原型與訊息處理函式的原型並不相同(本例pf與f原型就不一致),這就可能會產生錯誤,為了解決函式原型的問題,可以使用共用體型別的成員儲存訊息處理函式的原型,然後使用共用體成員間接呼叫訊息處理函式。比如:

union un;

un meff;

meff.pf=ss[0].pf; //初始化共用體變數meff,其中ss[0].pf指向的函式是f1。

meff.pf_0(w,l); //通過共用體成員pf_0間接呼叫訊息處理函式f1。

MFC訊息對映的原理

多型的實現機制有兩種,一是通過查詢絕對位置表,二是查詢名稱表 兩者各有優缺點,那麼為什麼 mfc的訊息對映採用了第二種方法,而不是 c 使用的第一種呢?因為在 mfc的 gui類庫是乙個龐大的繼承體系,而裡面的每個類有很多成員函式 只說訊息反映相關的成員函式啊 而且在派生類中,需要改寫的也比較少 我...

MFC訊息對映的原理 筆記

rel file list href file c 5cdocume 7e1 5cddnw 5clocals 7e1 5ctemp 5cmsohtml1 5c01 5cclip filelist.xml 多型的實現機制有兩種,一是通過查詢絕對位置表,二是查詢名稱表 兩者各有優缺點,那麼為什麼 mfc...

MFC訊息對映

run這個函式來建立和處理訊息迴圈 bool afxapi afxinternalpumpmessage return true 顯而易見,mfc中處理訊息也是利用了win32下的訊息處理 那麼還是這樣的結構 typedef struct tagmsg msg 有了這個概念之後我們知道,mfc通過訊...