我正在尝试制作一个记录用户点击内容的宏,然后记录鼠标坐标和点击之间的延迟。然后,在其他SendKey
更改之后,这将重复。当宏运行时,如何检测单击鼠标的时间?我已经知道如何获取坐标并记录延迟,但是检测鼠标点击的最佳操作方法是什么,以及保存所有这些信息的最佳方法是什么?一个文本文件?以下是我使用的鼠标点击事件的片段:
Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Public Type POINTAPI
x As Long
y As Long
End Type
Public pos As POINTAPI ' Declare variable
Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENTF_LEFTDOWN = &H2
Public Const MOUSEEVENTF_LEFTUP = &H4
Public Const MOUSEEVENTF_RIGHTDOWN As Long = &H8
Public Const MOUSEEVENTF_RIGHTUP As Long = &H10
Public Sub SingleClick()
Dim xval, yval
xval = GetSetting("Will's Program Sheet", "DPS Calibration", "PROGRAM X")
yval = GetSetting("Will's Program Sheet", "DPS Calibration", "PROGRAM Y")
Select Case xval
Case Is = "" 'Runs calibrate if it can't find an xval
Call CALIBRATE
End
End Select
SetCursorPos xval, yval 'x and y position
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub
还有另一个宏调用SingleClick
,它会移动到常量x和y,点击,做一些魔术,并返回到宏开始之前的位置。重申一下,是否有一种简单易懂的方法来记录点击之间的多次点击和延迟,并通过Excel VBA重播它们?
答案 0 :(得分:4)
理论上可能这样做,但你必须为WH_MOUSE_LL消息设置一个钩子。问题是我严重怀疑VBA可以跟上将要通过该管道发送的消息量。这就像在VBA中尝试用消防水管喝水一样。如果你真的想试一试,你可以看看它是否有效。
但首先:
如果您设置此工作簿并打开它,Excel很可能会停止响应。如果您打开VBE,它将确定停止响应。不要将其放在您无法删除的电子表格中。完全准备好用Shift键向下打开它来编辑代码。你被警告了。我对你的所作所为不承担任何责任。我知道最好不要在事件处理程序中使用 任何 代码进行尝试。您可能会崩溃Excel。你一定会崩溃VBE。你可能会崩溃任何事情或其他一切。
那应该涵盖它。所以......
在一个名为HookHolder的课程中:
Option Explicit
Private hook As Long
Public Sub SetHook()
hook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf ClickHook, _
0, GetCurrentThreadId)
End Sub
Public Sub UnsetHook()
'IMPORTANT: You need to release the hook when you're done with it.
UnhookWindowsHookEx hook
End Sub
在ThisWorkbook中:
Option Explicit
Private danger As HookHolder
Private Sub Workbook_Open()
Set danger = New HookHolder
danger.SetHook
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
danger.UnsetHook
End Sub
在模块中:
Option Explicit
Public Declare Function GetCurrentThreadId Lib "kernel32" () 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 Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const HC_ACTION As Long = 0
Public Const WH_MOUSE_LL As Long = &H2
Public Const WM_LBUTTONDOWN As Long = &H201
Public Const WM_LBUTTONUP As Long = &H202
Public Const WM_LBUTTONDBLCLK As Long = &H203
'Your callback function.
Public Function ClickHook(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If nCode = HC_ACTION Then
'Anything in particular you're interest in?
Select Case wParam
Case WM_LBUTTONDOWN
'Do your thing.
Case WM_LBUTTONUP
'Do your thing.
Case WM_LBUTTONDBLCLK
'Do your thing.
End Select
End If
CallNextHookEx 0, nCode, wParam, ByVal lParam
End Function