unit Tstpr2fm;
{Пример использования объекта Printer из модуля TPrinter.
Приведен избыточный стиль программирования для облегчения
восприятия материала.
Демонстрация величин, возвращаемых функцией Windows API GetDeviceCaps.
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Print: TButton;
Image1: TImage;
procedure PrintClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
USES
Printers;
{Константы WINAPI GetDeviceCaps получены из C++ windows.h и wingdi.h}
{Отдельные константы здесь приведены только для информации о их наличии}
CONST
DRIVERVERSION = 0;
TECHNOLOGY = 2; {Смотри windows.h для значения маски}
HORZSIZE = 4;
VERTSIZE = 6;
HORZRES = 8;
VERTRES = 10;
BITSPIXEL = 12;
PLANES = 14;
NUMBRUSHES = 16;
NUMPENS = 18;
NUMMARKERS = 20;
NUMFONTS = 22;
NUMCOLORS = 24;
PDEVICESIZE = 26;
CURVECAPS = 28; {Смотри windows.h для значения маски}
LINECAPS = 30; {Смотри windows.h для значения маски}
POLYGONALCAPS = 32; {Смотри windows.h для значения маски}
TEXTCAPS = 34; {Смотри windows.h для значения маски}
CLIPCAPS = 36; {Смотри windows.h для значения маски}
RASTERCAPS = 38; {Смотри windows.h для значения маски}
ASPECTX = 40;
ASPECTY = 42;
ASPECTXY = 44;
LOGPIXELSX = 88;
LOGPIXELSY = 90;
SIZEPALETTE = 104;
NUMRESERVED = 106;
COLORRES = 108;
PHYSICALWIDTH = 110; {Смотри определение в windows.h}
PHYSICALHEIGHT = 111; {Смотри определение в windows.h}
PHYSICALOFFSETX = 112; {Смотри определение в windows.h}
PHYSICALOFFSETY = 113; {Смотри определение в windows.h}
SCALINGFACTORX = 114; {Смотри определение в windows.h}
SCALINGFACTORY = 115; {Смотри определение в windows.h}
DeviceCapsString: ARRAY[1..34] OF STRING =
('DRIVERVERSION', 'TECHNOLOGY', 'HORZSIZE',
'VERTSIZE', 'HORZRES', 'VERTRES',
'BITSPIXEL', 'PLANES', 'NUMBRUSHES',
'NUMPENS', 'NUMMARKERS', 'NUMFONTS',
'NUMCOLORS', 'PDEVICESIZE', 'CURVECAPS',
'LINECAPS', 'POLYGONALCAPS', 'TEXTCAPS',
'CLIPCAPS', 'RASTERCAPS', 'ASPECTX',
'ASPECTY', 'ASPECTXY', 'LOGPIXELSX',
'LOGPIXELSY', 'SIZEPALETTE', 'NUMRESERVED',
'COLORRES', 'PHYSICALWIDTH', 'PHYSICALHEIGHT',
'PHYSICALOFFSETX','PHYSICALOFFSETY','SCALINGFACTORX',
'SCALINGFACTORY');
DeviceCapsIndex: ARRAY[1..34] OF INTEGER =
( 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
40, 42, 44, 88, 90, 104, 106, 108, 110, 111,
112, 113, 114, 115);
{$R *.DFM}
FUNCTION iPosition(const i: INTEGER): INTEGER;
BEGIN
RESULT := Integer(i * LongInt(Printer.PageWidth) DIV 1000)
END {iPosition};
FUNCTION jPosition(const j: INTEGER): INTEGER;
BEGIN
RESULT := Integer(j * LongInt(Printer.PageHeight) DIV 1000)
END {jPosition};
procedure TForm1.PrintClick(Sender: TObject);
VAR
DestinationRectangle: TRect;
GraphicAspectRatio : DOUBLE;
i : INTEGER;
j : INTEGER;
iBase : INTEGER;
iPixelsPerInch : WORD;
jBase : INTEGER;
jDelta : INTEGER;
jPixelsPerInch : WORD;
OffScreen : TBitMap;
PixelAspectRatio : DOUBLE;
SourceRectangle : TRect;
TargetRectangle : TRect;
value : INTEGER;
x : DOUBLE;
y : DOUBLE;
begin
Printer.Orientation := poLandscape;
Printer.BeginDoc;
{Делаем прямоугольник для показа полей}
Printer.Canvas.Rectangle(0,0, Printer.PageWidth, Printer.PageHeight);
{Свойства принтера и страницы}
Printer.Canvas.Font.Name := 'Times New Roman';
Printer.Canvas.Font.Size := 12;
Printer.Canvas.Font.Style := [fsBold];
Printer.Canvas.TextOut(iPosition(50), jPosition(40), 'Свойства принтера и страницы');
Printer.Canvas.Font.Style := [];
Printer.Canvas.Font.Size := 10;
iBase := iPosition(50);
jBase := 60;
jDelta := 18;
Printer.Canvas.TextOut(iPosition(50), jPosition(jBase),
Printer.Printers.Strings[Printer.PrinterIndex]);
INC (jBase, jDelta);
Printer.Canvas.TextOut(iBase, jPosition(jBase),
'Пикселей: ' + IntToStr(Printer.PageWidth) + ' X ' +
IntToStr(Printer.PageHeight));
INC (jBase, jDelta);
Printer.Canvas.TextOut(iBase, jPosition(jBase),
'Дюймов: ' + FormatFloat('0.000',
Printer.PageWidth / Printer.Canvas.Font.PixelsPerInch) + ' X ' +
FormatFloat('0.000',
Printer.PageHeight / Printer.Canvas.Font.PixelsPerInch));
INC (jBase, 2*jDelta);
Printer.Canvas.TextOut(iBase, jPosition(jBase),
'Шрифт: ' + Printer.Canvas.Font.Name + ' Размер: ' +
IntToStr(Printer.Canvas.Font.Size));
INC (jBase, jDelta);
Printer.Canvas.TextOut(iBase, jPosition(jBase),
'Пикселей в дюйме: ' + IntToStr(Printer.Canvas.Font.PixelsPerInch));
INC (jBase, jDelta);
Printer.Canvas.TextOut(iBase, jPosition(jBase),
'''ТЕКСТ'': ' + IntToStr(Printer.Canvas.TextWidth('ТЕКСТ')) + ' X ' +
IntToStr(Printer.Canvas.TextHeight('ТЕКСТ')) + '
пикселей');
{Значения GetDeviceCaps}
INC (jBase, 2*jDelta);
Printer.Canvas.Font.Size := 12;
Printer.Canvas.Font.Style := [fsBold];
Printer.Canvas.TextOut(iBase, jPosition(jBase), 'GetDeviceCaps');
INC (jBase, jDelta);
Printer.Canvas.Font.Size := 10;
Printer.Canvas.Font.Style := [];
FOR j := LOW(DeviceCapsIndex) TO HIGH(DeviceCapsIndex) DO
BEGIN
value := GetDeviceCaps(Printer.Handle, DeviceCapsIndex[j]);
Printer.Canvas.TextOut(iBase, jPosition(jBase), DeviceCapsString[j]);
IF (DeviceCapsIndex[j] < 28) OR (DeviceCapsIndex[j] > 38)
THEN Printer.Canvas.TextOut(iPosition(250), jPosition(jBase), Format('%-8d', [value]))
ELSE Printer.Canvas.TextOut(iPosition(250), jPosition(jBase), Format('%.4x', [value]));
INC (jBase, jDelta);
END;
{Помещаем изображение в левый нижний угол}
Printer.Canvas.Draw (iPosition(300), jPosition(100),
Form1.Image1.Picture.Graphic);
{Помещаем то же изображение, имеющее ширину 1" и пропорциональную
высоту в позиции 4"-правее и 1"-ниже верхнего левого угла}
GraphicAspectRatio := Form1.Image1.Picture.Height /
Form1.Image1.Picture.Width;
iPixelsPerInch := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
jPixelsPerInch := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
PixelAspectRatio := jPixelsPerInch / iPixelsPerInch;
TargetRectangle := Rect(4*iPixelsPerInch, {4"}
jPixelsPerInch, {1"}
6*iPixelsPerInch, {6" -- 2" ширина}
jPixelsPerInch +
TRUNC(2*iPixelsPerInch * GraphicAspectRatio *
PixelAspectRatio));
Printer.Canvas.TextOut(4*iPixelsPerInch, jPixelsPerInch -
Printer.Canvas.TextHeight('X'),
'2" ширина от (4", 1")');
Printer.Canvas.StretchDraw (TargetRectangle, Form1.Image1.Picture.Graphic);
{Создаем изображение в памяти и затем копируем его на холст принтера}
SourceRectangle := Rect (0,0, 3*iPixelsPerInch-1, 2*jPixelsPerInch-1);
{Это не должно работать! Rectangle = Left, Top, Right, Bottom
Top и Bottom считаются зарезервированными?}
DestinationRectangle := Rect(4*iPixelsPerInch, 6*jPixelsPerInch,
7*iPixelsPerInch-1, 4*jPixelsPerinch-1);
Printer.Canvas.TextOut(4*iPixelsPerInch, 4*jPixelsPerInch -
Printer.Canvas.TextHeight('X'),
IntToStr(3*iPixelsPerInch) + ' пикселей на ' +
IntToStr(2*jPixelsPerInch) + ' пикселей -- ' +
'3"-на-2" в (4",4")');
OffScreen := TBitMap.Create;
TRY
OffScreen.Width := SourceRectangle.Right + 1;
OffScreen.Height := SourceRectangle.Bottom + 1;
WITH OffScreen.Canvas DO
BEGIN
Pen.Color := clBlack;
Brush.Color := clWhite;
Rectangle(0,0, 3*iPixelsPerInch-1, 2*jPixelsPerInch-1);
Brush.Color := clRed;
MoveTo (0,0);
LineTo (3*iPixelsPerInch-1, 2*jPixelsPerInch-1);
Brush.Color := clBlue;
MoveTo (0,0);
FOR i := 0 TO 3*iPixelsPerInch - 1 DO
BEGIN
x := 12*PI*(i / (3*iPixelsPerInch - 1));
y := jPixelsPerInch + jPixelsPerInch*SIN(x);
LineTo (i, TRUNC(y));
END
END;
Printer.Canvas.CopyRect(DestinationRectangle, OffScreen.Canvas,
SourceRectangle);
FINALLY
OffScreen.Free
END;
{Список шрифтов для данного принтера}
iBase := iPosition(750);
Printer.Canvas.Font.Name := 'Times New Roman';
Printer.Canvas.Font.Size := 12;
Printer.Canvas.Font.Style := [fsBold];
Printer.Canvas.TextOut(iBase, jPosition(40), 'Шрифты');
Printer.Canvas.Font.Style := [];
Printer.Canvas.Font.Size := 10;
jDelta := 16;
FOR j := 0 TO Printer.Fonts.Count - 1 DO
BEGIN
Printer.Canvas.TextOut(iBase, jPosition(60 + jDelta*j), Printer.Fonts.Strings[j])
END;
Printer.EndDoc;
end;
end.