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

WinAPI:UnhookWindowsHookEx 卸載鉤子完全指南

     編輯:Delphi

UnhookWindowsHookEx 函數

用於移除先前由 SetWindowsHookEx 安裝的鉤子,釋放系統資源,恢復正常訊息流向。每個成功安裝的鉤子都必須在適當時機(如程式結束、卸載 DLL、停用功能)呼叫此函數,否則會導致鉤子鏈殘留、記憶體洩漏甚至系統不穩定。

函數原型

function UnhookWindowsHookEx(
  hhk: HHOOK  // SetWindowsHookEx 返回的鉤子句柄
): BOOL; stdcall; // TRUE 成功,FALSE 失敗

使用時機與最佳實踐

  • EXE 安裝的線程級鉤子:在主視窗 OnDestroy 或 FormClose 中呼叫。
  • DLL 安裝的系統級鉤子:在 DLL 的 DLL_PROCESS_DETACH 入口點呼叫,確保進程卸載 DLL 時自動清理。
  • 錯誤處理:若 SetWindowsHookEx 失敗(返回 0),切勿 呼叫 UnhookWindowsHookEx(0),會導致存取違規。

完整範例:安全安裝與卸載鍵盤鉤子

unit HookUnit;
interface
uses Windows;
var
  hHook: HHOOK = 0;
  hInstance: HINST = 0;

function KeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if nCode = HC_ACTION then
    // 處理鍵盤事件...
  Result := CallNextHookEx(hHook, nCode, wParam, lParam);
end;

function InstallHook: Boolean;
begin
  hHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, hInstance, 0);
  Result := hHook <> 0;
end;

function UninstallHook: Boolean;
begin
  if hHook <> 0 then
  begin
    Result := UnhookWindowsHookEx(hHook);
    if Result then hHook := 0;
  end
  else Result := True;
end;
implementation
end.

常見錯誤與除錯

錯誤現象原因解決
UnhookWindowsHookEx 返回 FALSE句柄無效、已被釋放、或非當前進程安裝檢查 hHook 是否為 SetWindowsHookEx 原始返回值,確保同進程呼叫
程式結束後鉤子仍生效未正確呼叫 UnhookWindowsHookEx在 FormDestroy / DLL_PROCESS_DETACH 強制清理
系統變慢、輸入延遲鉤子鏈過長或回調耗時精簡回調邏輯,避免在鉤子中做 I/O、同步等待

關鍵提醒

每一個 SetWindowsHookEx 都必須配對一個 UnhookWindowsHookEx。 這是 Windows 鉤子編程的鐵律,違反者必受其害。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved