关于hook的问题,高手请进!

oioioi-090 2004-08-16 04:48:26
最近写了一个监控鼠标键盘的hook程序
遇到以下问题:
dll写好后,写了一个exe程序调用,但是只有鼠标在form的区域内才能进行监控,鼠标移到
form区域外无论鼠标键盘都不能监控到,想问一下怎么实现全局的监控?
...全文
172 11 打赏 收藏 举报
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
手指风 2004-08-17
楼主碰到和我一样的问题了,我也不知道怎么解决。可能我想要用到内存映射,对于发送的话是发到数据库吗?我想先在dll里写到文本里,在读出来更新到数据库该行的吧,如果是用socket也应该简单的吧
  • 打赏
  • 举报
回复
fei19790920 2004-08-17
其实这样的HOOK是不需要写在DLL中的,如下:
unit Unit1;

interface

uses
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.
  • 打赏
  • 举报
回复
zizzzz 2004-08-17
可以先写到记事本中,然后下次运行时把记事本数据提交到数据库,然后清空!
  • 打赏
  • 举报
回复
zhu_yi 2004-08-17
已搞定,改写了一个控件, 感谢fei19790920(饭桶的马甲(抵制日货))

unit ZTimer;

interface

uses
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;

implementation

var
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.
  • 打赏
  • 举报
回复
zhu_yi 2004-08-17
必须写到dll里,要不就无法实现全局监控,我试过了!
  • 打赏
  • 举报
回复
oioioi-090 2004-08-16
我试着在dll里声明adoconnection和adotable,然后直接写数据库,一直编译不了,不知哪位也遇到过同样困难?
其实我要实现的功能也很简单,就是监控客户端电脑是否使用,如果隔一段时间不碰键盘鼠标(就跟屏保一样),就将结束时间发送给服务器,然后就可以减去开始使用时间来算得客户端实际使用电脑时间!
希望大家帮忙解决!
  • 打赏
  • 举报
回复
oioioi-090 2004-08-16
还有,如何将鼠标运动的信息传到服务器上,好像只能写道本地文件里!
  • 打赏
  • 举报
回复
oioioi-090 2004-08-16
我就是写的dll
然后再程序里面调用该dll
比如点击button后调用hook,但只有鼠标点击在该form上才有响应!
  • 打赏
  • 举报
回复
luke5678 2004-08-16
学习!!
  • 打赏
  • 举报
回复
ly_liuyang 2004-08-16
这样的例子网上有很多的
  • 打赏
  • 举报
回复
kaguo 2004-08-16
如果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.
  • 打赏
  • 举报
回复
发帖
Delphi

5124

社区成员

Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
帖子事件
创建了帖子
2004-08-16 04:48
社区公告
暂无公告