Разинкин Игорь дата публикации 17-04-2002 12:23 Пишем инспектор объектов
Начну со слов благодарности в адрес Романенко Владимира, который
поделился своими исходными текстами и мыслями по поводу написания Инспектора.
Все необходимые структуры и функции для работы со свойствами объекта содержатся в файле поставки 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 отрисовку компонента и тестовую форму.
В представленном листинге не реализовано редактирование свойств и методов.
Все предложения, пожелания, ругань и т.д. приму с благодарностью.
С уважением ко всем дочитавшим до этого места,
Разинкин И.В.
Скачать проект ObjInsp.zip (13 K)
[TObject] [Создание Object Inspector] [Инспектор объектов (Object Inspector)]
Обсуждение материала [ 29-11-2008 04:37 ] 4 сообщения |