首先让我说我已经粗略搜索了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(程序计数器或指令指针)的值是多少?
答案 0 :(得分:0)
MessageBox拥有自己的消息循环,就像所有模态对话框一样。
所以它使用PeekMessage / GetMessage。 WM_TIMER和WM_PAINT消息是消息循环执行时生成的伪消息。
这意味着MessageBox在内部调用GetMessage或PeekMessage,这会导致线程仍然执行MessageBox,但会将新消息传递给您的窗口。