C# DirectInput SendInput对游戏没有影响

5

我需要关于DirectInput的帮助,我会告诉你我正在尝试做什么。我想让我的程序在我按下一个键时向游戏发送键盘组合键。例如:我将按下“r”,它将按下“1”、“3”、“2”、“4”键。我从这里找到了一些代码,但它们并没有完全起作用。

    public static void Send_Key_Hold(short Keycode)
    {
        INPUT[] InputData = new INPUT[1];
        InputData[0].type = 1;
        InputData[0].ki.wScan = Keycode;
        InputData[0].ki.dwFlags = (int)(KEYEVENTF_SCANCODE);

        SendInput(1, InputData, Marshal.SizeOf(InputData[0]));
    }
    public static void Send_Key_Release(short Keycode)
    {
        INPUT[] InputData = new INPUT[1];
        InputData[0].type = 1;
        InputData[0].ki.wScan = Keycode;
        InputData[0].ki.dwFlags = (int)(KEYEVENTF_KEYUP | KEYEVENTF_SCANCODE);

        SendInput(1, InputData, Marshal.SizeOf(InputData[0]));
    }

这是我的代码和问题:当我仅使用Send_Key_Hold时,游戏中只按下一个键,其他组合键未被按下,因为第一个键被按住了。当我同时使用Send_Key_Hold和Send_Key_Release时,它不会在游戏中按下任何按钮。但在桌面上(我指的是其他应用程序而非游戏),它会按下该键。

1个回答

5

我在网上找到了这个例子。当我尝试做和你现在试图做的事情时,我也对它进行了测试。

[Flags]
private enum InputType
{
    Mouse = 0,
    Keyboard = 1,
    Hardware = 2
}

[Flags]
private enum KeyEventF
{
    KeyDown = 0x0000,
    ExtendedKey = 0x0001,
    KeyUp = 0x0002,
    Unicode = 0x0004,
    Scancode = 0x0008,
}

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

[DllImport("user32.dll")]
private static extern IntPtr GetMessageExtraInfo();

public static void SendKey(ushort key)
{
    Input[] inputs =
    {
        new Input
        {
            type = (int) InputType.Keyboard,
            u = new InputUnion
            {
                ki = new KeyboardInput
                {
                    wVk = 0,
                    wScan = key,
                    dwFlags = (uint) (KeyEventF.KeyDown | KeyEventF.Scancode),
                    dwExtraInfo = GetMessageExtraInfo()
                }
            }
        }
    };

    SendInput((uint) inputs.Length, inputs, Marshal.SizeOf(typeof (Input)));
}

private struct Input
{
    public int type;
    public InputUnion u;
}

[StructLayout(LayoutKind.Explicit)]
private struct InputUnion
{
    [FieldOffset(0)] public readonly MouseInput mi;
    [FieldOffset(0)] public KeyboardInput ki;
    [FieldOffset(0)] public readonly HardwareInput hi;
}

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

[StructLayout(LayoutKind.Sequential)]
private struct KeyboardInput
{
    public ushort wVk;
    public ushort wScan;
    public uint dwFlags;
    public readonly uint time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
private struct HardwareInput
{
    public readonly uint uMsg;
    public readonly ushort wParamL;
    public readonly ushort wParamH;
}

现在使用SendKey(0x14)将您的T键发送到活动窗口(或游戏)。 注意:你需要使用KeyEventF.Scancode作为标志,否则wScan属性将被忽略!

神奇的标志“Scancode”起了作用,在C++中该标志为“KEYEVENTF_SCANCODE”。 - razz
你能在回答中加入所需的using/open子句和引用吗?我似乎找不到Type INPUT - Maslow
@Maslow 抱歉回复晚了。我已经从http://www.pinvoke.net/default.aspx/Structures/INPUT.html添加了它。 - Measurity
我们需要哪些参考资料? - DreTaX
@DreTaX 看看这个答案,了解你需要定义的类型:https://dev59.com/Tl_Va4cB1Zd3GeqPUY-X 你还需要这两个 using:using System; using System.Runtime.InteropServices; - Measurity

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