如果不打开DLL子窗口,直接关闭MDI主窗口不会报错
当打开DLL子窗口后直接关闭主窗口——报错
当打开DLL子窗口,先关闭该子窗口,再关闭主窗口——依然报错,错误一致代码如下:

解决方案 »

  1.   

    DLLT
    library DLLT;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      ShareMem,
      SysUtils,
      Classes,
      Forms,
      Dialogs,
      Windows,
      Messages,
      F_T in 'F_T.pas' {MDIC_T};{$R *.res}
    var
    DLLApp: TApplication;function ShowForm(var App: TApplication;ParentForm: TForm): Boolean;export; stdcall;
    begin
      {获取调用窗体的Application,显而易见的功能是 能使你的窗体融合到调用程序中。通过它还能进行很多操作}
      Application:= App;//将DLL的Application转为App
      MDIC_T:= TMDIC_T.Create(ParentForm);//创建子窗体,子窗体随着ParentForm存在、释放。
      MDIC_T.FormStyle:= fsMDIChild;//设置窗体模式
      MDIC_T.Show;
    end;{重写Dll入口函数,否则程序会出错}
    procedure DLLUnloadProc(Reason: Integer); register;
    begin
      {DLL取消调用时,发送DLL_PROCESS_DETACH消息,此时将DLL的Application返回为本身}
      if Reason = DLL_PROCESS_DETACH then
        Application:=DLLApp;
    end;exports
      ShowForm;begin
      {在DLL入口预先储存DLL的Application}
      DLLApp:=Application;
      {DllProc:DLL入口函数指针。Delphi定义为 DllProc: TDLLProc;}
      {在此指向我们自己定义的函数}
      DLLProc := @DLLUnloadProc;
    end.
      

  2.   

    MdiApp
     program Mdiapp;uses
      Forms,
      MAIN in 'MAIN.PAS' {MainForm},
      CHILDWIN in 'CHILDWIN.PAS' {MDIChild},
      about in 'about.pas' {AboutBox};{$R *.RES}begin
      Application.Initialize;
      Application.CreateForm(TMainForm, MainForm);
      Application.CreateForm(TAboutBox, AboutBox);
      Application.Run;
    end.MainForm
    unit MAIN;interfaceuses Windows, SysUtils, Classes, Graphics, Forms, Controls, Menus,
      StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, ComCtrls, StdActns,
      ActnList, ToolWin, ImgList;type
      TMainForm = class(TForm)
        MainMenu1: TMainMenu;
        File1: TMenuItem;
        FileNewItem: TMenuItem;
        FileOpenItem: TMenuItem;
        FileCloseItem: TMenuItem;
        Window1: TMenuItem;
        Help1: TMenuItem;
        N1: TMenuItem;
        FileExitItem: TMenuItem;
        WindowCascadeItem: TMenuItem;
        WindowTileItem: TMenuItem;
        WindowArrangeItem: TMenuItem;
        HelpAboutItem: TMenuItem;
        OpenDialog: TOpenDialog;
        FileSaveItem: TMenuItem;
        FileSaveAsItem: TMenuItem;
        Edit1: TMenuItem;
        CutItem: TMenuItem;
        CopyItem: TMenuItem;
        PasteItem: TMenuItem;
        WindowMinimizeItem: TMenuItem;
        StatusBar: TStatusBar;
        ActionList1: TActionList;
        EditCut1: TEditCut;
        EditCopy1: TEditCopy;
        EditPaste1: TEditPaste;
        FileNew1: TAction;
        FileSave1: TAction;
        FileExit1: TAction;
        FileOpen1: TAction;
        FileSaveAs1: TAction;
        WindowCascade1: TWindowCascade;
        WindowTileHorizontal1: TWindowTileHorizontal;
        WindowArrangeAll1: TWindowArrange;
        WindowMinimizeAll1: TWindowMinimizeAll;
        HelpAbout1: TAction;
        FileClose1: TWindowClose;
        WindowTileVertical1: TWindowTileVertical;
        WindowTileItem2: TMenuItem;
        ToolBar2: TToolBar;
        ToolButton1: TToolButton;
        ToolButton2: TToolButton;
        ToolButton3: TToolButton;
        ToolButton4: TToolButton;
        ToolButton5: TToolButton;
        ToolButton6: TToolButton;
        ToolButton9: TToolButton;
        ToolButton7: TToolButton;
        ToolButton8: TToolButton;
        ToolButton10: TToolButton;
        ToolButton11: TToolButton;
        ImageList1: TImageList;
        ToolButton12: TToolButton;
        procedure FileNew1Execute(Sender: TObject);
        procedure FileOpen1Execute(Sender: TObject);
        procedure HelpAbout1Execute(Sender: TObject);
        procedure FileExit1Execute(Sender: TObject);
        procedure ToolButton12Click(Sender: TObject);
      private
        { Private declarations }
        procedure CreateMDIChild(const Name: string);
      public
        { Public declarations }
      end;var
      MainForm: TMainForm;
      SHandle:THandle;  function ShowForm(var App: TApplication; ParentForm: TForm): Boolean;stdcall; external 'DLLT.dll';//为了简单,使用静态调用方法implementation{$R *.dfm}uses CHILDWIN, about;procedure TMainForm.CreateMDIChild(const Name: string);
    var
      Child: TMDIChild;
    begin
      { create a new MDI child window }
      Child := TMDIChild.Create(Application);
      Child.Caption := Name;
      if FileExists(Name) then Child.Memo1.Lines.LoadFromFile(Name);
    end;procedure TMainForm.FileNew1Execute(Sender: TObject);
    begin
      CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));
    end;procedure TMainForm.FileOpen1Execute(Sender: TObject);
    begin
      if OpenDialog.Execute then
        CreateMDIChild(OpenDialog.FileName);
    end;procedure TMainForm.HelpAbout1Execute(Sender: TObject);
    begin
      AboutBox.ShowModal;
    end;procedure TMainForm.ToolButton12Click(Sender: TObject);
    begin
      ShowForm(Application, Self);//调用DLL函数调出窗体。传入当前主程序的Application对象和Form1本身
    end;procedure TMainForm.FileExit1Execute(Sender: TObject);
    begin
      Close;
    end;end.这个实例是我在网上找的,出错后搜了一下发现不少人遇到过这个问题,但是没找到我能看懂且能够解决问题的答案请大家帮帮忙,迁就一下我这个初学者,知道解决方法的请尽量写的详细点,最好是能写出具体的代码,多谢了!!
      

  3.   

    var
      Child: TMDIChild;
    子窗口的定义应该在外部的,你在函数内定义,函数调用后,它的生命周期已经结束。所以会产生内存泄露。
      

  4.   

    请问怎么销毁?还有四楼,我这个CHILDWIN是MDI子窗体,不是DLL里面的那个,我不调用DLL子窗体是不报错的,所以我觉得应该是3楼说的那样,
    但是我不知道怎么销毁,Destroy吗?在哪销毁呢?子窗体onFormClose事件吗?
      

  5.   

    解决了,改成动态调用就不报错了,不过还是不知道为什么静态就出错?另外,DLL开头那段英文注释很重要啊,如果涉及String,单元ShareMem不但在DLL中需要加,引用的pas里面也要加