design-time때 Component나 Control의 property를 복사하려면
그냥 control을 선택해서 ctrl+c / ctrl+v 하면 됩니다.
그런데 어저께 델마당에
run-time에 컴포넌트이 propery를 복사하는 방법에 대한 질문이 올라오더군요
http://www.delmadang.com/community/bbs_view.asp?bbsNo=17&bbsCat=0&st=&keyword=&indx=419336&keyword1=&keyword2=&page=2
동적으로 Control을 Create한후에
이전에 생성되어있던 control의 property를 모두 복사하는 방법입니다.
작년 델파이 연합 세미나 자료를 참조하여
http://www.delmadang.com/community/bbs_view.asp?bbsNo=21&bbsCat=0&st=C&keyword=RTTI&indx=416880
방금 간단히 구현해 보았습니다.
델파이버젼
procedure CopyControlProperty( OrgCtrl: TControl;DestCtrl: TControl);
var
I,PropCount: Integer;
PropList: PPropList;
PropInfo: PPropInfo;
TypeInfo: PTypeInfo;
begin
if(OrgCtrl.ClassType <> DestCtrl.ClassType)then Exit;
PropCount := GetTypeData(OrgCtrl.ClassInfo)^.PropCount;
if PropCount > 0 then
begin
GetMem(PropList, PropCount * SizeOf(Pointer));
try
GetPropInfos(OrgCtrl.ClassInfo, PropList);
for I := 0 to PropCount - 1 do
begin
PropInfo := PropList^[I];
if PropInfo = nil then Break;
if IsStoredProp(OrgCtrl, PropInfo) and Assigned(PropInfo^.SetProc) then
begin
TypeInfo := PropInfo^.PropType^;
case TypeInfo^.Kind of
tkInteger, tkChar, tkWChar, tkEnumeration, tkSet:
begin
SetOrdProp(DestCtrl, PropInfo.Name,
GetOrdProp(OrgCtrl, PropInfo));
end;
tkFloat:
begin
SetFloatProp(DestCtrl, PropInfo.Name,
GetFloatProp(OrgCtrl, PropInfo));
end;
tkString, tkLString, tkWString:
begin
SetStrProp(DestCtrl, PropInfo.Name,
GetStrProp(OrgCtrl, PropInfo));
end;
tkClass:
begin
SetObjectProp(DestCtrl, PropInfo.Name,
GetObjectProp(OrgCtrl, PropInfo));
end;
tkVariant:
begin
SetVariantProp(DestCtrl, PropInfo.Name,
GetVariantProp(OrgCtrl, PropInfo));
end;
tkInt64:
begin
SetInt64Prop(DestCtrl, PropInfo.Name,
GetInt64Prop(OrgCtrl, PropInfo));
end;
tkMethod:
begin
SetMethodProp(DestCtrl, PropInfo.Name,
GetMethodProp(OrgCtrl, PropInfo));
end;
tkInterface:
begin
SetInterfaceProp(DestCtrl, PropInfo.Name,
GetInterfaceProp(OrgCtrl, PropInfo));
end;
end;
end;
end;
finally
FreeMem(PropList, PropCount * SizeOf(Pointer));
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
mmo: TMemo;
lbl: TLabel;
begin
mmo:=TMemo.Create(Memo1.Owner);
mmo.Parent:=Panel2;
CopyControlProperty(Memo1,mmo);
//-------------------------------
lbl:= TLabel.Create(Label1.Owner);
lbl.Parent:=Panel2;
CopyControlProperty(Label1,lbl);
//--------------------------------
end;
procedure TForm1.Label1Click(Sender: TObject);
begin
ShowMessage('Label1Click');
end;
C++Builder 버젼
Delphi소스를 C++Builder로 변환이 까다롭네요
#include
void __fastcall CopyControlProperty( TControl *OrgCtrl,TControl *DestCtrl)
{
if(OrgCtrl->ClassType()!=DestCtrl->ClassType())return;
PTypeInfo TypeInfo =(TTypeInfo *)OrgCtrl->ClassInfo();
PTypeData TypeData= GetTypeData(TypeInfo);
PPropList PropList;
PPropInfo PropInfo;
int PropCount = TypeData->PropCount;
if( PropCount > 0 )
{
PropList=new PPropInfo[PropCount];
try
{
GetPropInfos(TypeInfo, PropList);
for( int I=0 ;I< PropCount;I++)
{
PropInfo = (TPropInfo *)PropList[I];
if( PropInfo ==NULL )break;
if( IsStoredProp(OrgCtrl, PropInfo) && (PropInfo->SetProc) )
{
TypeInfo = *PropInfo->PropType;
switch( TypeInfo->Kind)
{
case tkInteger:
case tkChar:
case tkWChar:
case tkEnumeration:
case tkSet:
SetOrdProp(DestCtrl, PropInfo->Name,
GetOrdProp(OrgCtrl, PropInfo));
break;
case tkFloat:
SetFloatProp(DestCtrl, PropInfo->Name,
GetFloatProp(OrgCtrl, PropInfo));
break;
case tkString:
case tkLString:
case tkWString:
SetStrProp(DestCtrl, PropInfo->Name,
GetStrProp(OrgCtrl, PropInfo));
break;
case tkClass:
SetObjectProp(DestCtrl, PropInfo->Name,
GetObjectProp(OrgCtrl, PropInfo));
break;
case tkVariant:
SetVariantProp(DestCtrl, PropInfo->Name,
GetVariantProp(OrgCtrl, PropInfo));
break;
case tkInt64:
SetInt64Prop(DestCtrl, PropInfo->Name,
GetInt64Prop(OrgCtrl, PropInfo));
break;
case tkMethod:
SetMethodProp(DestCtrl, PropInfo->Name,
GetMethodProp(OrgCtrl, PropInfo));
break;
case tkInterface:
SetInterfaceProp(DestCtrl, PropInfo->Name,
GetInterfaceProp(OrgCtrl, PropInfo));
break;
case tkArray:
case tkRecord:
case tkDynArray:
break;
};
}
}
}
__finally
{
delete PropList;
}
}
}
그럼..