Секреты печати из программы на Delphi

Здравствуйте дорогие читатели. Сегодня мы разберем механизмы печати в программах Делфи.

TPrinter

Для упрощенного доступа к принтеру Delphi имеет стандартный объектTPrinter который находится в модуле Printers, в этом же модуле имеется функция Printer:

function Printer: TPrinter;
begin
  if FPrinter = nil then FPrinter := TPrinter.Create;
  Result := FPrinter;
end;

Как видно из листинга она проверяет был ли создан экземпляр объекта FPrinter:TPrinter, если нет, то создает и возвращает ссылку на него, что избвляет разработчика от необходимости создавать объект самому.

Вот основные методы и свойства объекта TPtinter.

Свойства:

Свойство Описание
Aborted:boolean Показывает, что процесс печати прерван
Canvas:Tcanvas Обычный Canvas
Fonts:Tstrings Список шрифтов, поддерживаемых принтером
Handle:HDS Handle принтера для использования функций API
Printers:Tstrings Список принтеров
PrinterIndex:integer Номер используемого принтера в списке принтеров
Orientation:TprinterOrientation Ориентация листа при печати : (poPortrait, poLandscape)
Title:string Имя документа для диспетчера печати
PageWidth:integer Ширина листа в пикселах
PageHeight:integer Высота листа в пикселах
PageNumber:integer Номер страницы
Printing:boolean Флаг процесса печати

Методы:

Метод Описание
Abort Экстренно завершить печать
BeginDoc Начать печать документа
NewPage Печать на новой странице
EndDoc Завершить печать документа

Простейший пример печати:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Printer.BeginDoc;
  Printer.Canvas.TextOut(200,200,'Delphi is cool');
  Printer.EndDoc;
end;

Настройки принтера

Для чтения настроек принтера можно пользоваться функциией GetDeviceCaps(DC:HDC,Index:integer):Integer, для ее вызова нам потребуется DC принтера (Printer.Handle). Второй параметр функии - это код того параметра настроек принтера который необходимо получить, его можно задать одной из констант:

Имя константы Параметр
DriverVersion версия драйвера
HorzRes Горизонтальный размер листа (в пикселах)
VertRes Вертикальный размер листа (в пикселах)
HorzSize Горизонтальный размер листа (в милиметрах)
VertSize Вертикальный размер листа (в милиметрах)
LogPixelX Разрешение по горизонтали в dpi (пиксел / дюйм)
LogPixelY Разрешение по вертикали в dpi (пиксел / дюйм)

Теперь имея все эти данные мы можем распечатать документ с учетом полей и размеров шрифта.

И так поля практически у любого принтера имеется непечатаемая область (границы печати) и при установке полей печати документа необходимо учитывать эту непечатаемую область. Вот процедура вычисления границ печати:

var
  PixPerInchX,PixPerInchY,PageWidthInMM,PageHeightInMM,PhysOffsetX,PhysOffsetY,
  PageResX,PageResY,PhysPageWidth,PhysPageHeigth:integer;
  Margins:TRect;

procedure GetPrinterInfo;
var
  DC:HDC;
begin
  DC:=Printer.Handle;
  PixPerInchX:=GetDeviceCaps(DC,LOGPIXELSX);
  PixPerInchY:=GetDeviceCaps(DC,LOGPIXELSY);
  PageWidthInMM:=GetDeviceCaps(DC,HORZSIZE);
  PageHeightInMM:=GetDeviceCaps(DC,VERTSIZE);

  PhysOffsetX:=GetDeviceCaps(DC,PHYSICALOFFSETX);
  PhysOffsetY:=GetDeviceCaps(DC,PHYSICALOFFSETY);

  PhysPageWidth:=GetDeviceCaps(DC,PHYSICALWIDTH);
  PhysPageHeigth:=GetDeviceCaps(DC,PHYSICALHEIGHT);

  PageResX:=GetDeviceCaps(DC,HORZRES);
  PageResY:=GetDeviceCaps(DC,VERTRES);

  // границы печати
  Margins.Top:=round(PhysOffsetY/PixPerInchY*25.4);
  Margins.Left:=round(PhysOffsetX/PixPerInchX*25.4);

  Margins.Bottom:=round((PhysPageHeigth-PageResY-PhysOffsetY)/PixPerInchY*25.4);
  Margins.Right:=round((PhysPageWidth-PageResX-PhysOffsetX)/PixPerInchX*25.4);
end;

Теперь попробуем распечатать лист на котором будет рамка по периметру с отступами один сантиметр слева, справа и сверху и 1.5 см снизу.

procedure PrintMargins;
begin
  GetPrinterInfo;

  Printer.BeginDoc;
  Printer.Canvas.MoveTo(MilimetersToPixelsX(10-Margins.Left),
                        MilimetersToPixelsY(10-Margins.Top));
  Printer.Canvas.LineTo(MilimetersToPixelsX(10-Margins.Left),
                        MilimetersToPixelsY(PageHeightInMM-15+Margins.Bottom));
  Printer.Canvas.LineTo(MilimetersToPixelsX(PageWidthInMM-10+Margins.Right),
                        MilimetersToPixelsY(PageHeightInMM-15+Margins.Bottom));
  Printer.Canvas.LineTo(MilimetersToPixelsX(PageWidthInMM-10+Margins.Right),
                        MilimetersToPixelsY(10-Margins.Top));
  Printer.Canvas.LineTo(MilimetersToPixelsX(10-Margins.Left),
                        MilimetersToPixelsY(10-Margins.Top));
  Printer.EndDoc;
end;

А вот код процедуры печати текста обрамленного прямоугольником:

procedure TForm1.Button1Click(Sender: TObject);
var
  TextWidthMM:integer;
  TextHeightMM:integer;
begin
  GetPrinterInfo;

  Printer.BeginDoc;

  Printer.Canvas.Font.PixelsPerInch:=PixPerInchX;

  TextWidthMM:=round((Printer.Canvas.TextWidth('Печать')/PixPerInchX)*25.4);
  TextHeightMM:=round((Printer.Canvas.TextHeight('Печать')/PixPerInchY)*25.4);

  Printer.Canvas.Rectangle(MilimetersToPixelsX(19),MilimetersToPixelsY(19),
                           MilimetersToPixelsX(19+TextWidthMM+2),
                           MilimetersToPixelsY(19+TextHeightMM+2));
  Printer.Canvas.TextOut(MilimetersToPixelsX(20),MilimetersToPixelsY(20),'Печать');
  Printer.EndDoc;
end;

На этом пока все.

Автор: JB
www.asportal.h16.ru
13 июня 2006 года


Опубликовал admin
19 Июн, Понедельник 2006г.



Программирование для чайников.