Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
{
The following example project
shows how to print a memos lines, but you can as well use
listbox.items, it will work with every TStrings descendent, even a
TStirnglist.
}
unit PrintStringsUnit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls;
type
TForm1 = class
(TForm)
Memo1: TMemo;
Button1: TButton;
procedure
Button1Click(Sender : TObject);
private
{ Private declarations }
procedure
PrintHeader(aCanvas : TCanvas; aPageCount : integer;
aTextrect : TRect; var
Continue : boolean);
procedure
PrintFooter(aCanvas : TCanvas; aPageCount : integer;
aTextrect : TRect; var
Continue : boolean);
public
{ Public declarations }
end
;
var
Form1 : TForm1;
implementation
uses
Printers;
{$R *.DFM}
type
THeaderFooterProc =
procedure
(aCanvas : TCanvas; aPageCount : integer;
aTextrect : TRect; var
Continue : boolean) of
object
;
{ Prototype for a callback method that PrintString will call
when it is time to print a header or footer on a page. The
parameters that will be passed to the callback are:
aCanvas : the canvas to output on
aPageCount: page number of the current page, counting from 1
aTextRect : output rectangle that should be used. This will be
the area available between non-printable margin and
top or bottom margin, in device units (dots). Output
is not restricted to this area, though.
continue : will be passed in as True. If the callback sets it
to false the print job will be aborted. }
{+------------------------------------------------------------
| Function PrintStrings
|
| Parameters :
| lines:
| contains the text to print, already formatted into
| lines of suitable length. No additional wordwrapping
| will be done by this routine and also no text clipping
| on the right margin!
| leftmargin, topmargin, rightmargin, bottommargin:
| define the print area. Unit is inches, the margins are
| measured from the edge of the paper, not the printable
| area, and are positive values! The margin will be adjusted
| if it lies outside the printable area.
| linesPerInch:
| used to calculate the line spacing independent of font
| size.
| aFont:
| font to use for printout, must not be Nil.
| measureonly:
| If true the routine will only count pages and not produce any
| output on the printer. Set this parameter to false to actually
| print the text.
| OnPrintheader:
| can be Nil. Callback that will be called after a new page has
| been started but before any text has been output on that page.
| The callback should be used to print a header and/or a watermark
| on the page.
| OnPrintfooter:
| can be Nil. Callback that will be called after all text for one
| page has been printed, before a new page is started. The callback
| should be used to print a footer on the page.
| Returns:
| number of pages printed. If the job has been aborted the return
| value will be 0.
| Description:
| Uses the Canvas.TextOut function to perform text output in
| the rectangle defined by the margins. The text can span
| multiple pages.
| Nomenclature:
| Paper coordinates are relative to the upper left corner of the
| physical page, canvas coordinates (as used by Delphis Printer.Canvas)
| are relative to the upper left corner of the printable area. The
| printorigin variable below holds the origin of the canvas coordinate
| system in paper coordinates. Units for both systems are printer
| dots, the printers device unit, the unit for resolution is dots
| per inch (dpi).
| Error Conditions:
| A valid font is required. Margins that are outside the printable
| area will be corrected, invalid margins will raise
an EPrinter
| exception.
| Created: 13.05.99 by P. Below
+------------------------------------------------------------}
function
PrintStrings(Lines : TStrings;
const
leftmargin, rightmargin,
topmargin, bottommargin: single;
const
linesPerInch: single;
aFont: TFont;
measureonly: Boolean;
OnPrintheader,
OnPrintfooter: THeaderFooterProc): Integer;
var
continuePrint: Boolean; { continue/abort flag for callbacks }
pagecount: Integer; { number of current page }
textrect: TRect; { output area, in canvas coordinates }
headerrect: TRect; { area for header, in canvas
coordinates }
footerrect: TRect; { area for footes, in canvas
coordinates }
lineheight: Integer; { line spacing in dots }
charheight: Integer; { font height in dots }
textstart: Integer; { index of first line to print on
current page, 0-based. }
{ Calculate text output and header/footer rectangles. }
procedure
CalcPrintRects;
var
X_resolution : Integer; { horizontal printer resolution, in dpi }
Y_resolution : Integer; { vertical printer resolution, in dpi }
pagerect : TRect; { total page, in paper coordinates }
printorigin : TPoint; { origin of canvas coordinate system in
paper coordinates. }
{ Get resolution, paper size and non-printable margin from
printer driver. }
procedure
GetPrinterParameters;
begin
with
Printer.Canvas do
begin
X_resolution := GetDeviceCaps(Handle, LOGPIXELSX);
Y_resolution := GetDeviceCaps(Handle, LOGPIXELSY);
printorigin.X := GetDeviceCaps(Handle, PHYSICALOFFSETX);
printorigin.Y := GetDeviceCaps(Handle, PHYSICALOFFSETY);
pagerect.Left := 0;
pagerect.Right := GetDeviceCaps(Handle, PHYSICALWIDTH);
pagerect.Top := 0;
pagerect.Bottom := GetDeviceCaps(Handle, PHYSICALHEIGHT);
end
; { With }
end
; { GetPrinterParameters }
{ Calculate area between the requested margins, paper-relative.
Adjust margins if they fall outside the printable area.
Validate the margins, raise EPrinter exception if no text area
is left. }
procedure
CalcRects;
var
max : integer;
begin
with
textrect do
begin
{ Figure textrect in paper coordinates }
Left := Round(leftmargin * X_resolution);
if
Left < printorigin.x then
Left := printorigin.x;
Top := Round(topmargin * Y_resolution);
if
Top < printorigin.y then
Top := printorigin.y;
{ Printer.PageWidth and PageHeight return the size of the
printable area, we need to add the printorigin to get the
edge of the printable area in paper coordinates. }
Right := pagerect.Right - Round(rightmargin * X_resolution);
max := Printer.PageWidth + printorigin.X;
if
Right > max then
Right := max;
Bottom := pagerect.Bottom - Round(bottommargin *
Y_resolution);
max := Printer.PageHeight + printorigin.Y;
if
Bottom > max then
Bottom := max;
{ Validate the margins. }
if
(Left >= Right) or
(Top >= Bottom) then
raise
EPrinter.Create('PrintString: the supplied margins are too large, there'
+
'is no area to print left on the page.');
end
; { With }
{ Convert textrect to canvas coordinates. }
OffsetRect(textrect, - printorigin.X, - printorigin.Y);
{ Build header and footer rects. }
headerrect := Rect(textrect.Left, 0,
textrect.Right, textrect.Top);
footerrect := Rect(textrect.Left, textrect.Bottom,
textrect.Right, Printer.PageHeight);
end
; { CalcRects }
begin
{ CalcPrintRects }
GetPrinterParameters;
CalcRects;
lineheight := round(Y_resolution / linesPerInch);
end
; { CalcPrintRects }
{ Print a page with headers and footers. }
procedure
PrintPage;
procedure
FireHeaderFooterEvent(event : THeaderFooterProc; r : TRect);
begin
if
Assigned(event) then
begin
event(Printer.Canvas,
pagecount,
r,
ContinuePrint);
{ Revert to our font, in case event handler changed
it. }
Printer.Canvas.Font := aFont;
end
; { If }
end
; { FireHeaderFooterEvent }
procedure
DoHeader;
begin
FireHeaderFooterEvent(OnPrintHeader, headerrect);
end
; { DoHeader }
procedure
DoFooter;
begin
FireHeaderFooterEvent(OnPrintFooter, footerrect);
end
; { DoFooter }
procedure
DoPage;
var
y : integer;
begin
y := textrect.Top;
while
(textStart < Lines.Count) and
(y <= (textrect.Bottom - charheight)) do
begin
{ Note: use TextRect instead of TextOut to effect clipping
of the line on the right margin. It is a bit slower,
though. The clipping rect would be
Rect( textrect.left, y, textrect.right, y+charheight). }
printer.Canvas.TextOut(textrect.Left, y, Lines[textStart]);
Inc(textStart);
Inc(y, lineheight);
end
; { While }
end
; { DoPage }
begin
{ PrintPage }
DoHeader;
if
ContinuePrint then
begin
DoPage;
DoFooter;
if
(textStart < Lines.Count) and
ContinuePrint then
begin
Inc(pagecount);
Printer.NewPage;
end
; { If }
end
;
end
; { PrintPage }
begin
{ PrintStrings }
Assert(Assigned(afont),
'PrintString: requires a valid aFont parameter!');
continuePrint := True;
pagecount := 1;
textstart := 0;
Printer.BeginDoc;
try
CalcPrintRects;
{$IFNDEF WIN32}
{ Fix for Delphi 1 bug. }
Printer.Canvas.Font.PixelsPerInch := Y_resolution;
{$ENDIF }
Printer.Canvas.Font := aFont;
charheight := printer.Canvas.TextHeight('Дy');
while
(textstart < Lines.Count) and
ContinuePrint do
PrintPage;
finally
if
continuePrint and
not
measureonly then
Printer.EndDoc
else
begin
Printer.Abort;
end
;
end
;
if
continuePrint then
Result := pagecount
else
Result := 0;
end
; { PrintStrings }
procedure
TForm1.Button1Click(Sender : TObject);
begin
ShowMessage(Format('%d pages printed',
[PrintStrings(memo1.Lines,
0.75, 0.5, 0.75, 1,
6,
memo1.Font,
False,
PrintHeader, PrintFooter)
]));
end
;
procedure
TForm1.PrintFooter(aCanvas : TCanvas; aPageCount : integer;
aTextrect : TRect; var
Continue : boolean);
var
S: string
;
res: integer;
begin
with
aCanvas do
begin
{ Draw a gray line one point wide below the text }
res := GetDeviceCaps(Handle, LOGPIXELSY);
pen.Style := psSolid;
pen.Color := clGray;
pen.Width := Round(res / 72);
MoveTo(aTextRect.Left, aTextRect.Top);
LineTo(aTextRect.Right, aTextRect.Top);
{ Print the page number in Arial 8pt, gray, on right side of
footer rect. }
S := Format('Page %d', [aPageCount]);
Font.Name := 'Arial';
Font.Size := 8;
Font.Color := clGray;
TextOut(aTextRect.Right - TextWidth(S), aTextRect.Top + res div
18,
S);
end
;
end
;
procedure
TForm1.PrintHeader(aCanvas : TCanvas; aPageCount : integer;
aTextrect : TRect; var
Continue : boolean);
var
res: Integer;
begin
with
aCanvas do
begin
{ Draw a gray line one point wide 4 points above the text }
res := GetDeviceCaps(Handle, LOGPIXELSY);
pen.Style := psSolid;
pen.Color := clGray;
pen.Width := Round(res / 72);
MoveTo(aTextRect.Left, aTextRect.Bottom - res div
18);
LineTo(aTextRect.Right, aTextRect.Bottom - res div
18);
{ Print the company name in Arial 8pt, gray, on left side of
footer rect. }
Font.Name := 'Arial';
Font.Size := 8;
Font.Color := clGray;
TextOut(aTextRect.Left, aTextRect.Bottom - res div
10 -
TextHeight('W'),
'W. W. Shyster & Cie.');
end
;
end
;
end
.