将已完成的MFC对话框工程打包成动态dll,供另一个对话框工程调用(模态和非模态)

1. 首先设置将要打包成dll的对话框工程:项目->xxx属性->配置属性->常规->配置属性设为动态库(.dll)

2. 在xxxDlg.c文件头部添加如下代码:

作为模态对话框调用:

extern "C" __declspec(dllexport)void ShowDialog()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    xxxDlg dlg;
    dlg.DoModal();
}

作为非模态:

extern "C" __declspec(dllexport)CxxxDlg *ShowDialog()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    CxxxDlg *Dlg = new CxxxDlg;
    Dlg->Create(CxxxDlg::IDD);
    Dlg->ShowWindow(SW_SHOW);
    return Dlg;
}

3. 将xxx.c文件中的CxxxApp theApp以及xxx.h文件中的extern CxxxApp theApp注释。

4. 将xxx.c文件中,InitInstance()函数内显示对话框的一段代码注释,如下所示:

CxxxDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
        // TODO: 在此放置处理何时用
        //  “确定”来关闭对话框的代码
    }
    else if (nResponse == IDCANCEL)
    {
        // TODO: 在此放置处理何时用
        //  “取消”来关闭对话框的代码
    }*

5. 修改调用此dll的对话框代码,如下:

1). 在xxxDlg.c文件中的OnInitDialog()函数中加入如下代码:

作为模态对话框:

HINSTANCE hDll = LoadLibrary(L"xxx.dll");
    if(NULL == hDll)
    {
        MessageBox(L"DLL加载失败");
    }
    else
    {
        FARPROC proc;
        proc = GetProcAddress(hDll, "ShowDialog");
        proc();
    };

SendMessage(WM_CLOSE);

作为非模态对话框:

HINSTANCE hDll = LoadLibrary(L"xxx.dll");
    if(NULL == hDll)
        AfxMessageBox(L"xxx.dll 加载失败");
    else
    {
        
        typedef CxxxDlg*(*lpCall)(void);
        lpCall pShowDlg = (lpCall)GetProcAddress(hDll, "ShowDialog");
        if(NULL == pShowDlg)
        {
            AfxMessageBox(L"xxx.dll 中函数寻找失败");
        }
        CxxxDlg *m_lpCall =  pShowDlg();
        
    }*

2). 将打包成DLL工程代码的.h复制到调用dll的工程代码目录下(除了targetver.h   stdafx.h   Resource.h之外的所有要用到的.h)

3). 将生成的xxx.dll和xxx.lib复制到调用该dll工程代码,生成exe同等目录下。至此,结束。

 

心得:

1. 模态和非模态的区别:

若调用的是模态,则在代码运行时,dll的对话框先出现,调用dll的对话框不出现,但在关闭dll对话框时,会发生错误,此时调用SendMessage(WM_CLOSE),可消除错误,具体原因不是很清楚,因该是窗口句柄关闭了,然后又关闭,导致错误。

若调用的是非模态,则dll对话框和调用dll的对话框会同时出现,只有关闭调用dll的对话框才会同时关闭,此时不会出现错误。

两种方式遇到的问题:

1. 两种方式同时遇到的问题,当dll工程中存在子对话框向父对话框发送消息时,此时会找不到父对话框句柄,大概猜测可一下,应该是代码认为调用dll的对话框是主对话框,结果发送的对象就是调用dll的对话框,从而导致错误。

2. 非模态遇到的问题 是,当dll工程中,有调用FileDialog的函数时,程序会死掉,具体原因不清楚,但模态就不会。

你可能感兴趣的:(c++,MFC)