新建一个程序,在上面放一个panel1,再在panel1上放一个button1,在button1的单击事件里写panel1.free;结果出现如下错误:
Project Project1.exe raised exception class EAbstractError with message 'Abstract Error'. Process stopped. Use Step or Run to continue.奇怪的是再在窗体上放一个panel2,再在panel2上放一个button2,然后panel2.free就没有问题,但是点击button1仍然有问题。
这个问题好象只有delphi7才有,delphi6就不会有该问题。

解决方案 »

  1.   

    -_-# 真的很老乜?老鸟也会犯这种常识性的错误?“在上面放一个panel1,再在panel1上放一个button1,在button1的单击事件里写panel1.free;”当你"再在panel1上放一个button1"的时候,delphi偷偷做了一件事:button1.parent := panel1;
    所以你在panel1.free前必须先做好一件事:button1.parent := panel1.parent;
      

  2.   

    老夫要在panel1上把panel1连通button1一起给释放,不想改变parent。
      

  3.   

    调了一下VCL,发现是再Click后,又执行了mouseup事件,但不知道为什么,执行mouseup的时候类型变成了未知的类。如果前面有panel,这个类就不会变,还是Tbutton。奇怪,可能和实现方式有关。现在的解决办法是,把panel1.free写在button的onmouseup事件中,就可以了。
      

  4.   

    http://community.csdn.net/Expert/topic/5294/5294805.xml?temp=.730343
    这个不是Delphi的Bug
    容器释放,会将容器中的控件也释放procedure TForm1.Button1Click(Sender: TObject);
    var
      vParent: TWinControl;
    begin
      vParent := TControl(Sender).Parent;
      TControl(Sender).Parent := nil;
      vParent.Free;
      TObject(Sender).Free;
    end;//or-------------------------------const
      WM_DELETEOBJECT = WM_USER + 10;type
      TForm1 = class(TForm)
    //...
        procedure WMDELETEOBJECT(var Msg: TMessage); message WM_DELETEOBJECT;
      end;//...procedure TForm1.SpeedButton1Click(Sender: TObject);
    begin
      PostMessage(Handle, WM_DELETEOBJECT, Integer(SpeedButton1.Parent), 0);
    end;procedure TForm1.WMDELETEOBJECT(var Msg: TMessage);
    begin
      if Msg.WParam <> 0 then TObject(Msg.WParam).Free;
    end;
      

  5.   

    用SpeedButton是不会有问题的,一定要用TButton和TPanel才会有这个问题,如果把TPanel换成其他的容器也不会有问题。
      

  6.   

    明白了,click事件会掉用mouseup方法,而mouseup方法是用dynamic修饰的,如果把dynamic去掉就没有问题。
    我写了简单的类型测试了下:
    type
      Txx=class
      public
        procedure test;dynamic;
        procedure doo;
      end;
    { Txx }procedure Txx.doo;
    begin
      self.Free;
      test;
    end;procedure Txx.test;
    begin
      showmessage('df');
    end;调试代码
    begin
      xx:=Txx.Create;
      xx.doo;
    end;
    结果会出错,如果去掉dynamic;则可以show出'df'来。