Ракитин Р.Ю. ООП в Turbo Delphi
.PDF161
Глава 17. Текстовая и графическая печать
Диалоги настройки параметров печати необходимы каждой программе, которая выводит информацию на принтер. Современные устройства вывода имеют множество настроек, которые могут изменяться пользователем с помощью программ, поставляемых с такими устройствами. Таким образом, прикладная программа не имеет возможности поддержать все функции, реализуемые устройством, и должна использовать стандартные диалоги.
Диалоговые компоненты не имеют каких-либо возможностей для вывода информации на принтер. Однако они изменяют характеристики объекта типа TPrinter, ссылка на который возвращается функцией Printer, описанной в модуле Printers. Программа использует эту ссылку для непосредственного вывода на печать, а параметры устанавливаются диалогами TPrintDialog,
TPrinterSetupDialog и TPageSetupDialog.
Печать в текстовом режиме
Если Вам нужно напечатать на принтере документ в текстовом режиме, то это делается следующим образом. С принтером вы работаете, как с обычным текстовым файлом, за исключением того, что вместо процедуры 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;
Графическая печать
Рассмотрим, как из программы, созданной в Delphi можно вывести на печать графическую информацию. Как говорилось выше, для этого используется объект TPrinter. С помощью этого объекта печать на принтере
графической информации становится не сложнее вывода этой информации на экран. Основным является то, что Printer предоставляет разработчику свойство Canvas и методы, выводящие содержание канвы на принтер.
+ Чтобы объект TPrinter стал доступным вашему проекту, вы
должны добавить в раздел uses модуль Printers.
Рассмотрим подробнее свойства и методы объекта Printer.
162
Свойства:
Aborted – тип булевский; показывает, прервал ли пользователь работу принтера методом Abort;
Canvas – канва, место для вывода графики; Fonts – список доступных шрифтов;
Handle – используется при прямых вызовах Windows API; Orientation – ориентация страницы, вертикально или горизонтально;
PageWidth, PageHeight, PageNumber – соответственно ширина, высота и номер страницы;
Printers – перечисляет все установленные в системе принтеры; PrinterIndex – указывает, какой из них является текущим. Чтобы печатать
на |
принтере |
по |
умолчании |
здесь |
должно |
быть |
значение -1; |
|
|
|
|
|
Printing – тип булевский; показывает, начата ли печать (методом
BeginDoc);
Title – заголовок для Print Manager и для заголовка перед выводом на сетевом принтере.
Методы:
Abort – прерывает печать, начатую методом BeginDoc; BeginDoc – вызывается перед тем, как начать рисовать на канве;
EndDoc – вызывается, когда все необходимое уже нарисовано на канве, принтер начинает печатать именно после этого метода;
NewPage – переход на новую страницу.
Итак, порядок вывода на печать графической информации выглядит следующим образом:
1.выполняется метод BeginDoc;
2.на канве (Canvas) рисуем все, что нужно;
3.при необходимости разместить информацию на нескольких листах вызываем метод NewPage;
4.посылаем нарисованное на принтер, выполняя метод EndDoc;
Диалоги настройки параметров печати
1. Компонент TPrintDialog
Компонент TPrintDialog предназначен для установки следующих основных параметров печати:
∙печатающее устройство, выбираемое из списка доступных системе, с
возможностью его настройки с помощью специализированного диалога (при использовании кнопки «Свойства»);
∙часть документа, выводимая на печать – весь документ, несколько страниц или выделенная область;
∙число копий и их упорядочивание при печати.
163
+ Диалог является модальным, поэтому определение настроек,
выполненных пользователем, производится после вызова метода
Execute.
Свойства:
Copies – количество копий;
Collate – значение переключателя «Разобрать».
PrintRange – информация о той части документа, которую следует, в соответствии с выбором пользователя, вывести на печать. Значения:
prAllPages – печатать все страницы документа; prSelection – печатать выделенную часть документа;
prPageNums – печатать только некоторый диапазон страниц. FromPage и ТоРаgе – начальное и конечное значение страниц выводимых на печать;
PrintToFile – состояние переключателя «Печать в файл»; Options – внешний вид диалога.
2. Компонент TPrinterSetupDialog
Компонент TPrinterSetupDialog предназначен для установки следующих основных параметров печати:
∙печатающее устройство, выбираемое из списка доступных системе, с
возможностью его настройки с помощью специализированного диалога (при использовании кнопки «Свойства»);
∙размер бумаги из списка доступных форматов выбранного принтера, и тип подачи;
∙ориентация печати – книжная или альбомная.
164
3. Компонент TPageSetupDialog
Основным назначением диалога является предоставление пользователю возможности ввода отступов от краев страницы, дня чего в
диалоговом окне предусмотрены соответствующие поля ввода.
Компонент TPageSetupDialog сочетает в себе некоторые элементы ранее рассмотренных компонентов, а именно:
∙выбор ориентации печати (книжная или альбомная);
∙выбор формата бумаги из списка поддерживаемых выбранным принтером, и типа ее подачи.
Свойства:
MarginLeft, MarginTop, MarginRight, MarginBottom – значение отступов от краев страницы;
Units – единицы измерения, в которых пользователь указывает настройки документа. Допустимые значения: pmDefault, pmMillimeters, pmInches
PageHeight, PageWidth – размер страницы.
Практическое задание
Рассмотрим простейший пример печати.
Для примера понадобится форма, на которой будет расположен один компонент TPageControl. На нем можно создать несколько вкладок и поместить на вкладки различные компоненты. На первую вкладку установим текст и несколько компонентов TShape. На второй вкладке расположим картинку Tlmage. На печать будет выводиться содержимое вкладок компонента TPageControl вместе с компонентами и картинкой. Каждая вкладка печататается как отдельная страница.
165
Установим на форму кнопку Печать и компонент PrintDialog с вкладки Dialogs палитры компонентов. Теперь перейдем к написанию кода. Создадим обработчик события OnClick для кнопки «Печать».
procedure TForm1.Button1Click(Sender: TObject); var
i,
//начальная и конечная страницы для печати
Start, Stop: Integer; begin
//установка опций окна печати
PrintDialog1.Options:= [poPageNums, poSelection]; {начальное значение, с которого должна происходить печать}
PrintDialog1.FromPage:= 1;
{количество печатаемых страниц равно количеству вкладок у компонента PageControl1} PrintDialog1.ToPage := PageControl1.PageCount;
{минимальное и максимальное значения сраниц доступных для печати}
PrintDialog1.MinPage := 1;
PrintDialog1.MaxPage := PageControl1.PageCount;
{если нажата кнопка Cancel в диалоговом окне печать не произойдет}
if not PrintDialog1.Execute then exit;
//проверка диапазона выбранного пользователем if PrintDialog1.PrintRange = prAllPages then begin
Start := PrintDialog1.MinPage - 1;
Stop := PrintDialog1.MaxPage - 1; end
else
166
//если выбран печать фрагмента
if PrintDialog1.PrintRange = prSelection then begin
Start := PageControl1.ActivePageIndex; Stop := Start;
end else begin
Start := PrintDialog1.FromPage - 1; Stop := PrintDialog1.ToPage - 1;
end;
//начать формировать документ
Printer.BeginDoc;
{прорисовка очередной страницы на принтер
по умолчанию, где значение 10 – отступ} for i := Start to Stop do
begin
PageControl1.Pages[i].PaintTo(Printer.Handle, 10, 10); if i <> Stop then
Printer.NewPage;
end;
//распечатать весь документ
Printer.EndDoc; end;
167
Глава 18. Создание компонентов во время выполнения программы
Работа в визуальном построителе удобна и проста, однако иногда на этапе разработки программы неизвестно, какие именно компоненты должны быть созданы.
Для этого предусмотрена возможность создания компонента во время выполнения программы.
Основные действия, выполняемые при создании компонентов
Создание компонента без визуального построителя аналогично созданию экземпляра какого-либо класса, так как каждый компонент является классом. Для того, чтобы компонент стал частью общей структуры программы, необходимо придерживаться следующих правил:
1.Для каждого компонента должно быть установлено свойство принадлежности – ссылка на какой-либо компонент (компонент-владелец), который несёт ответственность за разрушение данного компонента при разрушении самого себя;
2.Для визуальных компонентов должно быть установлено свойство визуальной принадлежности – ссылка на компонент-контейнер (компонент-родитель), в котором должен отображаться данный компонент.
Ссылка на компонент-владелец передаётся в качестве параметра при вызове конструктора компонента.
constructor Create(AOwner: TComponent);
Например, создание компонента Timer может выглядеть следующим образом:
...
var
MyTimer: TTimer; {Описание ссылки на компонент Timer) begin
{созание экземпляра компонента Timer. Ответственность за его разрушение возложена на компонент Panel1, соответственно при вызове метода Free компонента Panel1 сначала будет автоматически вызван метод Free компонента
MyTimer1}
MyTimer := TTimer.Create(Panel1);
...
Заметим, что в качестве ссылки на компонент-владелец может быть передано значение nil (пустая ссылка), которая будет корректно распознана конструктором компонента. В таком случае, программа, создавшая компонент, должна его самостоятельно разрушить с помощью вызова метода Free, перед закрытием, либо при отсутствии необходимости его дальнейшего использования:
MyTimer.Free;
168
Создание визуальных компонентов
Процесс создания визуальных компонентов должен содержать в себе еще один дополнительный шаг, помимо установки свойства принадлежности – указание компонента, который является контейнером (визуальным владельцем) для создаваемого. Ссылка на контейнер заносится в свойство Parent:
property Parent: TWinControl;
Присвоение ссылки данному свойству автоматически перемешает компонент из одного контейнера в другой. Рассмотрим, например, создание визуального компонента (метки Label) во время выполнения программы.
var
MyLabe1: TLabe1; //ссылки на компонент Label begin
{создание экземпляра компонента Label. Ответственность за его разрушение возложена па компонент Panel1, соответственно при вызове метода Free компонента Panel1 сначала будет автоматически вызван метод Free компонента
MyLabe1}
MyLabe1:= TLabel.Create(Panel1);
{Указание визуальной принадлежности компонента MyLabel – в качестве контейнера для него указывается компонент Panel1 который является еще и его владельцем}
MyLabe1.Parent := Panel1;
...
Ещё одной существенной особенностью создания визуальных компонентов является необходимость настройки свойств, управляющих положением компонента, его размерами, и другими свойствами, определяющими представление элемента управления на экране. Такие действия выполняются обычным образом, с помощью изменения значений соответствующих свойств компонентов.
В качестве примера создания компонентов во время выполнения программы, рассмотрим приложение (левый рис.), создающее при нажатии кнопки «Создать» экземпляр компонента Edit, и располагающее его в панели (правый рис.).
169
При нажатии второй кнопки «Переместить» компонент, созданный ранее, перемещается в другой контейнер – главное окно приложения (см. рис.). Для
визуального переноса компонента в новый контейнер достаточно просто изменить свойство визуальной принадлежности.
Предусмотрим еще одну кнопку – «Разрушить панель» – и в обработчике нажатия на нее будем вызывать метод Free панели Panel1. В результате панель будет удаляться с экрана, разрушая при этом строку ввода, вне зависимости от того, где именно она расположена – на панели или в окне формы.
Для создания описанного приложения запустим среду разработчика Delphi, и расположим на форме компонент Panel, которому будет присвоено название Panel1. Далее расположим на форме три компонента Button, которым визуальный построитель назначит имена Buttonl, Button2 и Button3.
Добавим в описание класса TForml ссылку на экземпляр класса TEdit (строку ввода), которая будет создана во время выполнения программы
TForml = class(TForm)
...
private
Editl: TEdit;
...
Реализуем обработчики события OnClick для кнопки «Создать».
170
procedure TForm1.Button1Click(Sender: TObject); begin
{Создание экземпляра класса TEdit;, в качестве объектавладельца указан компонент Panel1}
Edit1:= TEdit.Create(Panel1);
{Установка свойств положения и размеров созданного компонента}
Edit1.Left:= 10;
Edit1.Top:= 10;
Edit1.Width:= Panel1.ClientWidth - 20;
Edit1.Height:= Panel1.ClientHeight - 20;
{Указание визуальной принадлежности компонента} Edit1.Parent := Panel1;
end;
Реализуем обработчики события OnClick для кнопки «Переместить».
procedure TForm1.Button2Click(Sender: TObject); begin
{Изменение свойства визуальной принадлежности. В качестве нового контейнера указывается ссылка на форму с помощью ключевого слова Self}
Edit1.Parent:= Self; end;
Реализуем обработчики события OnClick для кнопки «Разрушить панель».
procedure TForm1.Button3Click(Sender: TObject); begin
Panel1.Free; end;
Разрушение панели происходит вызовом метода Free. Перед непосредственным разрушением Panel1 будет вызван метод Free компонента Edit1, созданного во время выполнения программы, в результате чего он исчезнет с экрана, а обращение к нему через ссылку Edit1 станет невозможным.
Заметим, что при смене контейнера компонент перемещается относительно верхнего левого угла формы. Это связано с тем, что его положение, заданное свойствами Left и Тор не изменяется, тогда как эти значения рассматриваются относительно контейнера.
Теперь представим себе ситуацию, когда кнопки Button1, Button2 и Button3 были бы размещены в панели Panel1. В этом случае при разрушении панели они будут удалены из окна приложения, так как разрушается контейнер, в котором они находятся. При этом владельцем всех трех компонентов является форма, поэтому реально кнопки будут разрушены только при закрытии программы.