Работа с отчетами 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 можно так:

procedure TFormRTR.ListPropertyClick(Sender: TObject);

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 Обработчик события после завершения печати

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...