Раздел Подземелье Магов | рь , дата публикации 17 апреля 2002г. |
Начну со слов благодарности в адрес Романенко Владимира, который поделился своими исходными текстами и мыслями по поводу написания Инспектора.
Все необходимые структуры и функции для работы со свойствами объекта содержатся в файле поставки Delphi TypInfo.pas он и будет первоисходником для написания собственного Инспектора.
Для удобства работы со свойствами распишем два класса: класс свойств Tprop
TProp = class PropertyInfo: TPropInfo; - структура информации о свойстве PropertyType: TTypeInfo; - структура типа свойства PropertyKind: TTypeKind; - тип свойства PropertyName: ShortString; - название свойства sEnumName: string; iEnumValue: integer; vValue: Variant; - значение свойства iIndex: integer; ……………… ………………. end; и класс самого объекта TpropObject (исходн. FObjIspector.pas). TPropObject = class(TObject) oObject: TObject; - собственно объект нашего мониторинга arProp: array of TProp; - массив свойств данного объекта arMetod: array of TProp; - массив методов данного объекта ………….. …………. end; Класс Tprop - хранилище данных одного конкретного свойства (метода), а TpropObject - полное описание нашего объекта.
Получение свойств и методов объекта происходит при добавлении объекта в инспектор: procedure TPropObject.SetObject(const Value: TObject); var pProps: PPropList; nProps, i, iProp, iMetod: Integer; objTemp: TObject; begin oObject := Value; // Получаем количество Properte nProps := GetTypeData(oObject.ClassInfo).PropCount; GetMem(pProps, sizeof (PPropInfo) * nProps); try // Получаем список Property nProps := GetPropList (oObject.ClassInfo, [tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray],pProps); iProp := 0; iMetod := 0; // Заполняем данные по Property for i := 0 to nProps - 1 do if IsPublishedProp(oObject,pProps[i]^.Name) then if pProps[i]^.PropType^^.Kind = tkMethod then begin // Обрабатываем методы SetLength(arMetod,iMetod + 1); arMetod[iMetod] := TProp.Create; arMetod[iMetod].PropInfo := pProps[i]; Inc(iMetod); end else begin // Обрабатываем свойства SetLength(arProp,iProp + 1); arProp[iProp] := TProp.Create; arProp[iProp].PropInfo := pProps[i]; case arProp[iProp].PropertyKind of tkClass: begin objTemp := GetObjectProp(oObject,arProp[iProp].NameProperty); if objTemp<>nil then arProp[iProp].vValue := '(' + objTemp.ClassName + ')'; end; tkInterface: ; else arProp[iProp].vValue := GetPropValue(oObject,arProp[iProp].NameProperty); end; Inc(iProp); end; finally FreeMem(pProps); end; end;