如何在多线程函数MFC中获取对话框类的指针

Posted

技术标签:

【中文标题】如何在多线程函数MFC中获取对话框类的指针【英文标题】:How to take a pointer of dialog class in a multithread function MFC 【发布时间】:2017-07-21 10:35:24 【问题描述】:

我想在我定义全局或独立函数的多线程函数中访问我的对话框 UI(编辑框)。 CSampleDlg* m_dlg=(CSampleDlg*)_param; 这里是_param 是线程函数的参数。当我尝试这个时它在这里崩溃:ASSERT(::IsWindow(m_hWnd));

//这里是mfc示例代码

UINT MessageThread(LPVOID _param)

    CServerDlg* m_dlg=(CServerDlg*)_param; 
    char cChar[1024];
    CString strmsg=L"";

    while (!stopNow && (currValue < maxValue))
    
        m_dlg->m_messagebox.GetWindowTextW(strmsg); //m_messagebox :editbox
        sprintf(cChar,"%s",CW2A(strmsg));
        char *buff=(char*)&cChar;
        m_dlg->m_server.Send(buff,sizeof(cChar));
        currValue++;
        Sleep(50);  
    

    return TRUE;

【问题讨论】:

您是否曾经在Release 模式下构建过您的项目?或者您是否处于Debug 模式?请告诉我在将您的项目构建为Release 后发生了什么。 【参考方案1】:

如果你想访问它后面的窗口对象,跨线程使用 CWnd 指针是危险的。 CWnd 指针存储在每个线程映射中。使用由 MFC 包装的窗口 API 函数可能会失败或引发 ASSERT。

您可以使用嵌入的 m_hWnd 句柄,也可以将 GetWindowText 与此句柄一起使用。但即使不是一个很好的解决方案。

UI 和其他工作线程操作应该严格分开。因此,最好将您要发送的信息发送到工作线程 y 任何其他方法,而不是直接访问窗口。

【讨论】:

谢谢你能给我一个如何直接访问窗口的示例吗? 我写的。你有窗口的句柄。您可以使用 Windows API。但是我写的其他方法更好。【参考方案2】:

m_dlg-&gt;m_messagebox.GetWindowTextW(strmsg); 是来自工作线程的非常危险的语句。同样,不建议跨线程传递CDialog 的指针。

即使没有将CDialog 的指针传递给线程,也可以为您的问题提供许多解决方案。

我假设您想在对话框中跟踪编辑控件中的文本更改并将其传递给serverusing 工作线程。您可以选择拥有一个全局缓冲区,您可以在其中从编辑控件复制文本,然后将通知发送到线程以发送它。在将数据复制到上面之前,不要忘记将lock 放在全局缓冲区上。

您甚至可以考虑使用CList 对象来维护要发送到服务器的文本列表。 GUI 将push 文本发送到服务器到Clist 对象。您的线程可以从CList 发送pop 文本(如果可用)并将其发送到服务器。

【讨论】:

非常感谢您给出一个方向 您可以将m_server 的实例传递给线程函数,这将使您能够发送数据。最好的方法是拥有单独的ServerHandler 类,该类将具有线程函数和套接字实例。您的 UI 只需要将数据提供给 ServerHander 类即可发送到服务器。【参考方案3】:

“如何在多线程函数MFC中获取对话框类的指针”? 你不。任何具有句柄的对象(包括 MFC 窗口对象)都应将句柄传递给线程。手柄是独一无二的。如果您发送一个指针,它将指向线程本地存储中的不同区域(如果有)。 使用发送/发布消息 API 将消息发送到对话框。 您可以使用自定义消息或注册消息。

【讨论】:

以上是关于如何在多线程函数MFC中获取对话框类的指针的主要内容,如果未能解决你的问题,请参考以下文章

在多线程崩溃的 MFC 中使用 Techart activeX

在多线程情况下,如何获取当前线程id

怎么在基于对话框的MFC程序中实现多线程?

如何在多线程中将指针传递给子类 Qthread

怎么在基于对话框的MFC程序中实现多线程?

MFC C++ 在回调函数中编辑 Windows 控件