Компонент TPrintService
(C) 1998 Дмитрий Васильев
e-mail: silent@paracels.yrh.yar.ru

Компонент предназначен для реализации всех функций, связанных с выводом
на печать: выбор принтера, его настройка, предварительный просмотр и
собственно печать.

Методы TPrintService

public

Create,Destroy - стандартные конструктор и деструктор.
OpenPreview - открывает окно предварительного просмотра.
ClosePreview - закрывает окно предварительного просмотра.
UpdatePreview - перерисовывает окно предварительного просмотра.
Этот метод должен вызываться тогда, когда выводимые данные изменились
и необходимо отобразить изменения в окне предварительного просмотра.
Print - производит печать документа.
PrintDialog - вызывает стандартный диалог печати.
PrinterSetupDialog - вызывает стандартный диалог настройки принтера.

Свойства TPrintService

public

Previewer: TPreviewForm - свойство для доступа к окну предварительного
просмотра (равно nil, если оно не открыто).

published

Name,Tag - стандартные, унаследованы от TComponent.
PageCount: Integer - указывает количество страниц в печатаемом
документе. При равенстве нулю - одностраничный режим предварительного
просмотра (без кнопок переключения страниц и строки состояния).
PreviewerCaption: string - заголовок окна предварительного просмотра.

События TPrintService

published

OnCreate(Sender: TObject) - вызывается при создании компонента.
OnDestroy(Sender: TObject) - вызывается при уничтожении компонента.
OnPrinterSetupChange(Sender: TObject) - вызывается при изменении
настройки принтера.
OnPrint(Sender: TObject) - вызывается перед началом печати.
OnPreviewerOpen(Sender: TObject) - вызывается после открытия окна
предварительного просмотра.
OnPreviewerClose(Sender: TObject) - вызывается перед закрытием окна
предварительного просмотра.
OnDraw(Sender: TObject; Canvas: TCanvas; PageNumber: Integer;
	DrawTarget: TDrawTarget), где TDrawTarget=(dtPreview,dtPrint).
! Ключевое событие для всего TPrintService !
Именно в этом событии производится определение содержимого документа.
В минимальном варианте использования компонента пользователю
достаточно определить только это событие. При выводе должны
использоваться свойства PageWidth и PageHeight объекта Printer для
определения ширины и высоты листа (аналогично GetMaxX и GetMaxY из
BGI). Преобразование координат для предварительного просмотра
происходит без участия пользователя. Все, что нужно сделать, это
вывести изображение на передаваемую Canvas в масштабе принтера.
Шрифты масштабируются автоматически (это уже дело Windows),
поэтому, вне зависимости от модели принтера и установленного
разрешения, шрифт размером, скажем, 10, будет выглядеть одинаково
при печати из CorelDraw, Word97 и PrintService. Следует использовать
именно размер шрифта (Size), т.к. высота (Heigth) изменяется в
зависимости от текущего разрешения принтера. В PageNumber
передается номер страницы. При многостраничной печати пользователь
может определить вывод для всех страниц с номерами 1..PageCount. В
DrawTarget содержится информация о том, куда в данный момент
производится вывод - в окно предварительного просмотра или на принтер.
Эта информация, вообще говоря, не является необходимой, НО, вдруг
кому-нибудь захочется проанализировать количество цветов принтера и
сделать черно-белый вывод на черно-белый принтер при цветном
изображении в окне предварительного просмотра?
Еще одно замечание о выводе на печать. Мой опыт подсказывает, что
разные принтеры (или разные драйверы) ведут себя по-разному: некоторые
сохраняют настройки Canvas (заливки, цвета, шрифты) до выключения
и переносят их в другие задания, а некоторые "забывают" их при
переходе на другую страницу. В свете этого факта самым безопасным
будет: 1) заполнение всей площади каждой страницы желаемым фоновым
цветом; 2) установка всех параметров вывода (цвета, стили, параметры
шрифтов) непосредственно перед выводом.

Окно предварительного просмотра

Для получения указателя на окно предварительного просмотра необходимо
воспользоваться свойством Previewer. В том случае, если окно закрыто,
возвращается nil. У окна предварительного просмотра (TPreviewForm)
есть некоторые полезные свойства:

public

property ViewMode: TViewMode - текущий режим отображения.
TViewMode = (vm200,vm100,..,vmPageWidth,vmFullPage). Доступно для
записи и чтения.
property PageIndex: Integer - текущая отображаемая страница. Доступно
для записи и чтения.


Резюме.
Для вывода на печать средствами TPrintService необходимо определить
только сам вывод в событии OnDraw. Все остальное этот компонент
сделает сам. При этом не нужно заботиться ни о масштабировании
изображения для предварительного просмотра, ни о многостраничном
выводе, ни о выводе диапазона страниц, ни о количестве копий, ни о
(не знаю, как сказать) "разобрать по копиям". Нужно только определить
событие OnDraw и в нем, анализируя параметр PageIndex, вывести на
переданную Canvas необходимое изображение, пользуясь данными о высоте
и ширине страницы, полученными из объекта Printer.

Перспективы.
1.
В дальнейшем можно сделать переключение между реальной (размеры листа
в пикселах) и виртуальной (задаваемая пользователем ширина ИЛИ высота
листа и автоматически вычисляемая высота или ширина соотвественно)
системами координат. Меня удерживает снижение точности вывода в режиме
виртуальных координат (подобный эффект снижения точности заметен на
некоторых лазерных принтерах (в частности, HP Laser Jet IIP), т.к.
драйверы этих принтеров всегда возвращают в качестве ширины и высоты
страницы значения, соответствующие максимальному разрешению, что
приводит к неточности вывода при использовании меньших разрешений
ввиду того, что, например, точки с координатами (2,2) в разрешении
75 dpi физически не существует, и она будет пятном от точки (0,0) до
точки (3,3) включительно виртуальной (300 dpi) системы координат).
Это был первый аргумент "против", второй заключается в необходимости
отказа от масштабирования шрифтов средствами Windows и переход на
ручное масштабирование. Третий аргумент гораздо тривиальнее - лень.
Аргумент "за": рисовать на странице шириной 1000 или 10000 пикселов
неизмеримо легче и приятнее, чем на странице шириной 2328 пикселов.
2.
Можно дополнить компонент редактором свойств Canvas, устанавливаемых
по умолчанию на каждой странице.
3.
Можно сделать редактор полей страницы, как, например, в "параметрах
страницы" MS Word.