Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Копировать Объект


Иван ©   (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.


Удачи.


Наверх

Титульная страница Поиск, карта сайта Написать письмо