Секреты печати из программы на 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;
На этом пока все.