1

キーストロークを別のプロセスに送信する必要があるアプリケーションがあります。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
);
4

0 に答える 0