2010-09-16 65 views
0

我試圖在UI線程(CWinThread)中創建一個對話框。 但是,它在調用CDialog :: Create()時崩潰。 我已經驗證過以前的實現,該對話框在非線程模式下成功創建。在UI線程中創建一個對話框導致崩潰

這裏的任何大師是否知道在CWinThread中創建對話框的崩潰原因?

不必穿線:

class CProduction : public CDialog{ 
... 
} 
class CScrollProductionView : public CScrollView{ 
CProduction *m_pProduction; 
... 
} 

void CScrollProductionView::OnInitialUpdate(){ 
    m_pProduction = new CProduction(0, *m_pVisionAdapter); 
    m_pProduction->Create(IDD_DLG_PROD, this); //--> created dialog successfully 
    m_pProduction->ShowWindow(SW_SHOW); 
} 

實現UI線程:

class CProduction : public CDialog{ 
... 
} 
class CScrollProductionView : public CScrollView{ 
    CProductionThread* m_pProdThread; 
    ... 
} 

class CProductionThread : public CWinThread{ 
    CProduction *m_pProduction; 
    ... 
} 

void CScrollProductionView::OnInitialUpdate(){ 
    m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_INIT, (LPARAM)m_pVisionAdapter); 
    m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_CREATE_DLG, (LPARAM)this); 

} 

void CProductionThread::InitMessageHandler(WPARAM wParam, LPARAM lParam) 
{ 
    printf("Receiving InitMessageHandler msg %d\n", (UINT)wParam); 
    switch(wParam) 
    { 
    case PROD_INIT: 
    { 
     CVisionAdapter* pAdapter = (CVisionAdapter*)lParam; 
     m_pProduction = new CProduction(NULL, *pAdapter); 
    } 
    break; 
    case PROD_CREATE_DLG: 
    { 
     CScrollProductionView* pView = (CScrollProductionView*)lParam; 
     m_pProduction->Create(IDD_DLG_PROD, pView); //--> Crash here 
     m_pProduction->ShowWindow(SW_SHOW); 
    } 
     break; 
    default: 
     break; 
    } 
} 

錯誤消息:

調試斷言失敗! ..
文件:.... WINCORE.CPP
線:9906

感謝您觀看這個問題。

+0

你wincore.cpp的第9906行的斷言是什麼?通常情況下,斷言代碼本身或附近的評論給出了一個關於什麼是錯的重要線索。 – TheUndeadFish 2010-09-16 16:47:14

回答

0

我懷疑問題是您的CProduction對象在處理PROD_CREATE_DLG消息時尚未創建。這可能是因爲使用PostThreadMessage。使用PostThreadMessage充滿了問題。特別是,這些消息可能會丟失,所以線程永遠不會看到消息PROD_INIT

在單線程代碼中,您在Create調用之前創建了CProduction對象。你爲什麼不在多線程代碼中做同樣的事情?

如果你真的想使用Windows消息的線程間的通信,我將創建一個「唯一的消息」窗口(見http://msdn.microsoft.com/en-us/library/ms632599.aspx#message_only)代替,作爲窗口消息不會迷失在同樣的方式,線程的消息做。

另外,使用線程安全的隊列傳遞線程之間的自定義信息,如我的例子隊列在http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

0

崩潰是MFC在創建過程中引用無效窗口句柄(作爲父類傳入的)導致的。

作爲一般規則,線程只能訪問 它創建的MFC對象。這 是因爲臨時和永久 Windows處理映射保留在線程 本地存儲,以幫助保持 從多線程同時訪問 保護。

http://msdn.microsoft.com/en-us/library/h14y172e(VS.71).aspx

一個容易解決的MSDN規定涉及改變代碼到

... 

m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_CREATE_DLG, (LPARAM)this->GetSafeHwnd()); 

... 

CScrollProductionView* pView = (CScrollProductionView*)CScrollProductionView::FromHandle((HWND)lParam); 
m_pProduction->Create(IDD_DLG_PROD, pView); 
m_pProduction->ShowWindow(SW_SHOW); 

編輯
固定鏈接MSDN。

+0

不起作用... – wengseng 2010-09-17 09:02:42

+0

「如果您有一個多線程應用程序以不同於使用CWinThread對象的方式創建線程,則無法從該線程訪問其他MFC對象...」,網址爲http://msdn.microsoft.com/ .com/en-us/library/h14y172e(v = VS.90).aspx – wengseng 2010-09-17 09:08:34

+0

@wengseng,它在你身邊變得如何?我能夠模擬崩潰在我身邊,這是張貼修改後修復。 – YeenFei 2010-09-17 09:15:08

3

儘量不要創建的CWinThread,而不是創建一個工作線程,如果你有類之間多溝通比如傳遞對象指針,字符串等。
如果通過消息處理更新GUI,你會感到頭痛。