【问题标题】:Assertion failed when creating CPaneDialog In MFC在 MFC 中创建 CPaneDialog 时断言失败
【发布时间】:2015-06-30 01:26:13
【问题描述】:

我有一个简单的 .exe MFC 项目和一个静态链接 MFC 的 DLL 项目。它导出以下用于创建 CPaneDialog 的函数:

extern "C" __declspec(dllexport) void init_toolbox_gui(HWND ptr) {

AFX_MANAGE_STATE(AfxGetStaticModuleState());

CPaneDialog *_gui = new CPaneDialog;
CWnd *p = CWnd::FromHandle(ptr);

_gui->Create(_T("DialogBar"), p, TRUE, (IDD_DIALOG1),
    WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI,
    0);

}

我从我的主 .exe 应用程序类(派生自 CWinAppEx)中调用它,如下所示:

// dll is a handle to the DLL lib
ToolboxInitFunc func = (ToolboxInitFunc)GetProcAddress(dll, "init_toolbox_gui"); 

func(m_pMainWnd->GetSafeHwnd());

这在void CMFCDragFrameImpl::Init(CWnd* pDraggedWnd) 中的以下调试断言中失败:

m_pDockManager = afxGlobalUtils.GetDockingManager(pDockSite);
ENSURE(m_pDockManager != NULL);

我可以给出该函数的完整代码,但它来自标准 MFC 库。

这是调用堆栈:

toolbox-3d.dll!CMFCDragFrameImpl::Init(CWnd * pDraggedWnd) Line 106 C++
toolbox-3d.dll!CPane::CreateEx(unsigned long dwStyleEx, const wchar_t * lpszClassName, unsigned long dwStyle, const tagRECT & rect, CWnd * pParentWnd, unsigned int nID, unsigned long dwControlBarStyle, CCreateContext * pContext) Line 177   C++
toolbox-3d.dll!CDockablePane::CreateEx(unsigned long dwStyleEx, const wchar_t * lpszCaption, CWnd * pParentWnd, const tagRECT & rect, int bHasGripper, unsigned int nID, unsigned long dwStyle, unsigned long dwTabbedStyle, unsigned long dwControlBarStyle, CCreateContext * pContext) Line 175   C++
toolbox-3d.dll!CDockablePane::Create(const wchar_t * lpszWindowName, CWnd * pParentWnd, CSize sizeDefault, int bHasGripper, unsigned int nID, unsigned long dwStyle, unsigned long dwTabbedStyle, unsigned long dwControlBarStyle) Line 148 C++
toolbox-3d.dll!CPaneDialog::Create(const wchar_t * lpszWindowName, CWnd * pParentWnd, int bHasGripper, const wchar_t * lpszTemplateName, unsigned int nStyle, unsigned int nID, unsigned long dwTabbedStyle, unsigned long dwControlBarStyle) Line 48   C++
toolbox-3d.dll!CPaneDialog::Create(const wchar_t * lpszWindowName, CWnd * pParentWnd, int bHasGripper, unsigned int nIDTemplate, unsigned int nStyle, unsigned int nID) Line 42 C++
toolbox-3d.dll!init_toolbox_gui(HWND__ * ptr) Line 45   C++

可能出了什么问题?

【问题讨论】:

    标签: c++ dll mfc


    【解决方案1】:

    您不能“单独”使用对接功能。

    这个对接的东西需要一个专门准备的 CFrameWndEx 类。如果 MFC 项目使用这样的类,当你想使用 DLL 时,你就不得不使用动态链接的 MFC。

    您获得的 ASSERT 只是一个指示,表明当前模块(您的 DLL)既没有框架也没有停靠管理器来支持此类可停靠窗格。

    原因很简单。静态链接的 EXE 和 DLL 将只使用自己的 CObject 表示,因此 MFC 内部使用的所有 IsKindOf 调用都只能在模块内部工作。

    【讨论】:

    • 谢谢!但是,我想将我的代码与带有静态链接 (/MT) 的运行时库一起使用。也许我应该使用另一种策略从 DLL 导出停靠窗格?
    • 当您想从 MFC 使用此功能时,无法使用静态链接。为此,您应该始终使用扩展 DLL。顺便说一句:为什么要坚持使用链接。它花费了更多的内存。加载此类多个 DLL 的速度较慢,MFC 功能的灵活性较低,并且...
    • 但是我也可以将运行时链接用作静态链接吗?即 /MT
    • 只有在共享 DLL 版本中使用 MFC 和 CRT 时才能执行此操作。您坚持静态链接的原因是什么。当使用使用标准 DLL 的独立程序时,这是可以的。当使用复杂的 DLL szenarios 和插件技术时,我会说在共享庄园中使用 CRT 和 MFC 是更好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多