首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 訊息對應函式定義:每個訊息都要寫函式嗎?能否合併?

     編輯:程式設計疑難解答

直接回答

不需要為每個訊息單獨寫函式,但建議分開。MFC 提供多種機制靈活處理:

機制一:標準對應表(一訊息一函式)

BEGIN_MESSAGE_MAP(CMyView, CView)
    ON_WM_PAINT()
    ON_WM_SIZE()
    ON_COMMAND(ID_FILE_PRINT, &CMyView::OnFilePrint)
END_MESSAGE_MAP()
  • 優點:語意清晰、除錯容易、Class Wizard 支援完美。
  • 缺點:訊息多時函式膨脹。

機制二:ON_MESSAGE 單一處理函式

BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
    ON_MESSAGE(WM_USER + 1, &CMyWnd::OnCustomMsg)
    ON_MESSAGE(WM_USER + 2, &CMyWnd::OnCustomMsg) // 同一函式處理多訊息
END_MESSAGE_MAP()

LRESULT CMyWnd::OnCustomMsg(WPARAM wParam, LPARAM lParam) {
    switch (GetCurrentMessage()->message) { // 需自行取得當前訊息 ID
        case WM_USER + 1: /*...*/ break;
        case WM_USER + 2: /*...*/ break;
    }
    return 0;
}
  • 適用:自訂訊息(WM_USER/WM_APP 區間)、大量相似訊息。
  • 注意:GetCurrentMessage() 僅在訊息處理期間有效。

機制三:訊息反射(Reflected Messages)

控制項通知(WM_COMMAND、WM_NOTIFY)可由父視窗或控制項自身處理:

// 父視窗
ON_NOTIFY_REFLECT(NM_CLICK, &CMyListCtrl::OnClick)
// 控制項類別
ON_NOTIFY_REFLECT_EX(NM_CUSTOMDRAW, &CMyListCtrl::OnCustomDraw)

減少父視窗程式碼,符合封裝原則。

機制四:命令目標鏈路(Command Routing)

菜單、工具列、快速鍵命令(ID_*)可由:

  1. 作用中視圖
  2. 作用中框架視窗
  3. 文件
  4. 應用程式物件

依序嘗試處理,同一命令只需在最適合的類別實作一次。

訊息處理函式 vs 普通函式

特性訊息處理函式普通成員函式
簽名限制固定:afx_msg void OnXxx() 或 afx_msg LRESULT OnXxx(WPARAM, LPARAM)任意
呼叫方式透過訊息對應表由架構自動調度直接呼叫
this 指標自動綁定正確物件需物件實例
可被繼承覆寫是(虛擬函式機制)是

最佳實務建議

  1. 標準視窗訊息(WM_PAINT、WM_SIZE...)用 ON_WM_XXX 巨集,各自獨立函式。
  2. 命令訊息(ID_*)利用命令路由,放在最合邏輯的類別。
  3. 自訂訊息大量相似時,用 ON_MESSAGE 集中 switch 分派。
  4. 控制項通知優先考慮反射訊息封裝於控制項類別。
  5. 避免在單一巨大 switch 處理所有訊息,破壞可維護性。

結語

MFC 訊息對應極具彈性,「每個訊息一函式」是預設最佳實務,但 ON_MESSAGE、反射訊息、命令路由提供合併與分層處理能力。根據訊息性質與數量選擇適當策略,而非強求統一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved