如何在 CWinThread 派生类中正确创建 CDialog 框
Posted
技术标签:
【中文标题】如何在 CWinThread 派生类中正确创建 CDialog 框【英文标题】:How to properly create a CDialog box in a CWinThread derived class 【发布时间】:2013-09-28 22:29:30 【问题描述】:我有一个 MFC 常规 DLL 项目,在 Visual Studio 2008 下运行良好,但是当项目升级到 VS 2010 时,出现了一个新问题,即 appcore.cpp 中的以下断言将失败:
CWinApp::CWinApp(LPCTSTR lpszAppName)
[...]
ASSERT(AfxGetThread() == NULL);
当创建了多个 CDialog 派生类的实例时,断言将失败。根据我在网络上所做的研究,似乎 MFC 的行为发生了变化,这会导致此故障。
根据我的阅读,解决此问题的方法是在新的 CWinThread 中创建每个 CDialog 派生类,但我遇到了同样的问题,所以,我确定我的实现中缺少一些东西,但是,我不知道缺少什么。
我曾经尝试在 CWinThread 类中创建 CDialog 的示例来自 http://www.experts-exchange.com/Programming/System/Windows__Programming/A_1886-Create-a-Dialog-in-its-Own-Thread.html,但是我的代码仍然在上面列出的 ASSERT 处失败。
所以我的问题是,有没有人有一个很好的例子,有源代码,关于如何在 MFC 常规 DLL 中使用 CWinThread 正确创建多个 CDialog 派生类?
哦,如果我对创建多个线程来解决上面列出的 ASSERT 的理解是错误的,请告诉我原因。
【问题讨论】:
你在实例化多个CWinApp
对象吗?
当不是由 MFC 创建且不是由 MFC 准备的线程使用 MFC 函数之一时,会发生断言。... 在 DLL 中包含代码的问题是,您不需要知道哪个threed正在使用该代码。启动 MFC 线程并在新线程中调用 DoMdal 没有问题。它永远不会断言
@xMRi 您的描述与断言不符。断言要求AfxGetThread()
返回NULL
。
@IInspectableless,我的原始代码是创建多个 CWinApp 实例,我在网上阅读过这样做会导致问题。在我的新代码中,CWinApp 似乎仍然被多次调用,但是,我注意到有一次它没有在上面列出的行中获得 ASSERT,而是在其他地方失败,我现在无法重现。
哦!对不起!但在这种情况下,您创建了一个额外的 CWinApp 对象!为什么?每个 exe 始终只有一个与主线程关联的 CWInAp 对象。每个常规 DLL 可能有一个额外的。对于您创建的每个线程,您可能有多个 CWinThread 对象。 CWinAp 对象是“每个模块的单例”...
【参考方案1】:
不幸的是,问题的答案实际上涉及到正在使用的 MFC 版本。 DLL 使用的是 mfc10,而宿主应用程序链接到 mfc9;将 DLL 更改为使用 mfc9 后,上面列出的问题就消失了。
【讨论】:
以上是关于如何在 CWinThread 派生类中正确创建 CDialog 框的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 CWinThread 在 MFC 中创建工作线程?