SetWindowsHookEx 钩子

来源:互联网 发布:ak74知乎 编辑:程序博客网 时间:2024/05/21 14:41
SetWindowsHookEx(
  idHook: Integer;   {钩子类型}
  lpfn: TFNHookProc; {函数指针}
  hmod: HINST;       {包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}
  dwThreadId: DWORD  {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}
): HHOOK;            {返回钩子的句柄; 0 表示失败}

//钩子类型 idHook 选项:
WH_MSGFILTER       = -1; {线程级; 截获用户与控件交互的消息}
WH_JOURNALRECORD   = 0;  {系统级; 记录所有消息队列从消息队列送出的输入消息, 在消息从队列中清除时发生; 可用于宏记录}
WH_JOURNALPLAYBACK = 1;  {系统级; 回放由 WH_JOURNALRECORD 记录的消息, 也就是将这些消息重新送入消息队列}
WH_KEYBOARD        = 2;  {系统级或线程级; 截获键盘消息}
WH_GETMESSAGE      = 3;  {系统级或线程级; 截获从消息队列送出的消息}
WH_CALLWNDPROC     = 4;  {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}
WH_CBT             = 5;  {系统级或线程级; 截获系统基本消息, 譬如: 窗口的创建、激活、关闭、最大最小化、移动等等}
WH_SYSMSGFILTER    = 6;  {系统级; 截获系统范围内用户与控件交互的消息}
WH_MOUSE           = 7;  {系统级或线程级; 截获鼠标消息}
WH_HARDWARE        = 8;  {系统级或线程级; 截获非标准硬件(非鼠标、键盘)的消息}
WH_DEBUG           = 9;  {系统级或线程级; 在其他钩子调用前调用, 用于调试钩子}
WH_SHELL           = 10; {系统级或线程级; 截获发向外壳应用程序的消息}
WH_FOREGROUNDIDLE  = 11; {系统级或线程级; 在程序前台线程空闲时调用}
WH_CALLWNDPROCRET  = 12; {系统级或线程级; 截获目标窗口处理完毕的消息, 在 SendMessage 调用后发生}  

钩子类型******************************************************************************
钩子类型1-2:WH_CALLWNDPROC(4) and WH_CALLWNDPROCRET(12) Hooks
WH_CALLWNDPROC 和 WH_CALLWNDPROCRET钩子使你能够监视发送到window程序的消息。系统在将消息传递给正在接收的window程序之前,调用 WH_CALLWNDPROC钩子子程;在window程序处理完消息之后,调用WH_CALLWNDPROCRET钩子子程。
WH_CALLWNDPROCRET钩子将一个指向CWPRETSTRUCT结构的的指针传递给钩子子程。该结构包含有来自处理该消息的window程序的返回值,以及消息中的参数。子类窗体不能处理进程间的消息集。


钩子类型3:WH_CBT(5) Hook
在以下事件发生之前,系统会调用WH_CBT 钩子子程:
1、窗台被激活、创建、销毁、最小化、最大化、移动或者改变大小;
2、执行完系统命令;
3、从系统消息队列中移除鼠标或者键盘事件;
4、设置输入焦点;
5、同步系统消息队列;
钩子子程的返回值决定了系统是允许还是阻止了这些操作中的一个。WH_CBT钩子主要是用在基于计算机的练习(CBT) 程序中。


钩子类型4:WH_DEBUG(9) Hook
在调用与系统中任何其他钩子关联的钩子子程之前,系统会调用WH_DEBUG 钩子子程。使用该钩子来决定是否允许系统调用与其他类型的钩子相关联的钩子子程。


钩子类型5:WH_FOREGROUNDIDLE(11) HooK
WH_FOREGROUNDIDLE 钩子允许当前台线程空闲时,执行低权限的任务。系统在应用程序的前台线程即将空闲时,调用WH_FOREGROUNDIDLE钩子子程。


钩子类型6:WH_GETMESSAGE(3) Hook
WH_GETMESSAGE程序允许应用程序监视即将由方法GetMessage 或者PeekMessage返回的消息。可以使用WH_GETMESSAGE钩子监视鼠标和键盘输入,以及其他传递给消息队列的消息。


钩子类型7:WH_JOURNALPLAYBACK(1) Hook
WH_JOURNALPLAYBACK钩子允许应用程序将消息插入到系统消息队列中。使用该钩子回放先前使用WH_JOURNALRECORD 钩子记录的一系列鼠标和键盘事件。在WH_JOURNALPLAYBACK被安装后,常规的鼠标和键盘输入被禁用。WH_JOURNALPLAYBACK 钩子是全局钩子,不能被用作线程钩子。WH_JOURNALPLAYBACK钩子返回一个超时值。该值告诉系统在处理来自回放钩子的当前消息之前等待了多少毫秒。这允许该钩子控制回放事件的速度。


钩子类型8:WH_JOURNALRECORD(0) Hook
WH_JOURNALRECORD钩子允许监视并且记录输入事件。典型的,使用该钩子来记录顺序的的鼠标和键盘事件,以后可以使用 WH_JOURNALPLAYBACK.钩子进行回放。 该钩子是全局钩子,不能被用作进程钩子。


钩子类型9:WH_KEYBOARD_LL() Hook
WH_KEYBOARD_LL钩子监视在线程输入队列中,即将被传递的键盘输入事件。


钩子类型10:WH_KEYBOARD(2) Hook
WH_KEYBOARD钩子允许应用程序监视即将被GetMessage 或者 PeekMessage方法返回的WM_KEYDOWN 或者 WM_KEYUP消息。使用WH_KEYBOARD钩子可以监视传递到消息队列中的键盘输入。


钩子类型11:WH_MOUSE_LL(14) Hook
WH_MOUSE_LL钩子监视在线程输入队列中,即将被传递的鼠标输入事件。


钩子类型12:WH_MOUSE(7) Hook
WH_MOUSE钩子允许监视即将被GetMessage或者 PeekMessage方法返回的鼠标消息。使用该钩子监视传递到线程输入队列的鼠标输入。


*******************************回调函数参数结构********************************

结构1 CBT_CREATEWND***********************************************************
CBT_CREATEWND该结构包含有:在一个窗口被创建之前传递给WH_CBT钩子子程,即CBTProc,的信息。
成员1:LPCREATESTRUCT lpcs;一个指向CREATESTRUCT结构的指针,该结构包含即将被创建的窗体的初始化参数。
成员2:整数型 hwndInsertAfter;窗体的句柄,该窗体的Z轴位置在正在被创建的窗体的Z轴位置之前。

结构2:CBTACTIVATESTRUCT ****************************************************
CBTACTIVATESTRUCT 结构包含在窗体被激活之前,传递给WH_CBT钩子子程CBTProc 的信息。
成员1:BOOL fMouse;指定窗体是否是由于鼠标的点击而导致被激活.如果是因为鼠标的点击而引发了窗体的激活,返回true,否则返回false。
成员2:HWND hWndActive; 活动窗口的句柄。

结构3:CWPRETSTRUCT **********************************************************
CWPRETSTRUCT结构定义了传递给WH_CALLWNDPROCRET钩子子程CallWndRetProc的消息参数。
成员1:LRESULT lResult;指定了窗体程序的返回值,该窗体程序处理由 message 值指定的消息。
成员2:LPARAM lParam;指定消息的附加信息。附加的意义取决于message的值。
成员3:WPARAM wParam;指定消息的附加信息。附加的意义取决于message的值。
成员4:UINT message;指定消息。
成员5:HWND hwnd;处理由message的值指定的消息的窗体的窗体句柄。


结构4:CWPSTRUCT ************************************************************
CWPSTRUCT 结构定义了传递给WH_CALLWNDPROC钩子子程CallWndProc的消息参数。
成员1:LPARAM lParam;指定消息的附加信息。附加的意义取决于message的值。
成员2:WPARAM wParam;指定消息的附加信息。附加的意义取决于message的值。
成员3:UINT message;指定消息
成员4:HWND hwnd;接收消息的窗体的句柄。


结构5:DEBUGHOOKINFO *******************************************************
DEBUGHOOKINFO结构包含有传递给WH_DEBUG钩子子程DebugProc的调试信息。
成员1:DWORD idThread;包含过滤方法的线程的句柄。
成员2:DWORD idThreadInstaller;安装调试过滤方法的线程的句柄。
成员3:LPARAM lParam;指定在DebugProc回调函数的lParam/ wParam 参数中,要传递给钩子的值。
成员4:WPARAM wParam;指定在DebugProc回调函数的lParam/ wParam 参数中,要传递给钩子的值。
成员5:int code; 指定在DebugProc回调函数的nCode 参数中,要传递给钩子的值。


结构6:EVENTMSG *************************************************************
EVENTMSG该结构包含有关于硬件的消息,该消息被发送给系统的消息队列。该结构用来为JournalPlaybackProc回调函数存储消息的信息。
成员1:UINT message;指定消息。
成员2:UINT paramL;指定消息的附加信息。附加的意义取决于message的值。
成员3:UINT paramH;指定消息的附加信息。附加的意义取决于message的值。
成员4:DWORD time;消息被传递时的时间 。
成员5:HWND hwnd; 消息被传给的窗口的句柄。


结构7:KBDLLHOOKSTRUCT *****************************************************
KBDLLHOOKSTRUCT该结构包含有低层键盘输入事件的信息。
成员1:DWORD vkCode;指定虚拟键值。该值必须在1到254的范围内。
成员2:DWORD scanCode;指定键的硬件扫描码。
成员3:DWORD flags;指定扩展键标志,事件注入标志,上下文代码,转换状态码。成员如下所示。应用程序可以使用下列值来检查键盘敲击标志。
Value值 Purpose目的
LLKHF_EXTENDED Test the extended-key flag. 测试扩展键标志。
LLKHF_INJECTED Test the event-injected flag. 测试事件注入标志。
LLKHF_ALTDOWN Test the context code. 测试上下文代码。
LLKHF_UP Test the transition-state flag. 测试转换状态码。

0 :Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
指定该键是否是扩展键,例如:功能键、数字键盘上的键。是扩展键为1,否则为0。

1-3 :Reserved. 保留。

4 :Specifies whether the event was injected. The value is 1 if the event was injected; otherwise, it is 0.
指定事件是否被注入。被注入为1,否则为0。

5 :Specifies the context code. The value is 1 if the ALT key is pressed; otherwise, it is 0.
指定上下文代码。如果按下了ALT,该值为1,否则为0

6 :Reserved. 保留。

7 :
指定转换状态。如果该键被按下该值为1,如果被释放为0。
成员4:DWORD time;指定消息的时间戳,相当于GetMessageTime返回的值。
成员5:ULONG_PTR dwExtraInfo;指定和该消息相关联的扩展信息。


结构8 :MOUSEHOOKSTRUCT *******************************************************
MOUSEHOOKSTRUCT结构包含有传递给WH_MOUSE钩子子程MouseProc的,关于鼠标事件的信息。
成员1:POINT pt;指定在屏幕坐标系下,包含有光标x、y坐标的POINT结构。
成员2:HWND hwnd; 希望对鼠标事件做出响应、接收鼠标消息的窗体的句柄。
成员3:UINT wHitTestCode;指定点击测试值。查看WM_NCHITTEST消息可以得到值的列表。
成员4:ULONG_PTR dwExtraInfo;指定和该消息相关联的附加信息。


结构9:MOUSEHOOKSTRUCTEX *****************************************************
MOUSEHOOKSTRUCTEX 结构包含有传递给WH_MOUSE钩子子程MouseProc的关于鼠标事件的信息。这是对MOUSEHOOKSTRUCT的扩展。包含有滚轮的活动和X 键的使用。
成员1:MOUSEHOOKSTRUCT MOUSEHOOKSTRUCT; MOUSEHOOKSTRUCT结构的成员构成了该结构的前面部分
成员2:DWORD mouseData;如果消息是WM_MOUSEWHEEL,该成员的HIWORD就是wheel delta。LOWORD做为保留未定义。正值表示滚轮向前旋转,即远离用户的方向;负值表示滚轮向后旋转,即朝向用户的方向。滚轮的点击被定义为 WHEEL_DELTA, 具体值为120。
如果消息是WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, 或者 WM_NCXBUTTONDBLCLK, mouseData 的HIWORD值指定哪个X键被按下或者释放,LOWORD做为保留未定义。该成员可以是以下值中的一个或者多个。否则,mouseData未使用。
1.XBUTTON1 : 第一个X键被按下或者释放。
2.XBUTTON2 :第二个X键被按下或者释放。
} MOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX;


结构10:MSLLHOOKSTRUCT ********************************************************
MSLLHOOKSTRUCT 该结构包含有低层键盘输入事件的信息。
成员1:POINT pt; POINT 指定在屏幕坐标系下,包含有光标x、y坐标的POINT结构。
成员2:DWORD mouseData;如果消息是WM_MOUSEWHEEL,该成员的HIWORD就是wheel delta。LOWORD做为保留未定义。正值表示滚轮向前旋转,即远离用户的方向;负值表示滚轮向后旋转,即朝向用户的方向。滚轮的点击被定义为 WHEEL_DELTA, 具体值为120。
如果消息是WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, 或者 WM_NCXBUTTONDBLCLK, mouseData 的HIWORD值指定哪个X键被按下或者释放,LOWORD做为保留未定义。该成员可以是以下值中的一个或者多个。否则,mouseData未使用。
1.XBUTTON1: 第一个X键被按下或者释放。
2.XBUTTON2 :第二个X键被按下或者释放。
成员3:DWORD flags;指定事件注入标志。应用程序可以使用下列值来测试鼠标标志。
Value Purpose
测试事件注入标志。
0
事件是否被注入。如果被注入,为 1,否则为0
1-15 :Reserved.保留
成员4:DWORD time;消息的时间戳。
成员5:ULONG_PTR dwExtraInfo;消息的扩展信息。

****************************************************************************************************************

PMouseHookStruct = ^TMouseHookStruct;
  {$EXTERNALSYM tagMOUSEHOOKSTRUCT}
  tagMOUSEHOOKSTRUCT = packed record
    pt: TPoint;
    hwnd: HWND;
    wHitTestCode: UINT;
    dwExtraInfo: DWORD;
  end;
  TMouseHookStruct = tagMOUSEHOOKSTRUCT;

****************************************************************************************************************

library MouseHook;

uses
  Windows, Messages;

const
  WH_MOUSE_LL = 14;

var
  hook: HHOOK;

function MouseHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if (nCode = HC_ACTION) and (wParam = WM_LBUTTONDOWN) then
  begin
    MessageBeep(0);
  end;
  Result := CallNextHookEx(hook, nCode, wParam, lParam);
end;

function AddHook: Boolean; stdcall;
begin
  hook := SetWindowsHookEx(WH_MOUSE_LL, @MouseHook, HInstance, 0);
  Result := hook <> 0;
end;

function DelHook: Boolean; stdcall;
begin
  Result := UnhookWindowsHookEx(hook);
end;

exports
  AddHook name 'AddHook',
  DelHook name 'DelHook';

begin
end.

原创粉丝点击