当前位置:文档之家› 利用VB建立鼠标键盘操作回放

利用VB建立鼠标键盘操作回放

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

本文介绍如何通过使用VB来实现鼠标键盘操作的纪录和回放。

Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows消息,函数语法为:Public Declare Function SetWindowsHookEx Lib "user32" _Alias "SetWindowsHookExA" _(ByVal idHook As Long, _ByVal lpfn As Long, _ByVal hmod As Long, _ByVal dwThreadId As Long) As Long其中参数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类型,前者获得鼠标、键盘动作消息,后者回放鼠标键盘消息。

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

下面是具体的程序实现:首先建立一个新工程,在Form1中加入三个CommandButton控件用于控制消息钩子,另外还可以增加若干Command或者TextBox控件用于检验操作回放的效果。

然后在工程中增加一个模块文件,在模块中加入以下定义和代码:Option ExplicitPublic Type EVENTMSGmessage As LongparamL As LongparamH As Longtime As Longhwnd As LongEnd TypePublic Declare Function CallNextHookEx Lib "user32" _(ByVal hHook As Long, _ByVal ncode As Long, _ByVal wParam As Long, _ByVal lParam As Long) As LongPublic Declare Function SetWindowsHookEx Lib "user32" _Alias "SetWindowsHookExA" _(ByVal idHook As Long, _ByVal lpfn As Long, _ByVal hmod As Long, _ByVal dwThreadId As Long) As LongPublic Declare Sub CopyMemoryT2H Lib "kernel32" _Alias "RtlMoveMemory" _(ByVal Dest As Long, _Source As EVENTMSG, _ByVal Length As Long)Public Declare Sub CopyMemoryH2T Lib "kernel32" Alias "RtlMoveMemory" (Dest As EVENTMSG, ByVal Source As Long, ByVal Length As Long)Public Declare Function UnhookWindowsHookEx Lib "user32" _(ByVal hHook As Long) As LongPublic Const WH_JOURNALPLAYBACK = 1Public Const WH_JOURNALRECORD = 0Public Const HC_SYSMODALOFF = 5Public Const HC_SYSMODALON = 4Public Const HC_SKIP = 2Public Const HC_GETNEXT = 1Public Const HC_ACTION = 0Public EventArr(1000) As EVENTMSGPublicEventLog As LongPublic PlayLog As LongPublic hHook As LongPublic hPlay As LongPublic recOK As LongPublic canPlay As LongPublic bDelay As BooleanPublic Function HookProc(ByVal iCode As Long, ByVal wParam As Long, _ByVal lParam As Long) As LongDim Result As LongrecOK = 1Result = 0If iCode < 0 Then 'iCode小于0必须直接调用下一个消息钩子函数Result = CallNextHookEx(hHook, iCode, wParam, lParam)ElseIf iCode = HC_SYSMODALON Then '不允许纪录recOK = 0ElseIf iCode = HC_SYSMODALOFF Then '允许纪录recOK = 1ElseIf ((recOK > 0) And (iCode = HC_ACTION)) Then'将消息纪录在纪录队列中CopyMemoryH2T EventArr(EventLog), lParam, Len(EventArr(EventLog)) EventLog = EventLog + 1If EventLog >= 1000 Then'当纪录大于1000后释放消息钩子UnhookWindowsHookEx hHookEnd IfEnd IfHookProc = ResultEnd FunctionPublic Function PlaybackProc(ByVal iCode As Long, ByVal wParam As Long, _ ByVal lParam As Long) As LongDim Result As LongcanPlay = 1Result = 0If iCode < 0 Then 'iCode小于0必须直接调用下一个消息钩子函数Result = CallNextHookEx(hPlay, iCode, wParam, lParam)ElseIf iCode = HC_SYSMODALON Then '不允许回放canPlay = 0ElseIf iCode = HC_SYSMODALOFF Then '允许回放canPlay = 1ElseIf ((canPlay = 1) And (iCode = HC_GETNEXT)) ThenIf bDelay ThenbDelay = FalseResult = 50End If'从纪录队列中取出消息并赋予lParam指针指向的EVENTMSG区域CopyMemoryT2H lParam, EventArr(PlayLog), Len(EventArr(EventLog))ElseIf ((canPlay = 1) And (iCode = HC_SKIP)) ThenbDelay = TruePlayLog = PlayLog + 1End IfIf PlayLog >= EventLog ThenUnhookWindowsHookEx hPlayEnd IfPlaybackProc = ResultEnd Function在Form1的代码窗口中加入以下代码:Option ExplicitPrivate Sub Command1_Click()EventLog = 0hHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf HookProc, _ App.hInstance, 0)Command2.Enabled = TrueCommand1.Enabled = FalseEnd SubPrivate Sub Command2_Click()UnhookWindowsHookEx hHookhHook = 0Command1.Enabled = TrueCommand2.Enabled = FalseCommand3.Enabled = TrueEnd SubPrivate Sub Command3_Click()PlayLog = 0hPlay = SetWindowsHookEx(WH_JOURNALPLAYBACK, AddressOf PlaybackProc, _App.hInstance, 0)Command3.Enabled = FalseEnd SubPrivate Sub Form_Load()Command1.Caption = "纪录"Command2.Caption = "停止"Command3.Caption = "回放"Command2.Enabled = FalseCommand3.Enabled = FalseEnd Sub运行程序,点击“纪录”按钮,然后在TextBox中输入一些文字或者在窗口上移动光标后再按“停止”键停止消息纪录,然后按“回放”按钮,可以看到刚才鼠标键盘的操作被丝毫不差的回放了出来。

相关主题