別のプログラムのウィンドウにテキスト メッセージを送信する C# WPF プログラムを作成しています。キーボード ドライバー (Logitech g15) の一部として、既にこれを行っているマクロ プログラムがありますが、キーストロークをプロセスに直接送信するのではなく、現在フォーカスされているウィンドウに送信します。それはうまくいきますが、私のプログラムからも入力を送信できるようにする必要があります。このプロセスを使用している人が他にもいるため、私のプログラムからの入力テキスト メッセージは、私のテキストが彼らの入力を妨げないように十分に高速である必要があります。問題は、ac# プログラムでこれを実行しようとすると、遅延が大きくなりすぎることです。マクロ プログラム (Logitech G-Series Profiler) はコマンドを即座に送信します。処理するメッセージを送信するために、次の 3 つのコマンドを試しました。(最も遅いものから最も速いものへの順でリストされています)
SetForegroundWindow(_hWnd);
SendKeys.SendWait("{Enter}This is a keystroke input.{Enter}");
名前にあるのかもしれませんが、これは非常にゆっくりとコマンドを実行するので、実際にテキストを 1 文字ずつ入力するので、テキストを目で追うことができます。「SendKeys.Send」メソッドを使用してみましたが、「アプリケーションが Windows メッセージを処理していないため、このアプリケーション内で SendKeys を実行できません」というエラーが表示されます。</p>
PostMessage((IntPtr)_hWnd, (uint)WMessages.WM_KEYUP, (int)key, (int)key);
PostMessage は少し高速ですが、それでも私のプログラムの目的には十分ではありません。メッセージがプロセスによって読み取られる前にメソッドが戻ることに加えて、これは、2 つの連続する PostMessage 呼び出しが連続したメッセージを送信しない可能性があることを意味します。
SendMessage(_hWnd, 0x100, (int) VKeys.VK_2, (int) VKeys.VK_2);
これは PostMessage よりも高速ですが、Logitech のマクロ プログラムほど高速ではありません。また、受信プログラムは入力を奇妙に処理します。明らかに、キーボードからの「本物の」入力と同じようには処理しません。
SetForegroundWindow(_hWnd);
const string text = "This is a keystroke input.";
IInputElement target = Keyboard.FocusedElement;
IInputElement target = InputManager.Current.PrimaryKeyboardDevice.FocusedElement;
var routedEvent = TextCompositionManager.TextInputEvent;
target.RaiseEvent(new TextCompositionEventArgs(InputManager.Current.PrimaryKeyboardDevice, new TextComposition(InputManager.Current, target, text)) { RoutedEvent = routedEvent });
これは私が試した最後のことです。テキストがプロセスに送信される方法は瞬時に見えます。ただし、別のプログラムをフォアグラウンド ウィンドウとして設定すると、Keyboard.FocusedElement が null を返すため、これを自分のプログラムにしか送信できませんでした。誰かが別のウィンドウの IInputElement を取得する方法を教えてくれたら、ぜひ知りたいです。あるいは、誰かが入力を送信するためのより良い方法について提案を持っている場合は、それを聞きたいと思っています.
仕様: Windows 7、64 ビット Visual Studio 2010、Framework 4