本帖最后由 seleron 于 2014-08-06 19:06:02 编辑

解决方案 »

  1.   

    既然你的 Unit1.pas 里 uses 了 Unit2, 为何不直接把 nForm2: TForm2 放在 Unit2.pas 的 interface 里, 那样
    interface
    type
      TForm2 = class ....
      ...
    var
      nForm2: TForm2;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      showmessage('nForm2 start close');
      action:=cafree;
      nForm2:= nil; // 在此赋值
    end;
      

  2.   

    我一般都这样用
    TForm2.FormClose 代码清空implementation
    uses unit2;
    .....
    //TForm1.btn1Click的代码改为with Tform2.Create(application)do 
     try 
     showmodal;
    finally
     free;
    end
      

  3.   

    如果我要创建多个TForm2实例呢?
      

  4.   

    关键是不使用showmodule的情况下如何处理
      

  5.   


    如果我要创建多个TForm2实例呢?
      

  6.   

    变量如1楼声明procedure TForm1.btn1Click(Sender: TObject);
    begin
      if not Assign(nForm2)  then
          nForm2:=Tform2.Create(application);
      try
         nForm2.Show;
      except
         .....
       end;
    end;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        action:=cafree;
    end;procedure TForm2.FormDestroy(Sender: TObject); 
    begin
        nForm2:=nil;
    end;参考《DELPHI5开发人员指南》,模式窗体和非模式窗体的创建和销毁
      

  7.   


    var
      Form2: TForm2;implementation
    uses unit1;{$R *.dfm}procedure TForm2.btn1Click(Sender: TObject);
    begin
     close;
    end;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
     action:=cafree;
    end;procedure TForm2.FormDestroy(Sender: TObject);
    begin
        form2:=nil;
        nform2:=nil;
    end;
      

  8.   


    总觉得对nfrom2的管理(nForm2:=nil)应该放在创建它的unit1中,而不是TForm2对应的Unit2中
    你觉得呢?
      

  9.   


    这样就会导致,每增加一个TForm2实例,都需要在TForm2中修改代码来是的实例nil,而理论上这些释放实例的代码不应该放在TForm2中
      

  10.   

    释放TForm2的代码放在TForm里确实不太合理,因为这样二者耦合度太高
    可以使用委托的方法来解决这个问题
    在TForm的destory事件中,调用委托函数,将释放委托给TForm2之外的函数来完成
    这样,在TForm1中创建nForm2时,同时将nForm2的委托函数赋值
    这样就将TForm1和TFomr2之间解耦了
    修改楼主代码如下TForm1代码unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, unit2, StdCtrls;type
      TForm1 = class(TForm)
        btn1: TButton;
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        procedure SetFormNil();
      end;var
      Form1: TForm1;
      nForm2:TForm2;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    begin
      if nForm2=nil then
      begin
        showmessage('nForm2 is nil');
        nForm2:=Tform2.Create(application);
        nForm2.setnil:=SetFormNil;
      end
      else
      begin
        showmessage('nForm2 is not nil');
      end;
      nForm2.Show;
    end;procedure TForm1.SetFormNil();
    begin
      nForm2:=nil;
    end;end.TForm2代码unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TSetnil=procedure() of object;type
      TForm2 = class(TForm)
        btn1: TButton;
        procedure btn1Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
        setnil:TSetnil;
      end;implementationuses
      Unit1;{$R *.dfm}
    procedure TForm2.btn1Click(Sender: TObject);
    begin
      close;
    end;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      showmessage('nForm2 start close');
      action:=cafree;
      setnil();
    end;end.
      

  11.   

    其实还有一种更好的写法unit1代码如下unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, unit2, StdCtrls;type
      TForm1 = class(TForm)
        btn1: TButton;
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      nForm2:TForm2;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    var
      strFormName:string;
    begin
      strFormName:='nForm2';
      nForm2:=TForm2(FindGlobalComponent(strFormName));
      if nForm2=nil then
      begin
        showmessage('nForm2 is nil');
        nForm2:=Tform2.Create(application);
        nForm2.Name:=strFormName;
      end
      else
      begin
        showmessage('nForm2 is not nil');
      end;
      nForm2.Show;
    end;end.
    unit2代码如下unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm2 = class(TForm)
        btn1: TButton;
        procedure btn1Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;implementation{$R *.dfm}procedure TForm2.btn1Click(Sender: TObject);
    begin
      close;
    end;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      showmessage('nForm2 start close');
      action:=cafree;
    end;end.