Сохранение точных размеров при печати

Previous  Top  Next

    
 

 

 

Приведенный ниже модуль демонстрирует принцип использования GetDeviceCaps для получения исчерпывающей информации о вашем принтере, включая HORZRES и VERTRES (горизонтальное и вертикальное разрешение в пикселах) на дюйм бумаги. Используя значения LOGPIXELSX и LOGPIXELSY, вы можете откалибровать принтер для точного задания количества точек на дюйм в горизонтальном и вертикальном направлениях.

 

В дополнение к информации о принтере, приведенный модуль демонстрирует способ печати, при котором изображение выводится на принтер "естественного" размера; также показана возможность размещения изображения на бумаге в определенной позиции и определенного размера (т.е. с применением масштабирования). Я думаю это должно вам помочь в деле управления принтером.

 

Пример также демонстрирует вывод на печать синусной кривой в конкретной позиции печати с заданными в дюймах размерами. Я думаю вы без труда разберетесь как перейти на метрическую систему размеров.

 

Code:

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.

 

©Drkb::03241

Взято из Советов по Delphi от Валентина Озерова

Сборник Kuliba