Se MessageBox () / related for síncrono, por que o loop de minha mensagem não é congelado?

Por que é que se eu chamo uma função do Windows aparentemente síncrona comoMessageBox() dentro do meu loop de mensagem, o loop em si não congela como se eu chamasseSleep() (ou uma função similar) em vez disso? Para ilustrar o meu ponto, pegue o seguinte esqueléticoWndProc:

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;
}

No exemplo acima, a função principal do programa é executar um cronômetro e exibir o valor do contador a cada segundo. No entanto, se o usuário clicar em nossa janela, o programa exibirá uma caixa de mensagem e depois emitirá um sinal sonoro depois que a caixa for fechada.

Aqui é onde fica interessante: podemos dizerMessageBox() é uma função síncrona porqueMessageBeep() não é executado até que a caixa de mensagem seja fechada. No entanto, o temporizador continua em execução e a janela é repintada a cada segundo, mesmo quando a caixa de mensagem é exibida. Por enquantoMessageBox() aparentemente é uma chamada de função de bloqueio, outras mensagens (WM_TIMER/WM_PAINT) ainda pode ser processado. Tudo bem, exceto se eu substituir o MessageBox por outra chamada de bloqueioSleep()

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

Isso bloqueia completamente meu aplicativo e nenhum processamento de mensagens ocorre durante os 10 segundos (WM_TIMER/WM_PAINT não são processados, o contador não é atualizado, o programa 'congela', etc). Então porque é queMessageBox() permite que o processamento de mensagens continue enquantoSleep() não faz? Dado que a minha aplicação é single-threaded, o que é queMessageBox() faz para permitir essa funcionalidade? O sistema "replica" meu thread de aplicativo, de modo que ele possa concluirWM_LBUTTONDOWN código uma vezMessageBox() está feito, enquanto ainda permite que o segmento original para processar outras mensagens no ínterim? (esse foi o meu palpite inculto)

desde já, obrigado

questionAnswers(2)

yourAnswerToTheQuestion