血本急求:将对话框放入 DLL 文件当中,在主程序中作为子窗口非模态显示,做完操作后,释放该 DLL 的方法

是这样的:小弟正在尝试MFC基于对话框的程序,将界面与逻辑分离的方法。也就是说,对于一个软件,将不同的功能模块,单独做成DLL,作为组件来加载,并且是动态使用这个DLL,... 是这样的:
小弟正在尝试 MFC 基于对话框的程序,将界面与逻辑分离的方法。
也就是说,对于一个软件,将不同的功能模块,单独做成 DLL,作为组件来加载,并且是动态使用这个 DLL,可随时加载、释放。

已经成功将两个对话框分别放入各自的DLL文件中,并且在主程序中作为子窗口非模态显示,能通过两个按钮,进行两个子对话框的切换

但是,当调用一个DLL ,显示其对话框以后,尝试释放另一个对话框所在的DLL,失败了。

一、下面是我的两个DLL:

1、在“DlgDllTest1.dll”中的实现函数中,导出函数:
extern "C" __declspec(dllexport) void ShowDlg()
{
// 获得父窗指针
HWND hWnd = ::FindWindow(NULL,_T("Main_Dlg"));
CWnd* cWnd = CWnd::FromHandle(hWnd);

// 如果没有子窗 testDlg1 的句柄,则创建,并显示
if( !theApp.testDlg1.m_hWnd )
theApp.testDlg1.Create(MAKEINTRESOURCE(IDD_DIALOG1),cWnd);

::SetWindowText(theApp.testDlg1.m_hWnd,_T("TestDlg1"));
theApp.testDlg1.ShowWindow(SW_SHOW);
}

2、在“DlgDllTest2.dll”中的实现函数中,导出函数:
extern "C" __declspec(dllexport) void ShowDlg()
{
// 获得父窗指针
HWND hWnd = ::FindWindow(NULL,_T("Main_Dlg"));
CWnd* cWnd = CWnd::FromHandle(hWnd);

// 如果没有子窗 testDlg2 的句柄,则创建,并显示
if( !theApp.testDlg2.m_hWnd )
theApp.testDlg2.Create(MAKEINTRESOURCE(IDD_DIALOG1),cWnd);

::SetWindowText(theApp.testDlg2.m_hWnd,_T("TestDlg2"));
theApp.testDlg2.ShowWindow(SW_SHOW);
}

二、下面是我在主程序(即父窗程序)中,根据按钮的ID号,集中处理了按钮的单击事件:
void CWADlgTestDlg::OnBtnClicked(UINT nBtnID)
{
// 先释放 DLL 模块句柄,
// hIns 是 CWADlgTestDlg 类的成员:public: HINSTANCE hIns;
// 并且在初始化函数OnInitDialog()中默认加载子窗口 testDlg1 所在的DLL:
// hIns = LoadLibrary(_T("DlgDllTest1.dll"));

// 各位请看,就是在下面这个地方,释放不成功,第一次点击按钮是成功的,
// 第二次就出异常了,意思就是,再次释放不成功

//if( hIns )
//FreeLibrary(hIns);

// 不管有没有显示子窗,先全部关闭
HWND hWnd1 = ::FindWindowEx(this->m_hWnd,NULL,NULL,_T("TestDlg1"));
HWND hWnd2 = ::FindWindowEx(this->m_hWnd,NULL,NULL,_T("TestDlg2"));

if( hWnd1 )
::CloseWindow(hWnd1);
if( hWnd2 )
::CloseWindow(hWnd2);

// 根据按钮ID号决定是显示哪个子对话框
switch(nBtnID)
{
case IDC_BUTTON1://点击按钮1,显示子对话框1
hIns = LoadLibrary(_T(".\\WAResDlg.dll"));
break;

case IDC_BUTTON2://点击按钮2,显示子窗2
hIns = LoadLibrary(_T(".\\WAEditDlg.dll"));
break;
}

typedef void (*pShowDlg)();
pShowDlg ShowDlg = (pShowDlg)GetProcAddress(hIns, "ShowDlg");
ShowDlg();
}

那么,我要怎么样才能实现这样的效果:
无论关闭哪个子 对话框,都能释放该子对话框所在的 DLL ?

虽然,不加 FreeLibrary(hIns);这一句来释放任何 DLL ,是可以达到子对话框的切换,而且没有异常,但是我的目的就是,随时可以随心所欲的加载我想要的子对话框的 DLL,不然的话,何必将子对话框放入 DLL,直接在主程序中新建对话框类,还轻松得多。

敬请各位前辈、高手,帮帮小弟,如果解决,分不是问题!
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
非常感谢 四位前辈的指导,三楼“何处淬吴钩”这位前辈,您告诉我的方法,用WM_CLOSE关闭不掉窗口,我已经证明不是子窗口句柄错了,但就是关闭不掉,如果用::DestroyWindow();,发生了异常,不如如何调试,很是晕乎。

四楼“qiujiejia” 这位前辈,您的方法,虽然复杂了点,但是有例子程序。看得出来,这是您亲自写了个程序,帮我验证和测试,虽然我已经在其他地方找到解决的方法,并且方法极为简单,还解决了资源释放的问题。但是,您辛苦了,亲自写程序,谢谢!

这样吧,四楼前辈的知道级别没有三楼前辈的高,就将此分酬谢给四楼前辈用于升级吧,但为了公平起见,本来三楼前辈已经指出了我的程序的“要害”之处,也要感谢的,所以,我结贴的时候就不加分了。

再次感谢各位的指导!
展开
 我来答
qiujiejia
推荐于2016-10-31 · TA获得超过499个赞
知道小有建树答主
回答量:304
采纳率:0%
帮助的人:247万
展开全部
你的对话框程序应该这样做:
1.当对话框按关闭,“确定”,取消 时 要摧毁窗口。

void CMyDlg::OnClose()
{
DestroyWindow();
}

void CMyDlg::OnBnClickedOk()
{
OnOK();
DestroyWindow();
}

void CMyDlg::OnBnClickedCancel()
{
OnCancel();
DestroyWindow();
}

2.添加虚函数PostNcDestroy ,使窗口关闭时可以自动删除自己。
因为你前面用了theApp.testDlg2.Create(MAKEINTRESOURCE(IDD_DIALOG1),cWnd);
用创建就必须有删除。

#define WM_USERDEFMSG WM_USER + 101 //自定义消息

void CMyDlg::PostNcDestroy()
{
//删除自己
delete this;

//向主窗口发送自定义消息,告知对话框已关闭,可以调用FreeLibrary
::PostMessage(::FindWindow(NULL,"Demo"),WM_USERDEFMSG,NULL,NULL);

CDialog::PostNcDestroy();
}

3.主窗口添加自定义消息。
捕获来自子对话框的消息,并调用FreeLibrary
//自定义消息
LRESULT CDemoDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
HMODULE hModule = GetModuleHandle(_T("mydll.dll"));
ASSERT(hModule);

if (hModule)
FreeLibrary(hModule);

return 0;
}

例子下载:
http://cid-3ba16e78a53d2d3d.office.live.com/self.aspx/VC/Free-Dll-Dlg.zip(请不要使用下载工具)
阿弥陀佛!愿顺利!
何处淬吴钩
2011-09-22 · TA获得超过5044个赞
知道大有可为答主
回答量:2947
采纳率:50%
帮助的人:2396万
展开全部
你closewindow用在这里有问题。可以换为destroywindow,不过最好是发送WM_CLOSE消息。

你加载dll并调用其中资源后,必须先释放掉你使用的资源,才能freelibray。
反应在你的这个程序里,你每个dll都创建了一个线程,所以你需要一个句柄来保存当前在dll中创建的窗口,先要关闭掉窗口(WM_CLOSE)才能freelibrary
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
淡然还傲然的才俊i760
2011-09-22
知道答主
回答量:19
采纳率:0%
帮助的人:2.9万
展开全部
硬盘问题
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式