C++ 在UI线程中创建对话框导致崩溃
我试图在UI线程(CWinThread)中创建一个对话框。 但是,当调用CDialog::Create()时,它会崩溃。 我已经用以前的实现验证过,对话框是在非线程模式下成功创建的 这里有没有大师知道在CWinThread中创建对话框的崩溃原因 无螺纹:C++ 在UI线程中创建对话框导致崩溃,c++,multithreading,C++,Multithreading,我试图在UI线程(CWinThread)中创建一个对话框。 但是,当调用CDialog::Create()时,它会崩溃。 我已经用以前的实现验证过,对话框是在非线程模式下成功创建的 这里有没有大师知道在CWinThread中创建对话框的崩溃原因 无螺纹: class CProduction : public CDialog{ ... } class CScrollProductionView : public CScrollView{ CProduction *m_pProduction; ..
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
感谢您查看此问题。崩溃是由MFC在创建过程中引用无效的窗口句柄(作为父级传入)引起的 一般来说,线程可以访问 只有它创建的MFC对象。这 是因为暂时和永久 Windows句柄映射保存在线程中 本地存储有助于维护 防止同时访问 来自多个线程 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的链接。崩溃是由MFC在创建过程中引用无效的窗口句柄(作为父级传入)引起的 一般来说,线程可以访问 只有它创建的MFC对象。这 是因为暂时和永久 Windows句柄映射保存在线程中 本地存储有助于维护 防止同时访问 来自多个线程 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的链接。我怀疑问题在于处理
PROD\u CREATE\u DLG
消息时未创建您的CProduction
对象。这可能是因为使用了PostThreadMessage
。使用PostThreadMessage
充满了问题。特别是,消息可能会丢失,因此线程永远不会看到PROD_INIT
消息
在单线程代码中,您在create
调用之前创建CProduction
对象。为什么不在多线程代码中执行相同的操作
如果您真的想使用windows消息在线程之间进行通信,我将创建一个“仅消息”窗口(请参阅),因为窗口消息不会以与线程消息相同的方式丢失
或者,使用线程安全队列在线程之间传递自定义消息,例如我在的示例队列。我怀疑问题在于,在处理
PROD\u CREATE\u DLG
消息时,您的CProduction
对象尚未创建。这可能是因为使用了PostThreadMessage
。使用PostThreadMessage
充满了问题。特别是,消息可能会丢失,因此线程永远不会看到PROD_INIT
消息
在单线程代码中,您在create
调用之前创建CProduction
对象。为什么不在多线程代码中执行相同的操作
如果您真的想使用windows消息在线程之间进行通信,我将创建一个“仅消息”窗口(请参阅),因为窗口消息不会以与线程消息相同的方式丢失
或者,使用线程安全队列在线程之间传递自定义消息,例如我在的示例队列。如果类之间有很多通信,例如传递对象指针、字符串等,请尝试不要创建CWinThread,而不要创建工作线程。
如果通过消息处理更新GUI,您会感觉不那么头痛。如果类之间有很多通信,如传递对象指针、字符串等,请不要创建CWinThread,而不要创建工作线程。
如果通过消息处理更新GUI,您会感觉不那么头痛。wincore.cpp第9906行的断言是什么?通常情况下,断言代码本身或附近的注释会给出一个很大的错误线索。wincore.cpp第9906行的断言是什么?通常情况下,断言代码本身或附近的注释会给出一个很大的错误提示。@wengseng中的“如果您有一个多线程应用程序,该应用程序以除使用CWinThread对象之外的其他方式创建线程,您无法从该线程访问其他MFC对象…”这是怎么回事?我能够模拟我这边的崩溃,这在发布的修改后得到修复。“如果你有一个多线程应用程序,它以一种不同于使用CWinThread对象的方式创建线程,你不能从该线程访问其他MFC对象…”来自@wengseng,你那边的结果如何?我能够模拟我这边的碰撞,这是在发布修改后修复的。