如何在winform和wpf中通过编程实现鼠标移动、点击、右键点击和按键等操作?

17

如何在WinForm和WPF中以编程的方式模拟鼠标移动、单击、右键单击、按键等操作。如果可能,请提供代码片段。


1
相关但不是完全重复的内容:在WPF应用程序中注入鼠标输入 - ChrisW
为什么?使用辅助功能可能更容易实现你想要的功能。 - Roger Lipscombe
1个回答

31
如果我正确理解了你的问题,那么你想要真正模拟输入。在这种情况下,使用SendInput是正确的方法。从这个链接中可以看到:

PInvoke到SendInput - 这是模拟输入的官方方式。它通过所有预期的代码路径推送输入,并且与真实输入无法区分。

一个简单的方法是使用CodePlex上的InputSimulator。通过添加对InputSimulator.dll的引用,可以模拟按键操作,例如:
// Tab
InputSimulator.SimulateKeyDown(VirtualKeyCode.TAB);
// Shift+Tab
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, VirtualKeyCode.TAB);   
// etc.

然而,InputSimulator目前不支持鼠标,但是这里有一个MouseSimulator的入门级代码。目前它只支持LeftClickRightClick,但借助以下两个链接的帮助,您可以轻松扩展它以支持MouseMove等功能。 MouseSimulator
public class MouseSimulator
{
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

    [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()
    {
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));

        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    }
    public static void ClickRightMouseButton()
    {
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));

        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接