做了一个应用程序,主界面单独,其它子窗体封装在不同的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;语句是何时被执行的??

解决方案 »

  1.   

    楼主您好:
        我现在也试图将程序模块化,可是没有做过DLL,不知道从哪着手去做,您能不能把你的主程序和其中的一个模块(dll)发给我,我想学习一下具体是怎么写的和如何调用的。非常感谢。邮箱:[email protected]
      

  2.   

    为何不用全文检索呢?作为一个经常被提起的问题,很多人不知道怎么来从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;beginResult :=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;usesSysUtils,windows,Classes,Controls,Forms,DllForm in 'DllForm.pas' ;{$R *.res}varDllApp:TApplication;{ 用于初始化:保存DLL本身的Application,然后设置DLL的Application指向Host的Application }procedure InitDLL(App:TApplication);stdcall;beginDllApp:=Application;Application:=App;end;{ 善后工作:恢复DLL原来的Application }procedure FreeDLL;stdcall;beginApplication:=DllApp;end;{ 返回一个窗体对象,这是DLL的主要功能 }function GetDllChildForm(Parent:TComponent):TFrmDLLChild;stdcall;beginResult := TFrmDLLChild.Create(Parent);end;exportsInitDLL,FreeDLL,GetDllChildForm;beginend.至此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);beginInitDLL(Application);end;procedure TForm1.FormDestroy(Sender: TObject);beginFreeDLL;end;调用窗体代码:varDForm:TFrmDllChild;beginDForm :=DllFunction(Application,Self);DForm.Show;end;
      

  3.   

    谢谢楼上,可这不是我的问题答案.
    我的问题简单说:就是DLL里的共享窗体何时创建?请仔细阅读顶层的问题!
      

  4.   

    如果能够理解的话,我的方法还可以
    写一个Component来调用Dll,在Component的某个方法中创建窗体,好比OpenDialog.Execute的形式,因为Component的头上可以use Forms所以能够使用Application,传入Dll中,这样你再使用DLL的时候就不用那么复杂了,并且DLL的复用率很高,每次调用很麻烦!!!!