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

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

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, , Right, Bottom

 и 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.

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

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...