我有一个TPanel pnlMain,根据用户操作,数据验证等创建了几个动态TPanel(并且pnlMain是它们的Parent)。每个面板包含一个充满字符串的彩色网格。除了面板,还有一些开源箭头组件和图片。整堆东西。
现在我希望用户能够打印此面板(我问过如何操作on this question),但在打印之前,必须向用户显示一个包含pnlMain副本的新表单。在此表单上,用户必须进行一些更改,添加少量组件,然后打印自定义的pnlMain副本。打印后,用户将关闭此表单并返回原始表单与原始pnlMain。并且 - 正如你猜测的那样 - 原始的pnlMain必须保持完整。
那么有没有聪明的方法来复制整个TPanel及其内容?我知道我可以手动迭代pnlMain.Controls列表。
答案 0 :(得分: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文章的代码
答案 1 :(得分:2)
代码太多...... ObjectBinaryToText和ObjectTextToBinary很好地使用流式传输。 Delphi 7有一个代码示例,不知道2009(或2006年,从不打扰看)仍然拥有它。 有关这些功能,请参阅D5帮助文件(此处没有d5)。
答案 2 :(得分:1)
我是通过使用RTTI复制所有属性来实现的。您仍然需要迭代所有控件,但是当您需要设置属性值时,RTTI可以帮助自动化该过程。您可以在this article的底部找到一个示例,您可以在其中找到指向某个帮助程序代码的链接,包括CopyObject
例程。