Если 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()
не выполняется до тех пор, пока окно сообщения не закроется. Однако таймер продолжает работать, и окно перекрашивается каждую секунду, даже когда отображается окно сообщения. Так что покаMessageBox()
видимо блокирующий вызов функции, другие сообщения (WM_TIMER
/WM_PAINT
) еще можно обработать. Это нормально, за исключением случаев, когда я заменяю MessageBox на другой блокирующий вызов, такой какSleep()
case WM_LBUTTONDOWN:
Sleep(10000); //wait 10 seconds
MessageBeep(MB_OK);
break;
Это полностью блокирует мое приложение, и в течение 10 секунд не происходит обработка сообщений (WM_TIMER
/WM_PAINT
не обрабатываются, счетчик не обновляется, программа "зависает" и т. д.). Так почему жеMessageBox()
позволяет продолжить обработку сообщений, покаSleep()
Безразлично & APOS; т? Учитывая, что мое приложение является однопоточным, что это такое?MessageBox()
позволяет эту функциональность? Является ли система «копируемой»? мой поток приложения, чтобы он мог закончитьWM_LBUTTONDOWN
код один разMessageBox()
сделано, в то же время позволяя исходному потоку обрабатывать другие сообщения в промежуточный период? (это было мое необразованное предположение)
заранее спасибо