使用VB創(chuàng)建鼠標(biāo)鍵盤(pán)設(shè)置回放
發(fā)表時(shí)間:2024-02-22 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]很多的教學(xué)軟件或系統(tǒng)監(jiān)視軟件可以自動(dòng)記錄回放用戶(hù)的輸入文字或點(diǎn)擊按鈕等操作操作,這個(gè)功能的實(shí)現(xiàn)是使用 了Windows的Hook函數(shù)。本文介紹如何通過(guò)使用VB來(lái)實(shí)現(xiàn)鼠標(biāo)鍵盤(pán)操作的紀(jì)錄和回放。 Windows提供API函數(shù)SetwindowsHookEx來(lái)建立一個(gè)Hook,通過(guò)這個(gè)函數(shù)可以將...
很多的教學(xué)軟件或系統(tǒng)監(jiān)視軟件可以自動(dòng)記錄回放用戶(hù)的輸入文字或點(diǎn)擊按鈕等操作操作,這個(gè)功能的實(shí)現(xiàn)是使用
了Windows的Hook函數(shù)。本文介紹如何通過(guò)使用VB來(lái)實(shí)現(xiàn)鼠標(biāo)鍵盤(pán)操作的紀(jì)錄和回放。
Windows提供API函數(shù)SetwindowsHookEx來(lái)建立一個(gè)Hook,通過(guò)這個(gè)函數(shù)可以將一個(gè)程序添加到Hook鏈中監(jiān)視Windows
消息,函數(shù)語(yǔ)法為:
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
其中參數(shù)idHook指定建立的監(jiān)視函數(shù)類(lèi)型。通過(guò)Windows MSDN幫助可以看到,SetwindowsHookEx函數(shù)提供15種不同
的消息監(jiān)視類(lèi)型,在這里我們將使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK來(lái)監(jiān)視鍵盤(pán)和鼠標(biāo)操作。參數(shù)lpfn指定消
息函數(shù),在相應(yīng)的消息產(chǎn)生后,系統(tǒng)會(huì)調(diào)用該函數(shù)并將消息值傳遞給該函數(shù)供處理。函數(shù)的一般形式為:
Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
其中code為系統(tǒng)指示標(biāo)記,wParam和lParam為附加參數(shù),根據(jù)不同的消息監(jiān)視類(lèi)型而不同。只要在程序中建立這樣
一個(gè)函數(shù)再通過(guò)SetwindowsHookEx函數(shù)將它加入到消息監(jiān)視鏈中就可以處理消息了。
在不需要監(jiān)視系統(tǒng)消息時(shí)需要調(diào)用提供UnHookWindowsHookEx來(lái)解除對(duì)消息的監(jiān)視。
WH_JOURNALRECORD和WH_JOURNALPLAYBACK類(lèi)型是兩種相反的Hook類(lèi)型,前者獲得鼠標(biāo)、鍵盤(pán)動(dòng)作消息,后者回放鼠
標(biāo)鍵盤(pán)消息。所以在程序中我們需要建立兩個(gè)消息函數(shù),一個(gè)用于紀(jì)錄鼠標(biāo)鍵盤(pán)操作并保存到一個(gè)數(shù)組中,另一個(gè)用于
將保存的操作返給系統(tǒng)回放。
下面是具體的程序?qū)崿F(xiàn):首先建立一個(gè)新工程,在Form1中加入三個(gè)CommandButton控件用于控制消息鉤子,另外還
可以增加若干Command或者TextBox控件用于檢驗(yàn)操作回放的效果。然后在工程中增加一個(gè)模塊文件,在模塊中加入以下
定義和代碼:
Option Explicit
Public Type EVENTMSG
message As Long
paramL As Long
paramH As Long
time As Long
hwnd As Long
End Type
Public Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Long, _
ByVal ncode As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
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
Public 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 Long
Public Const WH_JOURNALPLAYBACK = 1
Public Const WH_JOURNALRECORD = 0
Public Const HC_SYSMODALOFF = 5
Public Const HC_SYSMODALON = 4
Public Const HC_SKIP = 2
Public Const HC_GETNEXT = 1
Public Const HC_ACTION = 0
Public EventArr(1000) As EVENTMSG
Public EventLog As Long
Public PlayLog As Long
Public hHook As Long
Public hPlay As Long
Public recOK As Long
Public canPlay As Long
Public bDelay As Boolean
Public Function HookProc(ByVal iCode As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
Dim Result As Long
recOK = 1
Result = 0
If iCode < 0 Then 'iCode小于0必須直接調(diào)用下一個(gè)消息鉤子函數(shù)
Result = CallNextHookEx(hHook, iCode, wParam, lParam)
ElseIf iCode = HC_SYSMODALON Then '不允許紀(jì)錄
recOK = 0
ElseIf iCode = HC_SYSMODALOFF Then '允許紀(jì)錄
recOK = 1
ElseIf ((recOK > 0) And (iCode = HC_ACTION)) Then
'將消息紀(jì)錄在紀(jì)錄隊(duì)列中
CopyMemoryH2T EventArr(EventLog), lParam, Len(EventArr(EventLog))
EventLog = EventLog + 1
If EventLog >= 1000 Then
'當(dāng)紀(jì)錄大于1000后釋放消息鉤子
UnhookWindowsHookEx hHook
End If
End If
HookProc = Result
End Function
Public Function PlaybackProc(ByVal iCode As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
Dim Result As Long
canPlay = 1
Result = 0
If iCode < 0 Then 'iCode小于0必須直接調(diào)用下一個(gè)消息鉤子函數(shù)
Result = CallNextHookEx(hPlay, iCode, wParam, lParam)
ElseIf iCode = HC_SYSMODALON Then '不允許回放
canPlay = 0
ElseIf iCode = HC_SYSMODALOFF Then '允許回放
canPlay = 1
ElseIf ((canPlay = 1) And (iCode = HC_GETNEXT)) Then
If bDelay Then
bDelay = False
Result = 50
End If
'從紀(jì)錄隊(duì)列中取出消息并賦予lParam指針指向的EVENTMSG區(qū)域
CopyMemoryT2H lParam, EventArr(PlayLog), Len(EventArr(EventLog))
ElseIf ((canPlay = 1) And (iCode = HC_SKIP)) Then
bDelay = True
PlayLog = PlayLog + 1
End If
If PlayLog >= EventLog Then
UnhookWindowsHookEx hPlay
End If
PlaybackProc = Result
End Function
在Form1的代碼窗口中加入以下代碼:
Option Explicit
Private Sub Command1_Click()
EventLog = 0
hHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf HookProc, _
App.hInstance, 0)
Command2.Enabled = True
Command1.Enabled = False
End Sub
Private Sub Command2_Click()
UnhookWindowsHookEx hHook
hHook = 0
Command1.Enabled = True
Command2.Enabled = False
Command3.Enabled = True
End Sub
Private Sub Command3_Click()
PlayLog = 0
hPlay = SetWindowsHookEx(WH_JOURNALPLAYBACK, AddressOf PlaybackProc, _
App.hInstance, 0)
Command3.Enabled = False
End Sub
Private Sub Form_Load()
Command1.Caption = "紀(jì)錄"
Command2.Caption = "停止"
Command3.Caption = "回放"
Command2.Enabled = False
Command3.Enabled = False
End Sub
運(yùn)行程序,點(diǎn)擊“紀(jì)錄”按鈕,然后在TextBox中輸入一些文字或者在窗口上移動(dòng)光標(biāo)后再按“停止”鍵停止消息
紀(jì)錄,然后按“回放”按鈕,可以看到剛才鼠標(biāo)鍵盤(pán)的操作被絲毫不差的回放了出來(lái)。
從上面的程序可以看到:通過(guò)WH_JOURNALRECORD可以建立一個(gè)鼠標(biāo)鍵盤(pán)消息鉤子,當(dāng)每一個(gè)鼠標(biāo)鍵盤(pán)消息產(chǎn)生時(shí)被
鉤子函數(shù)被調(diào)用。在鉤子函數(shù)中可以將消息保存在消息事件隊(duì)列中。然后通過(guò)WH_JOURNALPLAYBACK建立消息回放鉤子,
當(dāng)每一次系統(tǒng)可以回放消息時(shí)就會(huì)調(diào)用鉤子函數(shù),在鉤子函數(shù)中就可以從消息隊(duì)列中取出原來(lái)紀(jì)錄的消息返回給系統(tǒng)。
這樣就實(shí)現(xiàn)了鼠標(biāo)鍵盤(pán)操作的紀(jì)錄和回放。