Главная » Delphi » Присвоение значений свойствам с помощью RTTI

0

Ознакомившись со способами поиска  и определения свойств компонентов, будет весьма  полезно узнать,  как с помощью информации  RTTI  присвоить этим  свойствам значения. Такая  задача  довольно проста. В модуле  TypInfo.pas содержится много вспомогательных процедур, позволяющих опрашивать и устанавливать публикуемые (public) свойства компонентов. Речь  идет  о тех же самых  вспомогательных процеду рах,  которые используются интегрированной средой разработки Delphi  (IDE)  (в окнеObject Inspector). Было бы очень  полезно открыть модуль TypInfo.pas и ознакомиться с этими процедурами. Некоторые из них приведены ниже.

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

procedure SetIntegerPropertyIfExists(AComp: TComponent; APropName: String; AValue: Integer);

var

PropInfo: PPropInfo;

begin

PropInfo := GetPropInfo(AComp.ClassInfo, APropName);

if PropInfo <> nil then begin

if PropInfo^.PropType^.Kind = tkInteger then

SetOrdProp(AComp, PropInfo, Integer(AValue));

end;

end;

Данная процедура принимает три  параметра. Первый параметр, AComp, представ ляет  собой  компонент,  свойство которого  следует  модифицировать. Второй пара метр,   APropName, —   это  имя  свойства,  которому  необходимо присвоить  значение третьего параметра, AValue. В данной процедуре используется функция GetPro- pInfo(), предназначенная для считывания указателя  TPropInfo на заданное свойст во. Если этого  свойства не существует,  то функция GetPropInfo() вернет значение nil. Если же свойство существует,  то с помощью второго оператора if определяется корректность типа  заданного свойства. Тип  свойства tkInteger определен в модуле TypInfo.pas вместе с другими возможными типами свойств, как показано ниже:

TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);

Наконец, присвоение значения свойству  выполняется с использованием еще одной процедуры —  SetOrdProp() —  из модуля TypInfo.pas, которая как раз  и предназна чена для установки значений свойств перечислимого типа.  Обращение к этой  процеду ре может выглядеть примерно следующим образом:

SetIntegerPropertyIfExists(Button2, ‘Width’, 50);

Метод  SetOrdProp() называют методом установки (setter method), поскольку  он устанавливает заданное свойство равным заданному  значению. Существует  также  и метод  чтения значения свойства (getter method). В модуле TypInfo.pas есть несколь ко таких  вспомогательных процедур с соответствующими именами (SetXXXProp()), предусмотренных для всех возможных типов свойств  (табл. 10.7).

Таблица 10.7. Методы чтения и установки свойств

Тип свойства

Метод установки

Метод чтения

Порядковый

SetOrdProp()

GetOrdProp()

Перечислимый

SetEnumProp()

GetEnumProp()

Объект

SetObjectProp()

GetObjectProp()

Строка

SetStrProp()

GetStrProp()

С плавающей запятой

SetFloatProp()

GetFloatProp()

Вариант

SetVariantProp()

GetVariantProp()

Метод (Событие)

SetMethodProp()

GetMethodProp()

Int64

SetInt64Prop()

GetInt64Prop()

И опять  обращаю внимание на то,  что  в модуле TypInfo.pas содержится много других вспомогательных методов, которые могут оказаться очень  полезными.

В следующем фрагменте показано, как присваивается значение свойству объекта:

procedure SetObjectPropertyIfExists(AComponent: TComponent; APropName: String; AValue: TObject);

var

PropInfo: PPropInfo;

begin

PropInfo := GetPropInfo(AComponent.ClassInfo, APropName);

if PropInfo <> nil then begin

if PropInfo^.PropType^.Kind = tkClass then

SetObjectProp(AComponent, PropInfo, AValue);

end;

end;

Этот метод можно вызвать следующим образом:

var

F: TFont;

begin

F := TFont.Create;

F.Name        := ‘Arial';

F.Size        := 24;

F.Color       := clRed;

SetObjectPropertyIfExists(Panel1, ‘Font’, F);

end;

А вот как можно присвоить значение свойству метода:

procedure SetMethodPropertyIfExists(AComp: TComponent; APropName: String; AMethod: TMethod);

var

PropInfo: PPropInfo;

begin

PropInfo := GetPropInfo(AComp.ClassInfo, APropName);if PropInfo <> nil then begin

if PropInfo^.PropType^.Kind = tkMethod then

SetMethodProp(AComp, PropInfo, AMethod);

end;

end;

Данный метод требует использования типа TMethod, который определен в модуле Sy- sUtils.pas. Чтобы вызвать метод,  назначающий обработчик события одного  компо нента  другому, можно  использовать метод  GetMethodProp(), считывающий значение TMethod из исходного компонента:

SetMethodPropertyIfExists(Button5, ‘OnClick’, GetMethodProp(Panel1, ‘OnClick’));

На прилагаемом CD находится проект SetProperties.dpr, демонстрирующий использование этих методов.

Резюме

В настоящей главе обсуждались библиотека визуальных компонентов (VCL) и биб лиотека межплатформенных компонентов (CLX).  Кроме  того,  была  рассмотрена ие рархия классов, а также  характеристики компонентов различных уровней иерархии. К тому же подробно обсуждалась информация о типах времени выполнения (RTTI).

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии