【摘自网上】Delphi hook

//监控窗体在一定的时间内有没有鼠标和键盘事件。

procedure TForm1.Timer1Timer(Sender: TObject);

var

  vLastInputInfo: TLastInputInfo;

begin

  vLastInputInfo.cbSize := SizeOf(vLastInputInfo);

  GetLastInputInfo(vLastInputInfo);

  if GetTickCount - vLastInputInfo.dwTime > 5000 then

  begin

    timer1.Enabled:= false;

    showmessage('超过5秒,用户未动鼠标!');

  end;

end;

 

 

1.关于hook的例子

谢谢,我用HOOK搞定了,有一个例子可供大家参考   

  先是DLL   

  library   HKTest;   

 

  {   按下Ctro+B,启动记事本   }   

 

  uses   

      SysUtils,   

      Classes,   

      HKProc   in   'HKProc.pas';   

 

  exports   

      EnableHotKeyHook,   

      DisableHotKeyHook;   

  begin   

      hNextHookProc:=0;   

      procSaveExit:=   ExitProc;   

      ExitProc:=   @HotKeyHookExit;   

  end.   

 

  unit   HKProc;   

 

  interface   

 

  uses   

      Windows,   Messages,   Dialogs,Shellapi;   

 

  Var   

      hNextHookProc:   HHook;   

      procSaveExit:   Pointer;   

 

  function   KeyboardHookHandler(iCode:   Integer;wParam:   WPARAM;   

                                                            lParam:   LPARAM):   LResult;   stdcall;   export;   

  function   EnableHotKeyHook:   Bool;   export;   

  function   DisableHotKeyHook:   Bool;   export;   

  procedure   HotKeyHookExit;   far;   

 

  implementation   

 

  function   KeyboardHookHandler(iCode:   Integer;wParam:   WPARAM;   

                                                            lParam:   LPARAM):   LResult;   stdcall;   export;   

  const   

      _KeyPressMask   =   $80000000;   

  begin   

      Result:=0;   

      if   iCode<0   then   

      begin   

          Result:=   CallNextHookEx(hNextHookProc,   iCode,   wParam,   lParam);   

          exit;   

      end;   

      //侦测Ctrl+B组合键   

      if   ((lParam   and   _KeyPressMask)=0)and   

          (GetKeyState(vk_control)<0)and(wParam=Ord('B'))   then   

      begin   

          Result:=1;   

          //ShellExecute(hInstance,'open','Notepad.exe','','',sw_Normal);   

          WinExec('Notepad.exe',sw_Normal);   

      end;   

  end;   

 

  function   EnableHotKeyHook:   Bool;   export;   

  begin   

      Result:=   False;   

      if   hNextHookProc<>0   then   exit;   

      //挂上WH_KEYBOARD   的HOOK,   同时,传回值必须保留下来,免的HOOK调用链断掉   

      hNextHookProc:=   SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance,0);   

      Result:=   hNextHookProc<>0;   

  end;   

 

  function   DisableHotKeyHook:   Bool;   export;   

  begin   

      if   hNextHookProc<>0   then   

      begin   

          UnHookWindowsHookEx(hNextHookProc);   

          hNextHookProc:=0   ;   

          MessageBeep(0);   

          MessageBeep(0);   

      end;   

      Result:=   hNextHookProc   =0;   

  end;   

 

  procedure   HotKeyHookExit;   

  begin   

      //如果忘了解除HOOK,自动代理解除的动作   

      if   hNextHookProc<>0   then   DisableHotKeyHook;   

      ExitProc:=   procSaveExit;   

  end;   

  end.   

 

  下面是测试程序   

  program   hk;   

 

  uses   

      Forms,   

      Unit1   in   'Unit1.pas'   {Form1};   

 

  {$R   *.RES}   

 

  begin   

      Application.Initialize;   

      Application.CreateForm(TForm1,   Form1);   

      Application.Run;   

  end.   

 

  unit   Unit1;   

 

  interface   

 

  uses   

      Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,   

      StdCtrls;   

 

  type   

      TForm1   =   class(TForm)   

          procedure   FormClose(Sender:   TObject;   var   Action:   TCloseAction);   

          procedure   FormCreate(Sender:   TObject);   

      private   

          {   Private   declarations   }   

      public   

          {   Public   declarations   }   

      end;   

 

  var   

      Form1:   TForm1;   

 

  implementation   

 

  {$R   *.DFM}   

      function   EnableHotKeyHook:   Bool;external   'HKTest.DLL';   

      function   DisableHotKeyHook:   Bool;external   'HKTest.DLL';   

 

  procedure   TForm1.FormClose(Sender:   TObject;   var   Action:   TCloseAction);   

  begin   

      if   DisableHotKeyHook   then   

          Showmessage('HotKey   Testing...   DONE!!');   

  end;   

 

  procedure   TForm1.FormCreate(Sender:   TObject);   

  begin   

          if   EnableHotKeyHook   then   

          Showmessage('HotKey   Testing...');   

  end;   

 

  end.   

 

  这样按Ctrl+B就可调出写字板了  

 

2. 例子2,回放鼠标和键盘动作

Delphi建立键盘鼠标动作纪录与回放 很多的教学软件或系统监视软件可以自动记录回放用户的输入文字或点击按钮等操作操作,这个功能的实现是使用 

了Windows的Hook函数。 

Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows 

消息,函数语法为: 

SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD) 

其中参数idHook指定建立的监视函数类型。通过Windows MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同 

的消息监视类型,在这里我们将使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK来监视键盘和鼠标操作。参数lpfn指定消 

息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为: 

Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall; 

其中code为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样 

一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。 

在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。 

WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠 

标键盘消息。所以在程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中,另一个用于 

将保存的操作返给系统回放。 

下面来建立程序,在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个按钮控件和一 

个Edit控件用于验证操作。 

下面是Form1的全部代码 

 

unit Unit1; 

 

interface 

 

uses 

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 

StdCtrls; 

 

type 

TForm1 = class(TForm) 

Button1: TButton; 

Button2: TButton; 

Button3: TButton; 

Edit1: TEdit; 

Button4: TButton; 

procedure FormCreate(Sender: TObject); 

procedure Button1Click(Sender: TObject); 

procedure Button2Click(Sender: TObject); 

procedure Button3Click(Sender: TObject); 

private 

{ Private declarations } 

public 

{ Public declarations } 

end; 

 

var 

Form1: TForm1; 

 

EventArr:array[0..1000]of EVENTMSG; 

EventLog:Integer; 

PlayLog:Integer; 

hHook,hPlay:Integer; 

recOK:Integer; 

canPlay:Integer; 

bDelay:Bool; 

implementation 

 

{$R *.DFM} 

Function PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall; 

begin 

canPlay:=1; 

Result:=0; 

 

if iCode < 0 then //必须将消息传递到消息链的下一个接受单元 

Result := CallNextHookEx(hPlay,iCode,wParam,lParam) 

else if iCode = HC_SYSMODALON then 

canPlay:=0 

else if iCode = HC_SYSMODALOFF then 

canPlay:=1 

else if ((canPlay =1 )and(iCode=HC_GETNEXT)) then begin 

if bDelay then begin 

bDelay:=False; 

Result:=50; 

end; 

pEventMSG(lParam)^:=EventArr[PlayLog]; 

end 

else if ((canPlay = 1)and(iCode = HC_SKIP))then begin 

bDelay := True; 

PlayLog:=PlayLog+1; 

end; 

if PlayLog>=EventLog then begin 

UNHookWindowsHookEx(hPlay); 

end; 

end; 

 

function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall; 

begin 

recOK:=1; 

Result:=0; 

 

if iCode < 0 then 

Result := CallNextHookEx(hHook,iCode,wParam,lParam) 

else if iCode = HC_SYSMODALON then 

recOK:=0 

else if iCode = HC_SYSMODALOFF then 

recOK:=1 

else if ((recOK>0) and (iCode = HC_ACTION)) then begin 

EventArr[EventLog]:=pEventMSG(lParam)^; 

EventLog:=EventLog+1; 

 

if EventLog>=1000 then begin 

UnHookWindowsHookEx(hHook); 

end; 

end; 

end; 

 

procedure TForm1.FormCreate(Sender: TObject); 

begin 

Button1.Caption:='纪录'; 

Button2.Caption:='停止'; 

Button3.Caption:='回放'; 

Button4.Caption:='范例'; 

Button2.Enabled:=False; 

Button3.Enabled:=False; 

end; 

 

procedure TForm1.Button1Click(Sender: TObject); 

begin 

EventLog:=0; 

//建立键盘鼠标操作消息纪录链 

hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0); 

Button2.Enabled:=True; 

Button1.Enabled:=False; 

end; 

 

procedure TForm1.Button2Click(Sender: TObject); 

begin 

UnHookWindowsHookEx(hHook); 

hHook:=0; 

 

Button1.Enabled:=True; 

Button2.Enabled:=False; 

Button3.Enabled:=True; 

end; 

 

procedure TForm1.Button3Click(Sender: TObject); 

begin 

PlayLog:=0; 

//建立键盘鼠标操作消息纪录回放链 

hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc, 

HInstance,0); 

 

Button3.Enabled:=False; 

end; 

 

end. 

 

代码添加完毕后,运行程序,点击“纪录”按钮开始纪录操作,这时你可以在文本控件中输入一些文字或者点击 

“范例”按钮,然后点击“停止”按钮停止纪录,再点击“回放”按钮就可以讲先前所做的操作回放。 

在上面的程序中,HookProc是纪录操作的消息函数,每当有鼠标键盘消息发生时,系统都会调用该函数,消息信 

息就保存在地址lParam中,我们可以讲消息保存在一个数组中。PlayProc是消息回放函数,当系统可以执行消息回放 

时调用该函数,程序就将先前纪录的消息值返回到lParam指向的区域中,系统就会执行该消息,从而实现了消息回放。 

 

3.例子3,锁定键盘某些键

var

  hNextHookProc: HHook;

 

 

function keyhook(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;

begin

  Result:=0;

 

  if Code < 0 then

  begin

    Result:= CallNextHookEx(hNextHookProc, Code, wParam, lParam);

    exit;

  end;

 

  if wParam <> vk_Space then //?????

    Result := CallNextHookEx(hNextHookProc, code, wparam, lParam)

  else Result := 1; //??

 

  //if wParam = 98 then

  //  UnHookWindowsHookEx(hNextHookProc);

end;

 

procedure TfmPasswordChange.HookOn;

begin

  if hNextHookProc <> 0 then

    exit;

  hNextHookProc := SetWindowsHookEx(WH_KEYBOARD, keyHook, HInstance, 0);

end;

 

procedure TfmPasswordChange.HookOff;

begin

  if hNextHookProc<>0 then

  begin

    UnHookWindowsHookEx(hNextHookProc);

    hNextHookProc:=0;

    MessageBeep(0);

    MessageBeep(0);   

  end;

end;

 

 

 

// another example

 

unit UHookKBD;

 

interface

 

uses Windows, Messages;

 

type

  PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;

 

  KBDLLHOOKSTRUCT = packed record

    vkCode      : DWORD;

    scanCode    : DWORD;

    flags       : DWORD;

    time        : DWORD;

    dwExtraInfo : DWORD;

  end;

 

 

const

  LLKHF_EXTENDED = $00000001;

  LLKHF_INJECTED = $00000010;

  LLKHF_ALTDOWN  = $00000020;

  LLKHF_UP       = $00000080;

  LLMHF_INJECTED = $00000001;

  WH_Keyboard_LL = 13;

 

 

procedure StartHook; stdcall;

procedure StopHook; stdcall;

 

 

implementation

 

var

  OldHook: HHook;

 

function LowLevelHookProc(nCode:Integer; awParam: WPARAM; alParam:LPARAM): LRESULT; stdcall;

var

  ControlPressed, AltPressed, EscapePressed, WinPressed, TabPressed: boolean;

  pkbhs: PKBDLLHOOKSTRUCT;

  FilterThis: boolean;

begin

  FilterThis := false;

  if nCode = HC_ACTION then

  begin

    pkbhs := PKBDLLHOOKSTRUCT(alParam);

 

    ControlPressed := (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0;

    AltPressed := ((pkbhs^.flags and LLKHF_ALTDOWN)<>0);

    EscapePressed := (pkbhs^.vkCode = VK_ESCAPE);

    WinPressed := (pkbhs^.vkCode in [VK_LWIN, VK_RWIN]);

    TabPressed := (pkbhs^.vkCode = VK_TAB);

 

    // Disable WINDOWS Key

    if WinPressed then

      FilterThis := true

    else

      // Disable CTRL+ESC

      if ControlPressed and EscapePressed then

        FilterThis := true

      else

        // Disable ALT+TAB

        if AltPressed and TabPressed then

          FilterThis := true

        else

          // Disable ALT+ESC

          if AltPressed and EscapePressed then

            FilterThis := true

          else

            //Disable CTRL+ALT

            if ControlPressed and AltPressed then

              FilterThis := true;

  end;

  if not FilterThis then

    Result:= CallNextHookEx (OldHook, nCode, awParam, alParam)

  else

    Result := 1;

end;

 

procedure StartHook; stdcall;

begin

  OldHook := SetWindowsHookEx(WH_Keyboard_LL, LowLevelHookProc, HInstance, 0);

end;

 

procedure StopHook; stdcall;

begin

  UnHookWindowsHookEx(OldHook);

end;

 

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值