Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# DirectInput SendInput Doesn't affect to game

I need some help about DirectInput, I'll tell what i am trying to do. I want to do my program sends key combinations to a game when i press only one key. Examp.: I'll press "r" and it will pres "1","3","2","4" keys. I found some codes from here. But they didn't worked exactly.

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

Here is my code and my question: When I'm using Send_Key_Hold only it presses one key in the game and other combination keys not pressed because first key is holded i think. When I'm using Send_Key_Hold and Send_Key_Release together it doesn't press any buttons on game. But on desktop (i mean anyother application not game) it presses the key.

like image 554
eyups Avatar asked Jun 25 '13 10:06

eyups


1 Answers

I've found this example on internet. Tested it on my own when I tried to do the same thing as you are trying now.

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

Now use SendKey(0x14) to send your T key to the active window (or game).

Note: You need KeyEventF.Scancode as your flag or the wScan property will be ignored!

like image 54
Measuring Avatar answered Sep 28 '22 00:09

Measuring