MFC 主 UI 线程工作和模式对话框
MFC main UI thread workings and modal dialogs
首先声明一下,我已经粗略地搜索了Whosebug,但没有找到具体的答案。
我的问题比较理论化,任何代码的 运行ning 都没有问题。请考虑一个带有计时器事件和按钮(附加到 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 和 window 标题都给我相同的 thread-id: 22012(例如)。我的问题是,当显示 msgbox 时,线程 22012 的 PC/IP(程序计数器或指令指针)的值是多少?
与所有模态对话框一样,MessageBox 有自己的消息循环。
所以它使用PeekMessage/GetMessage。 WM_TIMER 和 WM_PAINT 消息是消息循环执行时生成的伪消息。
这意味着 MessageBox 在内部调用 GetMessage 或 PeekMessage,这会导致线程仍然执行 MessageBox,但新消息会传递给您 windows。
首先声明一下,我已经粗略地搜索了Whosebug,但没有找到具体的答案。
我的问题比较理论化,任何代码的 运行ning 都没有问题。请考虑一个带有计时器事件和按钮(附加到 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 和 window 标题都给我相同的 thread-id: 22012(例如)。我的问题是,当显示 msgbox 时,线程 22012 的 PC/IP(程序计数器或指令指针)的值是多少?
与所有模态对话框一样,MessageBox 有自己的消息循环。
所以它使用PeekMessage/GetMessage。 WM_TIMER 和 WM_PAINT 消息是消息循环执行时生成的伪消息。
这意味着 MessageBox 在内部调用 GetMessage 或 PeekMessage,这会导致线程仍然执行 MessageBox,但新消息会传递给您 windows。