Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance 拉撒路。如何调用动态创建实例的继承方法?_Inheritance_Dynamic_Controls_Lazarus_Rtti - Fatal编程技术网

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

Inheritance 拉撒路。如何调用动态创建实例的继承方法?,inheritance,dynamic,controls,lazarus,rtti,Inheritance,Dynamic,Controls,Lazarus,Rtti,我到处找,没有找到我的情况。 我有一些TCustomControl类型的变量: var fcontrol:TCustomControl; constructor TFGControl.Create(TheOwner: TComponent; control: string); var classofcontrol:string; class_ref: TPersistentClass; begin case control of 'formspec': classofcon

我到处找,没有找到我的情况。 我有一些TCustomControl类型的变量:

var fcontrol: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); 
然后,我使用一些RTTI魔术来创建TCustomControl的不同类后代的实例:

var fcontrol: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;   
            OnPaint:=@Paint;
而且效果非常好

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

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

  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;   
            OnPaint:=@Paint;
我可以看出它(替代)是有效的。但我应该在我的新绘制方法中加入什么来调用Tpanel.Paint,如果fcontrol真的是Tpanel;还有TLabel。如果fcontrol真的是一个TLabel,请绘制

问候

将fcontrol设置为class_ref do

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

OnPaint:=@Paint

这只适用于实际的
TCustomControl
派生对象,因此使用
is
操作符检查:

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

我很乐意提供更多信息-只是不知道需要什么信息。因此,问任何似乎相关的问题。这似乎不是任何问题的解决方案。不能将一个方法从一个类拼接到一个不相关的类上。我担心你在这条不明智的道路上走得太远,以至于你不想听我说的话。如果你不发布假代码,情况会一如既往地好。case语句未编译。控件已调用其祖先方法。除非你做了一些事情,使
TPanel
不像面板那样自行绘制,否则它将继续自行绘制。那你是怎么搞砸的?带有语句的
到底在做什么?
Parent:=Parent
赋值完全是胡说八道,而事件处理程序赋值也没有多大意义,因为
fcontrol.MouseDown
不是
OnMouseDown
事件的有效处理程序,所以代码一开始就不应该编译。摆脱
@
操作符;它隐藏错误。代码不是假的。“我周围没有德尔菲,所以,”在拉扎勒斯内部用-MDelphi开关继续说道。不带OnPaint的偶数:=@Paint;我得到的只是一个灰色的长方形;fcontrol.ClassName是“TFGControl”,而class_ref是“TPanel”或“TLabel”。因为类ref是TPersistentClass,所以我假设它是一个有效的类型转换。拉扎勒斯一点也没有抱怨。OnPaint:=@Paint的问题不在于它不能工作或无法编译。问题是我不能使fcontrol像TPanel或TLabel那样绘制。。。你能更详细地解释一下吗?我添加了一个github repo,这样代码就可以被查看了。请注意,在这里发布问题后,我尝试了更多的方法。哦,代码在editor.pas中