Метакласс TGsvColor16_INFO порожден от TGsvObjectInspectorTypeListInfo, который переопределяет методы IntegerToString, StringToInteger и FillList, а для задания списка перечислений вводит новый виртуальный метод ListEnumItems - этот метод напоминает ChildrenInfo, но возвращает не типовые метаданные, а данные по каждому элементу перечисления - его имя и ассоциированное с ним значение. Метакласс TFontStyles_INFO порожден от TGsvObjectInspectorTypeSetInfo, переопределяющего метод IntegerToString. Вот каким получится вид инспектора при инспектировании объекта типа TLabel для определенных нами метаданных:
Может показаться, что нам потребовалось довольно много описаний, но нужно учесть, что все определенные выше метаклассы могут быть использованы в большом числе других классов, создавая, таким образом, дерево классов метаданных. Например, если бы мы захотели теперь создать метаданные для TButton, то нам потребовалось определить всего один метакласс TButton_INFO.
Вы, вероятно, уже обратили внимание на то, как образуются имена метаклассов - к имени инспектируемого типа добавляется суффикс _INFO. Это основное соглашение об именовании метаклассов. Кроме него, можно вводить дополнительные соглашения. Если при инспектировании объектов предполагается учет категории пользователей, то имя метакласса может состоять из имени класса, категории и суффикса, например, TButton_EXPERT_INFO. Возможен и другой вариант, при котором метаклассы различных категорий пользователей располагаются в различных DLL.
Последний вопрос, который остался неосвещенным - это реестр метаданных. Для того, чтобы инспектор мог получить доступ к метаданным, инспектор должен на основе типа объекта, который передан ему для инспекции, сформировать имя соответствующего метакласса и запросить реестр о ссылке на метакласс. Метаклассы, в свою очередь, должны иметь возможность регистрировать себя в реестре. Для этого имеются три глобальных процедуры:
Code: |
procedure GsvRegisterTypeInfo(AClass: TGsvObjectInspectorTypeInfoClass); procedure GsvRegisterTypesInfo(AClasses: arrayof TGsvObjectInspectorTypeInfoClass); function GsvFindTypeInfo(const ATypeName: String): TGsvObjectInspectorTypeInfoClass; |
Процедура GsvRegisterTypeInfo регистрирует метакласс в реестре метаданных. Регистрируемый метакласс передается по ссылке на класс, которая определяется как:
Code: |
TGsvObjectInspectorTypeInfoClass = classof TGsvObjectInspectorTypeInfo; |
Вторая процедура подобна первой, но позволяет зарегистрировать сразу несколько метаклассов, например:
Code: |
GsvRegisterTypesInfo([TLabel_INFO, TFont_INFO, TButton_INFO)]; |
Удобнее всего регистрировать метаклассы в секции initialization того программного модуля, в котором они определяются. Третья функция выполняет поиск метакласса в реестре на основе его имени, причем она самостоятельно добавляет к имени суффикс _INFO, например, поиск метакласса по имени инспектируемого типа может выглядеть так:
cls := GsvFindTypeInfo(obj.ClassName);
Здесь obj - это экземпляр инспектируемого класса, а cls - ссылка на его метакласс. Если метакласс не найден в реестре, то функция возвращает nil. Реализация реестра метаданных весьма проста:
Code: |
var GsvTypesInfo: TStringList;
procedure GsvRegisterTypeInfo(AClass: TGsvObjectInspectorTypeInfoClass); begin ifnot Assigned(GsvTypesInfo) thenbegin GsvTypesInfo := TStringList.Create; GsvTypesInfo.Duplicates := dupIgnore; GsvTypesInfo.Sorted := True; end; GsvTypesInfo.AddObject(AClass.ClassName, TObject(AClass)); end;
procedure GsvRegisterTypesInfo(aClasses: arrayof TGsvObjectInspectorTypeInfoClass); var i: Integer; begin for i := Low(AClasses) to High(AClasses) do GsvRegisterTypeInfo(AClasses[i]); end;
function GsvFindTypeInfo(const ATypeName: String): TGsvObjectInspectorTypeInfoClass; var i: Integer; begin Result := nil; if Assigned(GsvTypesInfo) then if GsvTypesInfo.Find(ATypeName + '_INFO', i) then Result := TGsvObjectInspectorTypeInfoClass(GsvTypesInfo.Objects[i]); end; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!