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

C++Builder 訊息處理機制深度解析:從 Windows 訊息迴圈到 VCL 派發與自訂訊息

     編輯:關於C++

Windows 訊息驅動架構

  • 系統訊息佇列:收集硬體/系統事件。
  • 執行緒訊息佇列:每個 GUI 執行緒擁有獨立佇列。
  • 訊息迴圈:GetMessage → TranslateMessage → DispatchMessage。
  • 視窗程序:每個視窗類別註冊 WndProc,處理該視窗訊息。

C++Builder VCL 封裝層次

  1. TApplication:封裝 WinMain、初始化、訊息迴圈 (Run())。
  2. MainWndProc:每個控制項類別註冊的靜態視窗程序,非虛擬,僅轉呼 WndProc 並處理例外。
  3. WndProc:虛擬方法,各控制項可覆寫進行前置過濾 (如拖曳時忽略鍵盤)。
  4. Dispatch:虛擬方法,繼承自 TObject,根據 TMessage.Msg 查找對應處理方法,沿繼承鏈向上尋找,最終呼叫 DefaultHandler。

VCL 事件封裝

常用訊息 (如 WM_PAINT, WM_LBUTTONDOWN) 封裝為事件屬性 (OnPaint, OnClick),開發者只需編寫事件處理器並指派,無需處理訊息細節。

自訂訊息處理實作

當需處理 VCL 未定義的訊息 (如 WM_COPYDATA, 自訂 WM_USER+xxx),必須覆寫 Dispatch。VCL 提供三個巨集簡化:


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

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

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

使用範例:處理 WM_COPYDATA


class TMyForm : public TForm {
public:
    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(WM_COPYDATA, PCOPYDATASTRUCT, OnCopyData)
    END_MESSAGE_MAP(TForm)

    void __fastcall OnCopyData(PCOPYDATASTRUCT pcds) {
        // pcds->dwData, pcds->cbData, pcds->lpData
        ShowMessage("收到跨程序資料");
    }
};

巨集展開後產生新的 Dispatch,優先處理自訂訊息,其他轉交父類別,保證原有機制完整。

圖解:訊息在 VCL 中的流向

VCL 訊息派發流程圖

最佳實務

  • 優先使用事件屬性,僅在必要時覆寫 Dispatch。
  • 自訂訊息定義於 WM_USER (0x0400) 以上,避免衝突。
  • 跨執行緒傳送訊息使用 PostMessage / SendMessageTimeout,避免死結。
  • 大量訊息處理考慮 PeekMessage 非阻塞迴圈或 TTimer 定時處理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved