Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

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

Delphi , Компоненты и Классы , RTTI

Code:
uses
  StrUtils;
 
procedure CopyComponentProp(Source, Target: TObject; aExcept: array of string);
// Копирование всех одинаковых по названию свойств/методов одного компонента в
// другой за исключение "Name", "Left", "Top" и тех которые заданы в 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', 'Top']) <> -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;
 
Code:
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

Код, который вы предоставили, - это пары процедур на языке Delphi, которые копируют свойства из одного компонента в другой с некоторыми исключениями.

Первая процедура, CopyComponentProp, копирует все свойства из исходного компонента в целевой компонент, за исключением свойств "Name", "Left" и "Top". Она также игнорирует любые свойства, указанные в массиве aExcept.

Вторая процедура, AssignComponentProp, копирует только свойства, указанные в массиве aProp, из исходного компонента в целевой компонент.

Рассмотрим каждую процедуру:

CopyComponentProp

  1. Она сначала проверяет, являются ли оба компонента назначенными.
  2. Затем она получает количество свойств для обоих компонентов с помощью GetTypeData.
  3. Она выделяет память для двух списков информации о свойствах с помощью GetMem.
  4. Она получает список свойств для обоих компонентов с помощью GetPropInfos.
  5. Процедура затем проходит по каждому свойству в списке свойств исходного компонента.
  6. Для каждого свойства она проверяет, является ли это свойство исключением, сравнивая его имя с строками "Name", "Left" и "Top" или массивом aExcept.
  7. Если свойство не является исключением, она находит соответствующее свойство в списке свойств целевого компонента с помощью FindProperty.
  8. Затем она проверяет, совпадают ли типы свойств. Если они не совпадают, она пропускает это свойство.
  9. Наконец, она копирует значение свойства из исходного компонента в целевой компонент в зависимости от типа свойства.

AssignComponentProp

Эта процедура похожа на CopyComponentProp, но она копирует только свойства, указанные в массиве aProp.

Некоторые предложения по улучшению:

  1. Рассмотрите использование более эффективного алгоритма для поиска свойств, например, используя TStringList или TDictionary вместо линейного поиска.
  2. Вам может потребоваться добавление обработки ошибок для случаев, когда исходный или целевой компонент не назначен, или если возникла проблема при копировании свойства.
  3. Было бы полезно иметь более описательное имя для этих процедур, например, CopyComponentPropertiesExcept и AssignSpecificComponentProperties.

В целом, эти процедуры хорошо структурированы и легко понятны. Однако некоторые улучшения можно сделать, чтобы сделать их более эффективными и устойчивыми.

Копирование свойств одного компонента в другой, за исключением определенных свойств и методов.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: RTTI ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-29 00:55:32/0.0037500858306885/0