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

时间:2015-08-10 01:09:15

标签: c++ mfc ui-thread

首先让我说我已经粗略搜索了stackoverflow,但是找不到具体的答案。

我的问题是理论上的,任何代码的运行都没有问题。请考虑一个带有计时器事件和按钮(附加到OnClick事件)的简单MFC应用程序。

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

1 个答案:

答案 0 :(得分:0)

MessageBox拥有自己的消息循环,就像所有模态对话框一样。

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

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