Работа с отчетами Rave Report в режиме RunTime
Процедур GetListClassInfo и GetListProperty вполне достаточно, чтобы изучить необходимый объект. Но самой полезной является, конечно, процедура GetListProperty. Как видите процедура GetListProperty достаточно сложная по виду. Еще бы, ведь структуры PTypeInfo и особенно PTypeData довольно-таки «ветвистые» по своему строению. Понимание выше приведенных процедур осложняет еще и то, что Borland не документирует данную технологию так как, она может изменяться от одной версии Delphi к другой, вследствие чего это не может гарантировать работоспособность одного и того же кода в различных версиях Delphi. Для просмотра результата работы приведенных выше двух можно применить следующие строки кода:
if ListObjects.Items.Objects[ListObjects.ItemIndex] <> nil then
begin
GetListClassInfo(MemoInfo.Lines,
ListObjects.Items.Objects[ListObjects.ItemIndex]);
GetListProperty(ListProperty.Items,
ListObjects.Items.Objects[ListObjects.ItemIndex], True);
end;
...
Но и это еще не все возможности технологии RTTI. Также есть возможность получить достаточно полную информацию о свойстве или методе исследуемого объекта. Для извлечения столь немаловажной информации следует воспользоваться приведенной ниже процедурой.
procedure GetPropertyInfo(ListInfo: TStrings; PTI: PTypeInfo; PTD: PTypeData;
ClearList: Boolean = True);
type
// Структура для извлечения информации из методов (свойства-события)
PParamRec = ^TParamRec;
TParamRec = packed record
Flags: TParamFlags;
ParamName: ShortStringBase;
TypeName: ShortStringBase;
end;
var
I: Integer;
S, S2: string;
TeStr,
RStr: ^ShortStringBase;
ParamRec: PParamRec;
// Базовая информация для всех свойств
procedure Name_Info;
begin
ListInfo.Add(Format('Тип свойства: %s', [PTI.Name]));
ListInfo.Add(Format('Подтип свойства: %s',
[GetEnumName(TypeInfo(TTypeKind),
Integer(PTI^.Kind))]));
end;
// Информация для целочисленных, множеств и перечисляемых типов свойств
procedure Int_Info;
begin
ListInfo.Add(Format('Минимальное значение: %d', [PTD^.MinValue]));
ListInfo.Add(Format('Максимальное значение: %d', [PTD^.MaxValue]));
end;
// Информация для типов свойств с плавающей точкой
procedure Float_Info;
begin
// Определение подтипа свойства
case PTD^.FloatType of
ftSingle: S := 'ftSingle';
ftDouble: S := 'ftDouble';
ftExtended: S := 'ftExtended';
ftComp: S := 'ftComp';
ftCurr: S := 'ftCurr';
end;
ListInfo.Add(Format('Подтип tkFloat: %s', [S]));
ListInfo.Add('Минимальное значение: ' + FloatToStr(PTD^.MinInt64Value));
ListInfo.Add('Максимальное значение: ' + FloatToStr(PTD^.MaxInt64Value));
end;
// Информация для свойства представленного как класс
procedure Class_Info;
begin
ListInfo.Add(Format('Предок класса свойства: %s',
[PTD^.ParentInfo^.Name]));
ListInfo.Add(Format('Доступно свойств у объекта: %d', [PTD^.PropCount]));
ListInfo.Add(Format('Описан в модуле: %s',
[PTD^.UnitName]));
end;
// Информация для методов (свойства-события)
procedure Method_Info;
var
J: Integer;
begin
// Определение типа метода
case PTD^.MethodKind of
mkProcedure: S := 'Procedure ';
mkFunction: S := 'Function ';
mkConstructor: S := 'Constructor ';
mkDestructor: S := 'Destructor ';
mkClassProcedure: S := 'ClassProcedure ';
mkClassFunction: S := 'ClassFunction ';
mkSafeProcedure: S := 'SafeProcedure ';
mkSafeFunction: S := 'SafeFunction ';
end;
// Извлечение информации о передаваемом параметре
ParamRec := @PTD^.ParamList;
J := 1;
ListInfo.Add(Format('Передаваемых параметров: %d',
[PTD^.ParamCount]));
while J <= PTD^.ParamCount do
begin
if J = 1 then
S := S + '(';
// Определение метода передачи параметра
if pfVar in ParamRec.Flags then
S2 := 'var ';
if pfConst in ParamRec.Flags then
S2 := 'const ';
if pfArray in ParamRec.Flags then
S2 := 'array of ';
if pfOut in ParamRec.Flags then
S2 := 'out ';
// Извлечение информации о типе передаваемого параметра
TeStr := Pointer(Integer(@ParamRec^.ParamName) +
Length(ParamRec^.ParamName) + 1);
S := S + S2;
S := Format('%s%s: %s', [S, ParamRec^.ParamName, TeStr^]);
Inc(J);
// Извлечение информации о следующем передаваемом параметре
ParamRec := PParamRec(Integer(ParamRec) + SizeOf(TParamFlags) +
(Length(ParamRec^.ParamName) + 1) + (Length(TeStr^) + 1));
if J > PTD^.ParamCount then
S := S + ')';
// Если метод является функцией, то извлекается информация о возвращаемом параметре
if PTD^.MethodKind = mkFunction then
begin
RStr := Pointer(ParamRec);
S := Format('%s: %s;', [S, RStr^]);
end
else
S := S + '; ';
end;
ListInfo.Add(S);
end;
// Вывод информации для строковых типов свойств
procedure Str_Info;
begin
ListInfo.Add(Format('Максимальная длина: %d', [PTD^.MaxLength]));
end;
begin
if (ListInfo = nil) or (PTI = nil) or (PTD = nil) then
EXIT;
if ClearList then
ListInfo.Clear;
Name_Info;
// Извлечение информации для свойств множеств
if PTI^.Kind = tkSet then
begin
PTI := PTD^.CompType^;
PTD := GetTypeData(PTI);
Name_Info;
end;
case PTI^.Kind of
tkInteger: Int_Info;
tkFloat: Float_Info;
tkString: Str_Info;
tkLString: Str_Info;
tkWString: Str_Info;
// Извлечение информации для перечисляемых свойств
tkEnumeration:
begin
Int_Info;
ListInfo.Add('Варианты значений:');
for I := PTD^.MinValue to PTD^.MaxValue do
ListInfo.Add(Format('Значение: %s', [GetEnumName(PTI, I)]));
end;
tkClass: Class_Info;
tkMethod: Method_Info;
end;
end;
Примечание: Для перечисляемых свойств, информацию «Минимальное значение» и «Максимальное значение» выводимую процедурой GetPropertyInfo следует понимать как первый и последний индекс элемента перечисляемого свойства.
Использовать процедуру GetPropertyInfo можно так:
var
TI: PTypeInfo;
TD: PTypeData;
begin
if ListProperty.Items.Objects[ListProperty.ItemIndex] = nil then
EXIT;
TI := PTypeInfo(ListProperty.Items.Objects[ListProperty.ItemIndex]);
TD := GetTypeData(TI);
GetPropertyInfo(MemoInfo.Lines, TI, TD);
end;
Имея на вооружении такие замечательные процедуры, наконец, то можно изучить интересующие классы, узнать свойства и методы, а также тип свойств исследуемых классов. Получив достаточно подробную информацию с помощью технологии RTTI теперь, наконец, можно перейти к работе с проектом отчета Rave Report в режиме RunTime, но сначала ознакомимся с основными классами, которые встречаются в проекте отчета Rave Report.
Описание классов TRaveXXX
В этом разделе статьи содержится описание классов, из которых в основном состоит проект отчета. Проект отчета формируют три основных класса: TRaveProjectManager, TRaveReport, TRavePage. Для работы с источниками данных могут использоваться классы TRaveDataView, TRaveDataField, а так же TRaveRegion и TRaveDataBand. Разберем эти основные классы более конкретно.
Как описывалось выше, класс TRaveProjectManager обеспечивает всю базовую работу с проектом отчета Rave. Осуществляет такие основные задачи как: чтение/сохранение проекта отчета, работа с коллекцией отчетов и глобальными страницами, поиск необходимого отчета и компонентов TRaveXXX и многое другое. Ниже приведено описание основных свойств класса TRaveProjectManager.
Примечание: * – предположительное описание свойства, ввиду того, что в справочной системе Rave не предоставлена информация по данному свойству. (скрытый) – данное свойство доступно через технологию RTTI, но скрыто в инспекторе объектов среды разработки Rave Report.
TRaveProjectManager ■AdminPassword Пароль для доступа к проекту отчета * ■Categories Хранит список наименования категорий. Далее отдельному отчету можно указать тип категории, что помогает организовать более удобную работу и произвести поиск отчетов по категориям ■CompileNeeded Необходима компиляция (скрытый) * ■Description Сюда записывается более подробная информация о компоненте ■DevLocked Блокировка компонента от случайных изменений его свойств ■FullName Альтернативное наименование компонента ■Locked Блокировка компонента от случайных изменений его свойств ■Name Имя компонента ■Parameters Описание параметров, которые могут использоваться для сохранения временных вычислений или другой информации ■PIVars По назначению подобны Parameters, но присваиваются значения, которые определены после передачи команды на печать (After Print) ■SecurityControl Определяет параметры доступа к серверам баз данных для ввода имени и пароля пользователя ■Tag Тег, хранит целое число, которое используется разработчиком для собственных нужд ■Units Определяет единицу измерения для всех отчетов ■UnitsFactor Коэффициент для перевода текущей единицы измерения в дюймы ■OnBeforeReport Обработчик события перед генерацией отчета ■OnAfterReport Обработчик события после генерации отчета ■OnBeforePrint Обработчик события пред посылкой задания на печать ■OnAfterPrint Обработчик события после завершения печати
Отправить комментарий