Работа с принтером.
Работа с принтером.
Delphi имеет стандартный объект для доступа к принтеру — TPRINTER, находящийся в модуле PRINTERS. В этом модуле имеется переменная Printer:Tpinter, что избавляет от необходимости описывать свою. Он позволяет выводить данные на печать и управлять процессом печати. Правда, в некоторых версиях Delphi 1 он имеет "глюк" — не работают функции Draw и StrethDraw. Но эта проблема поправима - можно использовать функции API. Далее приведены основные поля и методы объекта Printers:
PROPERTY
Aborted:boolean — Показывает, что процесс печати прерван
Canvas:Tcanvas — Стандартный Canvas, как у любого графического объекта. Он позволяет рисовать на листе бумаге графику, выводить текст… Тут есть несколько особенностей, они описаны после описания объекта.
Fonts:Tstrings — Возвращает список шрифтов, поддерживаемых принтером
Handle:HDS — Получить Handle на принтер для использования функций API (см. Далее)
Orientation:TprinterOrientation — Ориентация листа при печати : (poPortrait, poLandscape)
PageHeight:integer — Высота листа в пикселах
PageNumber:integer — Номер страницы, увеличивается на 1 при каждом NewPage
PageWidth:integer — Ширина листа в пикселах
PrinterIndex:integer — Номер используемого принтера по списку доступных принтеров Printers
Printers:Tstrings — Список доступных принтеров
Printing:boolean — Флаг, показывающий, что сейчас идет процесс печати
Title:string — Имя документа или приложения. Под этим именем задание на печать регистрируется в диспетчере печати
METODS
AssignPrn(f:TextFile) — Связать текстовый файл с принтером. Далее вывод информации в этот файл приводит к ее печати. Удобно в простейших случаях.
Abort — Сбросить печать
BeginDoc — Начать печать
NewPage — Начать новую страницу
EndDoc — Завершить печать.
Пример :
Procedure TForm1.Button1Click(Sender: TObject);
Begin
With Printer do Begin
BeginDoc; { Начало печати }
Canvas.Font:=label1.font; { Задали шрифт }
Canvas.TextOut(100,100,'Это тест принтера !!!'); { Печатаем текст }
EndDoc; { Конец печати }
end;
end;
Особенности работы с TPrinter
1. После команды BeginDoc шрифт у Canvas принтера сбрасывается и его необходимо задавать заново
2. Все координаты даны в пикселах, а для нормальной работы необходимы миллиметры (по двум очевидным причинам: очень трудно произвести разметку страницы в пикселах (особенно если необходима точность), и, главное, при изменении разрешающей способности принтера будет изменяться число точек на дюйм, и все координаты "поедут".
3. У TPrinter информация о принтере, по видимому, определяются один раз — в момент запуска программы (или смены принтера). Поэтому изменение настроек принтера в процессе работы программы может привести к некорректной работе, например, неправильной печать шрифтов True Type.
Определение параметров принтера через API
Для определения информации о принтере (плоттере, экране) необходимо знать Handle этого принтера, а его можно узнать объекта TPrinter — Printer.Handle. Далее вызывается функция API (unit WinProcs) : GetDevice(Handle:HDC; Index:integer):integer;
Index – код параметра, который необходимо вернуть. Для Index существует ряд констант:
DriverVersion — вернуть версию драйвера
Texnology — Технология вывода, их много, основные
dt_Plotter — плоттер
dt_RasPrinter — растровый принтер
dt_Display — дисплей
HorzSize — Горизонтальный размер листа (в мм)
VertSize — Вертикальный размер листа (в мм)
HorzRes — Горизонтальный размер листа (в пикселах)
VertRes — Вертикальный размер листа (в пикселах)
LogPixelX — Разрешение по оси Х в dpi (пиксел /дюйм)
LogPixelY - Разрешение по оси Y в dpi (пиксел /дюйм)
Кроме перечисленных еще около сотни, они позволяют узнать о принтере практически все.
Параметры, возвращаемые по LogPixelX и LogPixelY очень важны — они позволяют произвести пересчет координат из миллиметров в пиксели для текущего разрешения принтера. Пример таких функций:
Procedure TForm1.GetPrinterInfo; { Получить информацию о принтере }
begin
PixelsX:=GetDeviceCaps(printer.Handle,LogPixelsX);
PixelsY:=GetDeviceCaps(printer.Handle,LogPixelsY);
end;
Function TForm1.PrinterCoordX(x:integer):integer; { переводит координаты из мм в пиксели }
begin
PrinterCoordX:=round(PixelsX/25.4*x);
end;
Function TForm1.PrinterCoordY(Y:integer):integer; { переводит координаты из мм в пиксели }
begin
PrinterCoordY:=round(PixelsY/25.4*Y);
end;
---------------------------------
GetPrinterInfo;
Printer.Canvas.TextOut(PrinterCoordX(30), PrinterCoordY(55),
'Этот текст печатается с отступом 30 мм от левого края и '+
'55 мм от верха при любом разрешении принтера');
Данную методику можно с успехом применять для печати картинок — зная размер картинки можно пересчитать ее размеры в пикселах для текущего разрешения принтера, масштабировать, и затем уже распечатать. Иначе на матричном принтере (180 dpi) картинка будет огромной, а на качественном струйнике (720 dpi) — микроскопической.
Вывести список установленных принтеров и установить принтер по умолчанию
unit MainFrm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TMainForm = class(TForm) cbPrinters: TComboBox; lblPrinter: TLabel; procedure FormCreate(Sender: TObject); procedure cbPrintersChange(Sender: TObject); private { Private declarations } public { Public declarations } end; var MainForm: TMainForm; implementation uses IniFiles, Printers; {$R *.DFM} procedure TMainForm.FormCreate(Sender: TObject); begin { Copy the printer names to the combobox and set the combobox to show the currently selected default printer } cbPrinters.Items.Assign(Printer.Printers); cbPrinters.Text := Printer.Printers[Printer.PrinterIndex]; // Update the label to reflect the default printer lblPrinter.Caption := Printer.Printers[Printer.PrinterIndex]; end; procedure TMainForm.cbPrintersChange(Sender: TObject); var IniFile: TIniFile; TempStr1, TempStr2: string; S: array[0..64] of char; begin with Printer do begin // Set the new printer based on the ComboBox's selected printer PrinterIndex := cbPrinters.ItemIndex; // Store the printer name into a temporary string TempStr1 := Printers[PrinterIndex]; // Delete the unnecessary portion of the printer name System.Delete(TempStr1, Pos(' on ', TempStr1), Length(TempStr1)); // Create a TIniFile class IniFile := TIniFile.Create('WIN.INI'); try // Retrieve the device name of the selected printer TempStr2 := IniFile.ReadString('Devices', TempStr1, ''); // Change the default printer to that chosen by the user IniFile.WriteString('windows', 'device', TempStr1 + ',' + TempStr2); // Tell all windows that the default printer changed. StrCopy(S, 'windows'); SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(@S)); finally IniFile.Free; end; end; // Update the label to reflect the new printer selection lblPrinter.Caption := Printer.Printers[Printer.PrinterIndex]; end; end.