Экспорт диалогового окна MFC от DLL

21-го июля: Обновленный, посмотрите нижнюю часть

В VC ++ 2005 у меня есть 2 проекта. Во-первых, проект DLL MFC (не дополнительный DLL), который имеет простое диалоговое окно:

TestDlg.h

#pragma once
#include "afxwin.h"
#include "resource.h"
// CTestDlg dialog
namespace Dialogs
{
    class __declspec(dllexport) CTestDlg : public CDialog
    {
        DECLARE_DYNAMIC(CTestDlg )

    public:
        CTestDlg (CWnd* pParent = NULL);   // standard constructor
        virtual ~CTestDlg ();

    // Dialog Data
        enum { IDD = IDD_TEST_DLG };
    }
}

Затем у меня есть приложение консоли Win32 с библиотеками MFC, который делает:

TestApp.cpp

#include "stdafx.h"
#include "TestApp.h"
#include <TestDlg.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: MFC initialization failed\n"));
        nRetCode = 1;
    }
    else
    {

        Dialogs::CTestDlg dlg;
        dlg.DoModal();
    }
    return nRetCode;
}

Это создает и увеличивается, но никакое диалоговое окно не появляется. Продвижение в DoModal ()...

dlgcore.cpp

INT_PTR CDialog::DoModal()
{
    // can be constructed with a resource template or InitModalIndirect
    ASSERT(m_lpszTemplateName != NULL || m_hDialogTemplate != NULL ||
        m_lpDialogTemplate != NULL);

    // load resource as necessary
    LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;
    HGLOBAL hDialogTemplate = m_hDialogTemplate;
    HINSTANCE hInst = AfxGetResourceHandle();
    if (m_lpszTemplateName != NULL)
    {
        hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
        HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
        hDialogTemplate = LoadResource(hInst, hResource);
    }
    if (hDialogTemplate != NULL)
        lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);

    // return -1 in case of failure to load the dialog template resource
    if (lpDialogTemplate == NULL)
        return -1;

    ... more stuff

По любой причине кажется, что это не может загрузить ресурс, возвратившись-1 в конце скопированного раздела. Я посмотрел на несколько статей о CodeGuru, и т.д., и не видел что-либо очевидное. Мой класс не являющийся, экспортировал/импортировал право? Или действительно ли это - проблема ресурса? Или состоит в том проблема, что я пытаюсь отобразить его от консоли (MFC) приложение?

21-го июля Обновление я создал переопределенный DoModal как так:

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

Это, кажется, работает, хотя должен я переопределить другой метод для получения более универсальной функциональности?

6
задан Mr. Boy 21 July 2010 в 08:13
поделиться

2 ответа

Как вы заметили, проблема в том, что MFC не находит ресурс, поскольку контекст модуля установлен на ваш основной EXE, а не на DLL, содержащую ресурс диалога.

Ручной вызов AFX_MANAGE_STATE, чтобы убедиться, что контекст DLL установлен, является одним из способов решения этой проблемы, но он не прозрачен. Идеальным способом является компиляция вашей DLL как DLL расширения, чтобы MFC мог позаботиться о загрузке ресурса из списка DLL расширения и управлении памятью между DLL.

Возможно, вы сможете обойтись без создания DLL расширения и просто создать собственный экземпляр CDynLinkLibrary, который добавит вашу DLL в список основных ресурсов. Я не пробовал этого, предпочитая вместо этого использовать путь расширения DLL _AFXDLL, так что это может сработать, а может и нет.

Статья MSDN о DLL расширения может помочь вам определить, подходят ли они в вашем случае, и какие преимущества/недостатки они дают.

9
ответ дан 8 December 2019 в 14:39
поделиться

Я не уверен, что эта конструкция действительно может работать. Если возможно, экспортируйте только функцию, которая открывает диалог внутри DLL.

Но, возможно, вам поможет использование макроса AFX_MANAGE_STATE .

2
ответ дан 8 December 2019 в 14:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: