在许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的监控程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用Hook(即钩子)技术编写的应用程序添加到Windows的任务栏的指示区中就能够很好的达到这个目的。我在参考了API帮助文档基础上,根据在Delphi开发环境中的具体实现分别对这两部分进行详细论述。
一、Hook(钩子)的实现:
Hook是应用程序在Microsoft Windows 消息处理过程中设置的用来监控消息流并且处理系统中尚未到达目的窗口的某一类型消息过程的机制。如果Hook过程在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对系统进行监控。根据需要,我们采用的是在DLL中实现Hook的方式。
1.新建一个导出两个函数的DLL文件,在hookproc.pas中定义了钩子具体实现过程。 代码如下:
library keyspy;
uses windows
messages
hookproc in ''hookproc.pas'';
exports setkeyhook
endkeyhook;
begin nexthookproc:=0;
procsaveexit:=exitproc;
exitproc:=@keyhookexit;
end.
2.在Hookproc.pas中实现了钩子具体过程:
unit hookproc;
interface uses Windows
Messages
SysUtils
Controls
StdCtrls;
var nexthookproc:hhook;
procsaveexit:pointer;
function keyboardhook(icode:integer;wparam:wparam;lparam:lparam):lresult;
stdcall;
export;
function setkeyhook:bool;export;//加载钩子
function endkeyhook:bool;export;//卸载钩子
procedure keyhookexit;
far;
const afilename=''c:\debug.txt'';//将键盘输入动作写入文件中
var debugfile:textfile;
implementation function keyboardhookhandler(icode:integer;wparam:wparam; lparam:lparam):lresult;
stdcall;
export;
begin if icode<0 then
begin result:=callnexthookex(hnexthookproc
icode
wparam
lparam);
exit;
end;
assignfile(debugfile
afilename);
append(debugfile);
if getkeystate(vk_return)<0 then
begin writeln(debugfile
'''');
write(debugfile
char(wparam));
end
else write(debugfile
char(wparam));
closefile(debugfile);
result:=0;
end;
function endkeyhook:bool;
export;
begin if nexthookproc<>0 then
begin unhookwindowshookex(nexthookproc);
nexthookproc:=0;
messagebeep(0);
end;
result:=hnexthookproc=0;
end;
procedure keyhookexit;
far;
begin if nexthookproc<>0 then
endkeyhook;
exitproc:=procsaveexit;
end;
end.
二、Win95/98使用任务栏右方指示区来显示应用程序或工具图标对指示区图标的操作涉及了一个API函数Shell_NotifyIcon,它有两个参数,一个是指向TnotifyIconData结构的指针,另一个是要添加、删除、改动图标的标志。通过该函函数将应用程序的图标添加到指示区中,使其作为图标运行
增加专业特色。当程序起动后,用鼠标右键点击图标,则弹出一个菜单,可选择sethook或endhook。
unit kb;
interface
uses
Windows
Messages
SysUtils
Classes
Graphics
Controls
Forms
Dialogs
StdCtrls
Menus
shellapi;
const icon_id=1;
MI_iconevent=wm_user+1;//定义一个用户消息
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
sethook1: TMenuItem;
endhook1: TMenuItem;
N1: TMenuItem;
About1: TMenuItem;
Close1: TMenuItem;
Gettext1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure sethook1Click(Sender: TObject);
procedure endhook1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Close1Click(Sender: TObject);
private
{ Private declarations }
nid:tnotifyicondata;
normalicon:ticon;
public
{ Public declarations }
procedure icontray(var msg:tmessage);