调用DLL中的MDI窗体

Alpha_Gu 2003-04-22 03:29:06
以下是我在网上看到的文章,但是我看不明白。
在C++Builder程序中,如果主窗体是MDI窗体而又要使用DLL中的MDI窗体时,VCL就会产生异常,即“No MDI forms are currently active”。这是因为在显示MDI子窗体时,VCL将检查Application对象的MainForm属性是否有效,虽然DLL中也包含Application对象,但VCL检查的是DLL中的MainForm属性,而不是Application对象中的属性,DLL中并没有主窗体,所以总是无效,就会产生异常。
解决方法是需要将Application赋予调用应用程序的Application对象,当然这只适用于调用应用程序是VCL应用程序。不过这样做在删除DLL之前必须使DLL中的Application对象恢复原来的状态,以便VCL内存管理器释放为DLL分配的内存。具体操作时就是把DLL中的Application对象指针存放在DLL的全局变量中,在删除DLL之前恢复原状态。
显示DLL中的MDI子窗体的操作步骤如下:
1、在DLL源代码单元开始处加入代码“TApplication *DllApp=0;”,以用来生成DLL中的全局变量TApplication指针。
2、指针赋值为0,目的是用来判断其是否已赋值。
3、将DLL中的Application对象存放在全局变量TApplication指针中。
4、将调用应用程序的Application对象赋予DLL中的Application对象。
5、生成和显示MDI子窗体。
生成切换TApplication和建立子窗体的函数如下:
void ShowMDIChildForm(TApplication *MainApp)
{
if(!DllApp)
{
DllApp=Application;
Application=MainApp;
}
TChildForm *Child = new TChildForm(Application->MainForm);
Child->Show();
}
该函数需要传入调用应用程序的Application对象。为了保证Application对象只设置一次,我们用if语句来判断DllApp指针是否已赋值,如果没有,则将Dll的Application对象赋予临时指针,并将调用应用程序的Application对象赋予Dll的Application对象。最后生成MDI窗体,传递调用应用程序的MainForm作为所有者,并显示窗体。
6、在删除DLL之前,需要恢复Dll的Application对象。由于在调用应用程序主窗体的OnClose()事件处理器中完成该操作太迟,此时DLL已经被删除,因此需要在主窗体的OnCloseQuery()事件处理程序中进行。实现方法见如下代码:
void ResetDllApplication()
{
if(DllApp)
Application=DllApp;
}
这样在OnCloseQuery()事件中调用该函数,就可以确保DLL顺利删除。

请高手回答如下问题:
我生成一个Dll文件在主程序中调用,在Dll中加入一个Form,作为主程序的MDI,其中,Unit1.cpp为Dll入口函数所在的文件,Unit2.cpp和Unit2.h为Form所在的文件。
一、文中TApplication指针在哪个地方定义?
二、文中的两个函数ShowMDIChildForm和ResetDllApplication是怎么用的,ShowMDIChildForm要用__export __declspec(dllexport)导出吗?
三,在主程序的响应事件(如菜单项被选择)中,如何调用,使Dll中的Form可以作为主程序的MDIChild被使用。
请高手详细讲解一下,最好有例子,十分感谢!
...全文
70 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
qiuafa 2003-04-23
  • 打赏
  • 举报
回复
劫分&捧场

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧