工作线程
首先是创建模态的对话框:
要清楚一点:DoModal函数是阻塞的,程序执行到这里就停了,直到把该模态对话框关闭之后,才继续执行。而非模态对话框是不管对话框创建完消没消失,程序都会向下走。
UINT _cdecl C多线程Dlg::ThreadProc(LPVOID lpParameter)
{
C多线程Dlg *pThisDlg = (C多线程Dlg *)lpParameter;//获取当前主对话框的指针,要进行强转
CTestDlg dlg1;
dlg1.DoModal();//在线程函数中创建模态的对话框,把dlg对象显示为模态对话框
return 0;
}
void C多线程Dlg::OnBnClickedBtn()
{
CWinThread *pThread = AfxBeginThread(ThreadProc,this);
}
线程退出了,线程函数就结束了,响应申请的资源就释放了,所以DoModal阻塞在那儿模态对话框不会退出,非模态对话框就自然而然的消失了。
工作线程没有消息循环,对话框界面的刷新工作,包括接受用户的鼠标键盘操作,都不会响应,但我们可以给他一个消息循环,但如果都这样做了,那为什么不去用界面线程呢,界面线程考虑的会更全面。
创建非模态对话框的代码如下:
UINT _cdecl C多线程Dlg::ThreadProc(LPVOID lpParameter)
{
C多线程Dlg *pThisDlg = (C多线程Dlg *)lpParameter;//获取当前主对话框的指针,要进行强转
CTestDlg *pTestDlg = new CTestDlg(); //创建指针非模态对话框才可以正常显示,开辟一个存放CTestDlg类型的存储空间,返回一个指向该存储空间的地址(即指针) 可以多处使用,和直接创建相比需要手动销毁,
//pTestDlg->Create(IDD_DIALOG1,pThisDlg);//参数Ⅰ创建的非模态对话框模板的ID 参数Ⅱ父窗口指针 但这个语句是不对的 两个对话框的资源没有在一个线程中,可以设为NULL,以桌面为其父窗口
pTestDlg->Create(IDD_DIALOG1,NULL);
pTestDlg->ShowWindow(SW_SHOW);//显示对话框
//以下几条语句(消息循环):从当前线程的消息队列中做消息处理
MSG msg = {0};
while(GetMessage(&msg, NULL, 0, 0))//无限的取消息
{
TranslateMessage(&msg);//消息的转换
DispatchMessage(&msg);//消息的分发
}
不加消息循环语句,对话框弹出几毫秒就随着线程结束消失了。
如何创建界面线程?
第一步:在解决方案中右击项目,选择添加,选择类,之后按下图选择,点击添加,
如此我们就向我们的工程中插入了一个CWinThread的子类。
第二步:重载InitInstance函数,在InitInstance函数(界面线程的初始化函数)中进行界面的创建。
先在UIThreadApp.cpp中添加头文件#include “TestDlg.h”,之后在函数中添加代码
BOOL CUIThreadApp::InitInstance()
{
// TODO: 在此执行任意逐线程初始化
CTestDlg dlg;
dlg.DoModal();
return TRUE;
}
第三步:调用AfxBeginThread函数开启界面线程。
在主对话框.cpp文件中添加头文件#include “UIThreadApp.h”,
首先创建模态对话框:
点击响应函数:
void C多线程Dlg::OnBnClickedBtn()
{
//m_Num = 123;
//CWinThread *pThread = AfxBeginThread(ThreadProc,this);
AfxBeginThread(RUNTIME_CLASS(CUIThreadApp));//参数 CWinThread类的子类,该函数会实例化该类的对象并让界面线程运行起来
}
界面线程初始化函数:
BOOL CUIThreadApp::InitInstance()
{
// TODO: 在此执行任意逐线程初始化
CTestDlg dlg;
dlg.DoModal();
return FALSE;//把TURE改为False 我们把模态框退出之后,界面线程就没有其存在的意义,我们就让它退出。设为TURE则会导致无法执行界面线程退出函数造成内存泄漏
}
创建非模态对话框
点击响应函数:
void C多线程Dlg::OnBnClickedBtn()
{
AfxBeginThread(RUNTIME_CLASS(CUIThreadApp));//参数 CWinThread类的子类,该函数会实例化该类的对象并让界面线程运行起来
}
界面线程初始化函数:
BOOL CUIThreadApp::InitInstance()
{
// TODO: 在此执行任意逐线程初始化
CTestDlg *pTestDlg = new CTestDlg();
pTestDlg->Create(IDD_DIALOG1,NULL);
pTestDlg->ShowWindow(SW_SHOW);//显示对话框
pTestDlg->RunModalLoop();//开启非模态框消息循环,没有就会一闪而过
return FALSE;
}