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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了血本急求:将对话框放入 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” 这位前辈,您的方法,虽然复杂了点,但是有例子程序。看得出来,这是您亲自写了个程序,帮我验证和测试,虽然我已经在其他地方找到解决的方法,并且方法极为简单,还解决了资源释放的问题。但是,您辛苦了,亲自写程序,谢谢!

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

再次感谢各位的指导!

你的对话框程序应该这样做:
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(请不要使用下载工具)
阿弥陀佛!愿顺利!
参考技术A 你closewindow用在这里有问题。可以换为destroywindow,不过最好是发送WM_CLOSE消息。

你加载dll并调用其中资源后,必须先释放掉你使用的资源,才能freelibray。
反应在你的这个程序里,你每个dll都创建了一个线程,所以你需要一个句柄来保存当前在dll中创建的窗口,先要关闭掉窗口(WM_CLOSE)才能freelibrary
参考技术B 硬盘问题

我的电脑老是丢失dll文件是怎么回事?

前几天打开酷狗提示缺失DLL文件,今天是迅雷缺失dll文件,到底是怎么了?

方法/步骤
1、首先,当提示出现这种文件丢失的对话框的时候,我们不要关闭这个对话框。打开百度,输入dll文件下载,可以找到许多专门提供dll文件下载的网站。然后在网站里面输入,对话框当中的dll文件,点击搜索。找到这个文件之后,下载下来。接着上传下载的文件到原文件所在的文件夹,具体的路径,在下载文件的网站上面,会有所提示。

2、如果以上方法无法解决你的问题。比如找不到dll文件,那么你就需要使用360系统急救箱,点开之后,360会自动核对你系统文件里面的所有文件,如果发现有缺失的dll文件,会自动筛选出来,然后你只需要点击修复即可!
3、当然,如果以上两种方法都觉得麻烦的话,那么最简单的方式就是使用“360电脑专家”,用言简意赅的文字描述你的问题,比如缺少npptools.dll文件,我们就可以直接在“360电脑专家”对话框当中输入“缺少npptools.dll”,根据提示操作即可!
参考技术A dll是你的应用程序正常运行的动态链接库文件,应该是电脑中毒了,杀毒软件把这些感染病毒的文件删除了 查看更多答案>>本回答被提问者采纳

以上是关于血本急求:将对话框放入 DLL 文件当中,在主程序中作为子窗口非模态显示,做完操作后,释放该 DLL 的方法的主要内容,如果未能解决你的问题,请参考以下文章

急求各位大侠帮忙,缺文件core.dll,怎么办?

当我在matlab中运行文件时出现对话框,应该怎么 办? 急求答案。。

急求:VB能不能有背景音乐

电脑出现缺失DLL文件怎么办?

何谓DLL文件?

我的电脑老是丢失dll文件是怎么回事?