一个form1为MDIForm,一个form2为MDIChild,
点击form1中的按钮,打开form2,在form2的close事件中写如下代码
procedure TForm2.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  FreeAndNil(Form1);
end;报内存地址的错误。如果改为procedure TForm2.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action:=caFree;
  Form1:=nil;
end;则不报错。
是何原因呢?

解决方案 »

  1.   


    procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      FreeAndNil(Form1);
    end;
    报错“Abstract Error”什么原因呢?
      

  2.   

    单击关闭按钮事件代码procedure TForm2.Button1Click(Sender: TObject);
    begin
      Self.close;
    end;
    窗体退出事件代码procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      FreeAndNil(Form1);
    end;
    如果是单击Form2右上角的自带的关闭按钮则不报错,如果单击关闭按钮,则有时报“Abstract Error”错误,有时报内存地址相关的错误。什么原因呢?
      

  3.   

    什么乱七八糟的应该是
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;
      Form2 := nil;
    end;子窗体关闭怎么能把主窗体给释放(FreeAndNil)呢, nil只是把指针置空而已,不是真正的释放。
      

  4.   


    form2的close事件中的语句是freeandnil(form2);我的意思是为什么点击窗体右上角自带的关闭按钮就不报错,而点击button执行self.close就报错呢?
      

  5.   

    首先Form1:=nil;不是释放窗体,只是把指针置空而已。
    然后就是你在Form2的close事件里把Form1给释放掉了,Form2还在,当然会报错了。
      

  6.   

    Form1是主窗体,Form2是子窗体,在Form2的Close事件调用FreeAndNil去释放Form1,有点乱套了,form1引用form2,form2引用form1,最好不要这样交叉引用。如果你是要释放MDIChild窗体,直接在Form2的Close事件,写上FreeAndNil(self)也可以,不过一般直接把Action设置为Free.
      

  7.   

    procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      FreeAndNil(Form1);
    end;
    报内存地址的错误。如果改为
    Delphi(Pascal) code
    procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      Action:=caFree;
      Form1:=nil;
    end;~~~~~~~~~~~~~~~~~~~
    楼主因为你改正确了所以不会报错。:)
    freeandnil不要再MDI窗体里面用,在其他窗体里也不要把freeandnil写在 close事件里。
    在MDI窗体里如果要最小化窗体可以用self.close,如果需要彻底的关闭该子窗体(内存释放),可以在close事件里再加 action := cafree;右上角自带关闭和self.close是一个道理的。只要close事件里不要用freeandnil,那应该是都不会报错的。
      

  8.   

    谢谢大家的关注,问题表述错了
    应该是这样的一个form1为MDIForm,一个form2为MDIChild,
    点击form1中的按钮,打开form2,在form2的close事件中写如下代码procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      FreeAndNil(Form2);
    end;
    报内存地址的错误或abstract err。
    如果改为procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      Action:=caFree;
      Form2:=nil;
    end;
    则不报错。
    是何原因呢?
      

  9.   

    procedure TForm2.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      FreeAndNil(Form2);
    end;系统在调用OnClose后,也就是运行你的FormClose之后,还要根据Action参数来判断,默认情况下
    会执行Hide(MDIChild),也就是FreeAndNil(Form2);之后还要执行Form2.Hide,当然会地址错误,
    因此不要在FormClose中执行本身的Free,Delphi专门搞了个参数Action,就是为了在Form事件中实现隐藏或者释放.
      

  10.   

    回复(蓝色光芒)
    如果只在form的close事件中执行 action:=cafree;  而不执行form2=nil;  的话。 如何在下次打开form2前判断form2是否已经存在呢?
    我现在的方法是,在close事件中执行form2=nil ;,然后在下次打开时做如下判断
    if  form2=nil then form2=Tform2.CreateForm(nil); 
      

  11.   

    首先Form1:=nil;不是释放窗体,只是把指针置空而已。
    然后就是你在Form2的close事件里把Form1给释放掉了,Form2还在,当然会报错了。
      

  12.   


    不好意思,是我写错了,是在Form2的Close事件中FreeAndNil(form2),不是释放Form1
      

  13.   

    如果是这样的话,你直接在Form2的OnDestroy事件写上Form2 := nil就可以了,不要写在OnClose事件里面。