拉撒路。如何调用动态创建实例的继承方法?

时间:2014-06-02 17:47:10

标签: inheritance dynamic controls lazarus rtti

我已经搜索了这个,并且没有找到我的情况。 我有一些TCustomControl类型的变量:

var fcontrol:TCustomControl;

然后我使用一些RTTI魔术来创建不同类的实例 - TCustomControl的后代:

constructor TFGControl.Create(TheOwner: TComponent; control: string);    
    var classofcontrol:string; class_ref: TPersistentClass;
begin
  case control of 'formspec': classofcontrol:='TPanel';
                     'label': classofcontrol:='TLabel';
                    'button': classofcontrol:='TSpeedButton';
  end;

  class_ref:=GetClass(classofcontrol);

  fcontrol:=TCustomControl(class_ref.Create); 

所以,在此之后我将fcontrol指向所需类的实例。并且可以指定它的一些方法(假设那些被描述为需要),如下所示:

  with fcontrol as class_ref do
       begin
            Parent:=Parent;
            if control='formspec' then
               begin
                    Width:=400;
                    Height:=300;
                    Color:=clGray;
               end
            else
                begin
                     top:=20;
                     left:=20;
                     Width:=50;
                     Height:=20;
                     Caption:=control+' - '+inttostr(Parent.ControlCount);
                     Font.Color:=clwhite;
                     Color:=clRed;
                end;

            OnMouseDown:=@MouseDown;
            OnMouseUp:=@MouseUp;
            OnMouseMove:=@MouseMove;
            OnClick:=@Click;   

它的效果非常好。

但后来我希望这些动态创建的控件使用不同的 Paint 方法。我希望我新创建的实例使用它的祖先的Paint方法,例如,如果class_ref.ClassName是" TPanel"然后我希望fcontrol看起来像TPanel;如果class_ref.ClassName是" TLabel"那么我希望fcontrol像普通标签一样被绘制。

问题是fcontrol声明为TCustomControl,如果我这样写:

            OnPaint:=@Paint;

我可以看到它(替换)有效。但是,如果fcontrol真的是TPanel,我应该在我的新Paint方法中调用Tpanel.Paint;和TLabel.Paint如果fcontrol真的是TLabel?

问候!

1 个答案:

答案 0 :(得分:0)

  

使用fcontrol作为class_ref执行

这不是有效的类型转换,甚至不需要。如果要动态设置属性,可以改用RTTI。

  

的OnPaint:= @油漆;

这仅适用于实际的TCustomControl派生对象,因此请使用is运算符检查:

if fControl is TCustomControl then
  TCustomControl(fControl).OnPaint:=@Paint;