形形色色的自定義消息(上)

 摘要:自從發了5篇關於消息的文章,有的網友來信希望我講一些比較實用的消息機制用法,這裏我想就用戶的自定義消息做一個全面的論述,希望能夠解除你心頭的困惑。

   一、普通的自定義消息方法。
    根據我在前面的幾篇文章中提到的消息值的範圍,我向大家都很清楚用戶自定義消息的範圍,不過,雖然說用會自定義消息從WM_USER開始,但是由於我們的工程裏面一般還有很多其他的控件,他們也要佔用一部分WM_USER消息範圍,所以我們必須爲他們留出一部分範圍,這裏,我們保留100個消息,一般情況下,這可以滿足我們的要求。
    (1)定義消息的值。在我們要發生消息的地方(例如CMyView.cpp的開始部分)進行如下定義#define WM_MSG_1 (WM_USER+100)
    接下來的工作其實很簡單,我們在前面說了,消息正常工作有3個部分必須協調:消息聲明、消息映射、消息體。我們就一次進行手工加入。
    (2)首先在AFX_MSG塊中加入消息聲明:在CMyView.h中,找到如下部分,並加入消息聲明:
     protected:    
      // {{AFX_MSG(CMyView)
      ......
      afx_msg LRESULT OnMyMsg(WPARAM wParam,LPARAM lParam);
      file://}}AFX_MSG
    (3)在MESSAGE_MAP塊中添加ON_MESSAGE宏指令:
      BEGIN_MESSAGE_MAP(CMyView, CView)
       file://{{AFX_MSG_MAP(CMyView)
        .....
       ON_MESSAGE(WM_MSG_1, OnMyMsg)
       file://}}AFX_MSG_MAP
      END_MESSAGE_MAP()
    (4)添加消息函數體:
     LPESULT CMyView::OnMyMsg(WPARAM wParam, LPARAM lParam)
     {
       AfxMessageBox("消息已經收到!");
       return 0;
     }
    消息至此就已經定義完畢,接下來我們就可以激活消息了,就可以用我們前面所說的PostMessage/SendMessage,一切OK!
 
  二、自定義消息塊
    消息塊就以一個Range,主要是用來一次處理多個消息,不過對消息有一個要求:消息的值必須是連續的。這樣做的好處就是:簡化類,可以通過一個函數來完成一組消息的處理工作。
    通常,消息塊有4個:ON_CONTROL_RANGE、ON_NOTIFY_RANGE、ON_COMMAND_RANGE和ON_UPDATE_COMMAND_UI_RANGE,他們的使用方法差不多,我就找個比較常用的來談談吧:ON_COMMAND_RANGE和ON_UPDATE_COMMAND_UI_RANGE
    步驟如下:
    1. 使用命令範圍宏
      ON_COMMAND_RANGE宏接收所有ID在某一範圍之內的命令消息(WM_COMMAND消息)。使用這個宏可以在一個函數中處理多條命令。
      1) 在類的. h 文件的{{ }}之後定義命令處理函數,以便不受Cl0assWizard的干擾。
       protected:
         file://{{AFX_MSG(CTestView)
         file://}}AFX_MSG
        afx_msg void OnTestCommandRange(UINT nID);
       DECLARE_MESSAGE_MAP()
      2) 同樣在{{ }}之後,加入ON_COMMAND_RANGE宏到類的消息映像。頭兩個參數定義了要處理的命令ID的範圍。這些ID有序列大小,且最後一個ID比第一個大。最後一個參數是在第一步中定義的消息處理函數的名稱。
       BEGIN_MESSAGE_MAP(CTestView,CView)
        file://{{AFX_MSG_MAP(CTestView)
        file://}}AFX_MSG_MAP
        ON_COMMAND_RANGE(ID_TEST_1,ID_TEST_4,OnTestCommandRange)
       END_MESSAGE_MAP()
      3) 用下面的語句添加消息處理函數。參數nID是要處理命令的ID。
        void CTestView::OnTestCommandRange(UINT nID)
        {
 switch (nID)
 {
  case ID_TEST_1: break ;
  case ID_TEST_2: break ;
  case ID_TEST_3: break ;
  case ID_TEST_4: break ;
 }
    }
   2. 使用用戶界面命令範圍宏
     ON_UPDATE_COMMAND_UI_RANGE宏截取一定範圍內的消息中更新用戶界面的請求。使用這個宏,可以啓用所有的菜單命令或者處理一組工具欄按鈕。
     1) 在類的.h 文件映像的{{ }}之後定義用戶界面命令處理函數,以便不受ClassWizard 的干擾。


      protected:
         file://{{AFX_MSG(CTestView)
         file://}}AFX_MSG
        afx_msg void OnUpdateTestCommandRange(CCmdUI* pCCmdUI);
     2) 同樣,在{{ }}之後,加入ON_UPDATE_COMMAND_UI_RANGE宏到用戶類的命令映像中。頭兩個參數定義了要處理的消息I D 的範圍。這些ID有序列大小,最後一個ID值比第一個大。最後一個參數是第一步中定義的用戶界面命令處理函數的名字。
       BEGIN_MESSAGE_MAP(CTestView,CView)
        file://{{AFX_MSG_MAP(CTestView)
        file://}}AFX_MSG_MAP
        ON_UPDATE_COMMAND_UI_RANGE(ID_TEST_1,ID_TEST_4,OnUpdateTestCommandRange)
       END_MESSAGE_MAP()
     3) 處理界面命令消息的語句如下:
      void CTestView::OnUpdateTestCommandRange(CCmdUI *pCmdUI)
      {
       switch (pCmdUI->m_nID)
       {
         case ID_TEST_1: break ;
         case ID_TEST_2:  pCmdUI->SetRadio();break ;
         case ID_TEST_3:  break ;
         case ID_TEST_4:  break ;
       }
      } 
 更多分享請關注:軟信網-編程-http://www.iis365.net.cn

發佈了13 篇原創文章 · 獲贊 5 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章