如何在动态加载的DLL中创建CPaneDialog

时间:2015-04-21 20:32:55

标签: c++ dll mfc

我有一个带有MFC(静态链接)的DLL和一个用MFC编写的主应用程序。

我在DLL中创建了一个CPaneDialog和一个CDialog,但我无法在DLL中调用CPaneDialog::Create函数,因为我没有指向parentWnd的指针。我也无法在主MFC应用程序中调用CPaneDialog::Create,因为它缺少对话框资源。

如何做到这一点?

更新

正如Dan建议的那样,我现在使用传递给DLL的指针调用create函数:

DLL中的代码:

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

  AFX_MANAGE_STATE(AfxGetStaticModuleState());

  CPaneDialog *_gui = new CPaneDialog;
  CWnd *_ptr = (CWnd*)ptr;

  _gui->Create(_T("DialogBar"), _ptr, TRUE, (IDD_DIALOG1),
    WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
    154980);

}

这称为如下(主应用程序,派生自CWinAppEx的类):

(...)
ToolboxInitFunc func = (ToolboxInitFunc)GetProcAddress(dll_instance, "init_toolbox_gui");

func(m_pMainWnd);
(...)

这不起作用并创建断言失败。可能有什么不对?

更新2

现在我正在传递主窗口HWND,如下所示:

ToolboxInitFunc func = (ToolboxInitFunc)GetProcAddress(dll, "init_toolbox_gui");

    func(m_pMainWnd->GetSafeHwnd());

但我得到以下失败的断言:

ENSURE(m_pDockManager != NULL);

这是调用堆栈

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++

1 个答案:

答案 0 :(得分:1)

您可以将NULL作为父窗口传递给MFC对话框的构造函数,或传递给CPaneDialog :: Create()。实际上,如果你查找CDialog::Create(),CWnd * pParentWnd参数是可选的,默认为NULL,并且doc声明,"如果它是NULL,则设置对话框对象的父窗口到主应用程序窗口。"

但是你可能想拥有一个全球性的" C"从DLL导出的函数,它将父窗口的HWND作为参数,然后使用传入的HWND调用CWnd::FromHandle(),并在调用CPaneDialog :: Create()时将其用作父CWnd。导出的函数应以AFX_MANAGE_STATE(AfxGetStaticModuleState());开头,以便正确加载DLL中的资源。