キーコードの送出
たまにキーコードを送出してくなりますよね!
RPA の仕組みを作っている時とか!
と、思ったら 2024 アドベントカレンダー 10日の @mammam103103 さんの記事「タッチキーボードを作成する」と完全に被っていたため、アドベントカレンダーからは除外…
方法
仮想キーコードを送出する SendInput API があるので、これを使えば簡単です。
古くは keybd_event API を使っていたのですが、今は SendInput API を使うのが推奨されています。
SendInput を使うと、キーボード、マウス、ハードウェア入力、を送出できます。
しかも、キーボードとマウスを混在させることも可能です(例えば Ctrl + Click などが実現できます)。
キーコードの送出にはコンソールが邪魔
キーコードを送出するアプリをコンソールアプリとして作ってしまうと、送出したキーがコンソールに入力されてしまうので、コンソールが表示されないようにしなければなりません。
そこで、以前の記事の内容を使ってコンソールが表示されないコンソールっぽいアプリとして実装します。
また、GUI アプリの場合は、自身がフォーカスを取ると入力が自分に入ってしまうので、以前の記事を参考にフォーカスを取らないようにします。
実装例
下記は Ctrl + ESC を送出するコードです。
dwFlags に KEYEVENTF_KEYUP を指定すると、キーのアップを示します。
これを指定し忘れるとずっと Control と ESC が押された状態になって色々大変なことになります(なった)。
begin
var Inputs: array [0.. 3] of TInput;
ZeroMemory(@Inputs, SizeOf(Inputs));
// Control + ESC の Down
Inputs[0].Itype := INPUT_KEYBOARD;
Inputs[0].ki.wVk := VK_CONTROL;
Inputs[0].ki.dwFlags := 0;
Inputs[1].Itype := INPUT_KEYBOARD;
Inputs[1].ki.wVk := VK_ESCAPE;
Inputs[1].ki.dwFlags := 0;
// Control + ESC の Up
Inputs[2].Itype := INPUT_KEYBOARD;
Inputs[2].ki.wVk := VK_ESCAPE;
Inputs[2].ki.dwFlags := KEYEVENTF_KEYUP;
Inputs[3].Itype := INPUT_KEYBOARD;
Inputs[3].ki.wVk := VK_CONTROL;
Inputs[3].ki.dwFlags := KEYEVENTF_KEYUP;
SendInput(Length(Inputs), @Inputs, SizeOf(TInput));
end.
まとめ
keybd_event を使おうと思ったら新しい API があったので紹介しました。
新しいといっても Windows 2000 からあるので…全然新しくなかった!