Cita:
|
Empezado por roman
Queda pendiente los de componentes con nombres en blanco.
|
Una forma de solucionarlo sería almacenar, en vez del nombre de los componentes, otro valor que identificara de forma única cada componente, como, por ejemplo, un índice.
Para calcular este índice, a la hora de recuperar componentes, tomaríamos como base el índice de nuestro componente, TDoublePanel (ya que el propietario de los controles insertados en nuestros panels va a ser el mismo que el de nuestro componente), y aprovecharíamos el hecho de que los controles se almacenarán de forma consecutiva, en el archivo de recursos .dfm, inmediatamente después de nuestro componente. Para la escritura, lo que podríamos hacer es generar un índice relativo para cada control insertado en los panels, comenzando, por ejemplo, en 0 (teniendo en cuenta que primero se almacena los controles del panel superior y después los del inferior).
Hice una prueba en base a esto y, de momento, parece que funciona bien (tanto en ejecución como en diseño). Aqui os dejo el código completo modificado:
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;
IndCtrl: Integer; 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
uses
SysUtils, Dialogs;
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.ReadString);
Reader.ReadListEnd;
end;
procedure TSubPanel.SetControls(Root: TComponent);
var
Component: TComponent;
I, J: Integer;
begin
inherited;
J := Owner.ComponentIndex + 1;
for I := 0 to DropList.Count - 1 do
begin
Component := Root.Components[StrToInt(DropList[i]) + J];
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
begin
Writer.WriteString(IntToStr(TDoublePanel(Owner).IndCtrl);
Inc(TDoublePanel(Owner).IndCtrl);
end;
Writer.WriteListEnd;
end;
procedure TSubPanel.GetControls(Proc: TGetChildProc; Root: TComponent);
var
Control: TControl;
I: Integer;
begin
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;
IndCtrl := 0; 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.
Comprobareis que ahora si da igual que los componentes tengan nombres o no, ya que siempre los recupera bien y los posiciona correctamente.
(De todas formas, cualquier error que econtréis avisadme!)
Saludos!