2009-08-06 11 views
4

Ich habe ein TPanel pnlMain, wo mehrere dynamische TPanels erstellt werden (und pnlMain ist ihr Parent) nach Benutzeraktionen, Datenvalidierungen, etc. Jedes Panel enthält ein farbiges Gitter voller Strings. Neben Panels gibt es einige Open-Source-Pfeilkomponenten und ein Bild. Ganzer Haufen Zeug.Erstellen Sie eine genaue Kopie von TPanel auf Delphi5

Jetzt möchte ich Benutzer in der Lage sein, dieses Panel zu drucken (ich fragte, wie es geht on this question), aber vor dem Drucken muss Benutzer mit einem neuen Formular präsentiert werden, das eine Kopie von pnlMain enthält. Auf diesem Formular muss der Benutzer einige Änderungen vornehmen, einige Komponenten hinzufügen und dann seine angepasste Kopie von pnlMain ausdrucken. Nach dem Drucken wird der Benutzer dieses Formular schließen und mit dem ursprünglichen pnlMain zum ursprünglichen Formular zurückkehren. Und - wie Sie sich denken können - original pnlMain muss intakt bleiben.

Also gibt es eine clevere Möglichkeit, ganze TPanel und seinen Inhalt zu kopieren? Ich weiß, dass ich manuell durch die pnlMain.Controls-Liste iterieren kann.

Antwort

3

-Code als Iterieren über Kinder Kontrollen basiert, aber in sowieso ;-)

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 aus Delphi3000 Artikel

+0

IT funktioniert zu einem gewissen Punkt - beim Lesen von TGroupBox mit THTMLCheckBox von TMS Kontrollen, habe ich "Klasse THTMLCheckBox nicht gefunden" in Zeile XMemoryStream.ReadComponent (Result); Einige andere Steuerelemente aus dem TMS-Paket werden jedoch korrekt gelesen. – smok1

1

Ich würde es nicht schlecht tun RTTI, indem Sie alle Eigenschaften zu kopieren. Sie müssten immer noch über alle Steuerelemente hinweg iterieren, aber wenn Sie die Eigenschaftswerte einrichten müssen, kann RTTI helfen, den Prozess zu automatisieren. Sie können ein Beispiel in Richtung der Unterseite von this article erhalten, wo Sie einen Link zu einem Helfer-Code finden, einschließlich einer CopyObject Routine.

2

Zu viel Code ... ObjectBinaryToText und ObjectTextToBinary machen den Job schön mit Streaming. Delphi 7 haben ein Codebeispiel, weiß nicht, 2009 (oder 2006, nie zu schauen) immer noch haben. Siehe D5-Hilfedatei für diese Funktionen (d5 ist hier nicht verfügbar).