很多的教學軟件或系統(tǒng)監(jiān)視軟件可以自動記錄回放用戶的輸入文字或點擊按鈕等操作操作,這個功能的實現(xiàn)是使用了Windows的Hook函數(shù)。Windows提供API函數(shù)SetwindowsHookEx來建立一個Hook,通過這個函數(shù)可以將一個程序添加到Hook鏈中監(jiān)視Windows消息,函數(shù)語法為:
      SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD)
      其中參數(shù)idHook指定建立的監(jiān)視函數(shù)類型。通過Windows MSDN幫助可以看到,SetwindowsHookEx函數(shù)提供15種不同
  的消息監(jiān)視類型,在這里我們將使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK來監(jiān)視鍵盤和鼠標操作。參數(shù)lpfn指定消息函數(shù),在相應的消息產生后,系統(tǒng)會調用該函數(shù)并將消息值傳遞給該函數(shù)供處理。函數(shù)的一般形式為:
      Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
      其中code為系統(tǒng)指示標記,wParam和lParam為附加參數(shù),根據不同的消息監(jiān)視類型而不同。只要在程序中建立這樣一個函數(shù)再通過SetwindowsHookEx函數(shù)將它加入到消息監(jiān)視鏈中就可以處理消息了。
      在不需要監(jiān)視系統(tǒng)消息時需要調用提供UnHookWindowsHookEx來解除對消息的監(jiān)視。
      WH_JOURNALRECORD和WH_JOURNALPLAYBACK類型是兩種相反的Hook類型,前者獲得鼠標、鍵盤動作消息,后者回放鼠標鍵盤消息。所以在程序中我們需要建立兩個消息函數(shù),一個用于紀錄鼠標鍵盤操作并保存到一個數(shù)組中,另一個用于將保存的操作返給系統(tǒng)回放。
      下面來建立程序,在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是紀錄操作的消息函數(shù),每當有鼠標鍵盤消息發(fā)生時,系統(tǒng)都會調用該函數(shù),消息信息就保存在地址lParam中,我們可以講消息保存在一個數(shù)組中。PlayProc是消息回放函數(shù),當系統(tǒng)可以執(zhí)行消息回放時調用該函數(shù),程序就將先前紀錄的消息值返回到lParam指向的區(qū)域中,系統(tǒng)就會執(zhí)行該消息,從而實現(xiàn)了消息回放。
 
            