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

C++Builder 處理 Windows 消息機制:從訊息結構到自定義消息實戰

     編輯:關於C++

Windows 消息驅動架構

Windows 以消息驅動:用戶操作(鼠標、鍵盤)、系統事件(繪製、定時器)均轉化為消息投遞到窗口隊列。C++Builder VCL 封裝常用消息為事件(OnClick、OnPaint),但部分消息(WM_NC* 非客戶區、WM_COPYDATA、自定義消息、Winsock 異步通知)無對應事件,需直接處理。

消息結構解析

通用結構 TMessage

struct TMessage {
    Cardinal Msg;        // 消息 ID
    union {
        struct {
            Word WParamLo, WParamHi;
            Word LParamLo, LParamHi;
            Word ResultLo, ResultHi;
        };
        struct {
            Longint WParam, LParam, Result;
        };
    };
};

專用結構示例:TWMNCHitTest

struct TWMNCHitTest {
    Cardinal Msg;
    Longint Unused;
    union {
        struct {
            TSmallPoint Pos;  // XPos, YPos
            Longint Result;
        };
        struct {
            Short XPos, YPos;
        };
    };
};

兩結構大小相同,可通過 reinterpret_cast 或 C 風格強轉互換,類似 union 用法。

消息處理三步驟

  1. 聲明消息處理函數:在類中聲明 void __fastcall WmNcHitTest(TWMNCHitTest& Message);。
  2. 消息映射宏:在類聲明中添加 BEGIN_MESSAGE_MAP ... MESSAGE_HANDLER(WM_NCHITTEST, TWMNCHitTest, WmNcHitTest) ... END_MESSAGE_MAP。
  3. 實現處理邏輯:讀取/修改 Message 字段,設置 Message.Result 返回值,或調用 DefaultHandler(Message) 轉交默認處理。

實戰場景

1. 自定義消息

#define WM_MY_CUSTOM (WM_USER + 100)
// 發送
PostMessage(Handle, WM_MY_CUSTOM, wParam, lParam);
// 接收類中
MESSAGE_HANDLER(WM_MY_CUSTOM, TMessage, OnMyCustom);

2. 非客戶區點擊響應(WM_NCHITTEST)

void __fastcall TForm1::WmNcHitTest(TWMNCHitTest& Msg) {
    // 讓標題栏區域也能拖動窗口
    if (Msg.Result == HTCLIENT) Msg.Result = HTCAPTION;
}

3. 跨進程數據傳遞(WM_COPYDATA)

void __fastcall TForm1::WmCopyData(TWMCopyData& Msg) {
    PCOPYDATASTRUCT pcds = Msg.CopyDataStruct;
    if (pcds->dwData == MY_DATA_ID) {
        string data((char*)pcds->lpData, pcds->cbData);
        // 處理數據
    }
    Msg.Result = 1;  // 表示已處理
}

最佳實踐建議

  • 優先使用 VCL 事件,僅在無對應事件時處理底層消息。
  • 消息處理函數保持輕量,耗時操作放入線程或異步隊列。
  • 調用 DefaultHandler 保證默認行為(如繪製、焦點管理)不丟失。
  • 使用專用結構體(TWM*)提高代碼可讀性與類型安全。
  • 注意 64 位兼容:WParam/LParam/Result 為 LONG_PTR,避免截斷。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved