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

C++ Builder 捕獲 VCL 未封裝的 Windows 消息:訊息映射表實戰

     編輯:關於C++

背景:VCL 封裝的邊界

C++ Builder 的 VCL 將大多數常見 Windows 消息封裝為事件(OnClick、OnKeyDown 等),但系統定義的消息數百種,VCL 無法面面俱到。當需處理 WM_NCHITTEST、WM_DEVICECHANGE 等未封裝消息時,必須使用訊息映射表直接掛接回呼函數。

訊息映射表語法

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(消息ID, 消息結構型別, 處理函數名)
    // 可多行
END_MESSAGE_MAP(基底類別名)
  • 消息結構型別:VCL 依消息定義不同結構,通用型別為 TMessage:
struct TMessage {
    unsigned int Msg;   // 消息 ID
    long         WParam;
    long         LParam;
    long         Result; // 回傳值,影響後續處理
};

實戰範例:拖動無標題列視窗

目標:建立無標題列(bsDialog + 隱藏 WS_CAPTION)視窗,滑鼠在用戶區按下即可拖動。

1. 移除標題列(重寫 CreateParams)

// MainForm.h - private 區
void __fastcall CreateParams(TCreateParams &Params);

// MainForm.cpp
void __fastcall TForm1::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);          // 先呼叫基底實作
    Params.Style &= ~WS_CAPTION;          // 移除標題列樣式
}

2. 宣告訊息映射與處理函數

// MainForm.h - public 區
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_NCHITTEST, TMessage, WMNchitTest)
END_MESSAGE_MAP(TForm)

// private 區
void __fastcall WMNchitTest(TMessage &Message);

3. 實作 WM_NCHITTEST 處理邏輯

void __fastcall TForm1::WMNchitTest(TMessage &Message)
{
    // 僅在左鍵按下時偽裝為標題列命中
    if (GetAsyncKeyState(VK_LBUTTON) < 0)
        Message.Result = HTCAPTION;   // 告訴系統:游標在標題列
    else
        Message.Result = HTCLIENT;    // 否則為用戶區
}

GetAsyncKeyState 回傳負值表示高位被設定(鍵盤/滑鼠按下),即時反映實體按鍵狀態,不受消息佇列延遲影響。

編譯與執行

環境:C++ Builder 3 / Windows 98。按 F9 執行,滑鼠在視窗任意處按住左鍵即可拖動。程式未提供關閉機制,可自行加入 TPopupMenu 實作。

核心觀念回顧

  1. 訊息映射表繞過 VCL 事件封裝,直接對應 Windows 消息迴路。
  2. TMessage.Result 是關鍵:設定後可改變系統後續行為(如拖動判斷)。
  3. CreateParams 是調整視窗建立參數(樣式、擴充樣式、類別名等)的標準切入點。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved