Hola, les tengo buenas noticias. El código que muestro es prácticamente lo que originalmente se quería: un panel con dos subpaneles en los cuales se pueden insertar componentes pero que no son modificables durante el diseño. Claro está que las componentes se quedan donde deben estar al ejecutar la aplicación y/o reabrir el formulario.
Quisiera decir que esto se me ha ocurrido a mi pero
no es así. Esto no evita que me de gusto descubrir, una vez más, que Delphi es mucho más potente de lo que imaginamos.
Como ahora ya me voy a dormir les dejaré en suspenso hasta más tarde en cuanto a la procedencia del código. Sólo diré ahora que lo he adaptado para nuestro caso y si algo falla seguramente será culpa mía y no desde luego del autor original.
La componente tiene aún un pequeño problema pero estoy seguro que
jmariano lo podrá arreglar. Los demás también pero él fue quien tomó en cuenta dicho problema.
Confieso además que no he terminado de entender cabalmente el código pero ya entre todos hallaremos la explicación.
Por hoy sólo me resta comentarles que lo he probado con Delphi 7 pero supongo que con algunos cambios funcionará en otras versiones (lo supongo porque para simplificar quité algunas condicionales de compilación
).
Código Delphi
[-]
unit DoublePanel;
interface
uses
Classes, Controls, ExtCtrls, Forms;
type
TSubPanel = class(TPanel)
private
FDropList: TStringList;
protected
property DropList: TStringList read FDropList;
procedure ReadControls(Reader: TReader);
procedure SetControls(Root: TComponent);
procedure WriteControls(Writer: TWriter);
procedure GetControls(Proc: TGetChildProc; Root: TComponent);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TDoublePanel = class(TPanel)
private
TopPanel: TSubPanel;
ClientPanel: TSubPanel;
protected
procedure CreateWnd; override;
procedure DefineProperties(Filer: TFiler); override;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
end;
procedure Register;
implementation
constructor TSubPanel.Create(AOwner: TComponent);
begin
inherited;
TabStop := false;
FDropList := TStringList.Create;
end;
destructor TSubPanel.Destroy;
begin
FDropList.Free;
inherited;
end;
procedure TSubPanel.ReadControls(Reader: TReader);
begin
FDropList.Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
DropList.Add(Reader.ReadIdent);
Reader.ReadListEnd;
end;
procedure TSubPanel.SetControls(Root: TComponent);
var
Component: TComponent;
I: Integer;
begin
inherited;
for I := 0 to DropList.Count - 1 do
begin
Component := Root.FindComponent(DropList[i]);
if Assigned(Component) then
TControl(Component).Parent := Self;
end;
end;
procedure TSubPanel.WriteControls(Writer: TWriter);
var
I: Integer;
begin
Writer.WriteListBegin;
for I := 0 to ControlCount - 1 do
Writer.WriteIdent(Controls[i].Name);
Writer.WriteListEnd;
end;
procedure TSubPanel.GetControls(Proc: TGetChildProc; Root: TComponent);
var
Control: TControl;
I: Integer;
begin
inherited;
for I := 0 to ControlCount - 1 do
begin
Control := Controls[i];
if Control.Owner = Root then
Proc(Control);
end;
end;
constructor TDoublePanel.Create(AOwner: TComponent);
begin
inherited;
ControlStyle := ControlStyle - [csAcceptsControls];
Width := 377;
Height := 249;
BevelOuter := bvLowered;
TopPanel := TSubPanel.Create(Self);
TopPanel.Align := alTop;
TopPanel.Parent := Self;
ClientPanel := TSubPanel.Create(Self);
ClientPanel.Align := alClient;
ClientPanel.Parent := Self;
end;
procedure TDoublePanel.CreateWnd;
begin
inherited;
end;
procedure TDoublePanel.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('TopPanel', TopPanel.ReadControls, TopPanel.WriteControls, true);
Filer.DefineProperty('ClientPanel', ClientPanel.ReadControls, ClientPanel.WriteControls, true);
end;
procedure TDoublePanel.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin
inherited;
TopPanel.GetControls(Proc, Root);
ClientPanel.GetControls(Proc, Root);
end;
procedure TDoublePanel.Loaded;
var
Root: TComponent;
begin
inherited;
Root := GetParentForm(Self);
TopPanel.SetControls(Root);
ClientPanel.SetControls(Root);
end;
procedure Register;
begin
RegisterComponents('Samples', [TDoublePanel]);
end;
end.
// Saludos