Не вдаваясь пока в подробности, опишем, в целом, назначение методов класса.
ObjectName - метод возвращает имя конкретного экземпляра инспектируемого объекта. Объект (или его заместитель) передается функции как аргумент, |
|
TypeName возвращает имя типа. Например, имя типа может быть таким - «Синхронный двигатель», а имя объекта - «Д 4/8», |
TypeInfo предоставляет метаданные о типе в целом, а ChildrenInfo - о всех его свойствах. ChildrenInfo за одно обращение возвращает информацию об одном свойстве, которое индексируется аргументом Index. При выходе за индекс последнего свойства ChildrenInfo возвращает nil. Так выполняется итерация по всем свойствам - инспектор вызывает функцию ChildrenInfo с монотонно возрастающим (от нуля) значением индекса и завершает итерацию, когда функция возвращает nil, |
|
FillList и ShowDialog реализуют необходимую функциональность в том случае, когда свойство представлено как список значений или когда для редактирования свойства требуется специализированный диалог-мастер. |
Все остальные функции реализуют различные вспомогательные преобразования, которые служат для преобразования значений свойств в строковый вид для отображения в инспекторе и, наоборот, преобразования строковых значений, измененных в инспекторе, к реальным типам свойств. Методы класса не являются абстрактными, а реализуют свою функциональность для некоторого общего случая (по умолчанию), например, в качестве имени объекта возвращается пустая строка, а преобразование из целого в строку выполняется стандартной функцией IntToStr. Это позволяет переопределять в наследуемых классах только некоторые, действительно нужные, методы.
Наибольший интерес для нас будет представлять тип PGsvObjectInspectorPropertyInfo - указатель на структуру типа TGsvObjectInspectorPropertyInfo. Данные именно этого типа возвращаются методами TypeInfo и ChildrenInfo. Каждое инспектируемое свойство (а также весь тип в целом) описывается константной записью. Для простоты опустим служебные поля, которые неважны с точки зрения метаданных, и которые не задаются в константной записи:
Code: |
TGsvObjectInspectorPropertyInfo = record Name: String; Caption: String; Kind: TGsvObjectInspectorPropertyKind; Tag: LongInt; NestedType: String; NestedClass: TGsvObjectInspectorTypeInfoClass; Help: Integer; Hint: String; end; PGsvObjectInspectorTypeInfo = ^TGsvObjectInspectorTypeInfo; |
Поле Caption содержит имя свойства, под которым оно будет отображаться в инспекторе, |
|
Kind. Это поле декларирует особенности отображения значения свойства в инспекторе, например, значение может быть текстом, списком, множеством, сложным объектом, который редактируется специальным редактором и так далее, |
Tag используется для задания специфических данных свойства. В текущей версии инспектора он использует только для описания свойств-множеств, |
|
NestedType и NestedClass. Два этих поля предоставляют альтернативные возможности указания типа вложенного свойства. Здесь целесообразно отметить, что вложенные свойства рассматриваются и описываются как самостоятельные - это позволяет описать их один раз и использовать в других классах метаданных. Забегая вперед, скажу что NestedType используется в том случае, если класс метаданных регистрируется в реестре метаданных, а NestedClass - если вложенный объект описывается в известном программном модуле и доступен при компиляции. Вложенное свойство трактуется весьма широко и, в общем случае, служит для ссылки на другой класс метаданных, который может быть действительно сложным объектом, или предоставлять метаданные об одном-единственном простом свойстве. Важным здесь является то, что классы метаданных могут ссылаться на другие метаклассы и создавать внутреннюю иерархическую структуру свойств инспектируемого объекта, |
Поля Help и Hint в особых комментариях не нуждаются. |
Поле Kind может принимать (в данной версии инспектора) следующие значения:
pkText - значение свойства отображается как текст, доступный для редактирования, |
|
pkDropDownList - значение свойства доступно для выбора из списка возможных значений, |
pkDialog - значения свойства редактируются специализированным диалогом-мастером, |
|
pkFolder - фиктивное свойство, не имеющее значения, но позволяющее выстроить иерархический список дочерних подсвойств, |
pkReadOnlyText - аналогично pkText, но доступно только для чтения, |
|
pkImmediateText - аналогично pkText, но изменение значения свойства фиксируются немедленно при любом изменении текста, |
pkBoolean - свойство отображается как CheckBox, |
|
pkTextList - подобно pkDropDownList, но значение свойства можно редактировать, то есть, диапазон значений не ограничен списком, |
pkSet - свойство-множество, отображается как родительское для вложенного списка элементов множества, каждый из которых представляется как логическое значение, |
|
pkColor - свойство для выбора цвета из заданного списка, |
pkColorRGB - подобно предыдущему, но цвет задается и редактируется в виде R.G.B и имеется возможность выбора цвета с помощью стандартного Windows-диалога. |
Для иллюстрации всего сказанного приведем конкретный пример. Для простоты предположим, что мы будем инспектировать объекты всем известного типа TLabel. Причем, будем считать, что пользователю доступны для инспекции только свойства Caption, Font, Color, а также координаты и размеры. Класс метаданных для TLabel будет, в данном случае, таким:
Code: |
type TLabel_INFO = class(TGsvObjectInspectorTypeInfo) public classfunction ChildrenInfo(Index: Integer): PGsvObjectInspectorPropertyInfo; override; end;
classfunction TLabel_INFO.ChildrenInfo(Index: Integer): PGsvObjectInspectorPropertyInfo; const DSK: array[0..3] of TGsvObjectInspectorPropertyInfo = ( ( Name: 'Caption'; Caption: 'Надпись'; Kind: pkImmediateText ), ( NestedClass: TGsvBounds_INFO ), ( Name: 'Font'; NestedType: 'TFont' ), ( Name: 'Color'; Caption: 'Цвет фона'; NestedType: 'TGsvColorRGB' ) ); begin ifIndex <= High(DSK) then Result := @DSK[Index] else Result := nil; end; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!