Reputation: 1567
I can send any windows application key strokes with PostMessage
api. But I can't send key strokes to Game window by using PostMessage
.
Anyone know anything about using Direct Input functions for sending keys to games from C#.
Upvotes: 10
Views: 29597
Reputation: 456
Worked for a friends Game (Nostale) without probems:
Also here a usefull list of Virtual Key Codes
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private void button1_Click(object sender, EventArgs e)
{
const int WM_SYSKEYDOWN = 0x0104;
const int VK_SPACE = 0x20;
IntPtr WindowToFind = FindWindow(null, "WINDOW NAME");
PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_SPACE, 0);
}
Upvotes: 0
Reputation: 6926
One alternative, instead of hooking into DirectX, is to use a keyboard driver (this is not SendInput()) to simulate key presses - and event mouse presses.
You can use Oblita's Interception keyboard driver (for Windows 2000 - Windows 7) and the C# library Interception (wraps the keyboard driver to be used in C#).
With it, you can do cool stuff like:
input.MoveMouseTo(5, 5);
input.MoveMouseBy(25, 25);
input.SendLeftClick();
input.KeyDelay = 1; // See below for explanation; not necessary in non-game apps
input.SendKeys(Keys.Enter); // Presses the ENTER key down and then up (this constitutes a key press)
// Or you can do the same thing above using these two lines of code
input.SendKeys(Keys.Enter, KeyState.Down);
Thread.Sleep(1); // For use in games, be sure to sleep the thread so the game can capture all events. A lagging game cannot process input quickly, and you so you may have to adjust this to as much as 40 millisecond delay. Outside of a game, a delay of even 0 milliseconds can work (instant key presses).
input.SendKeys(Keys.Enter, KeyState.Up);
input.SendText("hello, I am typing!");
/* All these following characters / numbers / symbols work */
input.SendText("abcdefghijklmnopqrstuvwxyz");
input.SendText("1234567890");
input.SendText("!@#$%^&*()");
input.SendText("[]\\;',./");
input.SendText("{}|:\"<>?");
Because the mechanism behind these key presses is a keyboard driver, it's pretty much unrestricted.
Upvotes: 8
Reputation: 4676
You can use the unmanaged SendInput function for this. It posts the input on a level lower then DirectInput. It is very important to know what keycodes to send. These can vary between games. If Windows Virtual keycodes don't work for a game, you can try sending DIKEYBOARD constants (like DIKEYBOARD_A etc.) and if it still doesn't work keep trying. Half Life or Counter Strike, for instance, expect ASCII codes as keycodes (it took me a while to figure this out)
Upvotes: 0
Reputation: 396
An alternate way would be to hook the DirectInput API directly - Microsoft Research has provided a library to do this already: http://research.microsoft.com/en-us/projects/detours/
Once you hook into the API, you can do whatever you want with it. However, it's worth noting that in recent versions of Windows, DirectInput for mouse & keyboard input is just a wrapper around the Win32 windows messages. DirectInput spawns a thread in the background and simply intercepts window messages before passing them along back to the application. It's one of the reasons why Microsoft no longer recommends the use of DirectInput - and it means that messaging APIs like PostMessage should work just fine.
Upvotes: 7
Reputation: 86353
There is now way to do this via the DirectInput API.
The only way to archive the same effect would be to write your own DirectInput COM object which just wraps the normal DirectInput object. Afterwards you can add code to simulate keystrokes. The trick is to replace the Win32 dinput.dll with your version. All games will then load your DLL on startup.
I'm afraid that you can't do that from a managed language though. You have to do this with native code as it requirs quite a bit of low level hackery.
Upvotes: 1