Если MessageBox () / related является синхронным, почему мой цикл сообщений не останавливается?

Почему, если я вызываю, казалось бы, синхронную функцию Windows,MessageBox() внутри моего цикла сообщений, сам цикл незамерзну, как если бы я позвонилSleep() (или аналогичная функция) вместо этого? Чтобы проиллюстрировать мою точку зрения, возьмите следующий скелет:WndProc

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

В приведенном выше примере программаОсновная функция - запустить таймер и отобразить счетчикЗначение каждую секунду. Однако, если пользователь нажимает на наше окно, программа отображает окно сообщения и затем издает звуковой сигнал после закрытия окна.

Вот'где это становится интересным: мы можем сказатьMessageBox() это синхронная функция, потому чтоMessageBeep() Безразлично»t выполнить, пока окно сообщения не закроется. Однако таймер продолжает работать, и окно перекрашивается каждую секунду, даже когда отображается окно сообщения. Так что покаMessageBox() по-видимому, это блокировка вызова функции, другие сообщения (/WM_TIMERWM_PAINT) еще можно обработать. Тот'Это нормально, за исключением случаев, когда я заменяю MessageBox на другой блокирующий вызов, напримерSleep()

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

Это полностью блокирует мое приложение, и в течение 10 секунд не происходит обработки сообщений (/WM_TIMERWM_PAINT Арен»т обработан, счетчик необновлять, программироватьзамораживает, так далее). Так почему жеMessageBox() позволяет продолжить обработку сообщений, покаSleep() Безразлично»т? Учитывая, что мое приложение является однопоточным, что это такое?MessageBox() позволяет эту функциональность? Есть ли система?повторить» мой поток приложения, чтобы он мог закончитьWM_LBUTTONDOWN код один разMessageBox() сделано, в то же время позволяя исходному потоку обрабатывать другие сообщения в промежуточный период? (это было мое необразованное предположение)

заранее спасибо

Ответы на вопрос(2)

Ваш ответ на вопрос