界面线程的创建步骤和以及在界面线程中创建模态对话框和非模态对话框
-
界面线程的创建
-
从CWinThread类派生自己的子类:如,CUIThreadApp
-
重载InitInstance()函数(必须重载),与ExitInstance(可选重载)函数 (类中方法的重载如下所示)
-
在InitInstance函数中进行界面的创建
// 在界面线程类的初始化函数中创建界面 BOOL CUIThreadApp::InitInstance()//必须重载 { // TODO: 在此执行任意逐线程初始化 CMyDlg dlg; dlg.DoModal(); // 创建模态对话框(创建界面) return TRUE; }
CMyDlg类是我们主动添加的一个对话框所绑定的类 test01Dlg是本工程对应的对话框类 CUIThreadApp是我们自己创建的界面线程类,用于创建界面线程
-
调用AfxBeginThread函数开启界面线程:AfxBeginThread(RUNTIME_CLASS(CUIThreadApp))
因为想要的效果是,在主对话框中点击按钮,即创建对话框,所以在test01Dlg.cpp中添加回调函数
调用之后的函数执行过程如下
点击按钮---> --->启动AfxBeginThread() --->对CUIThreadApp类进行实例化 --->CUIThreadApp::CUIThreadApp()调用构造函数 --->CUIThreadApp::InitInstance()进行线程的初始化 --->dlg.DoModal()创建模态对话框--->等待用户操作模态对话框--->模态对话框结束后 --->return true; --->进入应用程序的消息循环....不执行ExitInstance()函数和析构函数
如果要在结束模态对话框之后,直接退出线程,则应该在InitInstance()中返回FALSE
BOOL CUIThreadApp::InitInstance()//必须重载 { CMyDlg dlg; dlg.DoModal(); // 创建模态对话框(创建界面) return FALSE; }
调用线程开始函数后的函数执行过程为
点击按钮---> --->启动AfxBeginThread() --->对CUIThreadApp类进行实例化 --->CUIThreadApp::CUIThreadApp() --->CUIThreadApp::InitInstance()进行线程的初始化 --->dlg.DoModal()创建模态对话框--->等待用户操作模态对话框--->模态对话框结束后 --->return FALSE;(含义是模态对话框退出之后,界面线程就可以退出了) --->进入CUIThreadApp::ExitInstance()--->析构函数--->退出线程 // 需要注意的一点是,我们对话框框架的界面线程的实例化的时候,返回的就是FALSE,也即表明当用户关闭对话框时,对话框主线程结束,如下图所示
如果在关闭了对话框之后还需要进行消息循环,那么就应该在InitInstance()函数中返回TRUE.
-
另外,如果要创建一个非模态的对话框,而不是上述的模态对话框,那么InitInstance()函数要做适当的修改
BOOL CUIThreadApp::InitInstance()//必须重载 { CMyDlg* pDlg = new CMyDlg; pDlg->Create(IDD_DIALOG1, NULL); // 创建非模态对话框,父窗口为桌面(NULL) pDlg->ShowWindow(SW_SHOW); // 显示 return TRUE; }
因为非模态对话框不会阻塞程序运行,所以如果return FALSE; 会导致线程立马退出,对话框将一闪而过. 因此应该返回TRUE,让线程进入消息循环,这样就不退出了.
//也即是说,消息循环(消息泵)一直在循环,处理消息,程序不会退出. //除非消息泵收到了WM_QUIT消息 //那么也即是在我们认为其应该退出的时候给消息泵发送WM_QUIT消息即可 //可以在该非模态对话框的按钮上添加响应函数,在响应函数中,添加PostQuitMessage()函数发送
-