Создайте точную копию TPanel на Delphi5 - PullRequest
4 голосов
/ 06 августа 2009

У меня есть TPanel pnlMain, где создается несколько динамических TPanel (и pnlMain является их Родителем) в соответствии с действиями пользователя, проверкой данных и т. Д. Каждая панель содержит одну цветную сетку, полную строк. Помимо панелей, есть несколько компонентов стрелок с открытым исходным кодом и изображение. Целая куча вещей.

Теперь я хочу, чтобы пользователь мог печатать эту панель (я спросил, как это сделать по этому вопросу ), но перед печатью пользователю должна быть представлена ​​новая форма, содержащая копию pnlMain. В этой форме пользователь должен внести некоторые изменения, добавить несколько компонентов, а затем распечатать свою настроенную копию pnlMain. После печати пользователь закроет эту форму и вернется к исходной форме с оригинальным pnlMain. И, как вы можете догадаться, оригинальный pnlMain должен остаться без изменений.

Так есть ли какой-нибудь умный способ скопировать весь TPanel и его содержимое? Я знаю, что могу сделать это вручную, перебирая список pnlMain.Controls.

Ответы [ 3 ]

3 голосов
/ 06 августа 2009

Код основан на итерации дочерних элементов управления, но в любом случае неплох; -)

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 артикул

2 голосов
/ 07 августа 2009

Слишком много кода ... ObjectBinaryToText и ObjectTextToBinary прекрасно выполняют свою работу, используя потоковую передачу. В Delphi 7 есть пример кода, но я не знаю, что в 2009 году (или в 2006 году никогда не удосужился посмотреть) все еще есть. См. Файл справки D5 для этих функций (здесь нет d5).

1 голос
/ 06 августа 2009

Я бы сделал это, используя RTTI для копирования всех свойств. Вам все равно придется перебирать все элементы управления, но когда вам нужно настроить значения свойств, RTTI может помочь автоматизировать процесс. Вы можете получить пример в нижней части этой статьи , где вы найдете ссылку на некоторый вспомогательный код, включая подпрограмму CopyObject.

...