收藏 分销(赏)

用DELPHI编制钩子函数.doc

上传人:可**** 文档编号:4262146 上传时间:2024-09-02 格式:DOC 页数:13 大小:33.50KB
下载 相关 举报
用DELPHI编制钩子函数.doc_第1页
第1页 / 共13页
用DELPHI编制钩子函数.doc_第2页
第2页 / 共13页
用DELPHI编制钩子函数.doc_第3页
第3页 / 共13页
用DELPHI编制钩子函数.doc_第4页
第4页 / 共13页
用DELPHI编制钩子函数.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

1、用DELPHI编制钩子函数Windows消息管理机构提供了能使应用程序访问控制消息流c4所谓的钩子(HOOK)机制。钩子有多种,分别用于捕获某一特定类型或某一范围的消息。如:键盘消息,鼠标消息等。我们这里仅以键盘钩子的使用为例,讨论在DELPHI下怎样编写DLL程序和怎样在自己的程序中安装使用键盘钩子函数,并讨论了不同程序使用同一DLL文件时怎样共享数据。一、 钩子过滤函数的编写说明由于钩子过滤函数必须在独立的模块中,也就是说我们必须首先生成一个DLL框架,然后再在其中加入钩子函数代码以及其他相关函数代码。我们这里以键盘钩子过滤函数的编写为例来说明。具体步骤如下:1、先生成一个DLL框架2、编

2、写自己的键盘钩子过滤函数钩子过滤函数必须是回调函数,其函数的声明为:function KeyHookProc(iCode:Integer;wParam:WPARAM;lParam:LPARAM ) : LRESULT; stdcall ;export ;在生成的DLL框架中加入自己的键盘钩子处理函数处理键盘消息。代码如下:if(iCode=0) then beginResult:=0; /初始化返回值/ 在这里加入自己的代码end elsebeginResult:=CallNextHook(hOldKeyHookiCodewParamlParam);/ hOldKeyHook是保存的原键盘过滤

3、函数end;3、 安装键盘钩子过滤函数为安装一个钩子键盘过滤函数应调用SetWindowsHookEx函数(适用于Windows3.0的SetWindowsHook钩子安装函数现在已经废弃不用)。该函数的原形如下:HHOOK SetWindowsHookEx(int idHook/ 安装的钩子类型HOOKPROC lpfn/ 钩子过滤函数地址HINSTANCE hMod/ 任务句柄DWORD dwThreadId / 钩子用于的目的);需要说明的是:通常应该调用MakeProcInstance函数以获取一个输出函数的前导码的入口地址,再将此地址作为SetWindowsHookEx的第二个参数l

4、pfn。但由于Delphi提供了灵巧调用(smart callback),使得MakeProcInstance可以省去,而直接将钩子过滤函数名用作入口地址。这样当应用程序用GetMessage或PeekMessage函数从消息队列中读消息或有按键消息(WM_KEYDOWN或WM_KEYUP)要处理时,系统就要调用钩子过滤函数KeyHookProc处理键盘消息。4、 卸载钩子过滤函数。当钩子函数不再需要时,应调用UnHookWindowsHookProc卸载安装的钩子以释放系统资源。完整的程序清单如下Library KEYHOOK;uses Windows;const BUFFER_SIZE=1

5、6*1024;const HOOK_MEM_FILENAME=SAMPLE KEY_HOOK_MEM_FILE;const HOOK_MUTEX_NAME =SAMPLE KEY_HOOK_MUTEX_NAME;typeTShared=recordKeys : array0.BUFFER_SIZE of Char;KeyCount : Integer;end;PShared=TShared;varMemFileHookMutex : THandle;hOldKeyHook : HHook;ProcSaveExit : Pointer;Shared : PShared;/键盘钩子过滤函数func

6、tion KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT; stdcall; export;const KeyPressMask = $80000000;beginif iCode =BUFFER_SIZE-1 then Shared.KeyCount:=0;end;iCode:=-1;Result := CallNextHookEx(hOldKeyHookiCodewParamlParam);end;end;/ 设置钩子过滤函数function EnableKeyHook : BOOL ; export

7、;beginShared.KeyCount:=0; /初始化键盘指针if hOldKeyHook=0 then beginhOldKeyHook := SetWindowsHookEx(WH_KEYBOARDKeyHookProcHInstance0);end;Result := (hOldKeyHook 0);end;/撤消钩子过滤函数function DisableKeyHook: BOOL ; export;beginif hOldKeyHook 0 thenbeginUnHookWindowsHookEx(hOldKeyHook); / 解除 Keyboard HookhOldKeyH

8、ook:= 0;Shared.KeyCount:=0;end;Result := (hOldKeyHook = 0);end;/取得键盘缓冲区中击键的个数function GetKeyCount :Integer ; export;beginResult:=Shared.KeyCount;end;/取得键盘缓冲区的键function GetKey(index:Integer) : Char ; export;beginResult:=Shared.Keysindex;end;/清空键盘缓冲区procedure ClearKeyString ; export;beginShared.KeyCou

9、nt:=0;end;/DLL的退出处理过程procedure KeyHookExit; far;beginif hOldKeyHook 0 then DisableKeyHook;UnMapViewOfFile(Shared); / 释放内存映象文件CloseHandle(MemFile); / 关闭映象文件ExitProc := ProcSaveExit;end;exports / 定义输出函数EnableKeyHookDisableKeyHookGetKeyCountClearKeyStringGetKey;begin/ DLL 初始化部分HookMutex:=CreateMutex(ni

10、lTrueHOOK_MUTEX_NAME);/ 通过建立内存映象文件以共享内存MemFile:=OpenFileMapping(FILE_MAP_WRITEFalseHOOK_MEM_FILENAME);if MemFile=0 thenMemFile:=CreateFileMapping($FFFFFFFFnilPAGE_READWRITE0SizeOf(TShared)HOOK_MEM_FILENAME);Shared:=MapViewOfFile(MemFileFile_MAP_WRITE000);ReleaseMutex(HookMutex);CloseHandle(HookMutex

11、);ProcSaveExit := ExitProc; / 保存DLL的ExitProcExitProc := KeyHookExit; / 设置DLL新的ExitProcend./ 源代码结束二、 在自己的程序中使用编制好的键盘钩子过滤函数。钩子函数编制好后,使用起来其实很简单:首先调用SetWindowsHookEx安装自己的钩子过滤函数,同时保存原先的钩子过滤函数地址。这时钩子函数就开始起作用了,它将按照你的要求处理键盘消息。程序运行完毕或不再需要监视键盘消息时,调用UnHookWindowsHookProc函数卸载所安装的钩子函数,同时恢复原来的钩子过滤函数地址。下面就是使用在以上编制

12、的钩子函数的例子:unit Unit1;interfaceusesWindowsMessagesSysUtilsClassesGraphicsControlsFormsDialogsStdCtrlsExtCtrls;typeTForm1 = class(TForm)Memo1: TMemo;Panel1: TPanel;bSetHook: TButton;bCancelHook: TButton;bReadKeys: TButton;bClearKeys: TButton;Panel2: TPanel;procedure bSetHookClick(Sender: TObject);proce

13、dure bCancelHookClick(Sender: TObject);procedure bReadKeysClick(Sender: TObject);procedure bClearKeysClick(Sender: TObject);end;var Form1: TForm1;implementation$R *.DFMfunction EnableKeyHook : BOOL ; external KEYHOOK.DLL;function DisableKeyHook : BOOL ; external KEYHOOK.DLL;function GetKeyCount : In

14、teger ; external KEYHOOK.DLL;function GetKey(idx:Integer) : Char ; external KEYHOOK.DLL;procedure ClearKeyString ; external KEYHOOK.DLL;procedure TForm1.bSetHookClick(Sender: TObject); / 设置键盘钩子beginEnableKeyHook;bSetHook.Enabled :=False;bCancelHook.Enabled:=True;bReadKeys.Enabled :=True;bClearKeys.E

15、nabled :=True;Panel2.Caption:= 键盘钩子已经设置;end;procedure TForm1.bCancelHookClick(Sender: TObject); / 卸载键盘钩子beginDisableKeyHook;bSetHook.Enabled :=True;bCancelHook.Enabled:=False;bReadKeys.Enabled :=False;bClearKeys.Enabled :=False;Panel2.Caption:= 键盘钩子没有设置;end;procedure TForm1.bReadKeysClick(Sender: TO

16、bject); / 取得击键的历史记录var i:Integer;beginMemo1.Lines.Clear; / 在Memo1中显示击键历史记录for i:=0 to GetKeyCount-1 doMemo1.Text:=Memo1.Text+GetKey(i);end;procedure TForm1.bClearKeysClick(Sender: TObject); / 清除击键历史记录beginMemo1.Clear;ClearKeyString;end;end./ 源代码结束三、 Windows95下DLL中实现共享内存在上面的钩子函数所在的DLL文件中,需要使用共享内存,即,所

17、有击键的记录存储在同一个数据段中。为什么要这样做呢?这是因为Windows95的DLL调用方法与Windows3.X的方法不同。每个进(线)程在登录某动态连接库时都会为该动态连接库传入一个新的实例句柄(即DLL数据段的句柄)。这使得DLL各个实例之间互不干扰,但是这对那些所有DLL实例共享一组变量带来一些困难。为了解决这个问题,我们在这儿通过建立内存映射文件的方法来解决。即使用Windows的OpenFileMapping、CreateFileMapping和MapViewOfFile三个函数来实现。使用方法如下:MemFile是THandle类型,Shared是指针类型,HOOK_MEM_F

18、ILENAME是一常量串MemFile:=OpenFileMapping(FILE_MAP_WRITEFalseHOOK_MEM_FILENAME); /打开内存映射文件if MemFile=0 then /打开失败则创建内存映射文件MemFile:=CreateFileMapping($FFFFFFFFnilPAGE_READWRITE0SizeOf(TShared)HOOK_MEM_FILENAME);/映射文件到变量Shared:=MapViewOfFile(MemFileFile_MAP_WRITE000);到此为止,你已经知道用Delphi编制钩子函数有多么容易。最后不得不提醒大家:钩子函数虽然功能比较强,但如果使用不当将会严重影响系统的效率,所以要尽量避免使用系统钩子。非要使用不可时也应该格外小心,应使之尽可能小地影响系统的运行。

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服