关于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向上))

展开阅读全文

没有更多推荐了,返回首页