博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi全局勾子和局部勾子
阅读量:5039 次
发布时间:2019-06-12

本文共 5434 字,大约阅读时间需要 18 分钟。

1.安装勾子用SetWindowsHookEx function来实现,对于这个函数先来看MSDN解释

Installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread. 

1 HHOOK WINAPI SetWindowsHookEx(2 __in int idHook,//勾子类型3 __in HOOKPROC lpfn,//回调函数的地址4 __in HINSTANCE hMod,//一般为HInstance5 __in DWORD dwThreadId,//关联进程的句柄,如果0则关联所有正在运行的进程,全局勾子时为06 );

勾子类型为下面的值

2.定义勾子的回调函数(hook procedure),回调函数CallWndProc callback function的定义如下

An application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function before calling the window procedure to process a message sent to the thread

1 LRESULT CALLBACK CallWndProc(2   __in  int nCode,3   __in  WPARAM wParam,4   __in  LPARAM lParam5 );

Parameters

nCode [in]
Type: int
Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and must return the value returned by CallNextHookEx.

wParam [in]

Type: WPARAM
Specifies whether the message was sent by the current thread. If the message was sent by the current thread, it is nonzero; otherwise, it is zero.

lParam [in]

Type: LPARAM
A pointer to a CWPSTRUCT structure that contains details about the message.

Return value

Type: LRESULT

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROC hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero. 

3.回调函数中应调用CallNextHookEx function,并将它返回的值返回给CallWndProc callback function,让消息能够传给其它勾子,如果CallWndProc callback function返回的是0,则将中止消息传递给其它勾子,建议返回CallNextHookEx的返回值,如果你愿意。

4.定义删除勾子的函数UnhookWindowsHookEx

 

5.要想安装全局勾子,应当定义在DLL动态链接库中

完整代码
1 library myHook; 2  3 uses 4   System.SysUtils, 5   Inifiles, 6   System.Classes, 7   Messages,  {
消息 WM_LBUTTONDOWN 定义在 Messages 单元} 8 windows; {
钩子函数都来自 Windows 单元} 9 10 {
$R *.res}11 12 var13 hook:HHOOK;14 15 function hookCallBack(nCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;16 var17 me:CWPSTRUCT;//CallWndProc 缩写18 begin19 //處理20 MessageBox(0,PCHAR(inttostr(wparam)),'提示',MB_OK);21 Result:=CallNextHookEx(hook,nCode,wParam,lParam);22 end;23 24 25 function setHook:Boolean;stdcall;26 begin27 hook:=SetWindowsHookEx(WH_KEYBOARD,@hookCallBack,HInstance,0);28 Result:=hook<>0;29 end;30 31 function deleteHook:boolean;stdcall;32 begin33 result:=UnhookWindowsHookEx(hook);34 end;35 36 {
按 DLL 的要求输出函数}37 exports38 setHook name 'setHook',39 deleteHook name 'deleteHook',40 hookCallBack name 'hookCallBack';41 begin42 end.

6.调用DLL动态链接库中的函数来安装勾子

动态调用

先申明要调用的函数

1 type2   TDLLFun = function: Boolean; stdcall;{
定义和 DLL 中同样参数和返回值的的函数类型}

2)申明存储DLL句柄的变量和要调用函数的地址

1 var2  h: HWND;                   {
声明一个 DLL 句柄}3 SetHook, DelHook: TDLLFun; {
声明两个 TDLLFun 变量}

3)载入DLL文件,取得DLL中的函数地址,赋值给DelHook,和SetHook变量

1 procedure TForm5.Button1Click(Sender: TObject); 2 var 3  b:Boolean; 4 begin 5   h := LoadLibrary('myHook.dll'); {
载入 DLL 并获取句柄} 6 if h<>0 then 7 begin 8 SetHook := GetProcAddress(h, 'setHook'); {
让 SetHook 指向 DLL 中相应的函数} 9 DelHook := GetProcAddress(h, 'deleteHook'); {
让 DelHook 指向 DLL 中相应的函数}10 end else ShowMessage('Err');11 b:=SetHook; {
执行钩子建立函数, 这里的 SetHook 和它指向的函数是同名的, 也可以不同名}12 end;

4)程序关闭时删除勾子,释放DLL资源

1 procedure TForm5.Button2Click(Sender: TObject);2 begin3   DelHook;        {
执行钩子释放函数}4 FreeLibrary(h); {
释放 DLL 资源}5 end;
调用勾子的全部代码
1 unit Unit5; 2  3 interface 4  5 uses 6   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 8  9 type10   TForm5 = class(TForm)11     Button1: TButton;12     Button2: TButton;13     procedure Button1Click(Sender: TObject);14     procedure Button2Click(Sender: TObject);15   private16     {
Private declarations }17 public18 {
Public declarations }19 end;20 21 var22 Form5: TForm5;23 24 implementation25 26 {
$R *.dfm}27 {
要先要定义和 DLL 中同样参数和返回值的的函数类型}28 type29 TDLLFun = function: Boolean; stdcall;30 {
现在需要的 DLL 中的函数的格式都是这样, 定义一个就够了}31 var32 h: HWND; {
声明一个 DLL 句柄}33 SetHook, DelHook: TDLLFun; {
声明两个 TDLLFun 变量}34 35 36 procedure TForm5.Button1Click(Sender: TObject);37 var38 b:Boolean;39 begin40 h := LoadLibrary('myHook.dll'); {
载入 DLL 并获取句柄}41 if h<>0 then42 begin43 SetHook := GetProcAddress(h, 'setHook'); {
让 SetHook 指向 DLL 中相应的函数}44 DelHook := GetProcAddress(h, 'deleteHook'); {
让 DelHook 指向 DLL 中相应的函数}45 end else ShowMessage('Err');46 b:=SetHook; {
执行钩子建立函数, 这里的 SetHook 和它指向的函数是同名的, 也可以不同名}47 end;48 49 procedure TForm5.Button2Click(Sender: TObject);50 begin51 DelHook; {
执行钩子释放函数}52 FreeLibrary(h); {
释放 DLL 资源}53 end;54 55 end.

 

  

 

转载于:https://www.cnblogs.com/zhwx/archive/2012/05/16/2503844.html

你可能感兴趣的文章
System.ValueTuple 未定義或匯入預先定義的類型
查看>>
Redhat6.4安装Oracle 11gr2 64位 注意事项
查看>>
rpm
查看>>
Finance_books_LTCM
查看>>
Http协议
查看>>
2016福州大学软件工程第二次团队作业——预则立&&他山之石成绩统计
查看>>
HDU - 5338 ZZX and Permutations 线段树 + set
查看>>
Windbg分析蓝屏Dump文件
查看>>
问题集锦
查看>>
设置tomcat内存设定
查看>>
Django:中间件与csrf
查看>>
Access specifier 访问限定词
查看>>
js怎么获取动态链式属性呢?
查看>>
【python进阶】Garbage collection垃圾回收1
查看>>
调度系统任务创建---创建一个JoinTrigger的依赖任务(五)
查看>>
Leetcode-Read N Characters Given Read4
查看>>
九年程序人生 总结分享
查看>>
Balanced Lineup
查看>>
C语言:数据类型
查看>>
C# string和byte[]数组之间相互转换
查看>>