4

我有一个 TPanel pnlMain,其中根据用户操作、数据验证等创建了几个动态 TPanel(并且 pnlMain 是它们的父级)。每个面板都包含一个充满字符串的彩色网格。除了面板,还有一些开源箭头组件和一张图片。一大堆东西。

现在我希望用户能够打印这个面板(我在这个问题上问过如何做到这一点),但在打印之前,必须向用户呈现一个新表单,其中包含 pnlMain 的副本。在此表单上,用户必须进行一些更改,添加一些组件,然后打印他自定义的 pnlMain 副本。打印后用户将关闭此表单并使用原始 pnlMain 返回原始表单。而且——你可以猜到——原来的 pnlMain 必须保持原样。

那么有没有什么聪明的方法可以复制整个 TPanel 及其内容呢?我知道我可以通过 pnlMain.Controls 列表手动迭代。

4

3 回答 3

3

基于迭代子控件的代码,但无论如何都不错;-)

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;

Delphi3000文章中的代码

于 2009-08-06T12:01:45.650 回答
2

代码太多... ObjectBinaryToText 和 ObjectTextToBinary 使用流式传输很好地完成了这项工作。Delphi 7有一个代码示例,不知道2009(或2006,从不费心看)还有没有。有关这些功能,请参阅 D5 帮助文件(此处没有 d5)。

于 2009-08-07T09:01:54.423 回答
1

我会通过使用 RTTI 复制所有属性来做到这一点。您仍然需要遍历所有控件,但是当您需要设置属性值时,RTTI 可以帮助自动化该过程。您可以在本文底部找到一个示例,您可以在其中找到一些帮助代码的链接,包括一个CopyObject例程。

于 2009-08-06T13:55:43.710 回答