除非我移动光标,否则SendInput不会执行鼠标单击按钮

除非我移动光标,否则SendInput不会执行鼠标单击按钮。

我很感激对这一个的帮助,因为我似乎无法绕过它。

我有一个程序,在前景窗口上执行鼠标单击,我在其中使用SendInput模拟鼠标左键单击。 问题是,如果我将光标移动到点击位置而不是SendInput将进行点击,但是如果我不移动光标而不是没有点击发生,即使通过我传递x和y指向MouseInputData。 我想执行鼠标左键而不需要实际移动光标。

贝娄是我的课程(相当简单和直接前进)

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(pX, pY); } } } 

如果我删除这样的光标位置,则不会单击相同的ClickLeftMouseButton函数。

  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())); } 

先感谢您。

使用SendInput函数时,您应该考虑一些事项。

如果未指定MOUSEEVENTF_ABSOLUTE标志,则dxdy (MouseInputData结构)是当前鼠标位置的相对坐标。 如果确实指定了MOUSEEVENTF_ABSOLUTEdxdy是0到65535之间的绝对坐标。因此,如果x和y坐标是屏幕坐标,则应使用以下函数计算dxdy

 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); } 

此外,在通过SendInput发送MOUSEDOWN和MOUSEUP事件之前,您必须将鼠标移动到要单击的控件:

 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())); } 

上面的代码假设xy是屏幕像素坐标。 您可以使用以下代码计算winform上按钮(目标)的坐标:

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

希望这可以帮助。