我正在尝试为自定义游戏控制器应用程序模拟键盘命令。因为我需要在 DirectInput 环境中模拟命令,所以大多数常用方法都不起作用。我知道使用钩子可以 100% 工作,但我正试图找到一个更简单的实现。
我做了很多搜索,发现通过使用带有 Scancodes 而不是虚拟键的 SendInput API 应该可以工作,但它的行为似乎就像键是“粘着”的。我已经发送了 KEYDOWN 和 KEYUP 事件,但是当我尝试在 DirectInput 环境中发送消息时,游戏就像按键被按住一样。
例如,如果我模拟“W”键按下并将该键映射到第一人称射击游戏中的“向前移动”动作,一旦我进入游戏,下面的函数将导致角色向前移动。然而,只要发出一次命令,它就会无限期地向前移动角色。
这是我正在调用的 SendInput 函数的代码片段(在 C# 中):
[DllImport("user32.dll")]
static extern UInt32 SendInput(UInt32 nInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, Int32 cbSize);
public static void Test_KeyDown()
{
INPUT[] InputData = new INPUT[2];
Key ScanCode = Microsoft.DirectX.DirectInput.Key.W;
InputData[0].type = 1; //INPUT_KEYBOARD
InputData[0].wScan = (ushort)ScanCode;
InputData[0].dwFlags = (uint)SendInputFlags.KEYEVENTF_SCANCODE;
InputData[1].type = 1; //INPUT_KEYBOARD
InputData[1].wScan = (ushort)ScanCode;
InputData[1].dwFlags = (uint)(SendInputFlags.KEYEVENTF_KEYUP | SendInputFlags.KEYEVENTF_UNICODE);
// send keydown
if (SendInput(2, InputData, Marshal.SizeOf(InputData[1])) == 0)
{
System.Diagnostics.Debug.WriteLine("SendInput failed with code: " +
Marshal.GetLastWin32Error().ToString());
}
}
我不确定这种方法是否是一个失败的原因,或者我是否只是缺少一些愚蠢的东西。如果我不必使用钩子,我讨厌过度复杂化我的代码,但这对我来说也是一个新领域。
任何人都可以提供任何帮助,我们将不胜感激。
谢谢!