I've created a custom control which is a panel with another panel inside it.
I want the controls added to the outer panel to be actually placed inside the inner panel. TCategoryPanel actually does something similar to this redirecting controls to a surface inside.
Borrowing some code from it I was able to mostly create what I want. Adding a control to the outer panel gets correctly placed inside the inner panel. Also, those controls are correctly saved in the DFM and loaded back in. The problem is the control appears to be outside (a child of the Form) instead of the component in the Structure view:
This doesn't happen in the TCategoryPanel and I can't figure out what is the problem. Everything besides that seems to work. What am I missing?
My component (minimal reproducible example):
unit uTeste;
interface
uses ExtCtrls, Classes, Controls;
type
TTestePanel = class(TCustomPanel)
private
FSurface: TPanel;
procedure CMControlListChanging(var Message: TCMControlListChanging); message CM_CONTROLLISTCHANGING;
public
constructor Create(AOwner: TComponent); override;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
end;
procedure Register;
implementation
uses Graphics;
procedure Register;
begin
RegisterComponents('Teste', [TTestePanel]);
end;
{ TTestePanel }
constructor TTestePanel.Create(AOwner: TComponent);
begin
inherited;
Color := clRed;
FSurface := TPanel.Create(Self);
FSurface.AlignWithMargins := True;
FSurface.Margins.SetBounds(30, 30, 30, 30);
FSurface.Color := clGreen;
FSurface.Parent := Self;
FSurface.Align := alClient;
end;
procedure TTestePanel.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
Control: TControl;
begin
for I := 0 to FSurface.ControlCount - 1 do
begin
Control := FSurface.Controls[I];
Proc(Control);
end;
end;
procedure TTestePanel.CMControlListChanging(var Message: TCMControlListChanging);
begin
if Message.Inserting and (Message.ControlListItem^.Parent = Self) and
(Message.ControlListItem^.Control <> FSurface) then
begin
FSurface.InsertControl(Message.ControlListItem^.Control);
Message.ControlListItem^.Parent := FSurface;
end
else
inherited;
end;
end.

