Где инициализировать Subcomponent.Parent? - PullRequest
0 голосов
/ 02 июля 2019

Я хочу создать свой собственный элемент управления. Допустим, я хочу инициализировать его графические свойства. Очевидно, я не могу сделать это в 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...