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

WinAPI 鉤子回調:GetMsgProc 詳細解析

     編輯:Delphi

GetMsgProc 回調函數

GetMsgProc 配合 WH_GETMESSAGE 鉤子類型,用於攔截線程呼叫 GetMessage 或 PeekMessage 從訊息佇列取出訊息的瞬間。此鉤子可在訊息分派給視窗程序之前檢查、修改、甚至移除訊息。

函數原型

function GetMsgProc(
  nCode: Integer;    // 鉤子代碼
  wParam: WPARAM;    // 訊息處理標誌
  lParam: LPARAM     // 指向 MSG 結構
): LRESULT; stdcall;

參數詳解

  • nCode:
    • HC_ACTION (0):正常處理,lParam 指向有效 MSG
    • HC_NOREMOVE (3):PeekMessage(..., PM_NOREMOVE) 取得訊息但未移除,lParam 同樣指向 MSG,不可修改 訊息內容
    • 負值:必須呼叫 CallNextHookEx 直接傳遞
  • wParam:通常為 0,保留。
  • lParam:指向 MSG 結構:
    type
      tagMSG = record
        hwnd: HWND;      // 目標視窗
        message: UINT;   // 訊息 ID (WM_*)
        wParam: WPARAM;  // 參數 1
        lParam: LPARAM;  // 參數 2
        time: DWORD;     // 訊息時間戳
        pt: TPoint;      // 滑鼠座標 (螢幕座標)
      end;

典型應用場景

  • 全域熱鍵處理:攔截 WM_HOTKEY 在視窗程序前處理
  • 訊息過濾/記錄:記錄特定視窗收到的所有訊息,除錯用
  • 訊息修改/映射:如將 WM_RBUTTONDOWN 映射為 WM_LBUTTONDOWN 實現左右鍵互換
  • 攔截特定訊息:返回非零值並不呼叫 CallNextHookEx 可吞噬訊息 (慎用)

系統級 vs 線程級

屬性系統級 (dwThreadId=0)線程級 (dwThreadId>0)
回調位置必須在 DLL可在 EXE
影響範圍所有 GUI 線程指定線程
效能影響大 (每條訊息皆經過)小
典型用途全域熱鍵、輸入法、螢幕閱讀器單模組訊息監控

關鍵注意事項

  • 極度效能敏感:每條訊息 (滑鼠移動、定時器、繪圖) 都會觸發,回調必須在微秒級返回。
  • 避免死結:回調中絕不可 呼叫 GetMessage、PeekMessage、SendMessage、DialogBox 等進入訊息迴路的函數,會導致遞歸死結。
  • 修改 MSG 結構:僅在 HC_ACTION 且確定安全時修改 message、wParam、lParam;hwnd 修改可能導致訊息送達錯誤視窗。
  • 返回值:大多數情況返回 CallNextHookEx 結果;若吞噬訊息返回非零 (如 1)。

現代替代方案

  • SetWindowsHookEx(WH_GETMESSAGE, ...) 仍是全域訊息攔截唯一標準方式
  • 單應用內部可用 Application.OnMessage (VCL) 或 TApplicationEvents.OnMessage 事件,無需鉤子,效能更好、更安全
  • 低層級鍵盤/滑鼠攔截優先考慮 WH_KEYBOARD_LL/WH_MOUSE_LL (不需 DLL)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved