Inheritance 拉撒路。如何调用动态创建实例的继承方法?
我到处找,没有找到我的情况。 我有一些TCustomControl类型的变量: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
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中