キーストロークを別のプロセスに送信する必要があるアプリケーションがあります。user32.dllで定義されたPostMessage関数を使用して、限られた成功しか収めていません。通常のキーストロークは送信できますが、修飾キー (ALT、CTRL など) を含むキーストロークは送信できません。
私が今持っているものをお見せしましょう...
定数:
public const ushort WM_KEYDOWN = 0x0100;
public const ushort WM_KEYUP = 0x0101;
public const ushort WM_SYSKEYDOWN = 0x0104;
public const ushort WM_SYSKEYUP = 0x0105;
public const ushort WM_SYSCHAR = 0x0106;
public const ushort VK_MENU = 0x12; // ALT key
DLL インポート:
[DllImport("user32.dll")]
public static extern int PostMessage(IntPtr hWnd, int Msg, uint wParam, int lParam);
単一のキーを送信する方法:
public static void PostKey(ushort key, IntPtr hWnd)
{
SetActiveWindow(hWnd);
PostMessage(hWnd, WM_KEYDOWN, key, 0);
PostMessage(hWnd, WM_KEYUP, key, 0);
}
ALT とともに単一のキーを送信する方法 (機能しません):
public static void PostKeyWithAlt(ushort key, IntPtr hWnd)
{
SetActiveWindow(hWnd);
PostMessage(hWnd, WM_SYSKEYDOWN, VK_MENU, 0);
PostMessage(hWnd, WM_SYSKEYDOWN, key, 0);
PostMessage(hWnd, WM_SYSKEYUP, key, 0);
PostMessage(hWnd, WM_KEYUP, VK_MENU, 0);
}
PostKeyは問題なく動作します。別のプロセスに接続し、メイン ウィンドウ ハンドルを取得し、必要な任意のキーストロークを送信できます。
PostKeyWithAltを使用しようとすると問題が発生します。これはうまくいかないようです。(キーは送信されますが、ALT は送信されないため、基本的にはPostKeyと同じです。) Google で調べて、メソッド呼び出しの非常に多くの組み合わせを試しましたが、率直に言って、終了する準備ができています。:P
そこで、必死になって、Visual Studio Spy++ ツールを使用して、ターゲット アプリケーションで ALT + F1 キーを押すと何が起こるかを観察しました。メッセージ キャプチャの結果は次のとおりです。
Spy++ ログ:
<00001> 00080228 P WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00002> 00080228 P WM_SYSKEYDOWN nVirtKey:VK_F1 cRepeat:1 ScanCode:3B fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00003> 00080228 P WM_SYSKEYUP nVirtKey:VK_F1 cRepeat:1 ScanCode:3B fExtended:0 fAltDown:1 fRepeat:1 fUp:1
<00004> 00080228 P WM_KEYUP nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
ご覧のとおり、シーケンスはPostKeyWithAlt関数とまったく同じシーケンスです。だから私はそれがうまくいくと思うでしょうが、そうではありません。
ここで何か他のことが起こっているに違いありません。私が考えることができる唯一のものは、PostMessage関数の 4 番目のパラメーターです。Microsoft のドキュメントによると、この 4 番目のパラメーターはLPARAM lParamとして定義されています ( PostMessageの完全な関数定義については以下を参照してください)。
おそらく、 lParamを 0 以外に設定する必要がありますか? その場合、どの値を設定する必要がありますか? Spy++ ログを使用して把握できますか? もしそうなら、それらのログメッセージで _nVirtKey:VK_MENU_ を過ぎたものをどのように解釈するかは私にはわかりません:
<00001>.... cRepeat:1 ScanCode:38 fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00002>.... cRepeat:1 ScanCode:3B fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00003>.... cRepeat:1 ScanCode:3B fExtended:0 fAltDown:1 fRepeat:1 fUp:1
<00004>.... cRepeat:1 ScanCode:38 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
上記のログ メッセージを正しいlParam引数に変換できれば、うまくいくかもしれません。
その方法に関するヘルプ/提案は大歓迎です。
または、キーストロークをプロセスに送信する別のよりエレガントな方法はありますか? おそらくC#ライブラリ?SendKeysクラスについては知っていますが、そのクラスはキーストロークを他のアプリケーションに送信しません。
ありがとう!
PostMessage 関数の定義:
BOOL WINAPI PostMessage(
_In_opt_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);