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的函数时,程序会死掉,具体原因不清楚,但模态就不会。