Статьи Королевства Дельфи

       

Пишем инспектор объектов


Раздел Подземелье Магов рь ,
дата публикации 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;


Еще одним важным моментом при инспектировании свойств какого либо объекта является отслеживание изменений данного объекта на форме моделирования (редактирования). Наш инспектор должен быть оповещен о происходящих изменениях на форме. Для мониторинга изменений перекроем оконную процедуру у формы моделированияю Для этого в нашем инспекторе служит процедура SetWnd:

procedure TfmObjIspector.SetWnd(const Value: THandle); begin WndHandle := Value; // Устанавливаем новую процедуру окна для формы моделирования WndProcPtr := MakeObjectInstance(WndMetod); OldWndProc := Pointer(SetWindowLong(WndHandle,GWL_WNDPROC,integer(WndProcPtr))); end; Собственно новая оконная процедура выглядит так: procedure TfmObjIspector.WndMetod(var Msg: TMessage); // Обработчик сообщений для формы моделирования begin // Перечитаем наши проперти ReReadProperty; // и выполним старую оконную процедуру with Msg do Result := CallWindowProc(OldWndProc,WndHandle, Msg, wParam, lParam); end;

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

procedure TfmObjIspector.FormDestroy(Sender: TObject); begin // Если была подмена оконной процедуры - вернем все в зад // иначе бед не оберешься if OldWndProc<>nil then begin SetWindowLong(WndHandle,GWL_WNDPROC,integer(OldWndProc)); FreeObjectInstance(WndProcPtr); end; inherited; end; Отрисовка свойств и методов на форме инспектора малоинтересный процесс позиционирования линий и текства на компонентах TpaintBox поэтому все это вы найдете в прилагаемых исходный текстах. Исходные тексты содержат набросок инспектора объектов, компонент Timage иммитирующий designtime отрисовку компонента и тестовую форму.
В представленном листинге не реализовано редактирование свойств и методов.

Все предложения, пожелания, ругань и т.д. приму с благодарностью. С уважением ко всем дочитавшим до этого места,

Разинкин И.В.

Скачать проект (13 K)

Смотрите по этой теме:


Содержание раздела