如何在Excel VBA中记录鼠标点击?

时间:2015-04-20 21:10:55

标签: excel vba excel-vba

我正在尝试制作一个记录用户点击内容的宏,然后记录鼠标坐标和点击之间的延迟。然后,在其他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重播它们?

1 个答案:

答案 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