【问题标题】:Record mouse Middle button and wheel scroll录制鼠标中键和滚轮滚动
【发布时间】:2023-03-09 02:30:01
【问题描述】:

我已经创建了一个类来记录鼠标动作,例如用鼠标记录任务(在此处移动鼠标并在此处单击左键......)

记录鼠标动作/任务后,我可以使用我创建的线程从类中重现它。

我需要的是实现鼠标的中键和滚轮滚动,但我不知道该怎么做,对我来说有点难以使用和理解“ GetAsyncKeyState”,我找不到有关“GetAsyncKeyState 中间按钮状态”或滚轮滚动(向下/向上滚动)的信息。

#Region " Record Mouse Class "

' [ Record Mouse Functions ]
'
' // By Elektro H@cker
'
' Examples :
' Record_Mouse.Start_Record()
' Record_Mouse.Stop_Record()
' Record_Mouse.Play() : While Not Record_Mouse.Play_Is_Completed : Application.DoEvents() : End While
' Record_Mouse.Mouse_Speed = 50

Public Class Record_Mouse

''' <summary>
''' Sets the speed of recording/playing the mouse actions.
''' Default value is 25.
''' </summary>
Public Shared Mouse_Speed As Int64 = 25

''' <summary>
''' Gets the status pf the current mouse play.
''' False = mouse task is still playing.
''' True = Mouse task play is done.
''' </summary>
Public Shared Play_Is_Completed As Boolean = False

' Where the mouse coordenates will be stored:
Private Shared Coordenates_List As New List(Of Point)
' Where the mouse clicks will be stored:
Private Shared Clicks_Dictionary As New Dictionary(Of Int64, MouseButton)
' Timer to record the mouse:
Private Shared WithEvents Record_Timer As New Timer
' Button click count to rec/play clicks:
Private Shared Click_Count As Int32 = 0
' Thread to reproduce the mouse actions:
Private Shared Thread_MousePlay_Var As System.Threading.Thread = New Threading.Thread(AddressOf Thread_MousePlay)
' API to record the current mouse button state:
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
' API to reproduce a mouse button click:
Private Declare Sub Mouse_Event Lib "User32" Alias "mouse_event" (ByVal dwFlags As MouseButton, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As Integer)
' GetAsyncKeyState buttons status
Private Shared Last_ClickState_Left As Int64 = -1
Private Shared Last_ClickState_Right As Int64 = -1

Enum MouseButton

    Left_Down = &H2    ' Left button (hold)
    Left_Up = &H4      ' Left button (release)

    Right_Down = &H8   ' Right button (hold)
    Right_Up = &H10    ' Right button (release)

    Middle_Down = &H20 ' Middle button (hold)
    Middle_Up = &H40   ' Middle button (release)

    Left               ' Left   button (press)
    Right              ' Right  button (press)
    Middle             ' Middle button (press)

End Enum

''' <summary>
''' Starts recording the mouse actions over the screen.
''' It records the position of the mouse and left/right button clicks.
''' </summary>
Public Shared Sub Start_Record()
    Play_Is_Completed = False
    Record_Timer.Interval = Mouse_Speed
    Coordenates_List.Clear() : Clicks_Dictionary.Clear() : Click_Count = 0
    Record_Timer.Start()
End Sub

''' <summary>
''' Stop recording the mouse actions.
''' </summary>
Public Shared Sub Stop_Record()
    Record_Timer.Stop()
End Sub

''' <summary>
''' Reproduce the mouse actions.
''' </summary>
Public Shared Sub Play()
    Thread_MousePlay_Var = New Threading.Thread(AddressOf Thread_MousePlay)
    Thread_MousePlay_Var.IsBackground = True
    Thread_MousePlay_Var.Start()
End Sub

' Procedure used to store the mouse actions
Private Shared Sub Record_Timer_Tick(sender As Object, e As EventArgs) Handles Record_Timer.Tick

    Coordenates_List.Add(Control.MousePosition)

    If Not Last_ClickState_Left = GetAsyncKeyState(1) Then
        Last_ClickState_Left = GetAsyncKeyState(1)
        If GetAsyncKeyState(1) = 32768 Then
            Click_Count += 1
            Coordenates_List.Add(Nothing)
            Clicks_Dictionary.Add(Click_Count, MouseButton.Left_Down)
        ElseIf GetAsyncKeyState(1) = 0 Then
            Click_Count += 1
            Coordenates_List.Add(Nothing)
            Clicks_Dictionary.Add(Click_Count, MouseButton.Left_Up)
        End If
    End If

    If Not Last_ClickState_Right = GetAsyncKeyState(2) Then
        Last_ClickState_Right = GetAsyncKeyState(2)
        If GetAsyncKeyState(2) = 32768 Then
            Click_Count += 1
            Coordenates_List.Add(Nothing)
            Clicks_Dictionary.Add(Click_Count, MouseButton.Right_Down)
        ElseIf GetAsyncKeyState(2) = 0 Then
            Click_Count += 1
            Coordenates_List.Add(Nothing)
            Clicks_Dictionary.Add(Click_Count, MouseButton.Right_Up)
        End If
    End If

End Sub

' Procedure to play a mouse button (click)
Private Shared Sub Mouse_Click(ByVal MouseButton As MouseButton)
    Select Case MouseButton
        Case MouseButton.Left : Mouse_Event(MouseButton.Left_Down, 0, 0, 0, 0) : Mouse_Event(MouseButton.Left_Up, 0, 0, 0, 0)
        Case MouseButton.Right : Mouse_Event(MouseButton.Right_Down, 0, 0, 0, 0) : Mouse_Event(MouseButton.Right_Up, 0, 0, 0, 0)
        Case MouseButton.Middle : Mouse_Event(MouseButton.Middle_Down, 0, 0, 0, 0) : Mouse_Event(MouseButton.Middle_Up, 0, 0, 0, 0)
        Case Else : Mouse_Event(MouseButton, 0, 0, 0, 0)
    End Select
End Sub

' Thread used for reproduce the mouse actions
Private Shared Sub Thread_MousePlay()

    Click_Count = 0

    For Each Coordenate In Coordenates_List

        Threading.Thread.Sleep(Mouse_Speed)

        If Coordenate = Nothing Then
            Click_Count += 1
            If Click_Count > 1 Then Mouse_Click(Clicks_Dictionary.Item(Click_Count))
        Else
            Cursor.Position = Coordenate
        End If

        Application.DoEvents()

    Next

    Play_Is_Completed = True

End Sub

End Class

#End Region

【问题讨论】:

  • 在我看来,你让它变得比它需要的更复杂。您尝试记录的所有内容都已在 .net 中作为事件公开。所有按钮,单击,双击,滚轮。 MouseEventArgs 公开了所有需要的属性
  • @tinstaafl 感谢您的评论,但 MouseEventArgs 仅适用于表单内的事件,而不适用于表单外的事件,对吗?如果不是请纠正我,无论如何我无法想象如何使用mouseventargs来做到这一点,也许你可以用一个更好的方法来回答这个例子......无论如何,谢谢。
  • 好的。我在您的 OP 中没有看到任何内容,可以说您正在尝试在整个系统范围内执行此操作。这是一个article,可能会对您有所帮助
  • 这对我和 MSDN 中的任何代码示例来说似乎真的很难:(
  • 如果有人能提供帮助,这是我的新问题:stackoverflow.com/questions/16857370/setwindowshookex-for-wm-mousewheel

标签: .net vb.net mouse mouseevent mousewheel


【解决方案1】:

您可以使用 GetAsyncKeyState(4) 获得鼠标中键。但是使用这种方法你永远不会得到鼠标滚动消息,没有任何方法可以询问滚动按钮的位置。您必须依赖于告诉您鼠标已滚动的 Window 消息 WM_MOUSEWHEEL。

即使您自己的窗口没有焦点也需要进行录制,这需要一种完全不同的方法,您需要使用低级挂钩。 SetWindowsHookEx()设置的一个钩子,当鼠标事件发生时,它会调用你程序中的一个方法。

发布代码没有意义,互联网上有 很多 可用的示例。正确的 Google 查询是“vb.net setwindowshookex wh_mouse_ll”。 The first hit 已经很不错了,微软知识库文章几乎有你需要的一切。然而,它使用 SetWindowsHookEx() 的方式确实需要调整,如图所示,它只会为您自己的程序记录鼠标事件。相反,使用 LoadLibrary("user32.dll") 并将返回值作为第三个参数传递,第四个参数为 0 以使其记录每个鼠标事件。

【讨论】:

  • 谢谢,如果没有 VB 示例,如果该示例适用于 WM-MOUSEWHEEL,而我找到的所有示例都适用于 c#,但我无法翻译的东西,我真的无法做到这一点使用翻译器或我自己并使用 C# 指针,如果你不能发布代码,我想我会提出其他关于钩子的问题,再次感谢。
  • Microsoft 知识库文章适用于 VB.NET,只需复制/粘贴代码即可。我不想在这里复制它并在知识库文章更改时保持更新,这没有任何意义。甚至不确定这是否合法。如果这听起来像是一个无法解决的问题,那就把它放在架子上,直到你了解更多。
  • 可能是我的国家搜索条件的问题,但是当我在 google.com 和 google.es 中搜索“vb.net setwindowshookex wm_mouse_ll”时,结果的前三页中没有任何知识库文章,你可以张贴链接吗?我看到了一篇 MSDN 文章(不在 VB 中),但看到了任何 Microsoft KB 文章。
  • 我搞砸了一封信 :( 更新后的帖子包含指向知识库文章的链接。
  • 如果有人能提供帮助,这是我的新问题:stackoverflow.com/questions/16857370/setwindowshookex-for-wm-mousewheel
猜你喜欢
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多