我知道在某个地方看到过一个技巧,可以定义一个与现有VCL组件相同类名的自定义版本,比如TButton
或TEdit
,并采取某些措施使DFM流解器实例化您的版本而不是原始版本。 不幸的是,我现在需要能够做到这一点,但我找不到相关文档。 有人知道在哪里可以找到关于如何实现这一点的信息吗?
您可以像这样在表单中覆盖 ReadState
方法:
type
TMyForm = class(TForm)
protected
procedure ReadState(Reader: TReader); override;
end;
procedure TMyForm.ReadState(Reader: TReader);
begin
Reader.OnFindComponentClass := FindComponentClass;
inherited;
end;
procedure TMyForm.FindComponentClass(Reader: TReader; const ClassName: string;
var ComponentClass: TComponentClass);
begin
if ComponentClass=TButton then begin
ComponentClass := TMySuperDuperButton;
end else if ComponentClass=TEdit then begin
ComponentClass := TMyTotallyAwesomeEdit;
end;
end;
可能有许多其他方法可以做到这一点,但这是我做的方法!
编辑:TReader.GetFieldClass(Instance: TObject; const ClassName: string)
的检查表明了Mason回忆起的hack。第一行设置ClassType := Instance.ClassType
。因此,我怀疑通过将pas文件中的声明从Button1: TButton
更改为Button1:MyUnit.TButton
会导致您创建的按钮被创建。或者也许hack是在结尾处将MyUnit
添加到使用条款中,以便您的TButton版本是在范围内的那个版本。然而,所有这些听起来都不是很实际。
我猜你试图记住的是一个“中间层类”:继承一个给定名称与祖先相同但前缀为祖先单位名称的类。由于类名未更改,dfm流机制不会受到影响。只会影响重新声明该类的单元,除非将其放入一个单独的单元中并在基类之后的uses部分引用该单元。显然,您无法在中间层类中使用已发布的属性。
type
TButton = class(stdctrls.TButton)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TForm1 = class(TForm)
Button1: TButton;
[...]
private