關於MFC下多線程,在線程中建立非模態對話框以及消息傳遞

關於MFC下多線程,在線程中建立非模態對話框以及消息傳遞

問題:

1.在子對話框中它的子對話框須要實現脫離父對話框的束縛.(由於A對話框須要B對話框搜索的結果.) 多線程

2.非模態對話框須要得到主對話框的句柄來調用主對話框類的方法.(由於B對話框須要主對話框的方法來實現底層通訊.) 編輯器

解決辦法: 函數

1.建立線程,在線程中建立對話框,使得多個窗口能夠同時工做. ui

利用MFC中的UI線程實現: spa

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

相關文章
相關標籤/搜索