Visual c++ 从DLL导出MFC对话框

Visual c++ 从DLL导出MFC对话框,visual-c++,dll,mfc,Visual C++,Dll,Mfc,7月21日:更新,见底部 在VC++2005中,我有两个项目。首先,一个MFC DLL项目(不是扩展DLL),它有一个简单的对话框: TestDlg.h 然后我有一个带有MFC库的Win32控制台应用程序,它可以: TestApp.cpp 无论出于何种原因,它似乎无法加载资源,在复制的部分末尾返回-1。我看过一些关于CodeGuru等的文章,没有看到任何明显的东西。我的类是否未被导出/导入?还是资源问题?或者问题是我试图从控制台(MFC)应用程序显示它 7月21日更新 我创建了一个覆盖的DoMo

7月21日:更新,见底部

在VC++2005中,我有两个项目。首先,一个MFC DLL项目(不是扩展DLL),它有一个简单的对话框:

TestDlg.h 然后我有一个带有MFC库的Win32控制台应用程序,它可以:

TestApp.cpp 无论出于何种原因,它似乎无法加载资源,在复制的部分末尾返回-1。我看过一些关于CodeGuru等的文章,没有看到任何明显的东西。我的类是否未被导出/导入?还是资源问题?或者问题是我试图从控制台(MFC)应用程序显示它

7月21日更新 我创建了一个覆盖的DoModal,如下所示:

INT_PTR CTestDlg::DoModal()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
    return CDialog::DoModal();
}

这似乎是可行的,但我是否应该重写另一种方法以使功能更通用?

我不确定这种构造是否真的可行。如果可能,只导出一个函数,该函数将打开DLL内的对话框


但是,也许使用
AFX\u MANAGE\u STATE
-宏可以帮助您。

正如您所指出的,问题在于MFC找不到资源,因为模块上下文设置为您的主EXE,而不是包含对话框资源的DLL

手动调用AFX_MANAGE_STATE以确保建立DLL上下文是实现这一点的一种方法,但它不是透明的。理想的方法是将DLL编译为扩展DLL,这样MFC就可以从扩展DLL列表加载资源并管理DLL之间的内存

您可以简化创建扩展DLL的过程,只需创建自己的
CDynLinkLibrary
实例,即可将DLL添加到主资源列表中。我没有尝试过这种方法,而是选择了扩展dll AFXDLL路径,因此这可能会起作用,也可能不会起作用


上的MSDN文章可能会帮助您确定它们是否适合您的情况,以及它们带来的优点/缺点。

明确地加载您的*.lib

Hinstance = Loadlibray("*.lib");

AfxSetResourceHandle(Hinstance);
// this way you can load the resource in you dll not the current app's resource.
然后,您需要输入以下代码:

CTestDlg dlg;
dlg.DoModal();

AFX_MANAGE_STATE不适合我。在我的例子中,exe从另一个dll调用一个对话框,而另一个dll从第三个dll调用另一个对话框。AFX_管理_状态正在返回第二个dll的上下文,而不是第三个dll的上下文。为了解决这个问题,我覆盖了DoModel并在那里进行了上下文切换

INT_PTR YourDialog::DoModal()
{
    HINSTANCE _hInstance = AfxGetResourceHandle();

    __try
    {
        HMODULE dllModule = ::GetModuleHandle("<Your_DlgSourceDll>.dll");
        AfxSetResourceHandle(dllModule);
        return CDialog::DoModal();
    }
    __finally
    {
        AfxSetResourceHandle(_hInstance);
    }
}
INT\PTR YourDialog::DoModal()
{
HINSTANCE _HINSTANCE=AfxGetResourceHandle();
__试一试
{
HMODULE dllModule=::GetModuleHandle(“.dll”);
AfxSetResourceHandle(DLL模块);
返回CDialog::DoModal();
}
__最后
{
AfxSetResourceHandle(中国);
}
}

在我读到的几个地方,您可以从DLL导出基于CDialog的类。但是您的建议不错,像
Dialogs::CTestDlg*Dialogs::ShowTestDlg()
?是的,类似这样的方法,但不返回指向dialog类的指针。在这种情况下,你需要再次了解这个班级!我已经很长时间没有与MFC合作了,但我怀疑就是这样。我认为问题在于,应用程序和DLL之间有单独的资源/ID到类映射池,即使它们都是MFC,也不能访问彼此的资源/ID到类映射池。我认为,过去一直困扰我的一个问题是HWND到类的映射是每个线程(或者类似的东西)。有什么理由不使用MFC扩展DLL吗?扩展DLL设法进入应用程序的资源链,这样您的对话框就会找到它的资源。但我刚刚在你的更新中看到,我与AFX_MANAGE_STATE的提示也起到了作用!
Hinstance = Loadlibray("*.lib");

AfxSetResourceHandle(Hinstance);
// this way you can load the resource in you dll not the current app's resource.
CTestDlg dlg;
dlg.DoModal();
INT_PTR YourDialog::DoModal()
{
    HINSTANCE _hInstance = AfxGetResourceHandle();

    __try
    {
        HMODULE dllModule = ::GetModuleHandle("<Your_DlgSourceDll>.dll");
        AfxSetResourceHandle(dllModule);
        return CDialog::DoModal();
    }
    __finally
    {
        AfxSetResourceHandle(_hInstance);
    }
}