使用系统钩子可以实现鼠标和键盘的一系列组合动作纪录下来挂钩 SetWindowsHookEx(WH_JOURNALRECORD, HookProc , HInstance, 0);钩子 function HookProc(iCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin .. end;代码有点多。麻烦。上网查看下系统钩子,有介绍
我写的一个简单的纪录和回放程序: unit MainFrm;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TMainForm = class(TForm) HookBtn: TButton; RePlayBtn: TButton; ReadFileBtn: TButton; WriteFileBtn: TButton; procedure HookBtnClick(Sender: TObject); procedure RePlayBtnClick(Sender: TObject); procedure WriteFileBtnClick(Sender: TObject); procedure ReadFileBtnClick(Sender: TObject); private { Private declarations } public { Public declarations } end;var MainForm: TMainForm; 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 UnHookWindowsHookEx(hHook); end; end;procedure TMainForm.HookBtnClick(Sender: TObject); begin if HookBtn.Caption = '开始记录' then begin EventLog:=0; //建立键盘鼠标操作消息纪录链 hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0); RePlayBtn.Enabled := false; HookBtn.Enabled := true;
HookBtn.Caption := '停止记录'; end else begin UnHookWindowsHookEx(hHook); hHook:=0; RePlayBtn.Enabled := true;
HookBtn.Caption := '开始记录' end; end;procedure TMainForm.RePlayBtnClick(Sender: TObject); begin PlayLog:=0; //建立键盘鼠标操作消息纪录回放链 hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,HInstance,0); RePlayBtn.Enabled := false; HookBtn.Enabled := true; end;procedure TMainForm.WriteFileBtnClick(Sender: TObject); var TmpStr : String; SaveFile : TextFile; i : Integer; begin AssignFile ( SaveFile, 'HookRec.dat' ); Rewrite ( SaveFile ); for i := low (EventArr) to high (EventArr) do begin TmpStr := IntToStr ( EventArr[i].message ) + ',' + IntToStr ( EventArr[i].paramL ) + ',' + IntToStr ( EventArr[i].paramH ) + ',' + IntToStr ( EventArr[i].time ) + ',' + IntToStr ( EventArr[i].hwnd );
SetWindowsHookEx(WH_JOURNALRECORD, HookProc , HInstance, 0);钩子
function HookProc(iCode: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
..
end;代码有点多。麻烦。上网查看下系统钩子,有介绍
unit MainFrm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TMainForm = class(TForm)
HookBtn: TButton;
RePlayBtn: TButton;
ReadFileBtn: TButton;
WriteFileBtn: TButton;
procedure HookBtnClick(Sender: TObject);
procedure RePlayBtnClick(Sender: TObject);
procedure WriteFileBtnClick(Sender: TObject);
procedure ReadFileBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
MainForm: TMainForm; 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
UnHookWindowsHookEx(hHook);
end;
end;procedure TMainForm.HookBtnClick(Sender: TObject);
begin
if HookBtn.Caption = '开始记录' then
begin
EventLog:=0;
//建立键盘鼠标操作消息纪录链
hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0);
RePlayBtn.Enabled := false;
HookBtn.Enabled := true;
HookBtn.Caption := '停止记录';
end
else
begin
UnHookWindowsHookEx(hHook);
hHook:=0;
RePlayBtn.Enabled := true;
HookBtn.Caption := '开始记录'
end;
end;procedure TMainForm.RePlayBtnClick(Sender: TObject);
begin
PlayLog:=0;
//建立键盘鼠标操作消息纪录回放链
hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,HInstance,0); RePlayBtn.Enabled := false;
HookBtn.Enabled := true;
end;procedure TMainForm.WriteFileBtnClick(Sender: TObject);
var
TmpStr : String;
SaveFile : TextFile;
i : Integer;
begin
AssignFile ( SaveFile, 'HookRec.dat' );
Rewrite ( SaveFile ); for i := low (EventArr) to high (EventArr) do
begin
TmpStr := IntToStr ( EventArr[i].message ) + ',' +
IntToStr ( EventArr[i].paramL ) + ',' +
IntToStr ( EventArr[i].paramH ) + ',' +
IntToStr ( EventArr[i].time ) + ',' +
IntToStr ( EventArr[i].hwnd );
WriteLn ( SaveFile, TmpStr );
end; CloseFile ( SaveFile ); Application.MessageBox('Write to keyboard&Mouse event to data file OK!', 'Information', MB_OK+MB_ICONINFORMATION );
end;procedure TMainForm.ReadFileBtnClick(Sender: TObject);
function GetValue ( var AEvent : EVENTMSG; var EventStr : String ):Boolean;
var
TmpStr : String;
begin
try
TmpStr := Copy ( EventStr, 0, Pos( ',', EventStr ) - 1 );
AEvent.message := StrToInt ( TmpStr );
EventStr := Copy ( EventStr, Pos( ',', EventStr ) + 1, Length (EventStr) ); TmpStr := Copy ( EventStr, 0, Pos( ',', EventStr ) - 1 );
AEvent.paramL := StrToInt ( TmpStr );
EventStr := Copy ( EventStr, Pos( ',', EventStr ) + 1, Length (EventStr) ); TmpStr := Copy ( EventStr, 0, Pos( ',', EventStr ) - 1 );
AEvent.paramH := StrToInt ( TmpStr );
EventStr := Copy ( EventStr, Pos( ',', EventStr ) + 1, Length (EventStr) ); TmpStr := Copy ( EventStr, 0, Pos( ',', EventStr ) - 1 );
AEvent.time := StrToInt ( TmpStr );
EventStr := Copy ( EventStr, Pos( ',', EventStr ) + 1, Length (EventStr) ); AEvent.hwnd := StrToInt ( TmpStr );
except
Result := false;
Application.MessageBox ( 'Read file erroe!', 'Information', MB_OK+MB_ICONINFORMATION );
end; Result := true;
RePlayBtn.Enabled := true;
end;var
TmpStr : String;
SaveFile : TextFile;
i : Integer;
begin
AssignFile ( SaveFile, 'HookRec.dat' );
Reset ( SaveFile ); for i := low (EventArr) to high (EventArr) do
begin
Readln ( SaveFile, TmpStr ); GetValue ( EventArr[i], TmpStr );
end; CloseFile ( SaveFile );
end;end.