VB.NET mouse_event move error en destino

Iniciado por kuhi, 20 Mayo 2018, 07:08 AM

0 Miembros y 1 Visitante están viendo este tema.

kuhi

Tengo el siguiente problema con mouse_event move:
El mouse se mueve a la esquina de abajo a la derecha de la pantalla en vez de a sus coordenadas correctas.

Declaraciones:
Private Declare Function apimouse_event Lib "user32.dll" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dX As Int32, ByVal dY As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As IntPtr) As Boolean

<DllImport("user32.dll")>
Private Shared Sub mouse_event(dwFlags As UInteger, dx As UInteger, dy As UInteger, dwData As UInteger, dwExtraInfo As Integer)
End Sub


Pruebas:
Private Sub Button1_Click_4(sender As Object, e As EventArgs) Handles Button1.Click
    mouse_event(MouseEventFlags.MOUSEEVENTF_MOVE, Convert.ToUInt32(txtx3.Text), Convert.ToUInt32(txtx4.Text), 0, 0)
End Sub

Private Sub savex_Click(sender As Object, e As EventArgs) Handles savex.Click
    txtx3.Text = x1.Text
    txtx4.Text = x2.Text
End Sub

Private Sub NativeMethods_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    x1.Text = MousePosition.X.ToString
    x2.Text = MousePosition.Y.ToString
End Sub


Alguna idea? Saludos y gracias!
El conocimiento no ocupa lugar, somos libres de saber cuánto queramos...

Eleкtro

#1
Vamos por partes...

Primeramente, el flag MOUSEEVENTF_MOVE lo que hace es mover la posición del mouse relativamente desde su posición actual, dicho de otro modo, lo que estás haciendo es deslizar la posición actual mediante los offsets que le especifiques al parámetro dX y dY... por eso se te va a la esquina inferior derecha, no estás usando coordenadas absolutas.

Para realizar un movimiento absoluto debes especificar el flag MOUSEEVENTF_ABSOLUTE, pero para poder usar la función de esa manera primero debes convertir las coordenadas absolutas como indica la documentación:

Cita de: MSDNIf MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface, (65535,65535) maps onto the lower-right corner.

Ejemplo:

Código (vbnet) [Seleccionar]

<Flags>
Public Enum MouseEventFlags As UInteger
   Absolute = &H8000UI
   LeftDown = &H2UI
   LeftUp = &H4UI
   MiddleDown = &H20UI
   MiddleUp = &H40UI
   Move = &H1UI
   RightDown = &H8UI
   RightUp = &H10UI
   XDown = &H80UI
   XUp = &H100UI
   Wheel = &H800UI
   HWheel = &H1000UI
End Enum


Código (vbnet) [Seleccionar]
Friend NotInheritable Class NativeMethods

   <Obsolete>
   <SuppressUnmanagedCodeSecurity>
   <DllImport("User32.dll", EntryPoint:="mouse_event")>
   Friend Shared Sub MouseEvent(
  <MarshalAs(UnmanagedType.U4)> ByVal flags As MouseEventFlags,
                                ByVal x As UInteger,
                                ByVal y As UInteger,
                                ByVal data As UInteger,
                                ByVal extraInfo As UIntPtr)
   End Sub

End Class


Código (vbnet) [Seleccionar]
Dim pt As New Point(100, 100) ' Absolute position.

' Dim currentPosition As NativePoint
' NativeMethods.GetCursorPos(currentPosition)
' Dim scr As Screen = System.Windows.Forms.Screen.FromPoint(currentPosition)
Dim scr = System.Windows.Forms.Screen.PrimaryScreen

pt.X = ((pt.X * 65535) \ scr.Bounds.Width) + 1
pt.Y = ((pt.Y * 65535) \ scr.Bounds.Height) + 1

NativeMethods.MouseEvent(MouseEventFlags.Absolute Or MouseEventFlags.Move, pt.X, pt.Y, 0, UIntPtr.Zero)





Segundo, la función mouse_event lleva siglos marcada como obsoleta tras la aparición de la función SendInput, que es la que deberías usar para todo lo que concierna a la simulación de eventos del teclado y el mouse...

Un ejemplo de uso de SendInput para mover el mouse de forma absoluta, ya asumiendo que tengas todas las estructuras y miembros necesarios declarados en tu código (no voy a mostrar la implementación en .NET puesto que ocupa demasiado espacio para el post):

Código (vbnet) [Seleccionar]
Dim inputList As New List(Of Input)
Dim currentInput As New Input()

Dim pt As New Point(100, 100) ' Absolute position.
' Dim currentPosition As NativePoint
' NativeMethods.GetCursorPos(currentPosition)
' Dim scr As Screen = System.Windows.Forms.Screen.FromPoint(currentPosition)
Dim scr = System.Windows.Forms.Screen.PrimaryScreen

pt.X = ((pt.X * 65535) \ scr.Bounds.Width) + 1
pt.Y = ((pt.Y * 65535) \ scr.Bounds.Height) + 1

With currentInput
   .Type = InputType.Mouse
   .InputInfo.MouseInput.X = pt.X
   .InputInfo.MouseInput.Y = pt.Y
   .InputInfo.MouseInput.Flags = (MouseInputFlags.Absolute Or MouseInputFlags.Move)
   .InputInfo.MouseInput.Time = 0
End With
inputList.Add(currentInput)

Dim count As Integer = NativeMethods.SendInput(inputList.Count, inputList.ToArray(), Marshal.SizeOf(GetType(Input)))





Tercero y último, si tu único propósito es mover el mouse a unas coordenadas relativas o absolutas entonces te estás complicando la vida excesivamente, cuando simplemente puedes usar la función nativa SetCursorPos y de este modo evitar el tener que realizar tediosas transformaciones de coordenadas...

Código (vbnet) [Seleccionar]
<SuppressUnmanagedCodeSecurity>
<DllImport("User32.dll", SetLastError:=True)>
Public Shared Function SetCursorPos(ByVal x As Integer,
                                   ByVal y As Integer
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function


Pero mucho mejor incluso es sin duda alguna usar diréctamente la propiedad System.Windows.Forms.Cursor.Position, y así evitar el uso de código no administrado por tu parte...
Código (vbnet) [Seleccionar]
Cursor.Position = New Point(100, 100) ' Absolute position.

...puesto que no hay necesidad de hacer lo que estás haciendo, del modo en que lo esás intentando hacer para el fin que quieres conseguir, no en .NET. Deberías usar los miembros que el framework ya expone para manipular la posición del mouse. Para eso están ahí.

Saludos.








**Aincrad**

Solo es cuestión de Buscar :

Manual Como hacer para mover el mouse y hacer click en vb

Bueno hay tienes un Buen ejemplo para mover el puntero del mause.

Bueno no es un código tan bueno como el que te dejo el compañero @Elecktro;D