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

WinAPI 鍵盤鉤子回調函數 KeyboardProc 完整解析

     編輯:Delphi

KeyboardProc 回調函數概述

KeyboardProc 是 Windows 鍵盤鉤子(WH_KEYBOARD 或 WH_KEYBOARD_LL)的核心回調函數。當應用程式安裝鍵盤鉤子後,系統會在每次鍵盤輸入事件發生時呼叫此函數,讓開發者能夠攔截、監控或修改鍵盤訊息。

函數原型

LRESULT CALLBACK KeyboardProc(
  _In_ int    nCode,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);

參數詳細說明

參數類型說明
nCodeint鉤子處理代碼。若小於 0,表示不應處理該訊息,需直接呼叫 CallNextHookEx。常見值:
HC_ACTION (0):正常處理訊息
HC_NOREMOVE (3):訊息已被 PeekMessage 移除但未從佇列中刪除
wParamWPARAM鍵盤訊息類型:
WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP
lParamLPARAM指向 KBDLLHOOKSTRUCT 結構的指標(低階鉤子)或包含鍵盤掃描碼、擴展鍵標誌、上下文碼等資訊的位域(標準鉤子)

返回值

  • 若 nCode < 0,必須返回 CallNextHookEx 的結果
  • 若處理了該訊息且不想傳遞給下一個鉤子,返回非零值
  • 若繼續傳遞,返回 CallNextHookEx(hHook, nCode, wParam, lParam)

鍵盤鉤子類型比較

特性WH_KEYBOARD (標準)WH_KEYBOARD_LL (低階)
安裝方式SetWindowsHookEx 需 DLL 注入同進程即可,無需 DLL
效能影響較高(跨進程上下文切換)較低(同進程)
攔截範圍僅當前執行緒/進程全系統所有鍵盤輸入
適用場景應用程式內部快捷鍵全域熱鍵、鍵盤記錄器、螢幕鎖定

實戰範例:全域熱鍵實現 (Delphi)

unit KeyboardHookUnit;

interface

uses Windows, Messages;

type
  TKeyboardHook = class
  private
    FHook: HHOOK;
    FHotKeyPressed: TNotifyEvent;
    class var FInstance: TKeyboardHook;
    class function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Install;
    procedure Uninstall;
    property OnHotKeyPressed: TNotifyEvent read FHotKeyPressed write FHotKeyPressed;
  end;

implementation

{ TKeyboardHook }

constructor TKeyboardHook.Create;
begin
  inherited;
  FInstance := Self;
end;

destructor TKeyboardHook.Destroy;
begin
  Uninstall;
  FInstance := nil;
  inherited;
end;

class function TKeyboardHook.HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  KbdStruct: PKBDLLHOOKSTRUCT;
begin
  Result := 0;
  if (nCode = HC_ACTION) and Assigned(FInstance) then
  begin
    if (wParam = WM_KEYDOWN) or (wParam = WM_SYSKEYDOWN) then
    begin
      KbdStruct := PKBDLLHOOKSTRUCT(lParam);
      // 偵測 Ctrl+Alt+H 組合鍵
      if (KbdStruct.vkCode = Ord('H')) and
         (GetAsyncKeyState(VK_CONTROL) and $8000 <> 0) and
         (GetAsyncKeyState(VK_MENU) and $8000 <> 0) then
      begin
        if Assigned(FInstance.FHotKeyPressed) then
          FInstance.FHotKeyPressed(FInstance);
        Result := 1; // 攔截該按鍵
        Exit;
      end;
    end;
  end;
  Result := CallNextHookEx(FInstance.FHook, nCode, wParam, lParam);
end;

procedure TKeyboardHook.Install;
begin
  if FHook = 0 then
    FHook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0);
end;

procedure TKeyboardHook.Uninstall;
begin
  if FHook <> 0 then
  begin
    UnhookWindowsHookEx(FHook);
    FHook := 0;
  end;
end;

end.

最佳實踐與注意事項

  1. 低階鉤子超時機制:Windows 會監控 WH_KEYBOARD_LL 回調執行時間,若超過 300 毫秒(可透過 LowLevelHooksTimeout 登錄值調整),系統會自動移除鉤子。回調中務必避免耗時操作。
  2. 執行緒安全:回調在系統執行緒內容中執行,若需與主執行緒通訊,請使用 PostMessage 或執行緒安全佇列。
  3. 權限考量:低階鉤子需要應用程式具備相同或更高的完整性等級(UAC)。管理員權限程式可攔截所有輸入;標準權限僅能攔截同等或較低權限視窗的輸入。
  4. 除錯技巧:使用 OutputDebugString 或寫入記憶體對應檔案進行日誌記錄,避免在回調中呼叫可能阻塞的 API(如檔案 I/O、MessageBox)。

常見應用場景

  • 全域熱鍵註冊(如螢幕截圖工具、推播記事本)
  • 鍵盤巨集錄製與回放
  • 輸入法編輯器(IME)開發
  • 安全性軟體的鍵盤記錄防護
  • 遊戲外掛/輔助工具的按鍵模擬

相關 API 快速查閱

  • SetWindowsHookEx - 安裝鉤子
  • UnhookWindowsHookEx - 移除鉤子
  • CallNextHookEx - 傳遞給下一個鉤子
  • GetAsyncKeyState - 即時查詢按鍵狀態
  • GetKeyState - 查詢訊息佇列中的按鍵狀態
  • MapVirtualKey - 虛擬鍵碼與掃描碼轉換
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved