Основные потоки пользовательского интерфейса MFC и модальные диалоги

Сначала позвольте мне сказать, что я примерно искал stackoverflow для этого, но не смог найти конкретный ответ.

Мой вопрос довольно теоретический, и нет проблем с запуском любого кода. Пожалуйста, рассмотрите простое приложение MFC с событием таймера и кнопкой (прикрепленной к событию OnClick).

void SampleDlg::OnTimer(UINT_PTR nIDEvent)
{
CString msg;
msg.Format("time: %lld, tid: %d", (int64_t)time(0), GetCurrentThreadId());

SetWindowText(msg);
}

Интуиция подсказывает, что если я сплю внутри события OnClick, основной поток пользовательского интерфейса должен зависнуть, а события таймера не должны срабатывать.

void SampleDlg::OnClick()
{
Sleep(10000);
}

Это нормально, однако, если я показываю новый модальный диалог внутри OnClick, события таймера все равно происходят. Что здесь отличается?

void SampleDlg::OnClick()
{
CString msg;
msg.Format("tid: %d is waiting...", GetCurrentThreadId());

::MessageBox(GetSafeHwnd(), msg, "Msg", 0);
// at this point msgbox tells us that thread with tid is waiting

// thread with tid wont reach this line until msgbox is closed
}

Редактировать: Я включил GetCurrentThreadId() звонки, чтобы сделать то, что я хочу спросить более ясно.

Когда я запускаю приведенный выше код, msgbox и заголовок окна дают мне один и тот же идентификатор потока: 22012 (например). Мой вопрос, каково значение PC / IP (счетчик программы или указатель команд) потока 22012, когда отображается msgbox?

1

Решение

MessageBox имеет свой собственный цикл сообщений, как и все модальные диалоги.

Поэтому он использует PeekMessage / GetMessage. Сообщения WM_TIMER и WM_PAINT являются псевдо-сообщениями, которые генерируются при выполнении цикла сообщений.

Это означает, что MessageBox внутренне вызывает GetMessage или PeekMessage, и это приводит к тому, что поток все еще выполняет MessageBox, но новые сообщения доставляются в ваши окна.

0

Другие решения


По вопросам рекламы [email protected]