Я знаю, что я видел пример где-то взломанный, чтобы определить пользовательскую версию существующего компонента VCL, например TButton или TEdit, с тем же именем класса и сделать что-то, чтобы сделать это, чтобы стример DFM создавал ваши вместо оригинала. К сожалению, я в ситуации, когда мне нужно это сделать, и я не могу найти рецензию. Кто-нибудь знает, где найти информацию о том, как это сделать?
Замена класса компонента в delphi
Ответ 1
В вашей форме вы можете переопределить метод 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)
предполагает хак, который Мейсон вспоминает. Первая строка устанавливает ClassType := Instance.ClassType
. Поэтому я подозреваю, что, изменив объявление в файле pas от Button1: TButton
до Button1: MyUnit.TButton
, вы создадите свою кнопку. Или, может быть, взлом заключался в том, чтобы добавить MyUnit
в предложение uses прямо в конце, чтобы ваша версия TButton была той, которая находится в области видимости. Однако ничто из этого не кажется очень практичным.
Ответ 2
Я предполагаю, что вы пытаетесь вспомнить "класс интерполятора" : наследование класса с тем же именем, что и предок, префикс имени имени предка. Поскольку имя класса не изменяется, механизм потоковой передачи dfm не нарушается. Будет влиять только на объект, повторно объявленный классом, если только он не помещается в отдельный блок, и этот блок включен в раздел использования после базового класса. Очевидно, что вы не можете опубликовать свойства в промежуточном классе.
type
TButton = class(stdctrls.TButton)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TForm1 = class(TForm)
Button1: TButton;
[...]
private