Копирование свойств одного компонента другому

Копирование свойств одного компонента другому

uses
  StrUtils;
procedure CopyComponentProp(Source, Target: TObject; aExcept: array of string);
// Копирование всех одинаковых по названию свойств/методов одного компонента в
// другой за исключение "Name", "Left", "" и тех которые заданы в aExcept
// Примеры использования:
// CopyComponentProp(N11, N21, []);
// CopyComponentProp(ListBox2, ListBox3, []);
// CopyComponentProp(ListView1, ListView2, ['Items', 'Color']);
var
 I, Index: Integer;
 PropName: string;
 Source_PropList , Target_PropList : PPropList;
 Source_NumProps , Target_NumProps : Word;
 Source_PropObject, Target_PropObject: TObject;
 // Поиск в списке свойства с заданным именем
 function FindProperty(const PropName: string; PropList: PPropList; NumProps: Word): Integer;
 var
  I: Integer;
 begin
  Result:= -1;
  for I:= 0 to NumProps - 1 do
  if CompareStr(PropList^[I]^.Name, PropName) = 0 then begin
  Result:= I;
  Break;
  end;
 end;
begin
 if not Assigned(Source) or not Assigned(Target) then Exit;
 Source_NumProps:= GetTypeData(Source.ClassInfo)^.PropCount;
 Target_NumProps:= GetTypeData(Target.ClassInfo)^.PropCount;
 GetMem(Source_PropList, Source_NumProps * SizeOf(Pointer));
 GetMem(Target_PropList, Target_NumProps * SizeOf(Pointer));
 try
  // Получаем список свойств
  GetPropInfos(Source.ClassInfo, Source_PropList);
  GetPropInfos(Target.ClassInfo, Target_PropList);
  for I:= 0 to Source_NumProps - 1 do begin
  PropName:= Source_PropList^[I]^.Name;
  if (AnsiIndexText('None' , aExcept ) = -1) and
  ((AnsiIndexText(PropName, ['Name', 'Left', '']) <> -1) or
  (AnsiIndexText(PropName, aExcept ) <> -1)) then Continue;
  Index:= FindProperty(PropName, Target_PropList, Target_NumProps);
  if Index = -1 then Continue; // не нашли
  // Проверить совпадение типов
  if Source_PropList^[I]^.PropType^.Kind <> Target_PropList^[Index]^.PropType^.Kind then
  Continue;
  case Source_PropList^[I]^.PropType^^.Kind of
  tkClass: begin
  Source_PropObject:= GetObjectProp(Source, Source_PropList^[I ]);
  Target_PropObject:= GetObjectProp(Target, Target_PropList^[Index]);
  CopyComponentProp(Source_PropObject, Target_PropObject, ['None']);
  end;
  tkMethod: SetMethodProp(Target, PropName, GetMethodProp(Source, PropName));
  else
  SetPropValue(Target, PropName, GetPropValue(Source, PropName));
  end;
  end;
 finally
  FreeMem(Source_PropList);
  FreeMem(Target_PropList);
 end;
end;
uses
  StrUtils
procedure AssignComponentProp(Source, Target: TObject; aProp: array of string);
// Копирование свойств/методов заданых в aProp одного компонента в другой
// Пример использования:
// AssignedComponentProp(ListView1, ListView2, ['Items', 'Color']);
var
 I, Index: Integer;
 PropName: string;
 Source_PropList , Target_PropList : PPropList;
 Source_NumProps , Target_NumProps : Word;
 Source_PropObject, Target_PropObject: TObject;
 // Поиск в списке свойства с заданным именем
 function FindProperty(const PropName: string; PropList: PPropList; NumProps: Word): Integer;
 var
  I: Integer;
 begin
  Result:= -1;
  for I:= 0 to NumProps - 1 do
  if CompareStr(PropList^[I]^.Name, PropName) = 0 then begin
  Result:= I;
  Break;
  end;
 end;
begin
 if not Assigned(Source) or not Assigned(Target) then Exit;
 Source_NumProps:= GetTypeData(Source.ClassInfo)^.PropCount;
 Target_NumProps:= GetTypeData(Target.ClassInfo)^.PropCount;
 GetMem(Source_PropList, Source_NumProps * SizeOf(Pointer));
 GetMem(Target_PropList, Target_NumProps * SizeOf(Pointer));
 try
  // Получаем список свойств
  GetPropInfos(Source.ClassInfo, Source_PropList);
  GetPropInfos(Target.ClassInfo, Target_PropList);
  for I:= 0 to Source_NumProps - 1 do begin
  PropName:= Source_PropList^[I]^.Name;
  if (AnsiIndexText('None' , aProp ) = -1) and
  (AnsiIndexText(PropName, aProp ) = -1) then Continue;
  Index:= FindProperty(PropName, Target_PropList, Target_NumProps);
  if Index = -1 then Continue; // не нашли
  // Проверить совпадение типов
  if Source_PropList^[I]^.PropType^.Kind <> Target_PropList^[Index]^.PropType^.Kind then
  Continue;
  case Source_PropList^[I]^.PropType^^.Kind of
  tkClass: begin
  Source_PropObject:= GetObjectProp(Source, Source_PropList^[I ]);
  Target_PropObject:= GetObjectProp(Target, Target_PropList^[Index]);
  AssignComponentProp(Source_PropObject, Target_PropObject, ['None']);
  end;
  tkMethod: SetMethodProp(Target, PropName, GetMethodProp(Source, PropName));
  else
  SetPropValue(Target, PropName, GetPropValue(Source, PropName));
  end;
  end;
 finally
  FreeMem(Source_PropList);
  FreeMem(Target_PropList);
 end;
end;

Автор Alex
Взято с Vingrad.ru http://forum.vingrad.ru

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...