使用钩子函数

钩子分两种, 一种是系统级的全局钩子; 一种是线程级的钩子.
全局钩子函数需要定义在 DLL 中, 从线程级的钩子开始比较简单.

其实钩子函数就三个:
设置钩子: SetWindowsHookEx
释放钩子: 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;

{声明键盘钩子回调函数; 其参数传递方式要用 API 的 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 Beep; {每拦截到字母 A 会发声}
  Result := CallNextHookEx(hook, nCode, wParam, lParam);
end;

{设置键盘钩子}
procedure TForm1.FormCreate(Sender: TObject);
begin
  hook := SetWindowsHookEx(WH_KEYBOARD, @KeyHook, 0, GetCurrentThreadID);
end;

{释放键盘钩子}
procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnhookWindowsHookEx(hook);
end;

end.
posted @ 2023-05-13 14:57  lucken  阅读(45)  评论(0)    收藏  举报