我正在尝试模拟自定义游戏控制器应用程序的键盘命令。因为我需要在DirectInput环境中模拟命令,所以大多数常规方法都不起作用。我知道使用钩子可以100%地工作,但我正在尝试找到更容易实现的方法。
我已经进行了相当多的搜索,并发现使用SendInput API与Scancodes而不是虚拟键应该可以解决问题,但似乎会出现按键“粘滞”的情况。我已经发送了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());
}
}
我不确定这种方法是否行不通,或者是否只是有些愚蠢的地方我忽略了。如果不使用钩子(hooks)让代码变得过于复杂,我会很不情愿的,但这也是我不熟悉的领域。
非常感谢任何人能够给予的帮助。
谢谢!
INPUT[]
是什么?那应该来自于"user32.dll"
吗? - Taylor Lopez