カスタムゲームコントローラーアプリケーションのキーボードコマンドをシミュレートしようとしています。DirectInput環境でコマンドをシミュレートする必要があるため、通常のメソッドのほとんどは機能しません。フックを使用すると100%動作することはわかっていますが、もっと簡単な実装を見つけようとしています。
かなりの検索を行ったところ、仮想キーの代わりにスキャンコードでSendInput APIを使用することで機能するはずですが、キーが「固定」されているように動作するようです。KEYDOWNイベントとKEYUPイベントの両方を送信しましたが、DirectInput環境でメッセージを送信しようとすると、ゲームはキーが押されているかのように動作します。
たとえば、「W」キーの押下をシミュレートし、そのキーをファーストパーソンシューティングゲームで「前進」アクションにマッピングすると、ゲームに参加すると、以下の機能によってキャラクターが前進します。ただし、コマンドを1回発行するだけで、キャラクターが無期限に前進します。
これが、私が呼び出している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());
}
}
この方法が失われた原因なのか、それとも何か馬鹿げたものがあるのか、私にはわかりません。フックを使用する必要がない場合は、コードを過度に複雑にするのは嫌いですが、これは私にとっても新しい領域です。
誰もが与えることができるどんな助けも大いに感謝されます。
ありがとう!