VC++訊息對映的思考 (轉)
VC++訊息對映的思考:namespace prefix = o ns = "urn:schemas--com::office" />
作者:to:haoqingxin@263">郝慶欣
在學習VC++的時候,大家都不可避免的用到訊息對映。我們都知道C++是一種面向的語言,VC++中為什麼這樣來實現訊息對映呢?
首先要明白一個包含了訊息處理的是如何工作的。
一般來說一個包含了訊息處理的Windows程式至少要包含兩個
第一個:
int WIN WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);
第二個:
long FAR PASCAL WndProc(HWND hWnd, message,WORD wParam,LONG lParam);
我們不必糾纏程式實現的細節,只要明白在第一個函式WinMain中要註冊WndProc函式,通俗一些的理解就是WinMain告訴Windows,聽著,我知道你要產生很多訊息,我這裡有一個WndProc函式負責處理你傳遞來的各種訊息。當然訊息的格式都是系統規定好的。
其次要明白C++中是如何實現多型性的。
我們知道多型性實現的關鍵是晚繫結(或者稱為後期繫結),其實質就是並沒有在編譯期間指定函式的絕對地址,而是指定了某個類內部該函式的偏移地址。
為了實現上面的功能,編譯器為我們作了手腳
1、 在每個帶有虛擬函式的類中,編譯器秘密放置了一個指標,稱為Vpointer
2、 當系統執行時,為每個類建立一個VTABLE,其中包含了可以呼叫虛擬函式地址。
3、 Vpointer出始化,指向VTABLE,透過在Vtable中偏移,來找到正確的需要呼叫的函式地址。
然後是MFC對Window API進行的封裝
當我們利用MFC開發程式的時候,尤其是開發介面應用程式的時候,必定要用到CWnd或者派生於CWnd的類。根據物件導向的設計原則,對於CWnd的一些通用函式,例如視窗大學改變(OnSize),視窗移動(OnMove),最好是在CWnd中宣告為虛擬函式,然後在繼承的類裡面過載他們。但是,這樣以來,每個相關的派生類都要有一個Vpointer和一套記錄Vtable,而CWnd中通用函式是如此至多,CWnd的派生類也很多,必然會導致系統在執行是佔用過多的資源(),這樣顯然是不合適的。
那麼MFC是如何實現的呢?
答案就是在CWnd基類中儘可能的少用虛擬函式,採用訊息對映機制來代替。
大家可以看一下CWnd的類中的函式,就會發現這一點。
CWnd::OnMove
afx_msg void OnMove( int x, int y );
上面這個函式就不是虛擬函式。
最後的問題訊息對映是如何實現的呢?
用一句話說,就是利用宏定義來實現程式導向的訊息處理。
例如在VC中有如下的訊息對映宏。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
END_MESSAGE_MAP()
經過編譯後,程式碼被替換為如下形式(這只是作講解,實際情況比這複雜得多):
//BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
CMainFrame::newWndProc(...)
{
switch(...)
{
//{{AFX_MSG_MAP(CMainFrame)
// ON_WM_CREATE()
case(WM_CREATE):
OnCreate(...);
break;
//}}AFX_MSG_MAP
// ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
case(WM_COMMAND):
if(HIWORD(wP)==ID_FONT_DROPDOWN)
{
DoNothing(...);
}
break;
//END_MESSAGE_MAP()
}
}
這樣,VC++就消除了對部分虛擬函式的需要,從而節省了記憶體空間。
參考資料:
Thingking in C++,Bruce Eckel;
聞怡洋
寒巖之上,唯我獨行---小朱
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-979982/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於CCmdTarget及訊息對映
- VC++中用記憶體對映檔案 (轉)C++記憶體
- MFC 訊息對映機制詳解
- 在VC++ 6.0下利用訊息實現內部程式通訊 (轉)C++
- 訊息推送背後的思考
- 思考工具之概念對映 | Untools
- VC++基礎 判斷鍵盤訊息C++
- VC++ 的串列埠通訊 (轉)C++串列埠
- 自定義訊息和對訊息的理解
- 訊息處理:利用控制元件的動態派生[RunTime],為控制元件新增該控制元件未定義的訊息對映 (轉)控制元件
- VC++ 串列埠通訊(轉)C++串列埠
- 自定義訊息獲取訊息(轉)
- 面對物件的思考 (轉)物件
- MFC六大核心機制之五、六:訊息對映和命令傳遞
- WTL的訊息機制 (轉)
- OC訊息機制,訊息轉發機制
- iOS 訊息轉發iOS
- 面對物件的思考(二) (轉)物件
- 再次對於Matrix 的思考 (轉)
- Kafka、RabbitMQ、RocketMQ訊息中介軟體的對比 —— 訊息傳送效能KafkaMQ
- PHP轉Go系列:map對映PHPGo
- NAT(PAT)與埠對映(轉)
- 關於VC++中,兩種自定義訊息的傳送與接收的方法實現進行說明。 (轉)C++
- 訊息佇列效能對比佇列
- 用程式碼理解 ObjC 中的傳送訊息和訊息轉發OBJ
- 用程式碼理解ObjC中的傳送訊息和訊息轉發OBJ
- mfc中的訊息的應用 (轉)
- WINDOWS訊息說明 (轉)Windows
- 我對視訊號的思考和挑戰
- Guru of the week:#17 型別對映. (轉)型別
- 用於日期轉換的訊息轉換器
- Objective-C中的訊息轉發Object
- 深度解析VC中的訊息(上) (轉)
- 深度解析VC中的訊息(中) (轉)
- 截獲與管理Windows的訊息 (轉)Windows
- C#的訊息處理方法 (轉)C#
- 如何應對 RocketMQ 訊息堆積MQ
- 玩轉釘釘訊息推送!