How to record mouse clicks in Excel VBA?

前端 未结 1 1013
说谎
说谎 2020-12-07 06:05

I am trying to make a macro that records what a user clicked, which then records the mouse coordinates and the delay between the clicks. This will then repeat after some oth

1条回答
  •  北海茫月
    2020-12-07 06:59

    This is theoretically possible to do, but you'd have to set a hook for WH_MOUSE_LL messages. The problem is that I seriously doubt that VBA can keep up with the volume of messages that are going to be coming through that pipe. It would be like trying drinking from a fire hose in VBA. If you really want to give it a shot, you can see if this works.

    But first:

    DISCLAIMER

    In all likelihood, Excel will stop responding if you set up this Workbook and open it. It will certainlly stop responding if you open the VBE. Do not put this in a spreadsheet that you can't afford to delete. Be fully prepared to have to open it with the shift key down to make edits to the code. You have been warned. I take no responsibility for what you do with this. I know better than to have tried it with any code in the event handler. You will likely crash Excel. You will certainly crash the VBE. You may crash anything or everything else.

    That should cover it. So...

    In a class called 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
    

    In 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
    

    In a Module:

    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
    

    0 讨论(0)
提交回复
热议问题