I\'m making a simple WinForm car race game. I\'ve got two objects - cars, and they move on the form when key is pressed (Form1KeyDown_Event).
The only thing is, that wh
You might want to investigate going lower-level and using windows hooks to detect keyboard events. This requires P/Invoking into native methods, but is pretty straight-forward. The hook you'd want is WH_LL_KEYBOARD. Details can be found at pinvoke.net.
You'd need a bit of boilerplate, but it's as close to the keyboard events as you can reasonably expect to get:
[StructLayout(LayoutKind.Sequential)]
public struct KBDLLHOOKSTRUCT
{
public uint vkCode;
public uint scanCode;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
public delegate IntPtr LowLevelKeyboardProc(int, IntPtr, KBDLLHOOKSTRUCT);
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idhook, LowLevelKeyboardProc proc, IntPtr hMod, uint threadId);
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
public static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (var curProc = Process.GetCurrentProcess())
using (var curMod = curProc.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curMod.ModuleName), 0u);
}
}
public IntPtr MyKeyboardHook(int code, IntPtr wParam, ref KBDLLHOOKSTRUCT keyboardInfo)
{
if (code < 0)
{
return CallNextHookEx(IntPtr.Zero, wParam, ref keyboardInfo);
}
// Do your thing with the keyboard info.
return CallNextHookEx(IntPtr.Zero, code, wParam, ref keyboardInfo);
}
Make sure to unhook your handler when your app stops needing it. The KBDLLHOOKSTRUCT encapsulates all the info Windows will give you about a keyboard event; details of its members can be found at MSDN.
One detail of this kind of hook is that it gets executed on the thread that registered it, so make sure you take note of that, and don't set it on the UI thread if it's going to do anything long-running.