📄 atbinhexprint.inc
字号:
{
ATBinHex printing code.
File must be included in ATBinHex.pas.
}
function TATBinHex.PrinterCaption: string;
begin
if FFileName <> '' then
Result := MsgViewerCaption + ' - ' + SExtractFileName(FFileName)
else
Result := MsgViewerCaption;
end;
function TATBinHex.PrinterFooter(APageNumber: Integer): WideString;
begin
if FFileName <> '' then
Result := SExtractFileName(FFileName) + ' - ' + IntToStr(APageNumber)
else
Result := IntToStr(APageNumber);
end;
function PrinterPageWidth: Integer;
begin
Result := Trunc(Printer.PageWidth / (GetDeviceCaps(Printer.Handle, LOGPIXELSX) / Screen.PixelsPerInch));
end;
function PrinterPageHeight: Integer;
begin
Result := Trunc(Printer.PageHeight / (GetDeviceCaps(Printer.Handle, LOGPIXELSY) / Screen.PixelsPerInch));
end;
function TATBinHex.MarginsRectPx(
ATargetWidth,
ATargetHeight: Integer;
ATargetPPIX,
ATargetPPIY: Integer): TRect;
const
cUnitIn = 2.54 * 10;
begin
Result := Rect(
Trunc(FMarginLeft / cUnitIn * ATargetPPIX),
Trunc(FMarginTop / cUnitIn * ATargetPPIY),
ATargetWidth - Trunc(FMarginRight / cUnitIn * ATargetPPIX),
ATargetHeight - Trunc(FMarginBottom / cUnitIn * ATargetPPIY)
);
end;
function TATBinHex.MarginsRectRealPx: TRect;
begin
Result := MarginsRectPx(
Printer.PageWidth,
Printer.PageHeight,
GetDeviceCaps(Printer.Handle, LOGPIXELSX),
GetDeviceCaps(Printer.Handle, LOGPIXELSY));
end;
(*
//Old printing procedure: prints the same in Text/Binary/Hex modes
//and doesn't support Unicode modes at all.
procedure TATBinHex.PrintOld;
const
BlockSize = 64 * 1024;
var
Buffer: array[0 .. BlockSize - 1] of Char;
PosStart, PosEnd: Int64;
BytesRead: DWORD;
SBuffer: string;
LenAll, Len: Int64;
f: TextFile;
begin
Printer.Canvas.Font := Self.Font;
//Not ActiveFont! We always use ANSI font here, because Windows
//doesn't allow to print by OEM fonts in most cases
//(it substitutes other font instead of a given one).
if ACopies > 0 then
Printer.Copies := ACopies
else
Printer.Copies := 1;
if ACaption <> '' then
Printer.Title := ACaption
else
Printer.Title := PrinterCaption;
if ASelectionOnly then
begin
PosStart := FSelStart;
PosEnd := FSelStart + FSelLength - 1;
end
else
begin
PosStart := 0;
PosEnd := PosLast;
end;
try
AssignPrn(f);
Rewrite(f);
try
repeat
if not ReadSource(PosStart, @Buffer, BlockSize, BytesRead) then
begin
MsgReadError;
Exit
end;
LenAll := PosEnd - PosStart + 1;
Len := LenAll;
I64LimitMax(Len, BytesRead);
SetString(SBuffer, Buffer, Len);
//OEM decoding:
if FEncoding = vencOEM then
SBuffer := ToANSI(SBuffer);
Write(f, SBuffer);
Inc(PosStart, BlockSize);
until (BytesRead < BlockSize) or (LenAll <= BytesRead);
finally
CloseFile(f);
end;
except
end;
end;
*)
const
cFooterColor =
clWhite;
//clYellow; //d
procedure TATBinHex.PrintTo(
ACanvas: TCanvas; //ACanvas may be assigned only for Print Preview
APageWidth,
APageHeight: Integer;
APrintRange: TPrintRange;
AFromPage,
AToPage: Integer);
var
APageNumber: Integer;
//
procedure DrawFooter(ACanvas: TCanvas; const ARect: TRect);
var
AText: WideString;
ALeft: Integer;
begin
AText := PrinterFooter(APageNumber);
ACanvas.Brush.Color := cFooterColor;
ACanvas.FillRect(ARect);
ACanvas.Font.Assign(FontFooter);
ALeft := (ARect.Right + ARect.Left - STextWidth(ACanvas, AText)) div 2;
ILimitMin(ALeft, ARect.Left);
STextOut(ACanvas, ALeft, ARect.Top, AText);
end;
//
procedure DrawRect(ACanvas: TCanvas; const ARect: TRect);
begin
ACanvas.Brush.Style := bsClear;
ACanvas.Pen.Color := clBlack;
ACanvas.Pen.Style := psDash;
ACanvas.Rectangle(ARect);
end;
//
function FooterHeightSrc: Integer;
var
C: TCanvas;
begin
C := TCanvas.Create;
try
C.Handle := Self.Handle;
C.Font.Assign(FontFooter);
Result := Trunc(FontHeight(C) * 1.2);
finally
C.Free;
end;
end;
//
var
APosStart, APosEnd,
APosOld, ASelStartOld, ASelLengthOld: Int64;
AViewPageSize: Int64;
AViewAtEnd: Boolean;
ABitmap,
ABitmapOld: TBitmap;
ATextWrapOld,
ATextNonPrintOld,
ATextGutterOld: Boolean;
AMarginsRect: TRect;
ADrawWidth,
ADrawHeight,
AFooterHeightSrc,
AFooterHeightReal: Integer;
APrintPreview,
APrintThisPage: Boolean;
begin
if (APrintRange = prSelection) then
begin
APosStart := FSelStart;
APosEnd := FSelStart + FSelLength - CharSize;
end
else
begin
APosStart := 0;
APosEnd := PosLast;
end;
//Calc margins
AMarginsRect := MarginsRectPx(
APageWidth,
APageHeight,
Screen.PixelsPerInch,
Screen.PixelsPerInch);
ADrawWidth := AMarginsRect.Right - AMarginsRect.Left;
ADrawHeight := AMarginsRect.Bottom - AMarginsRect.Top;
AFooterHeightSrc := FooterHeightSrc;
Dec(ADrawHeight, AFooterHeightSrc);
//Initialize
Enabled2 := False; //During printing even redraw is not allowed
//(it will break some properties)
ABitmap := TBitmap.Create;
ABitmap.PixelFormat := pf24bit;
APageNumber := 1;
//Prepare for printing:
// - scroll to block start
// - clear selection
// - set WordWrap = True
// - set NonPrintable = False
// - set Gutter = False
// - change active bitmap to working one
APosOld := PosOffset;
ASelStartOld := SelStart;
ASelLengthOld := SelLength;
ATextWrapOld := TextWrap;
ATextNonPrintOld := TextNonPrintable;
ATextGutterOld := TextGutter;
ABitmapOld := FBitmap;
PosOffset := APosStart;
SetSelection(0, 0, False, False);
FTextWrap := True;
FTextNonPrintable := False;
FTextGutter := False;
FBitmap := ABitmap;
try
repeat
DrawTo(
ABitmap,
ADrawWidth,
ADrawHeight,
nil, //AStringsObject not needed
True, //APrintMode
APosEnd, //AFinalPos
FTextWidth,
FTextWidthHex,
FTextWidthUHex,
AViewPageSize,
AViewAtEnd
);
APrintPreview := Assigned(ACanvas);
APrintThisPage :=
(APrintRange <> prPageNums) or
(APageNumber >= AFromPage);
if APrintThisPage then
begin //Drawing begin
if APrintPreview then
begin
ACanvas.Brush.Style := bsSolid;
ACanvas.Draw(
AMarginsRect.Left,
AMarginsRect.Top,
ABitmap);
DrawFooter(ACanvas, Rect(
AMarginsRect.Left,
AMarginsRect.Bottom - AFooterHeightSrc,
AMarginsRect.Right,
AMarginsRect.Bottom));
DrawRect(ACanvas, AMarginsRect);
Break; //Don't preview other pages
end
else
begin
AMarginsRect := MarginsRectRealPx;
AFooterHeightReal := Trunc(AFooterHeightSrc *
(GetDeviceCaps(Printer.Handle, LOGPIXELSY) / Screen.PixelsPerInch));
Printer.Canvas.StretchDraw(Rect(
AMarginsRect.Left,
AMarginsRect.Top,
AMarginsRect.Right,
AMarginsRect.Bottom - AFooterHeightReal),
ABitmap);
DrawFooter(Printer.Canvas, Rect(
AMarginsRect.Left,
AMarginsRect.Bottom - AFooterHeightReal,
AMarginsRect.Right,
AMarginsRect.Bottom));
//DrawRect(Printer.Canvas, AMarginsRect); //d
end;
end; //Drawing end
//If EOF reached then stop
if AViewAtEnd then Break;
if not FFileOK then Break;
//Move page down (not the same code as PosPageDown)
Inc(APageNumber);
case FMode of
vbmodeText,
vbmodeUnicode:
PosNextLine(LinesNum(ABitmap), vdirDown);
else
PosInc(LinesNum(ABitmap) * ColsNum);
end;
//If page is below the selection then stop
case APrintRange of
prPageNums:
if (APageNumber > AToPage) then Break;
else
if (FViewPos > APosEnd) then Break;
end;
//Change printer page
if APrintThisPage then
if not APrintPreview then
Printer.NewPage;
until False;
finally
//Restore saved properties
FBitmap := ABitmapOld;
FTextWrap := ATextWrapOld;
FTextNonPrintable := ATextNonPrintOld;
FTextGutter := ATextGutterOld;
SetSelection(ASelStartOld, ASelLengthOld, False, False);
PosOffset := APosOld;
//Finalize
ABitmap.Free;
Enabled2 := True;
end;
end;
{$ifdef PREVIEW}
type
TTextPreviewHelper = class
FBinHex: TATBinHex;
FPrintRange: TPrintRange;
FFromPage: Integer;
FToPage: Integer;
procedure Callback(
ACanvas: TCanvas;
AOptPosition: TATPrintPosition;
AOptFit: TATPrintFitMode;
AOptFitSize: TFloatSize;
const AOptMargins: TFloatRect;
const AOptGamma: Extended;
const AOptFooter: TATPrintFooter);
end;
procedure TTextPreviewHelper.Callback;
begin
FBinHex.PrintTo(
ACanvas,
PrinterPageWidth,
PrinterPageHeight,
FPrintRange,
FFromPage,
FToPage);
end;
{$endif}
procedure TATBinHex.Print(
APrintRange: TPrintRange;
AFromPage: Integer = 1;
AToPage: Integer = MaxInt;
ACopies: Integer = 1;
const ACaption: string = '');
begin
{$ifdef PREVIEW}
with TTextPreviewHelper.Create do
try
FBinHex := Self;
FPrintRange := APrintRange;
FFromPage := AFromPage;
FToPage := AToPage;
if not ShowTextPreviewDialog(Callback, False) then Exit;
finally
Free;
end;
{$endif}
if ACopies > 0 then
Printer.Copies := ACopies
else
Printer.Copies := 1;
if ACaption <> '' then
Printer.Title := ACaption
else
Printer.Title := PrinterCaption;
Printer.BeginDoc;
PrintTo(
nil,
PrinterPageWidth,
PrinterPageHeight,
APrintRange,
AFromPage,
AToPage);
Printer.EndDoc;
end;
procedure TATBinHex.PrintPreview;
begin
{$ifdef PREVIEW}
if (FSelLength <> 0) then
Print(prSelection)
else
Print(prAllPages);
{$endif}
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -