• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi全局勾子和局部勾子

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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. 参考MSDN

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

勾子类型为下面的值

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 lParam
5 );

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 var
13   hook:HHOOK;
14 
15 function hookCallBack(nCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
16 var
17   me:CWPSTRUCT;//CallWndProc 缩写
18 begin
19     //處理
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 begin
27   hook:=SetWindowsHookEx(WH_KEYBOARD,@hookCallBack,HInstance,0);
28   Result:=hook<>0;
29 end;
30 
31 function deleteHook:boolean;stdcall;
32 begin
33   result:=UnhookWindowsHookEx(hook);
34 end;
35 
36 {按 DLL 的要求输出函数}
37 exports
38   setHook name 'setHook',
39   deleteHook name 'deleteHook',
40   hookCallBack name 'hookCallBack';
41 begin
42 end.

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

动态调用

先申明要调用的函数

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

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

1 var
2  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 begin
3   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 type
10   TForm5 = class(TForm)
11     Button1: TButton;
12     Button2: TButton;
13     procedure Button1Click(Sender: TObject);
14     procedure Button2Click(Sender: TObject);
15   private
16     { Private declarations }
17   public
18     { Public declarations }
19   end;
20 
21 var
22   Form5: TForm5;
23 
24 implementation
25 
26 {$R *.dfm}
27   {要先要定义和 DLL 中同样参数和返回值的的函数类型}
28 type
29   TDLLFun = function: Boolean; stdcall;
30   {现在需要的 DLL 中的函数的格式都是这样, 定义一个就够了}
31 var
32  h: HWND;                   {声明一个 DLL 句柄}
33  SetHook, DelHook: TDLLFun; {声明两个 TDLLFun 变量}
34 
35 
36 procedure TForm5.Button1Click(Sender: TObject);
37 var
38  b:Boolean;
39 begin
40   h := LoadLibrary('myHook.dll'); {载入 DLL 并获取句柄}
41   if h<>0 then
42   begin
43     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 begin
51   DelHook;        {执行钩子释放函数}
52   FreeLibrary(h); {释放 DLL 资源}
53 end;
54 
55 end.

 

  

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi容器类之---Tlist,TStringlist,THashedStringlist的效率比较发布时间:2022-07-18
下一篇:
matlab练习程序(直方图匹配)发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap