Хотя он не дает конкретного ответа на ваш вопрос, приведенный ниже код (подаренный старым группам новостей Borland Delphi несколько лет назад доктором Питером Белоу из TeamB) показывает, как использовать RTTI для клонирования другого компонента.В нем показано, как получить (и установить) под-свойства, такие как другие объекты, перечисляемые типы и т. Д.Этого должно быть достаточно, чтобы вы начали.Я оставил комментарии Питера в коде, а также пример использования его в виде некоторого примера кода под функцией.(Я также сохранил его форматирование кода и странный регистр букв некоторых ключевых слов.:)
// Unfortunately there is no easy way to "clone" a component in a way that
// will also preserve event handlers. It can be done using run-time type
// information and routines form the TypInfo unit, though. Try the following
// routine. It is only superficially tested.
Uses TypInfo;
{-- CloneComponent ----------------------------------------------------}
{: Make a copy of a component.
@Param anObj is the component to copy
@Param cloneChildren if true and anObj is a TWincontrol then all its
child controls will also be copied.
@Param aParent is the parent to use if anObj is a TControl.
@Returns the new object reference. It will have the same owner as anObj
and passes into the responsibility of the caller.
@Precondition anObj <> nil
@Desc The method creates a new object of the same class as anObj and then
uses TypInfo routines to copy all published properties. The logic used
for object properties is similar to what the form loading code uses:
if a property refers to a TComponent the component reference is copied.
If it refers to a TPersistent descendent the Assign method is used
to copy the objects contents. Currently TCollections do not receive
any special treatment, which may be necessary. <BR>
Note: the routine will not copy any objects *owned* by anObj, so it
cannot be used as is to clone a top-level container like a form,
frame, or datamodule. Those can be copied using WriteComponent and
ReadComponent with a TMemoryStream.
}{ Created 12.4.2002 by P. Below
-----------------------------------------------------------------------}
Function CloneComponent( anObj: TComponent;
cloneChildren: Boolean = false;
aParent: TWinControl = nil ): TComponent;
Var
numProps, I : Integer;
props: PPropList;
PropInfo: PPropInfo;
obj, obj2: TObject;
Begin { CloneComponent }
Assert( Assigned( anObj ));
Result := TComponentClass( anObj.ClassType ).Create( anObj.Owner );
Try
numProps := GetPropList(anObj, props );
Try
For I := 0 To numProps - 1 Do Begin
PropInfo := props^[I];
Case PropInfo^.PropType^.Kind Of
tkInteger, tkChar, tkEnumeration, tkSet, tkWChar:
SetOrdProp( Result, propinfo,
GetOrdProp( anObj, propinfo ));
tkFloat:
SetFloatProp( Result, propinfo,
GetFloatProp( anObj, propinfo ));
tkString, tkLString:
If not SameText( propinfo^.name, 'Name' ) Then
SetStrProp( Result, propinfo,
GetStrProp( anObj, propinfo ));
tkWString:
SetWideStrProp( Result, propinfo,
GetWideStrProp( anObj, propinfo ));
tkMethod:
SetMethodProp( Result, propinfo,
GetMethodProp( anObj, propinfo ));
tkInt64:
SetInt64Prop( Result, propinfo,
GetInt64Prop( anObj, propinfo ));
tkVariant:
SetVariantProp( Result, propinfo,
GetVariantProp( anObj, propinfo ));
tkInterface:
SetInterfaceProp( Result, propinfo,
GetInterfaceProp( anObj, propinfo ));
tkClass: Begin
obj := GetObjectProp( anObj, propinfo );
If Assigned( obj ) Then Begin
If obj Is TComponent Then
SetObjectProp( Result, propinfo, obj )
Else If obj Is TPersistent Then Begin
obj2 := GetObjectProp( result, propinfo, TPersistent);
If Assigned( obj2 ) Then
TPersistent( obj2 ).Assign( TPersistent(obj));
End; { If }
End; { If }
End; { Case tkClass }
Else
// we don't handle these property types:
// tkArray, tkRecord, tkDynArray
End; { Case }
End; { For }
Finally
FreeMem( props );
End; { Finally }
If anObj Is TControl Then
TControl( result ).Parent := aParent;
If cloneChildren and (anObj Is TWinControl ) Then
For i:= 0 To TWinControl( anObj ).ControlCount-1 Do
CloneComponent( TWinControl( anObj ).Controls[i], true,
TWinControl( Result ) );
Except
Result.Free;
raise
End; { Except }
End; { CloneComponent }
procedure TForm1.GroupBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
memo1.lines.add('Click on groupbox '+(sender as TComponent).Name );
end;
procedure TForm1.Button1Click(Sender: TObject);
Var
ctrl: TWinControl;
begin
ctrl := CloneComponent( groupbox1, true, self ) as TWincontrol;
With ctrl Do
SetBounds( left, top+height+8, width, height );
memo1.Lines.add( Format('Controlcount: %d', [ctrl.controlcount]));
end;