最近写了一个监控鼠标键盘的hook程序
遇到以下问题:
dll写好后,写了一个exe程序调用,但是只有鼠标在form的区域内才能进行监控,鼠标移到
form区域外无论鼠标键盘都不能监控到,想问一下怎么实现全局的监控?

解决方案 »

  1.   

    如果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.
      

  2.   

    我就是写的dll
    然后再程序里面调用该dll
    比如点击button后调用hook,但只有鼠标点击在该form上才有响应!
      

  3.   

    我试着在dll里声明adoconnection和adotable,然后直接写数据库,一直编译不了,不知哪位也遇到过同样困难?
    其实我要实现的功能也很简单,就是监控客户端电脑是否使用,如果隔一段时间不碰键盘鼠标(就跟屏保一样),就将结束时间发送给服务器,然后就可以减去开始使用时间来算得客户端实际使用电脑时间!
    希望大家帮忙解决!
      

  4.   

    其实这样的HOOK是不需要写在DLL中的,如下:
    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.
      

  5.   

    楼主碰到和我一样的问题了,我也不知道怎么解决。可能我想要用到内存映射,对于发送的话是发到数据库吗?我想先在dll里写到文本里,在读出来更新到数据库该行的吧,如果是用socket也应该简单的吧
      

  6.   

    必须写到dll里,要不就无法实现全局监控,我试过了!
      

  7.   

    已搞定,改写了一个控件, 感谢fei19790920(饭桶的马甲(抵制日货)) unit ZTimer;interfaceuses
      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.