关于DLL封装窗体的问题?

KEN180 2004-09-01 10:11:01
做了一个应用程序,主界面单独,其它子窗体封装在不同的DLL里,还有一个共享的窗体里面是一些图标,被各DLL及主窗体引用,但是在主窗体调用DLL里的子窗体的时候,其里面的图标不能显示,也就是我的共享图标窗体没创建,因此我的问题是:这个共享窗体何时在何处创建最合适,重复代码最少?
主窗体的dpr:
Application.Initialize;
Application.CreateForm(Tfrm_main,frm_main);
Application.CreateForm(Tfrm_share,frm_share);
Application.Run;
//主窗体的图标显示没有问题;
DLL里的dpr:
begin
oldApp:=Application;
end;
//在DLL里我要把Application变量保存,调用窗体要重新给Application赋值,然后在free前恢复Application的值;所以这个共享不知怎么去创建,对了现在还没搞明白DLL里的begin end;语句是何时被执行的??
...全文
207 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenxzh88 2004-09-01
  • 打赏
  • 举报
回复
楼主您好:
我现在也试图将程序模块化,可是没有做过DLL,不知道从哪着手去做,您能不能把你的主程序和其中的一个模块(dll)发给我,我想学习一下具体是怎么写的和如何调用的。非常感谢。邮箱:chenxzh_mail@163.com
司码君 2004-09-01
  • 打赏
  • 举报
回复
如果能够理解的话,我的方法还可以
写一个Component来调用Dll,在Component的某个方法中创建窗体,好比OpenDialog.Execute的形式,因为Component的头上可以use Forms所以能够使用Application,传入Dll中,这样你再使用DLL的时候就不用那么复杂了,并且DLL的复用率很高,每次调用很麻烦!!!!
Shiyl 2004-09-01
  • 打赏
  • 举报
回复
mark


----------------------------------------------------------------
花自飘零水自流,一种相思,两处闲愁。
此情无计可消除,才下眉头,又上心头。
----------------------------------------------------------------
KEN180 2004-09-01
  • 打赏
  • 举报
回复
谢谢楼上,可这不是我的问题答案.
我的问题简单说:就是DLL里的共享窗体何时创建?请仔细阅读顶层的问题!
oioioi-090 2004-09-01
  • 打赏
  • 举报
回复
以上取自于超级猛料!

再次强调,用全文检索,省点分:)
oioioi-090 2004-09-01
  • 打赏
  • 举报
回复
为何不用全文检索呢?

作为一个经常被提起的问题,很多人不知道怎么来从DLL中导出窗体,特别是MDI的子窗体,因此Kingron愿意在这里把一些经验写出来给大家分享,让大家在碰到类似的问题的时候,少走些弯路。

大家知道,DLL有两种加载方式,至于动态的,和静态的,稍微有点儿区别。动态的加载,大家可以参考Torry's Delphi Page上面的例子,其中有一个MDI的例子,非常简单的,很好用。我的例子以静态加载为主。

据目前来看,我们要在DLL中导出这个Form的话,必须通过DLL导出函数来做到,但是我们知道DLL工程的Application和Host程序的Application是有区别的,对于一般的应用程序来说,Application是VCL固定的,一般不会修改Application对象指针,但是在DLL中,我们需要使用窗体等,或者使用Application对象的时候,使DLL的Application和Host程序一样,这样才不至于混淆。以下面的例子为例,如果不修改Application对象,那么Host程序退出的时候,可能出现AV错误!例如:

在Host中Export一个函数:

function DllFunction(App:TApplication;PForm:TForm):TForm2;stdcall;

begin

Result :=TForm2.Create(PForm);

end;

那么主程序推出的时候,很可能发生AV错误。

下面一步一步来做:

首先,我们需要一个DLL工程,在IDE中New一个DLL,然后New一个Form,Save All File,工程名为DLL.DPR,Form的Unit文件为DLLForm.pas,窗体类名为FrmDLLChild。然后随便设计这个DLLChild Form即可。

然后,在DLL.DPR中修改代码,添加:

library Dll;

uses

SysUtils,windows,

Classes,Controls,Forms,

DllForm in 'DllForm.pas' ;

{$R *.res}

var

DllApp:TApplication;

{ 用于初始化:保存DLL本身的Application,然后设置DLL的Application指向Host的Application }

procedure InitDLL(App:TApplication);stdcall;

begin

DllApp:=Application;

Application:=App;

end;

{ 善后工作:恢复DLL原来的Application }

procedure FreeDLL;stdcall;

begin

Application:=DllApp;

end;

{ 返回一个窗体对象,这是DLL的主要功能 }

function GetDllChildForm(Parent:TComponent):TFrmDLLChild;stdcall;

begin

Result := TFrmDLLChild.Create(Parent);

end;

exports

InitDLL,FreeDLL,GetDllChildForm;

begin

end.

至此DLL已经完成了,在使用DLL的时候,需要注意:首先必须调用InitDLL,并且传递主程序的Application作为参数,否则主程序退出的时候,会报AV错误。

主程序调用如下:

为了简单方便地使用,可以把DLL中包含窗体的那个单元Use进来,如果不喜欢,用类型强制也可。

function GetDllChildForm(Parent:TComponent):TFrmDllChild;stdcall;external 'dll.dll';

procedure InitDLL(App:TApplication);stdcall;external 'dll.dll';

procedure FreeDLL;stdcall;external 'dll.dll';

procedure TForm1.FormCreate(Sender: TObject);

begin

InitDLL(Application);

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

FreeDLL;

end;

调用窗体代码:

var

DForm:TFrmDllChild;

begin

DForm :=DllFunction(Application,Self);

DForm.Show;

end;

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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