【问题标题】:How to programatically simulate a button press?如何以编程方式模拟按钮按下?
【发布时间】:2016-02-11 04:54:08
【问题描述】:

如何在 .NET 中模拟按钮按下?

我可以使用 AutoHotKey 轻松做到这一点:

#Persistent
SetTimer,PressTheKey,1000
Return

PressTheKey:
Send, {F5}
Return

任何应用程序都会知道该按钮被按下(就像我按下它一样)。我试着做同样的事情:

[DllImport("user32.dll", SetLastError = true)]
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

或:

[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

或使用 Windows 输入模拟器 (https://inputsimulator.codeplex.com/):

inputSimulator.Keyboard.KeyDown(VirtualKeyCode.VK_H)

它们都在记事本或其他一些应用程序中工作,但它们从未在我的全屏游戏中工作。知道如何实现吗?我想要一个在系统级别上模拟全局点击的解决方案。

【问题讨论】:

标签: c# .net


【解决方案1】:

那里有一个名为 Interceptor 的库,它是 Windows 键盘驱动程序的包装器,但是有一些限制 - 即不支持 win8 或更高版本 - 似乎它的工作已经停止(现在是 11 个月前)。看看它是否适合您的需求。

我在某处读到有一些方法可以通过DirectInput API 执行此操作 - 至于是否是这种情况,我不确定。我已经使用了几次Interceptor,它当时满足了我的需求。

希望对你有帮助

还有 Link

编辑:固定链接

【讨论】:

  • 谢谢加布!您对 DirectInput 的建议将我推向了正确的方向 :-)
  • @MichalB。没问题 - 老实说,这是一次盲目的刺伤。很高兴我的运气帮助了你哈哈
【解决方案2】:

我了解到我的应用程序正在使用 DirectInput(感谢 Gabe)。这让我更加专注于 SendInput,我设法向我的应用程序发送了一个“A”键,如下所示:

// A = 30
keyboardDirectInput.Press(30);

所有的关键代码都在这里:https://msdn.microsoft.com/en-us/library/windows/desktop/bb321074%28v=vs.85%29.aspx

KeyboardDirectInput 类:

public class KeyboardDirectInput
{
    [DllImport("user32.dll")]
    static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);

    public void Press(VirtualKeys key)
    {
        INPUT[] InputData = new INPUT[2];

        InputData[0].type = (int)InputType.INPUT_KEYBOARD;
        InputData[0].ki.wScan = (short)key;
        InputData[0].ki.dwFlags = (int)KEYEVENTF.SCANCODE;

        InputData[1].type = (int)InputType.INPUT_KEYBOARD;
        InputData[1].ki.wScan = (short)key;
        InputData[1].ki.dwFlags = (int)(KEYEVENTF.KEYUP | KEYEVENTF.SCANCODE);

        if (SendInput(2, InputData, Marshal.SizeOf(InputData[1])) == 0)
        {
            Logger.GetInstance().Warn("SendInput failed (CODE {0})", Marshal.GetLastWin32Error());
        }
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct INPUT
    {
        [FieldOffset(4)]
        public HARDWAREINPUT hi;
        [FieldOffset(4)]
        public KEYBDINPUT ki;
        [FieldOffset(4)]
        public MOUSEINPUT mi;
        [FieldOffset(0)]
        public int type;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct HARDWAREINPUT
    {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSEINPUT
    {
        public int dx;
        public int dy;
        public int mouseData;
        public int dwFlags;
        public int time;
        public IntPtr dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct KEYBDINPUT
    {
        public short wVk;
        public short wScan;
        public int dwFlags;
        public int time;
        public IntPtr dwExtraInfo;
    }

    [Flags]
    public enum KEYEVENTF
    {
        KEYDOWN = 0,
        EXTENDEDKEY = 0x0001,
        KEYUP = 0x0002,
        UNICODE = 0x0004,
        SCANCODE = 0x0008,
    }

    [Flags]
    public enum InputType
    {
        INPUT_MOUSE = 0,
        INPUT_KEYBOARD = 1,
        INPUT_HARDWARE = 2
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2012-05-27
    相关资源
    最近更新 更多