钩子 API

钩子函数能够监视线程或系统范围内发生的所有事件,并能够进行截取、修改等。

// 设置钩子函数
HHOOK SetWindowsHookEx(
    int idHook,      // type of hook to install
    HOOKPROC lpfn,   // address of hook procedure
    HINSTANCE hMod,  // handle to application instance
    DWORD dwThreadId // identity of thread to install hook for
);
// 调用下一个同类型的钩子(钩子链中较早放置的钩子)
CallNextHookEx(hHook, nCode, wParam, lParam)
参数 意义
idHook 钩子类型
lpfn 钩子回调函数地址

如果是远程钩子,应放在 DLL 中

hMod 钩子函数所在 DLL 的实例句柄

如果是局部钩子,则为 NULL

dwThreadId 监控的进程 ID,为 0 时关联所有进程

WH_JOURNALRECORD 和 WH_JOURNALPLAYBACK总是代表局部的系统范围的钩子

返回值 钩子句柄,失败返回 0
hHook 调用者的钩子函数地址

idHook 常量

说明
WH_CALLWNDPROC 调用 SendMessage 时
WH_CALLWNDPROCRET 调用 SendMessage 返回时
WH_CBT 当基于计算机的训练(CBT)事件发生时
WH_DEBUG 用来给钩子函数除错
WH_FOREGROUNDIDLE 由WINDOWS自己使用,一般的应用程序很少使用
WH_GETMESSAGE 调用GetMessage 或 PeekMessage时
WH_JOURNALPLAYBACK 当一个事件从系统的硬件输入队列中被请求时
WH_JOURNALRECORD 当WINDOWS从硬件队列中获得消息时
WH_KEYBOARD 当调用GetMessage 或 PeekMessage 来从消息队列中查询WM_KEYUP 或 WM_KEYDOWN 消息时
WH_KEYBOARD_LL Windows NT: Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.
WH_MOUSE 当调用GetMessage 或 PeekMessage 来从消息队列中查询鼠标事件消息时
WH_MOUSE_LL Windows NT: Installs a hook procedure that monitors low-level mouse input events. For more information, see the LowLevelMouseProc hook procedure.
WH_MSGFILTER 当对话框、菜单或滚动条要处理一个消息时。该钩子是局部的。它时为那些有自己的消息处理过程的控件对象设计的
WH_SHELL 当关于WINDOWS外壳事件发生时,譬如任务条需要重画它的按钮
WH_SYSMSGFILTER 和WH_MSGFILTER一样,只不过是系统范围的
WH_HARDWARE 当调用GetMessage 或 PeekMessage 来从消息队列种查询非鼠标、键盘消息时

WH_JOURNALRECORD 回调函数

这个钩子类型捕捉所有输入消息。

LRESULT CALLBACK JournalPlaybackProc( 
   int code,      // hook code 
   WPARAM wParam, // undefined 
   LPARAM lParam  // address of message being processed 
);
参数 意义
code 处理消息的方式
wParam NULL
lParam EVENTMSG 结构指针

WH_CALLWNDPROC

参数 意义
code 只能是 HC_ACTION
wParam 非零,则为发送的消息
lParam 指向CWPSTRUCT型结构体变量的指针
返回值 未使用,返回 0

WH_MOUSE

参数 意义
code 是 HC_ACTION 或 HC_NOREMOVE
wParam 鼠标事件消息
lParam 指向MOUSEHOOKSTRUCT型结构体变量的指针
返回值 未使用,返回 0

code 常量

Value Meaning
HC_ACTION =0
HC_GETNEXT =1 The hook procedure must copy the current mouse or keyboard message to the EVENTMSG structure pointed to by the lParam parameter.
HC_SKIP =2 The hook procedure must prepare to copy the next mouse or keyboard message to the EVENTMSG structure pointed to by lParam. Upon receiving the HC_GETNEXT code, the hook procedure must copy the message to the structure.
HC_NOREMOVE =3 An application has called the PeekMessage function with wRemoveMsg set to PM_NOREMOVE, indicating that the message is not removed from the message queue after PeekMessage processing.
HC_SYSMODALON =4 A system-modal dialog box is being displayed. Until the dialog box is destroyed, the hook procedure must stop playing back messages.
HC_SYSMODALOFF =5 A system-modal dialog box has been destroyed. The hook procedure must resume playing back the messages.

EVENTMSG 结构

typedef struct tagEVENTMSG {
   UINT message; 
   UINT paramL; 
   UINT paramH; 
   DWORD time; 
   HWND hwnd; 
}EVENTMSG;
成员 意义
message 消息常量
paramL $0000AABB,
AA 扫描码、BB 键值(大部分)
paramH 低16位扫描码(大部分)
time
hwnd 消息发往的窗口句柄

示例:

// 设置钩子,捕获所有输入(键盘,鼠标)
hHook := SetWindowsHookEx(WH_JOURNALRECORD, HookProc, HInstance,0);
 
// 关闭钩子
UnHookWindowsHookEx(hHook);
// 回调函数
function HookProc(iCode:integer; wParam:wParam; lParam:lParam):LResult; stdcall;
var
   msg : PEventMSG;
begin
   msg := PEventmsg(lparam);
   if msg.message = WM_KEYDOWN then
   begin
      Form1.Edit1.Text:=inttohex(msg.paramH,8) + '-' +
         inttohex(msg.paramL,8);
   end;
end;