Как заставить работать компонент

отредактировано September 2008 Раздел: FastReport 3.0
Здравствуйте.

Пытаюсь сделать графический компонент для FastReport'a, но возникли проблемы.
Компонент является наследником TfrxView. Отдельно работает нормально - на обычный Canvas он выводит графику нормально, а при переносе на FastReport отказался работать. Для проверки я сделал простенький пример компонента, который выводит текст в FastReporte, но он тоже не работает. Видимо, я что-то делаю не так. Пожалуйста, помогите разобраться с проблемой.

Пример тестового компонента прилагается.

P.S.: Предполагается что тестовый компонент привязывается к полю датасета и выводит его содержимое в FastReporte. Этот компонент сделан на основе документации для FastReport'a - "Руководство разработчика". Под отладчиком видно, что сначала вызывается метод GetData, а затем Draw, но почему-то в при вызове обеих методов переменная Self имеет разные значения, точнее: при вызове метода GetData Self имеет одно и то же значение, в то время, как при вызове Draw - всё время разные.

Используется версия FastReport 3.21.

Комментарии

  • отредактировано 18:47
    Дело в том, что FR сохраняет построенный отчет в XML, для записи св-в используется ран-тайм механизм Delphi.
    Т.е. в XML построенного отчета, записываются только published св-ва или св-ва добавленные через DefineProperties.

    В Вашем случае в построенный отчет попадают св-ва DataSet и DataField, но GetData вызывается только в момент построения отчета.
    Получается что строка полученная в момент построения отчета в методе GetData нигде не сохраняется.

    Выходов несколько:
    1. Объявить св-во Text как Published, а если его нужно скрыть св-во в инспекторе объектов дизайнера используйте функцию frxHideProperties(модуль frxDsgnIntf).
    2. Использовать виртуальный метод DefineProperties для добавления св-в.
  • отредактировано 18:47
    Спасибо. Помогло.

    А вот такая ситуация. Если компонент наследуется от TfrxStretcheable у него есть метод: function CalcHeight: Extended.
    Он вызывается до метода Draw или DrawPart.

    Но в этом методе я не могу обращаться к FX, FY, FX1, FY1, FDX, FDY, FFrameWidth, FScaleX, FScaleY, FCanvas, потому что функцию BeginDraw я из CalcHeight вызвать не могу. Т.е. я не знаю масштабы, координаты и т.п. Следовательно, не могу расчитать и высоту.

    Как быть?

    И вообще какая-то странная ситуация с CalcHeight, DrawPart и InitPart. Из документации не понятно, для TfrxStretcheable они должны использоваться совместно с Draw или нет. Если нет, то почему им не передаются те же параметры что и Draw.
  • отредактировано 18:47
    Для вычисления высоты начальные координаты не нужны в принципе, указываете смещение 0 и масштаб 1.
    Для примера добавляете поле FRect, переопределяете BeginDraw в своем классе( в ней естественно сначала вызываете этот же метод из родительского класса), там же можно сделать нужные вычисления(смешения, добавление к высоте ширины рамки итд).
    После чего все сохраняете в FRect.

    Тогда метод CalcHeight будет выглядеть приблизительно так:
    function TfrxMYView.CalcHeight: Extended;

    begin

    Создание канваса в памяти.
    BeginDraw(nil, 1, 1, 0, 0);
    установка границ отрисовки - FRect.
    вычисление высоты текста
    end;

    Эти методы используются только в момент построения отчета(поэтому масштаб нужно указывать единицу), при печати и предпросмотре FR отрисовывает объекты по уже имеющимся координатам(которые в момент построения могли быть вычислены через CalcHeight).
    Проще говоря эти методы не предназначены для использования их при непосредственной отрисовке в методе Draw.

    InitPart используется при инициализации разрываемого объекта.
    DrawPart - делает само разбиение на основе заданной высоты и возвращает величину не использованного пространства.
    На примере мемки: у объекта есть поле для хранения части текста(TempText), в InitPart этому полю нужно присвоить весь текст объекта(TempText = Text), а в DrawPart берется часть текста попадающая в границ и присваивается полю Text (поле которое хранит текст для отрисовки). Остаток не попадающий в границы присваивается полю TempText(и так до полной отрисовки текста).

    Теперь как ведет себя движок FR (чтобы вышеописанное стало понятно):
    - Вычисляется высота объекта, вот тут -то и используется CaclHeight.
    - Если объект помещается в свободное пространство, то печатается весь объект.
    - Если объект не помещается в свободное пространство :
    - объекту устанавливается высота = свободному пространству на странице
    - вызывается метод DrawPart, вычисляется сколько строк текста может поместится в заданную высоту.
    - DrawPart возвращает величину не использованного пространства.
    - Проверяется может ли объект быть разорван, если нет - рисует как есть.
    - Если объект разрывается, то рисуется его часть и для следующей части повторяется тоже самое.

    Для наглядности могу посоветовать заглянуть в код frxClass -> TfrxCustomMemoView.
  • отредактировано 18:47
    Большое спасибо. Буду пробовать.

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

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.