1

私は一般的にイベント ループ (あまりうまくいかない) を理解しようとしてきましたが、Windows メッセージング ループはシングル スレッドであることを読みました。もしそうなら、Application.DoEvents はどのように機能しますか? イベント ループは一度に 1 つのメッセージを処理し、各メッセージ/イベントの処理中にブロックしませんか? Application.DoEvents を可能にするには、メッセージを処理しているスレッドとは別のスレッドにメッセージ イベント ループが存在する必要があるのではないでしょうか。別々のスレッドがある場合、「メイン」スレッドと呼んでいるのはどれですか? 非常に単純なものが欠けていると確信しています。それが何であるかわかりません。

4

1 に答える 1

1

私はこれを理解するために一日の大部分を費やしています(私が言うことが間違っている場合は、コメントして知らせてください。修正できるようになります)。私は実際に古いWin32アプリケーションを構築し、自分でメッセージループを作成する必要がありました(私はかなり永続的なSOBです)。したがって、次のようなメッセージループを起動するWinMainという関数があります。

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

GetMessage()についてのことは、メッセージがメッセージキューで利用可能になるまでブロックすることです。Windowedアプリケーションを実行し、そこに座ってウィンドウを見ると(キューにメッセージを送信するアクションを発生させないでください)、メインスレッド(ウィンドウが作成されたスレッド)はGetMessage()で一時停止されます。 。ここで、メッセージが投稿されると、whileループに入ります(つまり、メッセージが終了しない場合は0です)。DispatchMessage()はここで興味深い関数です。この関数は、最終的に(.NETで)EventHandlerの制御と実行によって発生するイベントにつながります。呼び出しスタックがGetMessage()/ DispatchMessage()/.../ EventHandlerである場合、私が困惑したのは、Application.DoEvents()がメッセージを処理する方法を教えてください。まあ、それはかなり簡単です。Win32のDoEventsは次のようになります。

void DoEvents()
{
   MSG msg;
   HACCEL hAccelTable;

   hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_TESTWIN32));

   // Main message loop:
   while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0)
   {
       if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
       {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
       }
   }
}

したがって、DoEvents()は、最初のメッセージループのDispatchMessage()内で、イベントを処理するために実際に別のループを開始します。主な違いは、キューにメッセージが入るまでブロックするGetMessage()を使用する代わりに、0を返し、キューにメッセージがなくなるとループが存在するPeekMessage()を使用することです。

では、ボタンを2回クリックし、そのボタンのEventHandlerにDoEvents()呼び出しがあるとしたらどうでしょうか。最初のイベントループは最初のクリックを処理し、イベントを発生させます。EventHandlerの実行中、DoEvents()呼び出しで、イベントが2回発生し、EventHandlerが再度入力されます(再帰呼び出しのようなものです)。それが怖いです!

したがって、最終的には、すべてが単一のスレッドで発生し、DoEvents()は、すべてのメッセージが処理されてから返されるまで実際にブロックします。今、私は数日間寝るつもりです。

于 2011-11-20T04:59:28.163 に答える