Алексей Румянцев
Вступление.
tprintservice был написан в далеком 1998 году Дмитрием Васильевым, распространялся бесплатно и с исходниками, поэтому был на всякий случай скачан (чисто про запас) и пылился без дела где-то в архивах. Но как говорится: "хорошие вещи на полках долго не залеживаются" - то ли репорты-монстры достали своей неповоротливостью, то ли захотелось свободы действия, в общем решил написать свой репорт...
Небольшое отступление.
В принципе, написать что-либо не так сложно, если имеешь в голове какую-то идею и если подойти к реализации этой идеи с верной стороны, сложно начинать писать с нуля. Весь пыл растрачивается еще на подступах - в процессе написания стартовой площадки.
Сама идея с написанием своего репорта, в общем-то, появилась легко:
1. Нужен готовый компонент с окном предварительного просмотра с минимальным набором функций (в идеале умеющий только переключаться между просмотром/печатью и поддерживающий режим масштабирования изображения на "листе").
2. Нужен буфер, куда_будут_писаться/откуда_будут_считываться все объекты печати (линии, прямоугольники, текст, картинки...).
3. Необходимы свобода действий и творчества.
4. Желательна легкость расширения функций.
Итак, цель ясна, желание есть (а это самое главное) - зарываемся в архивы в поисках той самой стартовой площадки... И понимаем, что в следующий раз, создавая архивы, надо присваивать им (архивам) более конкретные имена, потому что память наотрез отказывается помнить все сокращения в именах файлов, называя все это бессмысленным набором букв.
Пролистывая архивы с сокращениями типа "rpt" и "rep", натолкнулся на некий "prnsvr", в комментариях которого обнаружил следующее: "Компонент предназначен для реализации всех функций, связанных с выводом на печать: выбор принтера, его настройка, предварительный просмотр и собственно печать." - ну вы поняли, да? - на блюдечке с голубой каемочкой.
Остальное дело техники: берем его за основу, зачищаем; берем идею, набиваем ее на клавиатуре; привинчиваем к основе; красим и смотрим, что получилось - в общем, получилось примерно то, что и задумывал. Слово за Вами, господа. Если не понравится, удалим из королевства (буду сам пользоваться), если понравится - оставим. На ошибки и дополнения постараюсь отреагировать.
tprintservice
Комментарий Дмитрия Васильева:
Как было уже сказано: Компонент предназначен для реализации всех функций, связанных с выводом на печать: выбор принтера, его настройка, предварительный просмотр и собственно печать.
Ключевым событием для tprintservice является ondraw(sender: tobject; canvas: tcanvas; pagenumber: integer; drawtarget: tdrawtarget), где tdrawtarget = (dtpreview, dtprint). Именно в этом событии производится определение содержимого документа. В минимальном варианте использования компонента пользователю достаточно определить только это событие. При выводе должны использоваться свойства pagewidth и pageheight объекта printer для определения ширины и высоты листа. Преобразование координат для предварительного просмотра происходит без участия пользователя. Все, что нужно сделать, это вывести изображение на передаваемую canvas в масштабе принтера. Шрифты масштабируются автоматически (это уже дело windows), поэтому, вне зависимости от модели принтера и установленного разрешения, шрифт размером, скажем, 10, будет выглядеть одинаково при печати из coreldraw, word97 и printservice. Следует использовать именно размер шрифта (size), т.к. высота (heigth) изменяется в зависимости от текущего разрешения принтера. В pagenumber передается номер страницы. При многостраничной печати пользователь может определить вывод для всех страниц с номерами 1..pagecount. В drawtarget содержится информация о том, куда в данный момент производится вывод - в окно предварительного просмотра или на принтер. Эта информация, вообще говоря, не является необходимой, НО, вдруг кому-нибудь захочется проанализировать количество цветов принтера и сделать черно-белый вывод на черно-белый принтер при цветном изображении в окне предварительного просмотра?
Комментарий Алексея Румянцева:
Короче говоря, в ondraw, вы сами определяете то что выводится на принтер (или в окно предварительного просмотра), просто рисуя это на канве.
tryprintservice
Основное отличие от tprintservice - это наличие "буфера печати", т.е. вам остается заполнить его содержимым (линиями, прямоугольниками, текстом, картинками...) причем, не связывая себя какими-либо рамками (в частности размером и положением или вообще отсутствием необходимого элемента в данном конкретном месте отчета), т.е. каждый лист отчета может быть оформлен по своим правилам или без правил. Весь результат работы хранится в этом "буфере" откуда может быть предворительно просмотрен в окне предварительного просмотра, распечатан, скопирован, сохранен, экспортирован (надеюсь вскоре добраться до этой функции) и т.п.
Для этого были созданы специальные объекты (rptrect, rptline, rptedit, rptbitmap, список легко может быть расширен), параметры (property) которых заполняются пользовательскими значениями (left, top..., color..., text и т.д.) в соответствии с которыми будет меняться их положение на странице, цвет, текст и т.д.
rptoбъекты создаются только один раз, после чего у них меняются лишь значения параметров и затем отправляются с новыми значениями в очередь на печать, где и дожидаются своего звездного часа.
rptОбъекты могут отправляться в буфер отчета в любой последовательности, в любом кол-ве и с любым положением на странице.
В демонстрационном примере показано, как создавать новый отчет, заполнить его некоторой информацией (прямоугольники, текст, картинки); сохранять в файле и загружать из него отчет, а также как вызывать предварительный просмотр и печатать.