Wenn MessageBox () / related synchron ist, warum friert meine Nachrichtenschleife nicht ein?

Warum ist es so, wenn ich eine scheinbar synchrone Windows-Funktion aufrufe?MessageBox() Innerhalb meiner Nachrichtenschleife friert die Schleife nicht ein, als hätte ich angerufenSleep() (oder eine ähnliche Funktion) statt? Um meinen Standpunkt zu veranschaulichen, nimm das folgende SkelettWndProc:

int counter = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_CREATE:
             SetTimer(hwnd, 1, 1000, NULL); //start a 1 second timer
             break;
        case WM_PAINT:
             // paint/display counter variable onto window
             break;
        case WM_TIMER: //occurs every second
             counter++;
             InvalidateRect(hwnd, NULL, TRUE); //force window to repaint itself
             break; 
        case WM_LBUTTONDOWN: //someone clicks the window
             MessageBox(hwnd, "", "", 0);
             MessageBeep(MB_OK); //play a sound after MessageBox returns
             break;
        //default ....
    }
    return 0;
}

Im obigen Beispiel besteht die Hauptfunktion des Programms darin, einen Timer auszuführen und den Zählerwert jede Sekunde anzuzeigen. Wenn der Benutzer jedoch auf unser Fenster klickt, zeigt das Programm ein Meldungsfenster an und piept, nachdem das Fenster geschlossen wurde.

Hier wird es interessant: Wir können es sagenMessageBox() ist eine synchrone Funktion, weilMessageBeep() wird erst ausgeführt, wenn das Meldungsfeld geschlossen wird. Der Timer läuft jedoch weiter und das Fenster wird jede Sekunde neu gezeichnet, auch wenn das Meldungsfeld angezeigt wird. Also, währendMessageBox() ist anscheinend ein blockierender Funktionsaufruf, andere Meldungen (WM_TIMER/WM_PAINT) kann noch bearbeitet werden. Das ist in Ordnung, es sei denn, ich ersetze MessageBox durch einen anderen blockierenden Anruf wieSleep()

    case WM_LBUTTONDOWN:
         Sleep(10000); //wait 10 seconds
         MessageBeep(MB_OK);
         break;

Dadurch wird meine Anwendung vollständig blockiert und 10 Sekunden lang wird keine Nachricht verarbeitet (WM_TIMER/WM_PAINT werden nicht verarbeitet, der Zähler wird nicht aktualisiert, Programm "friert ein" usw.). Warum ist es das?MessageBox() Ermöglicht die Fortsetzung der NachrichtenverarbeitungSleep() nicht? Angesichts der Tatsache, dass meine Anwendung Singlethread ist, was ist das?MessageBox() tut, um diese Funktionalität zu ermöglichen? "Repliziert" das System meinen Anwendungsthread, damit er den Vorgang abschließen kann?WM_LBUTTONDOWN Code einmalMessageBox() wird erledigt, während der ursprüngliche Thread in der Zwischenzeit noch andere Nachrichten verarbeiten kann? (das war meine ungebildete Vermutung)

Danke im Voraus

Antworten auf die Frage(2)

Ihre Antwort auf die Frage