资源描述:
《利用delphi实现键盘_鼠标事件的记录和回放》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、2003年11月安徽教育学院学报Nov.2003第21卷第6期JournalofAnhuiInstituteofEducationVol.21No.6利用Delphi实现键盘、鼠标事件的记录和回放李文博(安徽经济管理学院信息管理系,安徽合肥230059)[摘要]本文在Delphi中基于Windows的消息机制利用Hook技术实现了键盘、鼠标事件的记录和回放,并用一个实例演示了键盘鼠标挂钩的用法。[关键词]挂钩;Hook;Delphi[中图分类号]TP312DE[文献标识码]A[文章编号]1001-5
2、116(2003)06-0045-031Windows消息系统概述每当用户发出一个键盘或鼠标事件时,就会向Windows发出的一个通知(即消息),表示某个事件发生。Windows系统和应用程序之间交流是靠消息系统来完成的。Windows为每个应用程序产生一个消息队列,所有的消息都要放到操作系统的消息队列里,由操作系统分派(Dispatch),通过循环机制应用程序从消息队列中检索消息,再把它分派到适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适合的窗口,依次进行,如此形成了消息循环。应用程序
3、根据传入的消息来寻找相应的消息处理方法,如果找不到的话,就继续向上到父类的消息处理方法表中寻找消息的处理方法,一直到找到为止,如果找到顶还没有,则调用缺省方法来处理该消息。所以我们考虑在消息在从消息队列中被取出时,将它们逐个记录在一个消息数组中,这样,就可以记录用户的键盘鼠标事件了,同时能够在适当的时候将消息数组中的消息插入到消息队列中,由系统取出处理,这样就实现了事件的回放。2挂钩(Hook)工作原理挂钩(HOOK)机制是操作系统提供的消息拦截机制,挂钩函数就是要截获这些消息而设计。挂钩就是一个
4、函数(称为回调函数),加载了回调函数后,程序检索某些类型的消息时就会自动调用该函数。因此我们就在回调函数中对消息进行处理(记录),相当于对消息进行过滤。如果挂钩是放到程序内部的,那么它只能截获应用程序自身的消息和Win2dows通知给应用程序的那些公用消息。如果挂钩是放到DLL里,因为DLL是加载到系统的公用代码段运行,所以DLL可以截获整个系统的消息变化,也就是说可以截获其他应用程序的键盘鼠标消息等。我们可以利用挂钩监视放到目标线程消息队列的所有消息,从而来屏蔽或更改一些Win2dows消息和由此
5、引发的事件。安装HOOK时,必须传入一个指向挂钩函数的指针,每当被监视的线程消息队列有任何消息被取出时,HOOK函数就会被调用(回调),传入关于此窗口消息的所有数据,我们可以HOOK函数中查看、记录或修改存放消息窗口消息信息的TMsg结构。挂钩工作原理如图1所示:3挂钩实现挂钩有多种类型,分别用于捕获某一特定类型或某一范围的消息。如:键盘消息,鼠标消息等。本文仅以键盘鼠标挂钩的使用为例,讨论在DELPHI下怎样安装使用键盘鼠标图1挂钩函数。(1)挂钩函数的声明此函数的声明如下:functionKe
6、yMouseHookProc(Code:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;[收稿日期]2003-04-10[作者简介]李文博(1976-),男,安徽灵璧人,安徽经济管理学院信息管理系教师。45这些参数的含义是:Code:值为HC2GETNEXT表示应当准备处理下一个消息,值为HC2SKIP表示指向下一个消息的指针应当放到参数lParam中,如果小于零,表示应当调用Call2NextHookEx()函数。waram:未用。lPar
7、am:当Code参数为HC2SKIP时,应当把指向下一个TeventMsg记录的指针放到lParam参数中。(2)安装挂钩挂钩的安装较为简单,挂钩函数编写后,调用Api函数SetWindowsHookEx安装的挂钩函数即可,同时保存原先的挂钩过滤函数地址。这时挂钩函数就开始起作用了,它将按照要求处理键盘或鼠标消息。其声明如下:functionSetWindowsHookEx(idHook:integer;lpfn:TFN2HookProc;hMod:HINST;dwThreadID:DWORD):H
8、ook;stdcall;①idHook用于指定要安装的挂钩响应事件的类型,由于我们要监控和回放键盘和鼠标消息,所以我们使用到两个类型:WH2JOURNALPLAYRECORD当一个事件从系统消息队列中被请求时会调用这个挂钩函数,用于记录系统事件。WH2JOURNALPLAYBACK当从系统的消息队列中检索到一个消息时会调用这个挂钩函数,主要用于在消息队列中插入一个系统事件。②lpfn参数是挂钩函数的地址,如“@函数名”形式,但由于Delphi采取“巧妙调用(Smart