在运行时复制组件 [英] Duplicating components at Run-Time
问题描述
有没有一种简单的方式来复制父组件下的所有子组件,包括其已发布的属性?例如:
- TPanel
- TLabel
- TEdit
- TListView
- TSPecialClassX
当然是最重要的因素,它应该复制任何新的组件,我放在TPanel,而不修改代码在正常情况下。
我听说过RTTI,但从来没有使用过它。任何想法?
阅读此页
< a href =http://www.blong.com/Conferences/BorConUK98/DelphiRTTI/CB140.htm =nofollow noreferrer> Delphi中的运行时类型信息 - 可以为您做任何事情吗? / strong>
注意部分将属性从一个组件复制到另一个
其中有一个单元,RTTIUnit带有一个过程,似乎做了一部分你想要什么,但我不认为它将复制任何子组件与额外的代码。
(我认为它可以粘贴到这里...)
(ObjFrom,ObjTo:TObject);
var
PropInfos:PPropList;
PropInfo:PPropInfo;
计数,循环:整数;
OrdVal:Longint;
StrVal:String;
FloatVal:Extended;
MethodVal:TMethod;
begin
// {通过所有已发布的字段和属性来源代码}
// {将它们复制到目标}
// {了解有多少属性我们将考虑}
计数:= GetPropList(ObjFrom.ClassInfo,tkAny,nil);
// {分配内存以保存其RTTI数据}
GetMem(PropInfos,Count * SizeOf(PPropInfo));
try
// {获取我们新的缓冲区中的属性列表}
GetPropList(ObjFrom.ClassInfo,tkAny,PropInfos);
// {循环所有选定的属性}
为循环:= 0到计数 - 1 do
begin
PropInfo:= GetPropInfo(ObjTo.ClassInfo,PropInfos ^ [Loop ] ^。名称);
// {检查属性的一般类型}
// {并以适当的方式读取/写入}
case PropInfos ^ [Loop] ^。PropType ^ .Kind of
tkInteger,tkChar,tkEnumeration,
tkSet,tkClass {$ ifdef Win32},tkWChar {$ endif}:
begin
OrdVal:= GetOrdProp(ObjFrom,PropInfos ^ [Loop]) ;
如果Assigned(PropInfo)然后
SetOrdProp(ObjTo,PropInfo,OrdVal);
结束
tkFloat:
begin
FloatVal:= GetFloatProp(ObjFrom,PropInfos ^ [Loop]);
如果Assigned(PropInfo)然后
SetFloatProp(ObjTo,PropInfo,FloatVal);
结束
{$ ifndef DelphiLessThan3}
tkWString,
{$ endif}
{$ ifdef Win32}
tkLString,
{$ endif}
tkString:
begin
{避免复制'名称' - 组件必须有唯一的名称}
如果UpperCase(PropInfos ^ [Loop] ^。Name)='NAME'然后
继续;
StrVal:= GetStrProp(ObjFrom,PropInfos ^ [Loop]);
如果Assigned(PropInfo)然后
SetStrProp(ObjTo,PropInfo,StrVal);
结束
tkMethod:
begin
MethodVal:= GetMethodProp(ObjFrom,PropInfos ^ [Loop]);
如果Assigned(PropInfo)然后
SetMethodProp(ObjTo,PropInfo,MethodVal);
end
end
end
finally
FreeMem(PropInfos,Count * SizeOf(PPropInfo));
结束
结束
Is there a simple way to duplicate all child components under parent component, including their published properties?
For example:
- TPanel
- TLabel
- TEdit
- TListView
- TSpecialClassX
Of course the most important factor, it should duplicate any new component which I drop on the TPanel without modifying the code under normal circumstances.
I've heard of the RTTI, but never used it actually. Any ideas?
have a read of this page
Run-Time Type Information In Delphi - Can It Do Anything For You?
Noting the section Copying Properties From A Component To Another
which has a unit, RTTIUnit with a Procedure, which seems to do part of what you want but i don't think it will copy any child components with out extra code. (i think its ok to paste it here...)
procedure CopyObject(ObjFrom, ObjTo: TObject);
var
PropInfos: PPropList;
PropInfo: PPropInfo;
Count, Loop: Integer;
OrdVal: Longint;
StrVal: String;
FloatVal: Extended;
MethodVal: TMethod;
begin
//{ Iterate thru all published fields and properties of source }
//{ copying them to target }
//{ Find out how many properties we'll be considering }
Count := GetPropList(ObjFrom.ClassInfo, tkAny, nil);
//{ Allocate memory to hold their RTTI data }
GetMem(PropInfos, Count * SizeOf(PPropInfo));
try
//{ Get hold of the property list in our new buffer }
GetPropList(ObjFrom.ClassInfo, tkAny, PropInfos);
//{ Loop through all the selected properties }
for Loop := 0 to Count - 1 do
begin
PropInfo := GetPropInfo(ObjTo.ClassInfo, PropInfos^[Loop]^.Name);
// { Check the general type of the property }
//{ and read/write it in an appropriate way }
case PropInfos^[Loop]^.PropType^.Kind of
tkInteger, tkChar, tkEnumeration,
tkSet, tkClass{$ifdef Win32}, tkWChar{$endif}:
begin
OrdVal := GetOrdProp(ObjFrom, PropInfos^[Loop]);
if Assigned(PropInfo) then
SetOrdProp(ObjTo, PropInfo, OrdVal);
end;
tkFloat:
begin
FloatVal := GetFloatProp(ObjFrom, PropInfos^[Loop]);
if Assigned(PropInfo) then
SetFloatProp(ObjTo, PropInfo, FloatVal);
end;
{$ifndef DelphiLessThan3}
tkWString,
{$endif}
{$ifdef Win32}
tkLString,
{$endif}
tkString:
begin
{ Avoid copying 'Name' - components must have unique names }
if UpperCase(PropInfos^[Loop]^.Name) = 'NAME' then
Continue;
StrVal := GetStrProp(ObjFrom, PropInfos^[Loop]);
if Assigned(PropInfo) then
SetStrProp(ObjTo, PropInfo, StrVal);
end;
tkMethod:
begin
MethodVal := GetMethodProp(ObjFrom, PropInfos^[Loop]);
if Assigned(PropInfo) then
SetMethodProp(ObjTo, PropInfo, MethodVal);
end
end
end
finally
FreeMem(PropInfos, Count * SizeOf(PPropInfo));
end;
end;
这篇关于在运行时复制组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!