工作线程与界面线程的区别
1. 区别
- 消息循环
- 工作线程没有消息循环
- 界面线程有消息循环
- 模态对话框
- 模态对话框弹出时,用户不能与其他窗口交互,直到模态对话框关闭。
- 有自己的消息循环
- 不建议在工作线程中创建模态对话框
2. 需要了解一下模态对话框和非模态对话框
// 模态对话框在创建时,会调用DoModal()方法
CMyDlg dlg;
dlg.DoModal();
// 因为DoModal()方法是阻塞的,所以,模态对话框之后被关闭之后,程序才会继续向下执行
- 非模态对话框
UINT __cdecl MyThreadProc(LPVOID pParam)
{
Ctest01Dlg* pThisDlg = (Ctest01Dlg*)pParam;
// 模态对话框的创建
//CMyDlg dlg;
//dlg.DoModal(); // 在工作线程中创建模态对话框该方法是阻塞的
// 非模态对话框的创建
CMyDlg* pMyDlg = new CMyDlg;
pMyDlg->Create(IDD_DIALOG1, NULL);
pMyDlg->ShowWindow(SW_SHOW);
// 如果休眠时间变得长一些,当弹出非模态对话框时,就会出现未响应.如下图所示
Sleep(500);
return 0;
}
- 为什么呢?
- 因为创建该非模态对话框的线程是一个工作线程,而工作线程是没有消息循环的
- 因为没有消息循环,就导致鼠标等对其的操作,工作线程无法进行响应
- 回顾一下模态对话框出现时,我们只能操作该对话框,对话框可以响应鼠标操作,因为模态对话框自带了消息循环
- 如果尝试在这个工作线程中添加消息循环
UINT __cdecl MyThreadProc(LPVOID pParam)
{
Ctest01Dlg* pThisDlg = (Ctest01Dlg*)pParam;
// 模态对话框的创建
//CMyDlg dlg;
//dlg.DoModal(); // 在工作线程中创建模态对话框该方法是阻塞的
// 非模态对话框的创建
CMyDlg* pMyDlg = new CMyDlg;
pMyDlg->Create(IDD_DIALOG1, NULL);
pMyDlg->ShowWindow(SW_SHOW);
// 手动的添加消息循环
MSG msg = { 0 }; // 创建消息
while (GetMessage(&msg,NULL,0,0)) // 获取消息
{
TranslateMessage(&msg); // 翻译消息
DispatchMessage(&msg); // 分发消息
}
return 0;
}
-
此时运行程序弹出的非模态对话框就可以自由拖动了.如下所示
-
其实工作线程加上消息循环几乎就约等于界面线程(上一篇博客讲到,AfxBeginThread创建MFC的线程有两种:工作线程和界面线程)
3. 界面线程
- 如果是操作非本线程的窗口时,应该选择发消息
- MFC的对话框工程和文档视图对话框默认是界面线程