CallWndProc 配合 WH_CALLWNDPROC 鉤子類型,在SendMessage 將訊息發送給目標視窗程序之前被呼叫。它是同步訊息攔截的「入口哨」,可檢查、修改訊息參數、甚至決定是否允許訊息繼續傳遞。
function CallWndProc(
nCode: Integer; // 鉤子代碼
wParam: WPARAM; // 保留,通常 0
lParam: LPARAM // 指向 CWPSTRUCT 結構
): LRESULT; stdcall;
type
tagCWPSTRUCT = record
message: UINT; // 訊息 ID
wParam: WPARAM; // 參數 1
lParam: LPARAM; // 參數 2
hwnd: HWND; // 目標視窗句柄
end;
注意:無 lResult 欄位,因為訊息尚未處理,無返回值。
回調中可直接修改 PCWPSTRUCT(lParam)^.wParam、.lParam、甚至 .message、.hwnd,修改後的值將傳遞給目標視窗程序。這是實現全域訊息重映射的關鍵機制。
| 屬性 | 系統級 (dwThreadId=0) | 線程級 (dwThreadId>0) |
|---|---|---|
| 回調位置 | DLL (必須) | EXE 可行 |
| 監控範圍 | 全系統所有 SendMessage | 指定線程 SendMessage |
| 跨進程 | 支援 | 不支援 |
| 典型用途 | 全域熱鍵、UI 自動化、輔助技術 | 模組內訊息調試、單元測試 |
WM_KEYDOWN 映射為自定義命令訊息WM_COPYDATA 注入){ HookDll.dpr }
library HookDll;
uses Windows;
var hHook: HHOOK = 0;
function CallWndProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var p: PCWPSTRUCT;
begin
if nCode = HC_ACTION then
begin
p := PCWPSTRUCT(lParam);
// 將 WM_RBUTTONDOWN/UP/DBLCLK 映射為左鍵對應訊息
case p.message of
WM_RBUTTONDOWN: p.message := WM_LBUTTONDOWN;
WM_RBUTTONUP: p.message := WM_LBUTTONUP;
WM_RBUTTONDBLCLK: p.message := WM_LBUTTONDBLCLK;
end;
end;
Result := CallNextHookEx(hHook, nCode, wParam, lParam);
end;
function InstallHook: Boolean; stdcall;
begin
hHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance, 0);
Result := hHook <> 0;
end;
function UninstallHook: Boolean; stdcall;
begin
if hHook <> 0 then begin Result := UnhookWindowsHookEx(hHook); if Result then hHook := 0; end else Result := True;
end;
exports InstallHook, UninstallHook;
begin
end.
if nCode < 0 then Exit(CallNextHookEx(...));第二行 if p.message <> TargetMsg then Exit(CallNextHookEx(...))。SendMessage、WaitForSingleObject、Sleep、檔案 I/O、資料庫操作。需異步處理請 PostMessage 給主線程。CallNextHookEx 結果;若要攔截訊息 (不讓目標視窗收到),返回非零值 (如 1) 且不呼叫 CallNextHookEx。| 特性 | WH_CALLWNDPROC | WH_GETMESSAGE |
|---|---|---|
| 攔截對象 | SendMessage (同步) | GetMessage/PeekMessage 取出的所有訊息 |
| PostMessage | 不攔截 | 攔截 (從佇列取出時) |
| 修改參數 | 可修改 wParam/lParam/message/hwnd | 可修改 MSG 結構 |
| 執行上下文 | 目標線程 (接收端) | 接收線程 (取訊息端) |
| 典型用途 | 同步訊息重映射、參數修正 | 全域訊息監控、熱鍵、記錄 |
Application.OnMessage / TApplicationEvents.OnMessage (VCL) — 無鉤子開銷、類型安全WH_KEYBOARD_LL/WH_MOUSE_LL — 不需 DLL、支援注入