form2是动态创建的,我在form2里的FormClose里面写了这样代码
 action:=cafree;
  if Assigned(changemodify) then
    changemodify.Free;
  TForm2(sender):=nil;
其中changemodify是我定义的一个私有变量,类型是Tstringlist。我是在FormCreate里面创建的changemodify:=tstringlist.Create;现在又2个问题:1.有人说在FormCreate创建,最好在FormCloseQuery里释放?为什么
2.FormClose里面的代码。action:=cafree;这个不是已经将窗体和代码释放了吗?为什么Assigned(changemodify)还是为true呢?

解决方案 »

  1.   

    指针未释放 释放窗体使用freeandnil()
      

  2.   

    我这样写会不会报内存泄露问题?
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      try
        if Assigned(TForm(self.Owner)) then
          enablewindow(TForm(self.Owner).handle,true);//这个是让主窗口可用
      except on E: Exception do
        if Assigned(TForm(self.Owner)) then
           enablewindow(TForm(self.Owner).handle,true);//可用
      end;
      action:=cafree;
      
        changemodify.Free;
      TForm2(sender):=nil;
    end;
      

  3.   

    action:=cafree;  这个和freeandnil()有什么区别呢?
    我的程序里面都用到这个
      

  4.   

    窗体资源释放了,但是指针并未 指空释放窗体时 需 freeandnil(lform)不然assigned(lform)仍然是true
      

  5.   

    action:=cafree;
    意思 是释放不够彻底?指针还没释放?
      

  6.   

    对问题1:释放位置随意,onclose最好,因为onclosequery可以终止关闭过程,所以如果窗口没关闭你把需要用的变量释放了就不对了。
    问题2:action只是个标志,为了向后一个操作表明它的上一个操作的某种需求,可以肯定在onclose事件中窗体还没有被释放。
      

  7.   

    action:=cafree;并不会立即释放窗体,
    action参数的作用是让你决定FormClose结束后如何执行关闭操作,
    caFree:释放窗体
    caHide:隐藏窗体
    caMinimize:最小化窗体
    在FormClose执行完成后,VCL会根据你对action参数的赋值情况来进行相应的处理
    与onCreate对应的是onDestroy。
      

  8.   

    1。FormClose虽然执行了,但是会在结束后才根据action的指做判断。所以当前指针还没有释放。(应该明白了)
    2.你的意思是最好写在这onDestroy里面?
      

  9.   

    我觉得哪里两个地方释放都无问题的,FormClose比onDestroy先执行,你的代码最好优化下:
    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      try
        if Assigned(TForm(self.Owner)) then
          enablewindow(TForm(self.Owner).handle,true);//这个是让主窗口可用
      except on E: Exception do
        if Assigned(TForm(self.Owner)) then
           enablewindow(TForm(self.Owner).handle,true);//可用
      end;
      action:=cafree;//这句只是修改标志,放在这个事件哪里都无所谓。
      
        changemodify.Free;//最好是用Freeandnil(changemodify);让指针为空值
      TForm2(sender):=nil;//这句可以省略
    end;
      

  10.   

    OnCreate在对象构造之后被调用,
    OnDestroy在对象析构之前被调用。
    在OnClose如果有action:=cafree的时候都会调用到OnDestroy,如果Action没有赋值为caFree,窗体对象是不会释放的,也不会调用析构函数,析构函数是你最后可以释放相关地方。
    如果你在OnDestroy里把其他资源释放了,但没有action:=cafree,窗体本身不会释放,如果你后面的对窗体进行处理时用到了被释放的资源就会报错。
    可以去看看VCL的源代码,了解了窗体对象是怎么创建和释放后,在哪里写代码都可以,方法不只一种。OnClose和Ondestroy都可以用,就看你具体怎么用了。附上一点源代码 procedure TCustomForm.Close;
    var
      CloseAction: TCloseAction;
    begin
      if fsModal in FFormState then
        ModalResult := mrCancel
      else
        if CloseQuery then
        begin
          if FormStyle = fsMDIChild then
            if biMinimize in BorderIcons then
              CloseAction := caMinimize else
              CloseAction := caNone
          else
            CloseAction := caHide;
          DoClose(CloseAction);
          if CloseAction <> caNone then
            if Application.MainForm = Self then Application.Terminate
            else if CloseAction = caHide then Hide
            else if CloseAction = caMinimize then WindowState := wsMinimized
            else Release;
        end;
    end;CloseQuery 
    DoClose
    Release就自己看吧。
      

  11.   

    更正:
    如果你在OnClose里把其他资源释放了,但没有action:=cafree,窗体本身不会释放,如果你后面对窗体进行处理时用到了被释放的资源就会报错,
     
      

  12.   

    在OnClose如果有action:=cafree的时候都会调用到OnDestroy
    这一句话是不是有错误? fsModal in FFormState为false则 CloseQuery都会调用到???
    CloseModal里面有有调用CloseQuery。
    谢谢你哈  我再看看琢磨下
      

  13.   

    用下面的代码测试下就知道了怎么回事!
    Action:=caFree注释跟不注释的结果大不同
     
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      ShowMessage(' Form2 is  Destroying!');
    end;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      //Action:=caFree;end;
    end;[/code]
    看源代码是最好的方法!
      

  14.   

    为什么我注释掉 也弹出呢?procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    //Action:=caFree
    end;procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
    showmessage('sdf');
    end;
      

  15.   

    大哥看清楚阿,

    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      ShowMessage(' Form2 is  Destroying!');
    end;OnCloseQuery会先执行,跟OnCloses木有关系,
    古都的调用顺序如下:
    OnCloseQuery
    OnCloses
    OnDestroy
    自己看TCustomForm的源代码吧