如果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.
程。代码如下:
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.
然后再程序里面调用该dll
比如点击button后调用hook,但只有鼠标点击在该form上才有响应!
其实我要实现的功能也很简单,就是监控客户端电脑是否使用,如果隔一段时间不碰键盘鼠标(就跟屏保一样),就将结束时间发送给服务器,然后就可以减去开始使用时间来算得客户端实际使用电脑时间!
希望大家帮忙解决!
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
Procedure Hook(En: Boolean = true);
public
{ Public declarations }
end;var
Form1: TForm1;
hHook: LongWord;
xy: TPoint;implementation{$R *.dfm}
Function HookProc(iCode: Integer; wParam: wParam; lParam: lParam): LRESULT; stdcall;
Begin Result := 0;
If(peventmsg(lparam)^.message = WM_LBUTTONDOWN) Or
(peventmsg(lparam)^.message = WM_LBUTTONUP) Or
(peventmsg(lparam)^.message = WM_LBUTTONDBLCLK) Or
(peventmsg(lparam)^.message = WM_MOUSEMOVE) Or
(peventmsg(lparam)^.message = WM_RBUTTONDOWN) Or
(peventmsg(lparam)^.message = WM_RBUTTONUP) Or
(peventmsg(lparam)^.message = WM_RBUTTONDBLCLK) Or
(peventmsg(lparam)^.message = WM_MBUTTONDOWN) Or
(peventmsg(lparam)^.message = WM_MBUTTONUP) Or
(peventmsg(lparam)^.message = WM_MBUTTONDBLCLK)
Then
Begin
GETCURSORPOS(XY);
form1.Caption := IntToStr(XY.x) + ' ' + IntToStr(XY.y);
End;
Result := CallNextHookEx(hHook, iCode, wParam, lParam);End;
procedure TForm1.Button1Click(Sender: TObject);
begin
Hook;end;procedure TForm1.Hook(En: Boolean);
begin
If En Then
hHook := SetwindowsHookEx(WH_JOURNALRECORD, HookProc, HInstance, 0)
Else
UnHookWindowsHookEx(hHook);end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Hook(false);end;end.
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;type
TZTimer = class(TTimer)
private
function GetIdleTime: Longint;
procedure SetIdleTime(const Value: Longint);
protected
{ Protected declarations }
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property IdleTime: Longint read GetIdleTime write SetIdleTime;
published end;procedure Register;implementationvar
Instances: integer;
ElapsedTime: Longint;
hHook: LongWord;procedure Register;
begin
RegisterComponents('Z', [TZTimer]);
end;Function HookProc(iCode: Integer; wParam: wParam; lParam: lParam): LRESULT; stdcall;
Begin
Result := 0;
If(peventmsg(lparam)^.message = WM_LBUTTONDOWN) Or
(peventmsg(lparam)^.message = WM_LBUTTONUP) Or
(peventmsg(lparam)^.message = WM_LBUTTONDBLCLK) Or
(peventmsg(lparam)^.message = WM_MOUSEMOVE) Or
(peventmsg(lparam)^.message = WM_RBUTTONDOWN) Or
(peventmsg(lparam)^.message = WM_RBUTTONUP) Or
(peventmsg(lparam)^.message = WM_RBUTTONDBLCLK) Or
(peventmsg(lparam)^.message = WM_MBUTTONDOWN) Or
(peventmsg(lparam)^.message = WM_MBUTTONUP) Or
(peventmsg(lparam)^.message = WM_KEYDOWN) Then ElapsedTime := GetTickCount;
Result := CallNextHookEx(hHook, iCode, wParam, lParam);End;procedure Hook(En: Boolean);
begin
If En Then
hHook := SetwindowsHookEx(WH_JOURNALRECORD, HookProc, HInstance, 0)
Else
UnHookWindowsHookEx(hHook);end;
{ TZTimer }constructor TZTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
hook(true);
end;destructor TZTimer.Destroy;
begin
Hook(false);
inherited;
end;function TZTimer.GetIdleTime: Longint;
begin
Result := GetTickCount - ElapsedTime;
end;procedure TZTimer.SetIdleTime(const Value: Integer);
begin
ElapsedTime := GetTickCount + Value;
end;end.