使用DLL文件中封装的窗口http://www.csdn.net/Develop/read_article.asp?id=10919自已看吧·

解决方案 »

  1.   

    传递一个 application,其它的和正常的mdi类似;
      

  2.   

    代码如下:
    library mdidll;
    uses
    Windows,
    Messages,
    SysUtils,
    Classes,
    Graphics,
    Controls,
    Forms,
    Dialogs,
    mdi_Unit in 'mdi_Unit.pas' {Form1};procedure LoadChild(ParentApplication: TApplication; ParentForm: TForm); export; stdcall;
    var
    Form1: TForm1;
    DllProc: Pointer; begin
    Application:=ParentApplication;
    Form1:=TForm1.Create(ParentForm);
    Form1.MyParentForm:=ParentForm;
    Form1.MyParentApplication:=ParentApplication;
    Form1.Show;
    end;procedure DLLUnloadProc(Reason: Integer); register;
    begin
    if Reason = DLL_PROCESS_DETACH then Application:=DllApplication;
    end;{$R *.res}
    exports
    LoadChild;
    begin
    DllApplication:=Application;
    DLLProc := @DLLUnloadProc;
    end.
    1,请问:为什么要定义MyParentForm,ParentApplication作用是什么,
         释放的原理是什么?
    2,我要实现父窗体,用代码的方法关闭dll的mdi,如何实现???
    3,如何判断,dll的窗体已经打开
    4,如何使已经打开的dll窗体显示在前面
      

  3.   

    http://www.csdn.net/expert/topic/628/628608.xml?temp=.1550409
      

  4.   

    相关讨论很多,不过除了“带包编译”是最好的办法,还真没别的好办法了。
    传application之类的方法都由很大的缺陷,如果你的工程涉及到复杂的处理,你就会产生一大堆你想不到的问题了。
    以前做过,吃了不少亏了。呵呵
      

  5.   

    1,请问:为什么要定义MyParentForm,ParentApplication作用是什么,
         释放的原理是什么?
    2,我要实现父窗体,用代码的方法关闭dll的mdi,如何实现???
    3,如何判断,dll的窗体已经打开
    4,如何使已经打开的dll窗体显示在前面
      

  6.   

    传递Application 是必须的,其它的 parentform可是通过application.mainform来得到;
    在这方面,delphi本身是有不少问题,但,我们经常可以通过 sendmessage来实现解决问题的途径。我们可以用消息来传递各个 dll窗体的 handle, 可以用自定义消息在主窗体里面来关闭dll里的窗体;和进行其它的操作
      

  7.   

    传递 Application是必须的, mainform可以通过  application得到;在delphi的 mdi + dll里,我们经常要通过自定义消息来做一些标准消息可以做的事,比如,你的2,3,4.通过自定义消息来通知主窗体,来发送子窗体的handle.
      

  8.   

    还是带包VCL50。BPL编译所有的EXE和DLL吧,这样无须再传递Applicaiton,因为DELPHI的包能使调用它的模块(EXE和DLL)共用一个全局Application和Screen,但是DLL句柄应设置为全局变量,在关闭主程序时再释放DLL,之前最好用循环关闭所有的子窗体.1.应为DLL和EXE都有各自的APPLICATION,所以传递APPLICATION到DLL,使两者共用一个Application,传递MyParentForm 可能是解决这样的问题:因为DLL中的
    MDICHILD不能自动增加到MDI主窗体的MDICHILDREN数组中,所以想通过传递MyParenForm来解决,但是事实上只有传递SCREEN到DLL中,并赋给DLL的SCREEN就可自行解决2.释放的原理: 第一次LoadLibrary把DLL计数设为1,并映射DLL到EXE的进程空间,以后再LoadLibrary,如果DLL没有释放则计数递增1;FreeLibrary每调用一次就使DLL计数递减1,如果DLL计数为0,则释放DLL,如果其中的资源例如FORM没有释放就会出错!
      我们通常是LoadLibrary后调用FORM就马上FreeLibrary,这时DLL计数为0(LoadLibrary初次为1,而FreeLibrary为减1,计数自然为0 ),DLL自动释放,而FORM作为其中的资源却没有释放自然会出错!
      

  9.   

    //DLL
    library Func;uses
      ShareMem,
      SysUtils,
      Classes,
      Forms,
      Windows,
      MConnect,
      Child2 in 'Child2.pas' {FormChild2};{$R *.RES}procedure CallModule();stdcall;export;
    begin
        if not Assigned(FormChild2) then
            FormChild2 := TFormChild2.Create(Application);
        FormChild2.Show;
    end;exports
       CallModule;begin
    end;//MDIChild单元:procedure TFormChild2.N9Click(Sender: TObject);
    begin
        Close;
    end;procedure TFormChild2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
        Action := caFree;
    end;procedure TFormChild2.FormDestroy(Sender: TObject);
    begin
        FormChild2 := nil;
    end;
      

  10.   

    //主程序:
    type
      TCallModule =  procedure();stdcall;var
        FormMain: TFormMain;
        LibHandle: HModule;
        procedure LoadModule(AModuleName: String);implementation{$R *.DFM}
    procedure LoadModule(AModuleName: String);
    var
        CallModule: TCallModule;
    begin
        LibHandle := LoadLibrary(PChar(AModuleName));
        if LibHandle = 0 then Exit;
            @CallModule := GetProcAddress(LibHandle,'CallModule');
        if @CallModule <> nil then
            CallModule();
    end;procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    var
        iCount: Integer;
    begin
        if MessageDLG('是否退出?',mtConfirmation,[mbYes,mbNO],0) = mrYes then
        begin
            for iCount := 0 to MDIChildCount - 1 do
                MDIChildren[iCount].Close;       
            CanClose := True;
            if not (LibHandle = 0) then
                FreeLibrary(LibHandle);
        end else
            CanClose := False;
    end;关键是无论DLL还是EXE都要带运行时间包VCL50.bpl编译
      

  11.   

    ""关键是无论DLL还是EXE都要带运行时间包VCL50.bpl编译""
    怎么做才叫带运行时间包vcl50.bpl编译
      

  12.   

    DELPHI---> Project菜单--->Options菜单---->弹出的对话框选“Packages”页,有Build with RunTime Package复选框,选择该复选框,在下方Edit框内只保留Vcl50,其他去掉,即实行带包编译。