MFC主UI线程工作和模态对话框

MFC main UI thread workings and modal dialogs

本文关键字:模态 对话框 工作 线程 UI MFC      更新时间:2023-10-16

首先让我说,我已经大致搜索了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事件中睡觉,主UI线程应该挂起,计时器事件不应该踢。

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和窗口标题给了我相同的线程id: 22012(例如)。我的问题是,当msgbox被显示时,线程22012的PC/IP(程序计数器或指令指针)的值是什么?

与所有模态对话框一样,MessageBox也有自己的消息循环。

所以它使用PeekMessage/GetMessage。WM_TIMER和WM_PAINT消息是消息循环执行时生成的伪消息。

这意味着MessageBox内部调用GetMessage或PeekMessage,这导致线程仍然执行MessageBox,但新消息被传递到您的窗口。