form evento event down doble derecho c# winforms winapi mouse mouseevent

evento - mousedown c#



SendInput no realiza clic en el botón del mouse a menos que mueva el cursor (1)

Hay algunas cosas que debe considerar al usar la función SendInput .

Si no especifica el indicador MOUSEEVENTF_ABSOLUTE , entonces dx y dy (estructura MouseInputData) son coordenadas relativas a la posición actual del mouse. Si especifica MOUSEEVENTF_ABSOLUTE , dx y dy son coordenadas absolutas entre 0 y 65535. Por lo tanto, si las coordenadas xey son coordenadas de pantalla, debe usar la siguiente función para calcular dx y dy :

enum SystemMetric { SM_CXSCREEN = 0, SM_CYSCREEN = 1, } [DllImport("user32.dll")] static extern int GetSystemMetrics(SystemMetric smIndex); int CalculateAbsoluteCoordinateX(int x) { return (x * 65536) / GetSystemMetrics(SystemMetric.SM_CXSCREEN); } int CalculateAbsoluteCoordinateY(int y) { return (y * 65536) / GetSystemMetrics(SystemMetric.SM_CYSCREEN); }

Además, antes de enviar los eventos MOUSEDOWN y MOUSEUP a través de SendInput, debe mover el mouse al control en el que desea hacer clic:

public static void ClickLeftMouseButton(int x, int y) { INPUT mouseInput = new INPUT(); mouseInput.type = SendInputEventType.InputMouse; mouseInput.mkhi.mi.dx = CalculateAbsoluteCoordinateX(x); mouseInput.mkhi.mi.dy = CalculateAbsoluteCoordinateY(y); mouseInput.mkhi.mi.mouseData = 0; mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE |MouseEventFlags.MOUSEEVENTF_ABSOLUTE; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); }

El código anterior asume que y son las coordenadas del píxel de la pantalla. Puede calcular esas coordenadas para un botón (el objetivo) en un winform usando el siguiente código:

Point screenCoordsCentre= button1.PointToScreen(new Point(button1.Width/2, button1.Height/2));

Espero que esto ayude.

SendInput no realiza clic en el botón del mouse a menos que mueva el cursor.

Agradecería una ayuda en este caso, ya que parece que no puedo entenderlo.

Tengo un programa que hace clic con el mouse en la ventana de primer plano, en la que estoy usando SendInput para emular el clic izquierdo del mouse. El problema es que si muevo el cursor para hacer clic en la posición que SendInput hará clic, sin embargo, si no muevo el cursor, no ocurre ningún clic, incluso paso a través de los puntos xey hacia MouseInputData. Me gustaría hacer clic con el botón izquierdo del mouse sin la necesidad de mover realmente el cursor.

Bellow es la clase que tengo (es bastante simple y directa)

namespace StackSolution.Classes { public static class SendInputClass { [DllImport("user32.dll", SetLastError = true)] static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); [DllImport("user32.dll")] static extern bool SetCursorPos(int X, int Y); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GetCursorPos(out Point lpPoint); [StructLayout(LayoutKind.Sequential)] struct INPUT { public SendInputEventType type; public MouseKeybdhardwareInputUnion mkhi; } [StructLayout(LayoutKind.Explicit)] struct MouseKeybdhardwareInputUnion { [FieldOffset(0)] public MouseInputData mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] struct HARDWAREINPUT { public int uMsg; public short wParamL; public short wParamH; } struct MouseInputData { public int dx; public int dy; public uint mouseData; public MouseEventFlags dwFlags; public uint time; public IntPtr dwExtraInfo; } [Flags] enum MouseEventFlags : uint { MOUSEEVENTF_MOVE = 0x0001, MOUSEEVENTF_LEFTDOWN = 0x0002, MOUSEEVENTF_LEFTUP = 0x0004, MOUSEEVENTF_RIGHTDOWN = 0x0008, MOUSEEVENTF_RIGHTUP = 0x0010, MOUSEEVENTF_MIDDLEDOWN = 0x0020, MOUSEEVENTF_MIDDLEUP = 0x0040, MOUSEEVENTF_XDOWN = 0x0080, MOUSEEVENTF_XUP = 0x0100, MOUSEEVENTF_WHEEL = 0x0800, MOUSEEVENTF_VIRTUALDESK = 0x4000, MOUSEEVENTF_ABSOLUTE = 0x8000 } enum SendInputEventType : int { InputMouse, InputKeyboard, InputHardware } public static void ClickLeftMouseButton(int x, int y) { INPUT mouseInput = new INPUT(); mouseInput.type = SendInputEventType.InputMouse; mouseInput.mkhi.mi.dx = x; mouseInput.mkhi.mi.dy = y; mouseInput.mkhi.mi.mouseData = 0; //getting current cursor location Point p; if (GetCursorPos(out p)) SetCursorPos(x, y); mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); //returning cursor to previous position SetCursorPos(p.X, p.Y); } } }

La misma función ClickLeftMouseButton no hará clic si elimino la posición del cursor de esa manera.

public static void ClickLeftMouseButton(int x, int y) { INPUT mouseInput = new INPUT(); mouseInput.type = SendInputEventType.InputMouse; mouseInput.mkhi.mi.dx = x; mouseInput.mkhi.mi.dy = y; mouseInput.mkhi.mi.mouseData = 0; mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); }

Gracias de antemano.