Секреты печати из программы на 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
|