首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

深入 VCL 理解 BCB 訊息機制 (一):訊息對應巨集與 Dispatch 虛函數

     編輯:關於C++

前言

BCB/Delphi 核心 VCL 封裝了 Windows 訊息機制。理解 VCL 如何分派訊息,是掌握進階開發的關鍵。本系列三篇文章從源碼層面剖析。

方法一:訊息對應巨集重載 Dispatch

巨集定義 (sysmac.h)


#define BEGIN_MESSAGE_MAP \
    virtual void __fastcall Dispatch(void *Message) { \
    switch (((PMessage)Message)->Msg) {

#define VCL_MESSAGE_HANDLER(msg, type, meth) \
    case msg: \
        meth(*((type *)Message)); \
        break;

#define END_MESSAGE_MAP(base) \
    default: \
        base::Dispatch(Message); \
        break; \
    } \
}

使用範例


class TMyForm : public TForm {
protected:
    void __fastcall OnPaint(TMessage &Msg);
    BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(WM_PAINT, TMessage, OnPaint)
    END_MESSAGE_MAP(TForm)
};

預處理器展開後等效程式碼


virtual void __fastcall Dispatch(void *Message) {
    switch (((PMessage)Message)->Msg) {
        case WM_PAINT:
            OnPaint(*((TMessage *)Message));
            break;
        default:
            TForm::Dispatch(Message);
            break;
    }
}

關鍵技術點解析

1. Dispatch 繼承自 TObject

  • TObject 為所有 VCL 類別基類,定義虛擬 Dispatch 與 DefaultHandler
  • 衍生類別覆寫 Dispatch 即可自訂訊息分派邏輯
  • 若 Dispatch 找不到對應處理,最終呼叫 DefaultHandler (預設呼叫 DefWindowProc)

2. MESSAGE_HANDLER vs VCL_MESSAGE_HANDLER

  • ATL 也定義 MESSAGE_HANDLER 巨集,與 VCL 衝突
  • BCB 5+ 引入 VCL_MESSAGE_HANDLER 避免衝突
  • 若未使用 ATL,MESSAGE_HANDLER 會自動映射為 VCL_MESSAGE_HANDLER
  • 建議永遠使用 VCL_MESSAGE_HANDLER 確保相容性

訊息處理流向

[系統] → [視窗程序 MainWndProc] → [WndProc] → [Dispatch] → [訊息對應巨集 case 分支]
                                                              ↓ 未匹配
                                                    [父類別 Dispatch] → [DefaultHandler]

優缺點評估

優點缺點
語法清晰、集中管理訊息處理需在類別宣告中使用巨集,較非標準 C++
型別安全 (自動轉型為指定 TMessage 衍生類型)僅適用於 VCL 類別體系
自動維護繼承鏈 (END_MESSAGE_MAP 指定父類別)巨集展開後難以除錯 (需看預處理輸出)

下一篇預告

方法二:重載 TControl.WndProc,更早攔截訊息,處理滑鼠/鍵盤等預處理邏輯。

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