I'm working with Delphi 12.
I want to create a visual component derived from TPanel with several components grouped together.
One piece is to create a PageControl with 2 (at the moment) tabsheets, and one cxGrid on the tabsheets.
The same code that I use to create the pagecontrol and childs sheets is working on a normal "one form project", but raise an "Control xx has no parent window" when is used inside the component.
After I isolate the code I'm 100% sure that creating tabsheet is the problem. If I create the page control with no sheet has no problem.
After I read some stackoverflow sugested article I still not figure out what to do. Some articles are talking about overriding CreateWnd procedure but i dont understand it.
function CreatePageControl(AOwner: TComponent; AParent : TWinControl; const aNAME : String = '') : TPageControl;
begin
Result := TPageControl.Create(AOwner);
if aNAME = '' then begin
Randomize;
Result.Name := 'pc_' + Random(999999).ToString;
end;
Result.Parent := AParent;
Result.TabPosition := tpTop;
Result.TabWidth := 100;
Result.Top := 100;
Result.Left := 100;
end;
function CreateTabSheet(AOwner: TPageControl; const aNAME : String = '') : TTabSheet;
begin
Result := TTabSheet.Create(AOwner);
if aNAME = '' then begin
Randomize;
Result.Name := 'tc_' + Random(999999).ToString;
end;
Result.PageControl := AOwner;
end;
constructor TCustomGr.Create(AOwner: TComponent);
var workSheet : TTabSheet;
begin
inherited Create(AOwner);
fPanelTop := TPanel.Create(Self);
fPanelTop.Parent := Self;
fPageControlMain := CreatePageControl(Self, Self);
workSheet := CreateTabSheet(fPageControlMain); <- error here
workSheet := CreateTabSheet(fPageControlMain);
InitComponents;
end;
I'm working with Delphi 12.
I want to create a visual component derived from TPanel with several components grouped together.
One piece is to create a PageControl with 2 (at the moment) tabsheets, and one cxGrid on the tabsheets.
The same code that I use to create the pagecontrol and childs sheets is working on a normal "one form project", but raise an "Control xx has no parent window" when is used inside the component.
After I isolate the code I'm 100% sure that creating tabsheet is the problem. If I create the page control with no sheet has no problem.
After I read some stackoverflow sugested article I still not figure out what to do. Some articles are talking about overriding CreateWnd procedure but i dont understand it.
function CreatePageControl(AOwner: TComponent; AParent : TWinControl; const aNAME : String = '') : TPageControl;
begin
Result := TPageControl.Create(AOwner);
if aNAME = '' then begin
Randomize;
Result.Name := 'pc_' + Random(999999).ToString;
end;
Result.Parent := AParent;
Result.TabPosition := tpTop;
Result.TabWidth := 100;
Result.Top := 100;
Result.Left := 100;
end;
function CreateTabSheet(AOwner: TPageControl; const aNAME : String = '') : TTabSheet;
begin
Result := TTabSheet.Create(AOwner);
if aNAME = '' then begin
Randomize;
Result.Name := 'tc_' + Random(999999).ToString;
end;
Result.PageControl := AOwner;
end;
constructor TCustomGr.Create(AOwner: TComponent);
var workSheet : TTabSheet;
begin
inherited Create(AOwner);
fPanelTop := TPanel.Create(Self);
fPanelTop.Parent := Self;
fPageControlMain := CreatePageControl(Self, Self);
workSheet := CreateTabSheet(fPageControlMain); <- error here
workSheet := CreateTabSheet(fPageControlMain);
InitComponents;
end;
Share
Improve this question
edited Jan 20 at 12:28
Antonio Petricca
11k5 gold badges44 silver badges87 bronze badges
asked Jan 20 at 12:11
Popa Ovidiu-RazvanPopa Ovidiu-Razvan
4951 gold badge6 silver badges23 bronze badges
3
|
2 Answers
Reset to default 3The error occurs because the TCustomGr
does not have its Parent
assigned yet in its constructor, so it cannot create its HWND
yet when the TPageControl
and TTabSheet
try to create their HWND
s. The TTabSheet
requires the TPageControl
's HWND
, so you need to delay the creation of the TTabSheet
until after the TCustomGr
has created its own HWND
first.
Well i have found an answer.
I have created all the "objects" on the constructor, with absolutely no references to each other (only the create method), and in the CreateWnd overrided procedure I put all the logical (parents and so on) dependences between objects.
Randomize
only once during execution of your program, for example in theinitialization
section of your main unit. CallingRandomize; Random;
multiple times with short time delay may result in very non-random numbers. – Matej Commented Jan 21 at 16:57