2019独角兽企业重金招聘Python工程师标准>>>
关于MFC下多线程,在线程中创建非模态对话框以及消息传递
问题:
1.在子对话框中它的子对话框需要实现脱离父对话框的束缚.(因为A对话框需要B对话框搜索的结果.)
2.非模态对话框需要获得主对话框的句柄来调用主对话框类的方法.(因为B对话框需要主对话框的方法来实现底层通信.)
解决办法:
1.创建线程,在线程中创建对话框,使得多个窗口可以同时工作.
利用MFC中的UI线程实现:
a.CSearch为B对话框
b.创建CMyThread继承于CWinThread,修改其方法:
类中定义CSearch *m_dlg;(定义为指针因为后续要用.)
CMyThread::InitInstance():
m_dlg=new CSearch(m_mainDlg);
m_dlg->Create(IDD_Search,NULL);
m_dlg->ShowWindow(SW_SHOW);
CMyThread::ExitInstance():
m_dlg->DestroyWindow();
(头文件等不细说!)
c.在A对话框的cpp中,
if(hasSearch){//用来限制只能打开一次
return;
}else{
hasSearch=true;
CWinThread * pThread = AfxBeginThread (RUNTIME_CLASS (CMyThread));
//现在可以不看此3行
//CWinThread * pThread = AfxBeginThread (RUNTIME_CLASS (CMyThread),0,0,CREATE_SUSPENDED,NULL);
//((CMyThread*)pThread)->m_mainDlg=CClientInterfaceDlg::GetDialog();
//pThread->ResumeThread();
m_runDlg=(CMyThread*)pThread;//类成员
}
d.CSearch::CSearch(CView *m_pView /*=NULL*/) 使编辑器知道是非模态的DLG
这时.几乎大功告成,如果有同我一样的需要即需要使用主对话框的方法,则会弹出一个assert!解决办法如下:
2
思想:因为现在已经创建一个线程,所以接下来的事情就是线程间的通信.因此,使用消息传递机制PostMessage与SendMessage来实现.解决思路:
a.非模态对话框中需要给主对话框发送消息.自然而然需要获得主对话框句柄?How?
i:GetMainWnd()?No!
ii:((CClientInterfaceDlg*)AfxGetApp()->m_pMainWnd)?No!
b.为了获得主对话框的句柄,进入线程以后变得困难,那么怎么办?答案是,进入前我们把指针传递进去.就是说,在创建线程的时候用以上方法获得主对话框句柄,赋给CMyThread,然后保存在类中,接着重载CSearch构造函数,传递过去.然后保存在类中,以后就可以无限使用了.
c.问题又出现了,如何传参数?查询AfxBeginThread函数,如果是线程函数,比较容易,第n(具体查手册)就是参数.但是现在是用的RUNTIME_CLASS.因此用到
CWinThread * pThread = AfxBeginThread (RUNTIME_CLASS (CMyThread),0,0,CREATE_SUSPENDED,NULL);
((CMyThread*)pThread)->m_mainDlg=CClientInterfaceDlg::GetDialog();
pThread->ResumeThread();
对CMyThread类中的成员进行赋值!OK.大功告成!
现在可以通过指针去访问主对话框的成员函数咯!不过问题继续出现,怎么去访问成员函数?即如何进行线程间通信?解决方案如下:
1.主类.h中定义afx_msg void OnSearch(); 在cpp消息队列中ON_MESSAGE(WM_SEARCHQUIT,QuitSearch)
2.void CClientInterfaceDlg::OnSearch(){
UpdateData(FALSE);
OnSend();
SetTimer(TimerID10,200,timerProcSearchBook);
}可以对任意函数进行调用.
3.pDl->PostMessage(WM_UPDATEDATA);(刚刚传进来的指针)
同时,在此程序中运用到了定时器,本来想在建一个线程的.但是发现定时器够用就定时器了.带一下定时器
声明static void CALLBACK EXPORT timerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);
调用:SetTimer(TimerID10,200,timerProcSearchBook);
(注:上文中WM_SEARCHQUIT、TimerID10等均在resource.h中#define xxx WM_USER+10* (100向上))