Click here to Skip to main content
15,891,704 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello community,

I want to send a Key (in this case 'T') to a game.
This game (Battlefield 3) gets it's Keyinformation from DirectInput.

So I need additional classes/ sources for DirectX.

I took SlimDX, XNA is aviable as well but I only tested SlimDX.


In the internet people wrote, it would work with DirectX Keycodes (when use with SendInput). Unfortuanly, this wont work.

The Virtualkey for T is 0x54
In DirectX case, it's 0x14

So when I'm ingame, and I start my program, my Capslock is active.


I don't get it. :s
The World Wide Web didn't help me out (half aviable code or not working code).


Maybe someone can help me?
Would be awesome!


Thanks in advance.
Posted

Alright, somehow I managed to get this working.

Because I think I am not the only one had problems with this topic I gotta answer my own question.


First thing we have to do is to import the "user32.dll" because .NET doesn't support DirectInput (atleast that's what I understood, correct me if not).

So we do..

C#
using System.Runtime.InteropServices;   //Needed to import your .dll



After that line we can import our dll..
C#
[DllImport("user32.dll")]
        static extern UInt32 SendInput(UInt32 nInputs,     [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);



Now we need to declare some variables to get out program working.
Because we want to emulate a Key, we only need to use the following code:
C#
[StructLayout(LayoutKind.Sequential)]
        struct KEYBDINPUT
        {
            public short wVk;      //Virtual KeyCode (not needed here)
            public short wScan;    //Directx Keycode 
            public int dwFlags;    //This tells you what is use (Keyup, Keydown..)
            public int time;       
            public IntPtr dwExtraInfo;
        }



Now we need to declare the 'INPUT' variable..
C#
[StructLayout(LayoutKind.Explicit)]
       struct INPUT
       {
           [FieldOffset(0)]
           public int type;
           [FieldOffset(4)]
           public KEYBDINPUT ki;
       }



After we initialised our variables we can send some Keys to DirectX Games.
C#
public void Send_Key(short Keycode, int KeyUporDown)
      {
          INPUT[] InputData = new INPUT[1];

          InputData[0].type = 1;                 
          InputData[0].ki.wScan = Keycode;       
          InputData[0].ki.dwFlags = KeyUporDown;  
          InputData[0].ki.time = 0;
          InputData[0].ki.dwExtraInfo = IntPtr.Zero;

          SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT)));
      }


InputData[0].ki.wScan => Means out Keycode we like to send.
If we want to send the Key T, we have to type in 0x14.
0x14 means T in DirectX. Lists with KeyCodes are easy findable in the net.

InputData[0].ki.dwFlags => Means our Flag, we could type 0x0008 (for Sendkey)
or create a constant variable. What you prefer.



Our final code could look like the following class:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

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

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

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

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

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

        const int KEYEVENTF_EXTENDEDKEY = 0x0001;
        const int KEYEVENTF_KEYUP = 0x0002;
        const int KEYEVENTF_UNICODE = 0x0004;
        const int KEYEVENTF_SCANCODE = 0x0008;


        public void Send_Key(short Keycode, int KeyUporDown)
        {
            INPUT[] InputData = new INPUT[1];

            InputData[0].type = 1;
            InputData[0].ki.wScan = Keycode;
            InputData[0].ki.dwFlags = KeyUporDown;
            InputData[0].ki.time = 0;
            InputData[0].ki.dwExtraInfo = IntPtr.Zero;

            SendInput(1, InputData, Marshal.SizeOf(typeof(INPUT)));
        }

    }
}
 
Share this answer
 
v2
Comments
metehan_1 5-Nov-12 15:58pm    
i have error "cant found INPUT" __???
yazimi2 7-Nov-12 18:32pm    
hi.. nice work!
by the way, i am doing similar program related to your problem.
but i can't send the key into the games. i'm using the your code for my program. am I missing something?
MadeByVince 17-Feb-18 10:54am    
Hey guys, this is a very old post so I hope someone will still be able to help me...

I have tried this solution and it works really well, thank you so much for this.
Where I have a problem is that I'm trying to also send key combination like CTRL+J for example and I can't find how to make it work based on what I have here (I'm really a newbie in C#).
Is there anyone who knows and can help me?
Thanks a lot.
Can you supply a usage example, 10x!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900