jueves, 30 de mayo de 2013

"Mouse Recorder" desde .NET

Una manera eficiente de capturar el recorrido de un mouse para luego implementarlo al estilo"Robot" ésta colaboración es de ElecKtro H@cker;

Captura/Guarda cada coordenada en una lista de punteros.
Captura/Guarda cada click en un tipo de diccionario.
Luego, reproduce el contenido de la lista y del diccionario.

Aquí el code para .NET 2012 

Public Class Form1

    ' BY ELEKTRO H@CKER
    ' Copia este Form en un nuevo proyecto y ejecútalo.

    Dim Coordenates_List As New List(Of Point)
    Dim Clicks_Dictionary As New Dictionary(Of Int64, MouseButton)

    Dim Click_Count As Int32 = 0
    Dim Last_ClickState_Left As Int64 = 999
    Dim Last_ClickState_Right As Int64 = 999

    Dim WithEvents Record_Timer As New Timer

    Dim WithEvents Button_Record As New Button, Button_Stop As New Button, Button_Reproduce As New Button

    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer

    Public 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)

    Public Thread_is_completed As Boolean = False

    Dim Thread_MousePlay_Var As System.Threading.Thread = New Threading.Thread(AddressOf Thread_MousePlay)

    Public 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

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Record_Timer.Interval = 15
        Button_Record.Text = "Record" : Button_Stop.Text = "Stop" : Button_Reproduce.Text = "Reproduce"
        Button_Record.Location = New Point(20, 20) : Button_Stop.Location = New Point(Button_Record.Right + 10, 20) : Button_Reproduce.Location = New Point(Button_Stop.Right + 10, 20)
        Me.Controls.Add(Button_Record) : Me.Controls.Add(Button_Stop) : Me.Controls.Add(Button_Reproduce)
        Me.Size = New Point(300, 100)
    End Sub

    Private Sub Button_Record_Click(sender As Object, e As EventArgs) Handles Button_Record.Click
        Coordenates_List.Clear() : Clicks_Dictionary.Clear() : Click_Count = 0
        Record_Timer.Start()
    End Sub

    Private Sub Button_Stop_Click(sender As Object, e As EventArgs) Handles Button_Stop.Click
        Record_Timer.Stop()
    End Sub

    Private Sub Button_Reproduce_Click(sender As Object, e As EventArgs) Handles Button_Reproduce.Click

        Thread_MousePlay_Var = New Threading.Thread(AddressOf Thread_MousePlay)
        Thread_MousePlay_Var.IsBackground = True
        Thread_MousePlay_Var.Start()

        Thread_is_completed = False
        While Not Thread_is_completed = True : Application.DoEvents() : End While
        MsgBox("Finished")

    End Sub

    Private Sub Record_Timer_Tick(sender As Object, e As EventArgs) Handles Record_Timer.Tick

        Coordenates_List.Add(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

    Private 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

    Sub Thread_MousePlay()

        Click_Count = 0

        For Each Coordenate In Coordenates_List
            Application.DoEvents()
            Threading.Thread.Sleep(15)

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

        Next

        Thread_is_completed = True

    End Sub

End Class
Hay otras formas de realizarlo pero a mi criterio esta es mas eficiente que las otras que vi.

Saludos.

No hay comentarios:

Publicar un comentario