在运行时复制组件 [英] Duplicating components at Run-Time

查看:93
本文介绍了在运行时复制组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



有没有一种简单的方式来复制父组件下的所有子组件,包括其已发布的属性?例如:




  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆