![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Копировать Объект
Иван © (2002-05-14 01:24:00)Я Делфи не давно знаю, вопрос следующий, как в Делфи копировать объект в другой. В C++ этот вопрос решается просто - есть конструктор копирования, в Delphi же объект реально - указатель на объект и пр явном присваивании a:=b; приравниваются указатели, а хотелось бы получить копию. Как это сделатьв Delphi?
Бурундук (2002-05-14 17:08:00) [1]Например, так:
(разумеется, только для published св-в)
procedure CopyPublishedProperties(Src, Dest: TObject);
var i: Integer;
Cls: TClass;
PropCnt: Integer;
PropList: PPropList;
PropInfo: PPropInfo;
function IsField(PropProc: Pointer): Boolean;
type ba = array[0..3]of Byte;
begin
Result := ba(PropProc)[3] > $FE;
end;
begin
if not Dest.InheritsFrom(Src.ClassType) then
raise Exception.CreateFmt("Cannot copy properties from %s to %s", [Src.ClassName, Dest.ClassName]);
PropCnt := GetTypeData(Src.ClassInfo)^.PropCount;
GetMem(PropList, PropCnt*SizeOf(Pointer));
try
GetPropInfos(Src.ClassInfo, PropList);
for i := 0 to PropCnt-1 do
begin
PropInfo := PropList^[i];
if (PropInfo^.Name <> "Name") then
begin
if PropInfo^.PropType^^.Kind = tkMethod then
SetMethodProp(Dest, PropInfo,
GetMethodProp(Src, PropInfo))
else if PropInfo^.PropType^^.Kind = tkClass then
begin
{
Cls := GetTypeData(PropInfo^.PropType^).ClassType;
if (not Cls.InheritsFrom(TComponent)) and
(Cls.InheritsFrom(TPersistent)) and
IsField(PropInfo^.SetProc)
}
if PropInfo^.Name = "Constraints"
then
// По непонятной причине свойство
// property Constraints: TSizeConstraints read FConstraints write FConstraints;
// производит запись прямо в поле, а не через Set-метод + Assign
// Поэтому приходится делать обходной маневр.
//
// Не исключено, что имеются подобные глюки и с другими (более редкими) св-вами.
TPersistent(GetObjectProp(Dest, PropInfo)).Assign
(TPersistent(GetObjectProp(Src, PropInfo)))
else
begin
SetObjectProp(Dest, PropInfo,
GetObjectProp(Src, PropInfo));
end;
end
else
SetPropValue(Dest, PropInfo^.Name, GetPropValue(Src, PropInfo^.Name));
end;
end;
finally
FreeMem(PropList, PropCnt*SizeOf(Pointer));
end;
// if (Src is TControl) then
// TControl(Dest).Parent := TControl(Src).Parent;
end;
PS Я не уверен, что учёл все тонкости, но вроде работает.
Иван (2002-05-14 15:17:00) [2]Спасибо, не очень красиво, но что делать :-(,
а есть способ пройти по всем свойствам объекта, и прокопировать их в другой в цикле?
cpp (2002-05-14 09:13:00) [3]Обычные объекты нельзя.
Можно
1. через Assign. Но только потомки TPersistent
2. Можно Через поток TStream. У него есть метод WriteComponent ReadComponent. Но только потомки TComponent. И копируются только published свойства.
Кулюкин Олег (2002-05-14 08:32:00) [4]Только для своих собственных классов, Assign придется самому ручками реализовывать.
Лёша (2002-05-14 02:20:00) [5]Assign, AssignTo.
Almaz (2002-05-14 02:17:00) [6]Для объектов - потомков TPersistent (практически все стандартные объекты и компоненты Delphi) это реализуется с помошью метода Assign. Например:
var
A, B: TCanvas;
A := TCanvas.Create;
...
B := TCanvas.Create;
B.Assign(A); // Копируем A в B.
Удачи.