7

「メッセージループ」を理解しようとしています。これはそれがどのように見えるかです:

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

これまでのところ、コンセプトは明確です(少なくともそう願っています)。ユーザーがキーボードとマウスを使用してWindowsアプリケーションを操作すると、これらのイベントはそれぞれのデバイスドライバーによって適切なメッセージに変換され、システムメッセージキューに投稿されます。

OSは、メッセージを1つずつキューから削除し、各メッセージを調べて、宛先ウィンドウの作成を担当するそれぞれのアプリケーションのスレッドのキューにメッセージを送信します。

今私のアプリケーションで

MSG msg;
GetMessage(&msg, NULL, 0, 0);

スレッド固有のメッセージキューからメッセージを削除し、MSG構造を埋めます。

ただしTranslateMessage、仮想キーストロークを文字に変換し、呼び出し元のスレッドのメッセージキューにポストバックすると言われています。

DispatchMessage適切なターゲットウィンドウのWindowsプロシージャを呼び出すようにOSに指示します。

2つの疑問:

1)TranslateMessageの正確な機能は何ですか;仮想キーストロークを文字メッセージに変換するだけです(仮想キーストロークはアルファベットと数字以外のキーストロークであると想定しています)、文字メッセージがキューにポストバックされた場合、ループは壊れていません?

2)マウスイベントはどうですか?直接ディスパッチされますか?

4

2 に答える 2

10

はい、メッセージループがそのように見えるときに TranslateMessage() を呼び出す必要があるのは意味がありません。しかし、正規の Petzold メッセージ ループは次のようにはなりません。

while (GetMessage(&msg, NULL, 0, 0))
{
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

ここで重要なのはアクセラレータであり、「ショートカット キー」とも呼ばれます。どのウィンドウにフォーカスがあるかに関係なく、プログラムはそれらに応答したいと考えています。F1 と同様に、どのコントロールにフォーカスがあるかに関係なく、プログラムのヘルプ ファイルが表示されます。F1 を認識するためにすべてのコントロール ウィンドウをサブクラス化するコードを記述する必要はありません。

したがって、ショートカット キーの場合は、TranslateMessage を呼び出したくありません。キーがたまたま入力キーと一致した場合、キーは WM_CHAR メッセージを生成するべきではありません。それが別の呼び出しである理由です。

于 2012-09-25T12:17:42.257 に答える
3

要するに、

  1. はい、仮想キーストロークを文字メッセージに変換するだけです
  2. はい、直接発送されます。msdn のこのブログを参照してください。

詳細については、

于 2012-09-25T11:31:24.277 に答える