VS2010/MFC編程入門之四(MFC消息映射機制概述)

上一講雞啄米爲大家簡單分析了MFC應用程序框架,這一講是關於MFC消息映射機制的內容。

       前面已經說過,Windows應用程序是消息驅動的。在MFC軟件開發中,界面操作或者線程之間通信都會經常用到消息,通過對消息的處理實現相應的操作。比較典型的過程是,用戶操作窗口,然後有消息產生,送給窗口的消息處理函數處理,對用戶的操作做出響應。

       什麼是消息

       窗口消息一般由三個部分組成:1.一個無符號整數,是消息值;(2)消息附帶的WPARAM類型的參數;(3)消息附帶的LPARAM類型的參數。其實我們一般所說的消息是狹義上的消息值,也就是一個無符號整數,經常被定義爲宏。

       什麼是消息映射機制

       MFC使用一種消息映射機制來處理消息,在應用程序框架中的表現就是一個消息與消息處理函數一一對應的消息映射表,以及消息處理函數的聲明和實現等代碼。當窗口接收到消息時,會到消息映射表中查找該消息對應的消息處理函數,然後由消息處理函數進行相應的處理。SDK編程時需要在窗口過程中一一判斷消息值進行相應的處理,相比之下MFC的消息映射機制要方便好用的多。

       Windows消息分類

       先講下Windows消息的分類。Windows消息分爲系統消息和用戶自定義消息。Windows系統消息有三種:

       1.標準Windows消息。除WM_COMMAND外以WM_開頭的消息是標準消息。例如,WM_CREATEWM_CLOSE

       2.命令消息。消息名爲WM_COMMAND,消息中附帶了標識符ID來區分是來自哪個菜單、工具欄按鈕或加速鍵的消息。

       3.通知消息。通知消息一般由列表框等子窗口發送給父窗口,消息名也是WM_COMMAND,其中附帶了控件通知碼來區分控件。

       CWnd的派生類都可以接收到標準Windows消息、通知消息和命令消息。命令消息還可以由文檔類等接收。

       用戶自定義消息是實際上就是用戶定義一個作爲消息,此宏的值應該大於等於WM_USER,然後此宏就可以跟系統消息一樣使用,窗口類中可以定義它的處理函數。

       消息映射表

       除了一些沒有基類的類或CObject的直接派生類外,其他的類都可以自動生成消息映射表。下面的講解都以前面例程HelloWorldCMainFrame爲例。消息映射表如下:

C++代碼

1.  BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)  

2.      ON_WM_CREATE()  

3.      ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)  

4.      ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)  

5.      ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)  

6.      ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)  

7.      ON_WM_SETTINGCHANGE()  

8.  END_MESSAGE_MAP()  

       BEGIN_MESSAG_MAPEND_MESSAGE_MAP之間的內容成爲消息映射入口項。消息映射除了在CMainFrame的實現文件中添加消息映射表外,在類的定義文件MainFrm.h中還會添加一個宏調用:

       DECLARE_MESSAGE_MAP()

       一般這個宏調用寫在類定義的結尾處。

       添加消息處理函數

       如何添加消息處理函數呢?不管是自動還是手動添加都有三個步驟:

       1.在類定義中加入消息處理函數的函數聲明,注意要以afx_msg打頭。例如MainFrm.hWM_CREATE的消息處理函數的函數聲明:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

       2.在類的消息映射表中添加該消息的消息映射入口項。例如WM_CREATE的消息映射入口項:ON_WM_CREATE()

       3.在類實現中添加消息處理函數的函數實現。例如,MainFrm.cppWM_CREATE的消息處理函數的實現:

          intCMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
         {
                 ......
         }

       通過以上三個步驟以後,WM_CREATE等消息就可以在窗口類中被消息處理函數處理了。

       各種Windows消息的消息處理函數

       標準Windows消息的消息處理函數都與WM_CREATE消息類似。

       命令消息的消息映射入口項形式如:ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize),消息爲ID_VIEW_CUSTOMIZE,消息處理函數爲OnViewCustomize

       如果想要使用某個處理函數批量處理某些命令消息,則可以像CMainFrame消息映射表中的ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000,ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)一樣添加消息映射入口項,這樣值在ID_VIEW_APPLOOK_WIN_2000ID_VIEW_APPLOOK_WINDOWS_7之間的菜單項等的命令消息都由CMainFrameOnApplicationLook函數處理。函數原型爲afx_msg void OnApplicationLook(UINT id);,參數id爲用戶操作的菜單項等的ID

       在操作列表框等控件時往往會給父窗口發送WM_NOTIFY通知消息。WM_NOTIFY消息的wParam參數爲發送通知消息的控件的IDlParam參數指向一個結構體,可能是NMHDR結構體,也可能是第一個元素爲NMHDR結構體變量的其他結構體。NMHDR結構體的定義如下(僅作了解):

       Typedef sturcttagNMHDR{
               HWND hwndFrom;
               UINT idFrom;
               UINT code;
       } NMHDR;

       hwndFrom爲發送通知消息控件的句柄,idFrom爲控件IDcode爲要處理的通知消息的通知碼,例如NM_CLICK

       
通知消息的消息映射入口項形式如:

       ON_NOTIFY(wNotifyCode,id,memberFxn)

       wNotifyCode爲要處理的通知消息通知碼,例如:NM_CLICKid爲控件標識IDMemberFxn爲此消息的處理函數。

       通知消息的處理函數的原型爲:

       afx_msg voidmemberFxn( NMHDR * pNotifyStruct, LRESULT * result);

       如果需要使用用戶自定義消息,首先要定義消息宏,如:#define WM_UPDATE_WND (WM_USER+1),再到消息映射表中添加消息映射入口項:ON_MESSAGE(WM_UPDATE_WND,&CMainFrame::OnUpdateWnd),然後在MainFrm.h中添加消息處理函數的函數聲明:afx_msg LRESULT OnUpdateWnd(WPARAM wParam, LPARAM lParam);,最後在MainFrm.cpp中實現此函數。

      雞啄米本節對MFC消息映射機制只是做了比較簡單的講解,讓大家對它有一定的認識,編程入門者不必強求完全掌握。在以後的教程中會經常涉及到消息的使用,大家會逐漸熟悉MFC的消息映射機制。
發佈了3 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章