Search code examples
delphidynamic-controlsdelphi-5tpanel

Create an exact copy of TPanel on Delphi5


I have a TPanel pnlMain, where several dynamic TPanels are created (and pnlMain is their Parent) according to user actions, data validations, etc. Every panel contains one colored grid full of strings. Apart from panels, there are some open source arrows components and a picture. Whole bunch of stuff.

Now I want user to be able to print this panel (I asked how to do it on this question), but before printing, user must be presented with a new form, containing copy of pnlMain. On this form user has to do some changes, add few components and then print his customized copy of pnlMain. After printing user will close this form and return to original form with original pnlMain. And – as you can guess – original pnlMain must remain intact.

So is there any clever way to copy whole TPanel and it’s contents? I know I can make it manually iterating through pnlMain.Controls list.


Solution

  • Code based as iterating on child controls, but not bad in anyway ;-)

    procedure TForm1.btn1Click(Sender: TObject);
    
        function CloneComponent(AAncestor: TComponent): TComponent;
          var
            XMemoryStream: TMemoryStream;
            XTempName: string;
          begin
            Result:=nil;
            if not Assigned(AAncestor) then
              exit;
            XMemoryStream:=TMemoryStream.Create;
            try
              XTempName:=AAncestor.Name;
              AAncestor.Name:='clone_' + XTempName;
              XMemoryStream.WriteComponent(AAncestor);
              AAncestor.Name:=XTempName;
              XMemoryStream.Position:=0;
              Result:=TComponentClass(AAncestor.ClassType).Create(AAncestor.Owner);
              if AAncestor is TControl then TControl(Result).Parent:=TControl(AAncestor).Parent;
              XMemoryStream.ReadComponent(Result);
            finally
              XMemoryStream.Free;
            end;
          end;
    
        var
          aPanel: TPanel;
          Ctrl, Ctrl_: TComponent;
          i: integer;
        begin
          //handle the Control (here Panel1) itself first
          TComponent(aPanel) := CloneComponent(pnl1);
          with aPanel do
          begin
            Left := 400;
            Top := 80;
          end;
    
          //now handle the childcontrols
          for i:= 0 to pnl1.ControlCount-1 do begin
            Ctrl := TComponent(pnl1.Controls[i]);
            Ctrl_ := CloneComponent(Ctrl);
            TControl(Ctrl_).Parent := aPanel;
            TControl(Ctrl_).Left := TControl(Ctrl).Left;
            TControl(Ctrl_).top := TControl(Ctrl).top;
          end;
        end;
    

    code from Delphi3000 article