Delphi вывод на печать используя профиль. Печать из Delphi с возможностью просмотра


    Содержание урока 6:
    Обзор
    Печать в текстовом режиме
    Вывод содержимого формы на печать
    Графическая печать (объект TPrinter)
    Пример ex06.zip
      1. Обзор

      2. В данной статье рассказывается о возможных способах вывода информации на печать из программы, созданной в Delphi. Рассматривается вывод документа в текстовом режиме принтера, вывод графики с помощью объекта TPrinter и печать содержимого формы. О выводе на печать отчетов с помощью генератора отчетов ReportSmith рассказывается ниже.

      3. Печать в текстовом режиме
Если Вам нужно напечатать на принтере документ в текстовом режиме, то это делается следующим образом. С принтером Вы работаете, как с обычным текстовым файлом, за исключением того, что вместо процедуры AssignFile нужно вызывать процедуру AssignPrn. В примере на принтер выводится одна строка текста :

procedure TForm1.Button1Click(Sender: TObject);
var
To_Prn: TextFile;
begin
AssignPrn(To_Prn);
Rewrite(To_Prn);
Writeln(To_Prn, "Printer in Text Mode");
CloseFile(To_Prn);
end;

Здесь необходимо, видимо, пояснить, что по сравнению с BP 7.0 в Delphi изменены названия некоторых функций и переменных в модуле System:

    • AssignFile вместо Assign
    • CloseFile вместо Close
    • TextFile вместо Text
      1. Вывод содержимого формы на печать

      2. Иногда в программе требуется просто получить твердую копию экранной формы. В Delphi это делается более, чем просто - у объекта TForm есть метод Print, который и нужно вызвать в нужный момент.

      3. Графическая печать (объект TPrinter )
И все же, более интересно, как из программы созданной в Delphi можно вывести на печать графическую информацию. Для этого есть специальный объект Printer (класса TPrinter). Он становится доступен, если к программе подключить модуль Printers (т.е. добавить имя модуля в разделе uses ) . С помощью этого объекта печать на принтере графической информации становится не сложнее вывода этой информации на экран. Основным является то, что Printer предоставляет разработчику свойство Canvas ( работа с канвой описана в предыдущем уроке) и методы, выводящие содержание канвы на принтер. Рассмотрим подробнее свойства и методы объекта Printer.

Свойства Printer: Aborted - тип булевский ; показывает, прервал ли пользователь работу принтера методом Abort.

Canvas - канва, место для вывода графики ; работа с Canvas описана в Уроке 5.

Fonts - список доступных шрифтов.

Handle - используется при прямых вызовах Windows API.

Orientation - ориентация страницы, вертикально или горизонтально.

PageWidth , PageHeight , PageNumber - соответственно ширина, высота и номер страницы.

Printers перечисляет все установленные в системе принтеры, а

PrinterIndex указывает, какой из них является текущим. Чтобы печатать на принтере по умолчанию здесь должно быть значение -1.

Printing - тип булевский ; показывает, начата ли печать (методом BeginDoc ).

Title - заголовок для Print Manager и для заголовка перед выводом на сетевом принтере.

Методы Printer:

Abort - прерывает печать, начатую методом BeginDoc BeginDoc - вызывается перед тем, как начать рисовать на канве.

EndDoc - вызывается когда все необходимое уже нарисовано на канве, принтер начинает печатать именно после этого метода.

NewPage - переход на новую страницу. Остальными методами объекта в обычных случаях пользоваться не нужно.

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

  • выполняется метод BeginDoc
  • на канве (Canvas) рисуем все, что нужно
  • при необходимости разместить информацию на нескольких листах вызываем метод NewPage
  • посылаем нарисованное на принтер, выполняя метод EndDoc
      1. Пример ex06.zip
В примере (проект PRINTS.DPR, рис.1 ) реализованы все три вышеописанных ситуации.

1

Рассматриваются возможности печати из программ, написанных в Delphi7. В первую очередь внимание уделено печати отчетов баз данных. Во второй части статьи приводятся способы печати текста и графики.

печать базы данных

компонент QuickReport

установка пакета

полосы печати

колонтитул

графический контекст принтера

диалоги печати

задание на печать

1. Архангельский А.Я. Программирование в Delphi 7. – М.: OOO «Бином-Пресс», 2003 г. – 1152с: ил.

2. Фленов М. Библия Delphi. – БХВ-Петербург, 2008. – 880 с.

Печать отчетов

Любое приложение по работе с базами данных можно считать неполным, если в приложении не реализована печать данных. Если во многих других приложениях без печати можно обойтись, а в некоторых из них это все лишь красивый маркетинг, то приложениями для работы с базами данных, у которых отсутствует печать, редко кто будет пользоваться.

В Delphi7 для предварительного просмотра и печати отчетов существует достаточный набор компонентов под названием QuickReport.

Надо заметить, что раздел справки по этой теме, находящийся в файле «c:\Program Files\Borland\Delphi7\Help\QUICKRPT.HLP», достаточно скудный. Исходных модулей по данным компонентам тоже нет. Все компоненты расположены в откомпилированных файлах ‘dcu’. Поэтому необходимо привести начальные шаги по использованию имеющихся возможностей печати в Delphi7. Здесь, и в дальнейшем упоминается путь по умолчанию «c:\Program Files\Borland\Delphi7».

Начать следует с того, чтобы проверить факт установки компонентов этой группы. Для этого можно воспользоваться подпунктом главного меню View-Component List, и попробовать там найти, например, компонент TQuickRep.

В большинстве случаев, при установке по умолчанию, нужный пакет не установлен. Об этом также упомянуто в файле: «c:\Program Files\Borland\Delphi7\Demos\Quickrpt\QReport_README.txt», в этом файле также описан и процесс установки.

Для того, чтобы установить пакет нужно выполнить следующие действия.

В главном меню Delphi7 выбираем пункт «Component», а в нем подпункт «Install Packages». В открывшемся диалоговом окне выбираем кнопку “Add”, находим в “bin”-директории Delphi (...\Borland\Delphi7\bin) файл “dclqrt70.bpl”.

После установки, в конце палитры компонентов появится вкладка QReport; а также в репозитории, на вкладке New - элемент Report.

Вкладку можно переместить в удобное для работы место, как и сами компоненты на вкладке. Для этого в главном меню Delphi7 выбираем пункт «Component», а в нем подпункт «Configure Palette», и выполняем нужные действия.

Формирование отчета можно начинать двумя путями. Либо разместить на форме компонент QuickRep с вкладки QReport, либо использовать элемент Report из Репозитория. Для работы практичнее использовать второй вариант.

Оба элемента построены на базе одного класса - TquickRep. Однако во время выполнения, содержимое компонента QuickRep на форме будет выглядеть почти также как в конструкторе. А для отображения самого отчета нужно выполнить еще некоторые действия. Так, при вызове кода QuickRep1.Preview (например, в обработчике события кнопки), предварительный просмотр отчета все равно будет показан совершенно в отдельном окне. Поэтому во время выполнения, демонстрация формы с расположенным на ней компонентом QuickRep не несет какой-либо конструктивности. При втором варианте для данного компонента во время дизайна создается своя форма, где можно настроить внешний вид отчета. А его использование, как уже упоминалось, выполняется другими методами.

Во время работы программы, непосредственно в окне отчета можно просматривать собранную информацию из базы данных - перелистывая страницы, меняя масштаб просмотра. И непосредственно из этого окна можно выполнять печать. Также печать можно выполнить вызовом кода: QuickRep1.Print

При двойном щелчке по компоненту QuickRep в режиме конструктора можно настроить свойства будущего документа: размер бумаги, поля и т.д. Что равносильно выбору пункта Report Setting из контекстного меню компонента.

ПРИМЕР

Будем использовать элемент Report из Репозитория. По умолчанию имеет имя QuickReport2.

Помещаем на него (в любое место) компонент Table с вкладки BDE.

Для дальнейшей работы воспользуемся демонстрационными примерами баз данных, устанавливаемых вместе с Delphi.

Настраиваем свойства компонента Table1: DatebaseName выставляем в ‘DBDEMOS’, TableName в ‘animals.dbf’, Active в ‘true’.

На вкладке QReport берем компонент QRBand и помещаем на QuickReport2.

Меняем свойство BandType у компонента QRBand на rbDetail.

Помещаем на этот полосу компонент QRDBText.

Настраиваем у него свойство DataSet в ‘Table1’, DataField в ’NAME’.

Помещаем на полосу компонент QRDBImage.

Настраиваем у него свойство DataSet в ‘Table1’ DataField в ‘BMP’.

Из контекстного меню QuickReport2 выбираем пункт Preview (в режиме конструктора). Аналогично (в режиме выполнения) можно выполнить код

QuickRep1.Preview. Не забываем подключить Unit2.

В результате отобразится окно предварительного просмотра данных. Но в нем отображается только первая запись из набора данных.

Для того, чтобы увидеть весь набор нужно у самого компонента QuickReport2 настроить свойство DataSet в ‘Table1’.

Вот так, достаточно просто можно работать с компонентами QuickReport.

Несколько советов по дальнейшей работе.

В отношении свойства BandType компонента QRBand.

По умолчанию имеет тип rbTitle (полоса заголовка). Появляется только на первой странице.

RbColumnHeader (полоса заголовков столбцов) отображается на каждой странице.

Для отображения информации на указанных полосах обычно используют компонент QRLabel (компонент Label с вкладки Standart - не отображается).

RbDetail (полоса деталей). Как было показано в примере - выводит весь набор из базы данных.

Вообще, реализуется достаточно большой набор полос. Есть колонтитулы, итоговые полосы и т.д. Полоса с указанным типом, после помещения ее на компонент QuickReport, сразу занимает свое место.

Функциональность компонентов с вкладки QReport становится очевидной на практике. Аналогично можно сказать про полосы и их выравнивание в режиме конструктора.

Будет не лишним обратить внимание на пару примеров из папки:

“C:\Program Files\Borland\Delphi7\Demos\Quickrpt\”,которые устанавливаются вместе с Delphi.

Из событий QuickReport стоит отметить OnPreview и OnNeedData.

1-е можно использовать для вывода своего собственного окна просмотра вместо заданного по умолчанию.

2-е используется, когда источник данных не является базой данных VCL. Например, вы можете создать отчет для списка строк, массива или текстового файла .

Печать текста и графики

В случаях, когда необходимо выполнить вывод на печать текста, либо графики не из базы данных, следует использовать возможности, построенные на базе класса TPrinter.

Чтобы объект TPrinter стал доступен в проекте, необходимо добавить в раздел uses модуль Printers. Объект TPrinter не надо инициализировать. Достаточно только подключить модуль и объект становится доступным через переменную Printer, которая объявлена в данном модуле. Работа с объектом TPrinter базируется на его свойстве TCanvas. Поскольку данное свойство представляет собой графический контекст, то нужно быть готовым к тому, что вывод текста выполняется также в виде графики. В тоже время, свойство TCanvas инкапсулирует в себе низкоуровневые функции по работе с графическим контекстом, что значительно облегчает работу программиста.

Перечислим основные Свойства объекта TPrinter:

Aborted - переменная типа Boolean. Если она равна true, то пользователь прекратил вывод информации на принтер.

Canvas - объект типа TCanvas. Это холст, на который можно выводить информацию в графическом виде.

Copies - количество копий документа необходимых для печати.

Fonts - список шрифтов поддерживаемых принтером.

Handle - здесь храниться дескриптор контекста принтера. Через него можно воспользоваться напрямую функциями WinAPI.

Orientation - ориентация страницы. Это свойство может иметь одно из следующих значений: poPortrait - книжный, или poLandscape - альбомный.

PageHeight - высота страницы в пикселях.

PageWidth - ширина страницы в пикселях.

PageNumber - номер текущей печатаемой страницы.

PrinterIndex - число, которое указывает на номер активного принтера.

Printers - список типа TStrings установленных в системе принтеров.

Printing - если это свойство равно true, то принтер в данный момент печатает.

Title - заголовок или просто текстовое описание печатаемого документа. Этот заголовок будет отображаться во время печати в менеджере печати.

Методы объекта TPrinter:

Abort - прерывает текущую печать.

BeginDoc - начало печатаемого документа.

EndDoc - конец документа.

GetPrinter - получить индекс текущего принтера.

NewPage - новая страница документа.

Refresh - обновить информацию о шрифтах

В начале кода, выводящего на печать, будет разумно, а также профессионально, воспользоваться компонентом TPrintDialog. Для того, чтобы пользователь мог задать особенности печати. Это, как минимум, диапазон печатаемых страниц, количество копий и т.п.

Настройка таких свойств печати, как ориентация бумаги или выбор принтера автоматически помещается компонентом TPrintDialog в объект TPrinter.

Возможно, программист захочет отойти от предлагаемых стандартных диалогов TPrintDialog, TPrinterSetupDialog, и реализовать свои, в каком-либо собственном стиле. В этом случае потребуется напрямую обращаться к свойствам Orientation, Printers, PrinterIndex и методам GetPrinter, SetPrinter объекта TPrinter. Если эта реализация окупается здравым смыслом - почему бы нет. Но при этом нужно быть готовым к дополнительным затратам разработки. И, конечно же, разработанный пользовательский стиль диалога печати должен отвечать некоторым стандартам, и быть понятным и удобным для пользователя.

Следующим шагом будет настройка нужного шрифта, например так: Printer.Canvas.Font:= Memo1.Font;

И необходимо внести коррективу размера шрифта под разрешение контекста принтера, например так:

LineHeight:= Abs(

MulDiv(Printer.Canvas.Font.Size,

GetDeviceCaps(Printer.Handle, LOGPIXELSY), 72));

Рассмотрим эту формулу более подробно.

Переменная LineHeight будет хранить высоту строки уже на канве принтера. Функция WinAPI GetDeviceCaps ищет информацию об указанном устройстве. В нашем случае особый интерес представляет параметр LOGPIXELSY. Он возвращает число пикселей в логическом дюйме по высоте контекста. Свойство Font.Size по умолчанию ориентировано на разрешение равное 72. Поэтому необходимо выполнить формулу Font.Size * LOGPIXELSY / 72. На большинстве принтеров LOGPIXELSY равно 600. WinAPI функция MulDiv умножает два 32-разрядных значения и затем делит 64-битовый результат на третье 32-разрядное значение. Возвращаемое значение округлено вверх или вниз к самому близкому целому числу. Использование этой функции удобнее обычной арифметики тем, что функция кроме самого вычисления совмещает в себе округление.

К полученному результату добавляем 40 % на межстрочный интервал

Inc(LineHeight, (LineHeight*4) div 10);

Определение количества строк на странице.

LinesPerPage:= (Printer.PageHeight div LineHeight) ;

После этого можно приступать непосредственно к формированию задания на печать. Для этого вызывают метод

Printer.BeginDoc;

и в цикле начинают выполнять вывод строк. При этом нужно помнить, что при работе с контекстом принтера следует придерживаться графических функций.

Для вывода текста обычно используют Printer.Canvas.TextOut. Для вывода заголовков, либо колонтитулов, удобно воспользоваться WinAPI функцией DrawText, которая удобным образом центрирует текст на странице.

При выводе строк в цикле имеет смысл организовать переменную-счетчик, которая будет следить за достижением выведенного количества строк значения переменной LinesPerPage. И в этом случае, новая страница начинается при помощи метода Printer.NewPage.

Когда задание на печать сформировано, должен быть вызван метод Printer.EndDoc. И только после этого начнется непосредственная печать документа на принтере.

Замечание для тех случаев, когда понадобится воспользоваться функциями WinAPI напрямую, например для рисования, типа:

Printer.BeginDoc;

Rectangle(Printer.Canvas.Handle, 0,0,500,500);

то контекст канвы принтера одинаков и через

Printer.Canvas.Handle

Замечена разница:

Обращение к дескриптору 1-го типа за пределами BeginDoc, EndDoc, например:

memo1.Lines.Append(inttostr(Printer.Canvas.Handle));

поднимает исключение “raised exception class EPrinter with message ‘Printer is not currently printing”.

Вариант c дескриптором 2-го типа

memo1.Lines.Append(inttostr(Printer.Handle));

работает без исключения, и номер дескриптора возвращает правильный - такой же, как и внутри BeginDoc, EndDoc в процессе печати.

Однако вызов

Rectangle(Printer.Handle,500,50,700,800);

без входа в BeginDoc, EndDoc - печати конечно не делает. Происходит “мягкое” игнорирование без исключения.

Также, для печати текста без какого-либо форматирования, можно использовать код:

Writeln(f, ‘Hello world’);

В этом случае, также необходимо подключить модуль Printers. Поскольку в данном коде объект TPrinter используется неявным образом.

В статье рассмотрены основные приемы программирования печати. Выбор нужного способа за программистом, и зависит от конкретной ситуации.

Библиографическая ссылка

Бартосик Ф.М., Молдаванова И.Г., Мурых Е.Л., Авилова Е.К. ПЕЧАТЬ В DELPHI 7 // Международный журнал экспериментального образования. – 2015. – № 12-3. – С. 363-366;
URL: http://expeducation.ru/ru/article/view?id=9127 (дата обращения: 06.04.2019). Предлагаем вашему вниманию журналы, издающиеся в издательстве «Академия Естествознания»

В этой статье я постараюсь рассказать Вам о самых удобных и распространенных способах печати текстов и изображений из Ваших приложений. Печать используется в приложениях не так часто, вот и возникают различные вопросы по этому поводу. Иногда бывает необходимо "вывести на принтер" график получившейся функции или отчет о деятельности фирмы и т.д. Прочитав эту статью Вы освоите все самое необходимое для печати данных из Ваших приложений.

Итак, начнем рассмотрение этих способов.

Печать с помощью функций файлового ввода/вывода

Здесь мы будем использовать простейшие функции ввода/вывода в файл, только свяжем выходной поток не с файлом, а с принтером. Рассмотрим пример печати текста, содержащегося в компоненте TEdit:

Var P:TextFile;
begin
AssignPrn(P);
Rewrite(P);
Writeln(P, Edit1.text);
CloseFile(P);
End;

Здесь мы объявляем переменную P типа TextFile. Процедура AssignPrn является разновидностью процедуры Assign. Она настраивает переменную P на порт принтера и позволяет работать с ним как с файлом. Rewrite открывает порт для работы, а WriteLn - выводит информацию на печать. Важно закрыть порт принтера командой CloseFile!!!

Этот способ можно использовать для распечатки строк списка или каких-нибудь других данных, по мере их поступления в программу.

Печать текстов в обогащенном формате методом Print

Если Вы пытались попробовать распечатать тексты из Вашего приложения, то, наверно, Вам известно, что компонент TRichEdit имеет метод Print, позволяющий печатать текст, хранящийся в этом компоненте. Этот метод имеет только один параметр - строку, которая при просмотре в Windows очереди печатаемых заданий является именем задания. Приведу пример использования (хотя он очевиден:)

RichEdit1.Print("Print of our RichEdit1");

Следует заметить, что печать воспроизводит все особенности форматирования текста, так же происходит автоматический перенос строк и разбиение текста на страницы. При этом длина строк ни как не связана с размерами компонента RichEdit.

Печать с помощью объекта Printer

В Дельфи имеется класс печатающих объектов TPprinter, который обеспечивает печать текстов, изображений и других объектов, расположенных на его канве (Canvas).

Модуль Дельфи Printers, содержит переменную Printer, которая является объектов типа TPrinter. Поэтому для использования этой переменной в Ваших программах, надо подключить модуль Printers в оператор Uses (к сожалению автоматически этого не делается)

Рассмотрим подробнее некоторые свойства и методы объекта TPrinter:

Свойство, метод Описание
Canvas Канва - место в памяти, в котором формируется страница или документ перед печатью.
TextOut Метод канвы, позволяющий посылать в нее текст
BeginDoc Используется для начала задания печати
EndDoc Используется для завершения задания печати. При этом печать начинается только после вызова этого метода!
PageHeight Возвращает высоту страницы в пикселах
NewPage Принудительно начинает новую страницу
PageNumber Возвращает номер печатаемой страницы

Приведу два примера печати с помощью объекта TPrinter текста и изображения.

Печать текста можно осуществить так:

Printer.BeginDoc;
Printer.Canvas.TextOut(10,10,"Печатаем с помощью объекта Printer");
Printer.EndDoc;

Если Вы хотите напечатать изображение, находящееся, например, в компоненте Image1, то код может быть таким: Printer.BeginDoc;
with Image1.Picture.Bitmap do Printer.Canvas.CopyRect(Rect(0,0,Height,Width),Canvas,Rect(0,0,Height,Width));
Printer.EndDoc;

Казалось и бы и здесь все просто, но у объекта Printer есть существенный недостаток: он не производит автоматическое разбиение на строки и страницы, поэтому печатать длинные тексты предпочтительнее с помощью компонента RichEdit или Memo.

Печать форм

У форм в Delphi есть метод Print, который печатает всю клиентскую область формы. При этом полоса заголовка и полоса главного меню формы не печатаются.

Свойство PrintScale определяет опции масштабирования изображения формы при печати:

На этом мы заканчиваем обзор способов печати данных из Ваших приложений. Надеюсь, что еще одним вопросом у Вас стало меньше:))

Печать сейчас широко используется в приложениях Delphi, когда нужно напечатать текст, изображение и т.д. Большинство приложений Windows поддерживают возможность печати. В Delphi есть несколько способов печати, в зависимости от качества, которого Вы хотите достичь.

Печать формы

В Delphi у формы Form имеется функция Print , которая может выводить на печать форму.

Procedure TForm1.Button1Click(Sender: TObject); begin Form1.Print; end;

Также Вы можете использовать свойство PrintScale , которое изменяет масштаб печатаемого объекта. Это свойство содержит три опции:

  • poNone - печать будет произведена с настройками принтера.
  • poProportional - печать страницы, которая будет иметь те же размеры, что и на экране.
  • poPrintToFit - размер изменяется в зависимости от размера страницы.

При этом получается не самое высокое качество печати.

Печать управления TRichEdit

Функция Print имеется также у компонента TRichEdit .

Procedure TForm1.Button2Click(Sender: TObject); begin RichEdit1.Print("Имя документа"); end;

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

Печать текстовых файлов при помощи ShellExecute

Также можно использовать функцию API ShellExecute для печати текстового документа.

Uses { … } ShellApi { … } procedure TForm1.Button3Click(Sender: TObject); begin ShellExecute(Handle, "Print", "C:\Test.txt", nil, nil, SW_Hide); end;

При этом открывается приложение, которое ассоциировано с файлом. В моем случае это Блокнот.

Диалоговое окно печати

В Delphi имеется два диалоговых окна для печати: диалоговое окно при помощи компонента TPrintDialog и при помощи диалогового окна установок принтера TPrinterSetupDialog .

Диалоговое окно TPringDialog

Компонент диалогового окна TPrintDialog Вы можете использовать непосредственно перед началом печати. Компонент TPrintDialog имеет свои свойства и метода, которые Вы сможете найти в справке по Delphi. Диалоговое окно вызывается конструкцией:

Procedure TForm1.Button4Click(Sender: TObject); begin PrintDialog1.Execute; end;

Диалоговое окно Настройка печати

При вызове этого диалогового окна появляется возможность выбрать настройки печати, такие как размер бумаги, ориентацию и т.д. Можно также использовать это окно для настроек принтера. Вызывается это диалоговое окно функцией Execute .

Procedure TForm1.Button5Click(Sender: TObject); begin PrinterSetupDialog1.Execute; end;

TPrinter

Объект TPrinter используется для печати документов, текста и т.д. Вот пример использования TPrinter для печати прямоугольника. Не забудьте добавить модуль Printers в раздел uses формы.

Procedure TForm1.Button6Click(Sender: TObject); begin Printer.BeginDoc; Printer.Canvas.Rectangle(100, 100, 300, 300); Printer.EndDoc; end;

Таким же образом, на холсте Canvas объекта Printer можно напечатать и текст.

Procedure TForm1.Button7Click(Sender: TObject); begin Printer.BeginDoc; Printer.Canvas..EndDoc; end;

А также вывести растровое изображение на печать, словно на холст.

Procedure TForm1.Button8Click(Sender: TObject); var bmp: TBitmap; begin bmp:= TBitmap.Create; bmp.LoadFromFile("C:\athena.bmp"); Printer.BeginDoc; Printer.Canvas.Draw(10, 10, bmp); Printer.EndDoc; bmp.Free; end;

При печати растровое изображение будет небольшим, чтобы вывести нужный Вам размер на печать, используйте StretchDraw .

Реализация Просмотра Печати

Предварительный просмотр печати важен в приложениях для пользователя, потому как позволяет просматривать изображение или текст перед выводом его на печать. Здесь мы создадим предварительный просмотр печати с возможностью изменения масштаба изображения.

Небольшое приложение с использованием предварительного просмотра печати Вы можете посмотреть

Копирование содержимого формы в буфер обмена

Uses { ... }, Clipbrd; procedure TForm1.Button2Click(Sender: TObject); var FormImage: TBitmap; begin FormImage:= GetFormImage; try Clipboard.Assign(FormImage); Image1.Picture.Assign(Clipboard); finally FormImage.Free; end; end;

Глава 9

Печать документов

Многие разработчики сталкиваются с необходимостью организации печати из приложения текстовых документов или графики. Среда разработки Delphi предоставляет для решения этой задачи достаточно простой в использовании и эффективный инструментарий.

Механизм печати содержится в специальном модуле printers. раs. Достаточно добавить его в секцию uses приложения и ваша программа готова к взаимодействию с принтером. Для организации печати в исходном коде применяется класс Tprinter, свойства и методы которого обеспечивают доступ к принтерам, установленным в системе.

При помощи этого класса программист может распечатывать в своем приложении не только тексты, но и растровые изображения и графические элементы.

Настроить принтер можно при помощи специального компонента в составе VCL - стандартного системного диалога настройки принтера

TPrinterSetupDialog.

В этой главе рассматриваются следующие вопросы:

  • свойства и методы класса Tprinter;
  • программирование печати текстов и списков строк;
  • как напечатать изображение формы, без помощи класса Tprinter.

Класс TPrinter

Каждое приложение, в котором используется принтер, должно содержать в секции uses модуль printers. Если ссылка на данный модуль имеется, то при выполнении приложения автоматически создается экземпляр класса Tprinter, предоставляющий программисту все необходимые средства для организации вывода данных на один из подключенных к компьютеру принтеров. Рассмотрим свойства и методы класса Tprinter.

Таблица 9.1. Свойства и методы класса Tрrinter

Объявление

Описание

property Aborted: Boolean;

Определяет, было ли задание на печать удалено пользователем. Если задание удалено - возвращает значение True

property Canvas: TCanvas ;

Канва принтера (см. главу 8). Предоставляет пользователю возможность определить значения свойств Brush, Font и Pen для печати графики на принтере

TPrinterCapability = (pcCopies, pcOrienta-tion, pcCollation); TPrinterCapabilities = set of TPrinterCapability;

Содержит текущие установки драйвера принтера: PcCopies - количество копий; PcOrientation - ориентация листа;

property Copies: Integer;

Указывает требуемое количество копий документа

property Fonts: TStrings ;

Содержит список имен всех шрифтов, поддерживаемых текущим принтером

property Handle: HDC;

Контекст устройства. Применяется при вызове из программы функций Windows API

TPrinterOrientation = (poPortrait, poLand-scape) ;

Определяет ориентацию листа бумаги: PoPortrait - вертикальная;

property Orientation: TPrinterOrientation;

PoLandscape - горизонтальная

property PageHeight: Integer;

Содержит высоту страницы в пикселах

property PageNuinber: Integer;

Содержит номер текущей страницы

property PageWidth: Integer;

Возвращает значение ширины страницы в пикселах

property Printerlndex: Integer;

Индекс имени текущего принтера в списке Printers

property Printers: TStrings;

Содержит список установленных в системе принтеров

property Printing: Boolean;

Имеет значение True до тех пор, пока продолжается процесс печати

property Title: String;

Строка, идентифицирующая печатаемый документ в окне состояния текущего принтера

property Capabilities: TPrinterCapabilities;

PcCollation - включен или нет параметр разбора по копиям

procedure Abort;

Метод прерывает процесс печати, и принтер приступает к обработке следующего задания. При этом значение свойства Aborted устанавливается равным True

procedure BeginDoc;

Начинает выполнение нового задания печати

procedure EndDoc;

Завершает печать документа, очищает буфер принтера и, если необходимо, прокручивает последнюю страницу. Этот метод не следует вызывать, если печать была прервана методом Abort

procedure NewPage;

Инициализирует печать с новой страницы. Значение свойства PageNumber при этом увеличивается на единицу

Обращаем внимание читателя на то, что большинство свойств (Fonts, Handle, PageWidth, PageHeight, Aborted, Printing, Capabilities И Др.) доступны только для чтения.

Для создания и обращения к экземпляру класса TPrinter используется объявленная В Модуле Printers функция

function Printer: TPrinter;

Она возвращает указатель на созданный экземпляр класса.

Как видно из таблицы 9.1, класс TPrinter не только обеспечивает доступ к параметрам текущего принтера, но и создает индексированный список printers имен всех доступных принтеров системы. Любой принтер из списка можно сделать активным при помощи свойства printerindex.

Управление печатью осуществляется описанными в таблице методами Abort, BeginDoc, EndDoc И NewPage. Очень важную роль играет свойство canvas, представляющее собой канву принтера (см. главу 8). С ее помощью принтер можно использовать для рисования или вывода текстов так же, как и формы или любые другие компоненты, имеющие канву.

Печать текстов

С точки зрения программиста простейший способ печати текстов из приложений Delphi не изменился со времен ранних версий Turbo Pascal. Для печати используются процедуры write и writein, которым в качестве устройства вывода назначается принтер.

Решим простейшую задачу - напечатаем на принтере сакраментальную фразу “Hello, printer!” (что поделать - традиция). Для этого создадим консольное приложение (пункт меню File/New ) и добавим следующий исходный код (не забудьте о необходимости добавить в секцию uses модуль Printers):

program Project1;

{$APPTYPE CONSOLE} uses SysUtils, Printers;

var FPrint: TextFile;

AssignPrnfFPrint);

Rewrite(FPrint);

Writeln(FPrint,"Hello Printer!");

CloseFile(FPrint);

Процедура Assignprn из модуля printers связывает текстовую файловую переменную с текущим принтером системы и создает буфер вывода в памяти. Оператор Rewrite открывает устройство вывода. Процедура Writein осуществляет печать строки и переводит позицию печати на новую строку (процедура write в отличие от Writein переход на новую строку не делает). И наконец, процедура CloseFile завершает печать и разрывает связь файловой переменной и принтера (рис. 9.1).

Рис. 9.1. Главная форма проекта DemoPrint

Подробнее об использовании файловых переменных и процедур ввода/вывода рассказывается в главе 6.

В одном операторе write или writein можно вывести несколько значений разных типов - целые числа, переменные с плавающей точкой и т. д. Для этого значения или переменные разделяются запятыми.

Кроме этого, в составе переменных вывода могут быть текстовые строки объектов TSrings И TStringList.

В качестве примера рассмотрим небольшой проект DemoPrint. В нем при помощи диалога открытия файла выбирается нужный файл. В зависимости от состояния группы переключателей RadioGrp, вывод файла направляется на экран в компонент тмето или непосредственно на принтер.

При щелчке на кнопке printBtn содержимое компонента тмето выводится на принтер (листинг 9.1.).

Листинг 9.1. Секция implementation модуля главной формы проекта DemoPrint

implementation uses printers;

procedure TMainForm.DirectPrint;

var FileTxt, PrintTxt: TextFile;

TempStr: String;

AssignFile(FileTxt, OpenDlg.FileName);

AssignPrn(PrintTxt);

Rewrite(PrintTxt);

while Not EOF(FileTxt) do

begin Readin(FileTxt, TempStr);

Writein(PrintTxt, TempStr)

CloseFile(FileTxt);

CloseFile(PrintTxt);

procedure TMainForm.OpenBtnClick(Sender: TObject);

if Not OpenDIg.Execute then Exit;

if RadioGrp.Itemlndex = 0

then Memol.Lines.LoadFromFile(OpenDIg.FileName)

else DirectPrint;

var PrintTxt: TextFile;

AssignPrn(PrintTxt);

Rewrite(PrintTxt);

for i :=0 to Memol.Lines.Count -1 do Writeln(PrintTxt, Memol.Lines[i]);

CloseFile(PrintTxt);

procedure TMainForrn.RadioGrpClick (Sender: TObject);

begin PrintBtn.Enabled := RadioGrp.Itemlndex = 0;

Процедура DirectPrint обеспечивает прямой вывод текстового файла на принтер. Для этого две файловые переменные связываются с выбранным файлом и принтером. Прочитанная из файла строка сразу же отправляется на принтер.

Метод-обработчик PrintBtnClick обеспечивает вывод на печать строк из компонента ТМето. Для этого каждая строка из индексированного списка строк (свойство Lines) печатается процедурой writein. Файловая переменная Fprint настроена на текущий принтер.

Метод-обработчик RadioGrpciick обеспечивает отключение кнопки печати файла при переключении устройства вывода на принтер.

Для управления печатью можно использовать следующие управляющие символы:

  • #9 - табуляция;
  • # 10 - новая строка;
  • #13 - возврат каретки;
  • ^L - новая страница. Например:

Write(FPrint, "После этой строки произойдет переход на новую строку", #10, #13);

Writein (FPrint, "После этой строки включится прогон страницы",^L);

При печати текстового файла по умолчанию используется шрифт System размером 10. Для изменения параметров шрифта (в том числе и во время печати) используется свойство canvas объекта printer. Это может выглядеть так:

with Printer.Canvas.Font do

Печать графики

При печати графики используется свойство canvas типа TCanvas экземпляра класса Tprinter из модуля printers. Класс канвы обладает богатым набором возможностей по отображению разнообразных графических элементов и растровых изображений. Подробно свойства и методы канвы обсуждаются в главе 8, поэтому заинтересованный читатель может обратиться к ней, а здесь мы остановимся только на особенностях печати графики.

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

  1. Для начала печати используется метод BeginDoc.
  2. При помощи свойств и методов класса TCanvas, экземпляр которого для текущего принтера доступен в свойстве canvas, создается рисуемый сюжет. При вызове методов соответствующие графические элементы отправляются на печать.
  3. Для завершения печати вызывается метод EndDoc.

Обратите внимание, что обращение к канве принтера выполняется только после начала печати. Иначе возникает ошибка времени выполнения.

При переносе содержимого канвы на лист бумаги вид напечатанной копии сильно зависит от параметров принтера. Поэтому перед печатью желательно проверять размер изображения и при необходимости проводить его масштабирование. Оно выполняется не только при слишком больших картинках, но и при необходимости увеличить небольшое изображение до размеров листа.

Размер листа бумаги для текущего принтера определяется свойствами PageHeight и PageWidth класса TPrinter.

Кроме этого, качество представления графики (разрешение) для экрана и принтера могут существенно различаться. Текущее разрешение принтера можно узнать при помощи функции Windows API GetDeviceCaps, которая возвращает значения масштаба по горизонтали и вертикали, соответствующих числу логических пикселов на дюйм для используемого по умолчанию принтера.

Примеры реализации программного кода для печати графики приведены ниже.

Печать растровых изображений

Для печати растрового изображения необходимо загрузить его в экземпляр класса TBitmap или его наследника. Проще всего использовать в приложении компонент Timage или созданный самостоятельно объект типа TBitmap. Затем изображение передается на канву принтера при помощи стандартных методов и класс TPrinter обеспечивает его печать.

Например, печать изображения в центре страницы без изменения масштаба может быть реализована так:

procedure TForml.ButtonlClick(Sender: TObject);

with Printer, Imagel do

if (Picture.Width > PageWidth) or(Picture.Height > PageHeight) then begin

ShowMessage("Изображение больше страницы");

Canvas.Draw((PageWidth - Picture.Width) div 2,(PageHeight - Picture.Height) div 2, Picture.Bitmap);

Если изображение помещается на страницу, то метод Canvas. Draw обеспечивает вывод изображения по центру страницы.

Для непропорционального масштабирования изображения по размерам страницы можно сделать так:

var ImageRect: TRect;

with Printer, Imagel do

ImageRect.Top:= 0;

ImageRect.Left:= 0;

ImageRect.Right:- PageWidth;

ImageRect.Bottom:= PageHeight;

Canvas.StretchDraw(ImageRect, Picture.Bitmap);

В этом случае всю работу по масштабированию выполняет метод StretchDraw канвы, который изменяет размеры изображения в соответствии с размерами прямоугольника ImageRect.

Для пропорционального масштабирования необходимо провести элементарные вычисления по расчету размеров сторон прямоугольника. Исчерпывающий пример есть в поставке Delphi: папка heip\examples\jpeg.

Печать графических примитивов

Печатать произвольные графические фигуры и текст как графику можно и без создания растровых изображений, а непосредственно с использованием возможностей свойства Canvas объекта printer.

procedure TFormI.ButtonlClick(Sender: TObject);

Printer.BeginDoc;

with Printer.Canvas do begin Pen.Color:= clBlack;

Brush.Color:= clBlue;

Brush.Style:= bsCross;

R:= Rect(10, 10, 160, 160);

Ellipse(R.Left, R.Top, R.Right, R.Bottom);

P:= Point(60, 180);

TextOut (P.X, P.Y, "Ellipse");

При выполнении данного кода на принтере должен напечататься круг с подписью "Ellipse" под ним. Обратите внимание, что в этом случае текст под рисунком печатается при помощи графических средств.

Свойство canvas класса TPrinter позволяет реализовывать еще одну интересную возможность: содержимое канвы формы или другого визуального компонента можно распечатать без особых хлопот.

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

Рис. 9.2. Геометрический рисунок на канве формы

Для его создания используются свойства и методы класса TCanvas. В приложении DemoPrintCanvas (рис. 9.2) для создания рисунка используется метод-обработчик OnPaint.

Чтобы направить этот рисунок на печать, достаточно скопировать прямоугольник нужного размера из канвы формы в канву принтера. В листинге 9.2. это делается в методе-обработчике printBtnclick при помощи метода CopyRect.

Листинг 9.2 Секция implementation модуля главной формы проекта DemoPrintCanvas

procedure TMainForm.FormPaint(Sender: TObject);

begin with Canvas do begin Pen.Color:= clBlack;

Brush.Color:= clWhite;

Brush.Style:= bsClear;

Ellipse(10, 10, 160, 160);

Brush.Color := clRed;

Ellipse(60, 60, 110, 110);

Brush.Color := clBlue;

Brush.Style := bsFDiagonal;

Ellipse(17, 35, 153, 75);

Brush.Color := clBlue;

Brush.Style:= bsBDiagonal;

Ellipse; 16, 85, 154, 135);

Text0ut(50, 180, "Нечто");

procedure TMainForm.PrintBtnClick(Sender: TObject);

var ImageRect: TRect;

begin ImageRect := Rect(10, 10, 160 , 200);

with Printer do begin BeginDoc;

Canvas.CopyRect(ImageRect, MainForm.Canvas, ImageRect);

Печать формы и элементов управления

В данном пункте мы освоим полезную и в то же время простую операцию,

позволяющую напечатать форму в том виде, как она выглядит на экране.

Для ее реализации следует вызвать метод print формы. При этом включать в секцию uses модуль printers не нужно.

Метод класса TForm

procedure Print;

работает следующим образом. Он копирует клиентскую область текущего окна во внеэкранное растровое изображение, а затем печатает его с помощью функции Windows API stretchDiBits. Для управления режимом масштабируемой копии используется свойство

type TPrintScale = (poNone, poProportional, poPrintToFit) ;

property PrintScale: TPrintScale;

Значения свойства имеют такой смысл:

  • PoNone - масштабирования нет. Размер напечатанного изображения зависит от разрешения принтера.Как правило, бумажная копия оказывается в этом случае в несколько раз меньше оригинала.
  • poProportional - форма печатается таким образом, что примерно сохраняется видимый на экране размер изображения.
  • poPrintToFit - масштабирование осуществляется до размеров страницы. То есть форма заполняет страницу в одном из направлений.

Есть и другой путь печати как форм, так и любых других элементов управления - наследников класса TwinControl. У всех оконных элементов управления есть метод paintTo, позволяющий отрисовывать "себя" на любой канве. В нашем случае это канва принтера.

Контроль ошибок печати

Для повышения надежности приложений при работе с принтером применяется специальный класс исключительной ситуации EPrinter, происходящий непосредственно от базовой исключительной ситуации Exception. Поэтому класс EPrinter обладает стандартным набором свойств и методов (см. главу 4).

Применяется он также стандартным образом, внутри блока try ... except:

with Printer do try

Canvas.TextOut(100, 100, "SomeTexf);

on E: EPrinter do ShowMessage("Ошибка печати");

Резюме

В данной главе рассмотрены вопросы, связанные с организацией вывода на печать текстов, списков строк, форм, растровых изображений и произвольных графических объектов. Определяющую роль в этих процессах играет модуль printers, описывающий класс TPrinter. Экземпляр класса доступен разработчику через функцию Printer.

Печать текстов основана на хорошо известных процедурах ввода/вывода, перед использованием которых необходимо связать файловую переменную с текущим принтером при помощи метода Assignprn.

Печать графики основывается на использовании возможностей класса TCanvas, доступного в объекте типа TPrinter через свойство Canvas.

При изучении этой главы полезно вспомнить материал следующих глав:

  • глава 4 "Обработка исключительных ситуаций";
  • глава 6 "Файлы и устройства ввода/вывода";
  • глава 8 "Графика".


Поделиться