Я хочу создать свой собственный элемент управления. Допустим, я хочу инициализировать его графические свойства. Очевидно, я не могу сделать это в Create, потому что canvas / handle не выделен YET. То же самое, если мой пользовательский элемент управления содержит подкомпонент (и я также установил его визуальные свойства).
В SO есть несколько мест, где обсуждается создание пользовательского элемента управления. Они не совсем согласны с этим.
Итак, я сделал этот тест, который показывает порядок создания.
Вывод:
Dropping control on a form:
Create
AfterConstruction
SetParent
CreateWnd
CreateWindowHandle
CreateWnd (post inherited)
SetParent (post inherited)
Executing the program
Create
AfterConstruction
SetParent
SetParent (post inherited)
SetParent
SetParent (post inherited)
Loaded
CreateWnd
CreateWindowHandle
CreateWnd (post inherited)
SetParent
SetParent (post inherited)
Dynamic creation
Create
AfterConstruction
Reconstructing the form
Not tested yet
Я использовал для создания подкомпонента в Create и установить MySubcomponents.Parent = self в CreateWnd. Но это не очень хорошее место, потому что CreateWnd не всегда вызывается. AfterConstruction также не подлежит сомнению, потому что дескриптор еще не готов.
UNIT cvTester;
{This file tests the initialization order of a custom control.}
INTERFACE
{$WARN GARBAGE OFF}
USES
System.SysUtils, System.Classes, vcl.Controls, vcl.Forms, Vcl.ExtCtrls;
TYPE
TCustomCtrlTest = class(TPanel)
private
protected
public
constructor Create(AOwner: TComponent); override;
procedure Loaded; override;
procedure AfterConstruction; override;
procedure CreateWnd; override;
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure WriteToString(s: string);
published
end;
procedure Register;
IMPLEMENTATION
USES System.IOUtils;
procedure Register;
begin
RegisterComponents('mine', [TCustomCtrlTest]);
end;
constructor TCustomCtrlTest.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
WriteToString('Create'+ #13#10);
// Create other subcomponents here:
// Subcomponent.Owner:= Self;
end;
procedure TCustomCtrlTest.Loaded;
begin
inherited;
WriteToString('Loaded'+ #13#10);
end;
procedure TCustomCtrlTest.AfterConstruction;
begin
inherited;
WriteToString('AfterConstruction'+ #13#10);
end;
procedure TCustomCtrlTest.CreateWnd;
begin
inherited;
WriteToString('CreateWnd'+ #13#10);
// Subcomponent.Parent = Self;
end;
procedure TCustomCtrlTest.CreateWindowHandle(const Params: TCreateParams);
begin
inherited CreateWindowHandle(Params);
WriteToString('CreateWindowHandle'+ #13#10);
end;
procedure TCustomCtrlTest.SetParent(AParent: TWinControl);
begin
WriteToString('SetParent'+ #13#10);
inherited SetParent(AParent);
WriteToString('SetParent (post inherited)'+ #13#10);
end;
function GetAppDir: string;
begin
Result:= ExtractFilePath(Application.ExeName);
end;
procedure TCustomCtrlTest.WriteToString(s: string);
begin
System.IOUtils.TFile.AppendAllText(GetAppDir+ 'test.txt', s);
end;
end.