Windows 鉤子機制讓應用程式能攔截、監控、甚至修改系統訊息流。本文以最通俗易懂的比喻建立核心心智模型,介紹三大核心 API,並實作最簡單的線程級鍵盤鉤子攔截字母 A。
| 類型 | 範圍 | 回調位置 | 適用場景 |
| 線程級 | 單一線程訊息佇列 | EXE 內部函數 | 應用內熱鍵、訊息監控、除錯 |
| 全域級 | 全系統所有線程 | **必須在 DLL** | 跨程式熱鍵、按鍵記錄、滑鼠手勢、螢幕錄製 |
三大核心 API
- SetWindowsHookEx:安裝鉤子,返回鉤子句柄 (
HHOOK)。
- UnhookWindowsHookEx:移除鉤子,釋放資源。
- CallNextHookEx:將訊息傳遞給鉤子鏈中下一個鉤子,**維持鏈完整性的關鍵**。
輔助函數:GetCurrentThreadId 取得當前線程 ID (線程級鉤子必需)。
最簡入門範例:線程級鍵盤鉤子攔截 'A'
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
end;
{ 回調函數聲明:必須 stdcall }
function KeyHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
hook: HHOOK;
{ 鍵盤鉤子回調實作 }
function KeyHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
if (wParam = 65) then // 虛擬鍵碼 65 = 'A'
Beep; // 發出提示音
Result := CallNextHookEx(hook, nCode, wParam, lParam); // 繼續傳遞
end;
{ 視窗建立:安裝線程級鍵盤鉤子 }
procedure TForm1.FormCreate(Sender: TObject);
begin
{ WH_KEYBOARD=2, 函數指標, 當前模組句柄, 當前線程 ID }
hook := SetWindowsHookEx(WH_KEYBOARD, @KeyHook, HInstance, GetCurrentThreadId);
end;
{ 視窗銷毀:移除鉤子 }
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnhookWindowsHookEx(hook);
end;
end.
程式碼關鍵點逐行解析
| 代碼 | 說明 |
function KeyHook(...) stdcall | 系統回調規範呼叫慣例,缺少會導致堆疊不平衡崩潰 |
wParam = 65 | 虛擬鍵碼對應表:VK_A = 65, VK_0 = 48 等 |
Beep | 簡單驗證鉤子觸發的同步聲音回饋 |
CallNextHookEx(...) | **必須呼叫**,否則訊息鏈中斷,系統其他鉤子/目標視窗不再收到訊息 |
GetCurrentThreadId | 限定只攔截當前線程訊息,不影響其他線程/程式 |
FormDestroy 呼叫 UnhookWindowsHookEx | 釋放鉤子資源,避免記憶體洩漏與殘留鉤子干擾 |
執行驗證
- 編譯執行程式,視窗顯示。
- 點擊視窗使其取得焦點。
- 按鍵盤 A → 聽到「嗶」聲。
- 按其他鍵 → 無聲音,正常輸入。
- 關閉視窗 → 鉤子自動移除。
常見新手誤區
- 以為鉤子在視窗程式碼中:實際上鉤子回調獨立於 VCL 事件迴圈,由系統直接呼叫。
- 忘記 CallNextHookEx:導致系統訊息死結,嚴重時需重開機恢復。
- 缺少 stdcall:最隱蔽的崩潰原因,編譯通過但執行即崩潰。
- 混淆線程級/全域級:線程級無需 DLL,全域級**強制** DLL。
學習路線圖
- 第 1 步 (本文):線程級鍵盤鉤子基本架構。
- 第 2 步:參數深度解析 (
lParam 位元結構)、stdcall 必要性。
- 第 3 步:全域滑鼠鉤子 + DLL 建置 + 靜態/動態載入。
- 第 4 步:鉤子鏈機制、
CallNextHookEx 返回值、攔截/放行控制。
- 第 5 步:DLL 資料回傳 (Timer 輪詢 / 訊息推送 /
WM_COPYDATA)。
- 第 6 步:雙向通訊 (
SetHWnd + PostMessage)、低層級鉤子 (WH_MOUSE_LL)。
鉤子技術是 Windows 系統程式設計的皇冠上的明珠,掌握它能開發出熱鍵管理器、自動化測試工具、螢幕錄製軟體、遊戲防外掛等高階應用。從最簡單的線程級鉤子開始,逐步建立完整知識體系。
- 上一篇文章: Delphi 鉤子開發實戰 (2):線程級鍵盤鉤子參數詳解與 stdcall 呼叫慣例必要性
- 下一篇文章: Delphi 多線程程式設計 (19):無同步物件手動協調線程依序執行與 Mutex 同步對比
Copyright ©
程式碼之家 All Rights Reserved