VC++ 訊息映射的思考

來源:互聯網
上載者:User

VC++訊息映射的思考

作者:郝慶欣

在學習VC++的時候,大家都不可避免的用到訊息映射。我們都知道C++是一種物件導向的程式設計語言,VC++中為什麼這樣來實現訊息映射呢?
  首先要明白一個包含了訊息處理的Windows程式是如何工作的。
  一般來說一個包含了訊息處理的Windows程式至少要包含兩個函數
   第一個:
    int WINAPI 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,WORD 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++就消除了對部分虛擬函數的需要,從而節省了記憶體空間。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.