본문 바로가기
Application/Delphi Lecture

Print Preview in Delphi for .NET

by 현이빈이 2008. 8. 13.
반응형
This is a simple demo of how you can integrate a .NET compiler into your applications and compile and use the code at runtime.

How does this all work.

For this example i created a simple form with a button on it. Pressing this button starts a OpenFile Dialog and when you select a text file it renders this file to a Preview component.

To print you need to create a PrintDocument component. For this sample i created a new Class wich is specialized in printing text files.
I created a TTextFilePrintDocument component for handling the reading of a stream and printing to the canvas as long as there are lines in the stream.

The most important routine of this all is the OnPrintPage routine.

  procedure TTextFilePrintDocument.OnPrintPage(aPrintPageEventArgs: PrintPageEventArgs);


Next we copy some information from te Args we received with the call to local vars.

  leftMargin := aPrintPageEventArgs.MarginBounds.Left;
  topMargin := aPrintPageEventArgs.MarginBounds.Top;
  lpp := aPrintPageEventArgs.MarginBounds.Height  / FPrintFont.GetHeight(aPrintPageEventArgs.Graphics);
  Line := FStreamToPrint.ReadLine;

We tell the caller that we have stil more pages to print and start printing lines. The Lpp is filled with the number of lines we can print on this page. Note: we don't do wordwrap in this demo. In this routine where all lines are printed notice the (System.String(Line) = NIL) this is done to detect the end of the stream. The actual string isn't '' but a not assigned string.

  aPrintPageEventArgs.HasMorePages := true;
  while (count < lpp) do
  begin
    if Count <> 0
 then
      Line := FStreamToPrint.ReadLine;
    if (System.String(Line) = NIL) then
    begin
      aPrintPageEventArgs.HasMorePages := false;
      break;
    end
    else
    begin
      yPos := topMargin + (count * FPrintFont.GetHeight(aPrintPageEventArgs.Graphics));
      aPrintPageEventArgs.Graphics.DrawString (line, FPrintFont, Brushes.Black, leftMargin, yPos, StringFormat.Create);
      inc(Count);
    end;
  end;
end;

For more info look at the source code. As told earlier the routine above is the power of the printing.













program PrintPreviewSample;
uses
  System.Drawing,
  System.Drawing.Printing,
  System.IO,
  System.Collections,
  System.ComponentModel,
  System.Windows.Forms,
  System.Data;

type
  TTextFilePrintDocument = class(PrintDocument)
  private
   FPrintFont: Font;
   FStreamToPrint: StreamReader;
  protected
    procedure OnBeginPrint(aPrintEventArgs: PrintEventArgs); override;
    procedure OnPrintPage(aPrintPageEventArgs: PrintPageEventArgs); override;
  public
   constructor Create(AStreamToPrint: StreamReader); virtual;
  published
  end;

   TPreviewSampleForm = class(System.Windows.Forms.Form)
   private
    FFileName: string;
  protected
    procedure InitializeComponents; virtual;
    procedure PreviewClick(sender: System.Object; eventArgs:System.EventArgs);
  public
    PreviewButton: Button;
    AOpenFileDialog: System.Windows.Forms.OpenFileDialog;
    constructor Create; virtual;
  published
  end;

constructor TTextFilePrintDocument.Create(AStreamToPrint: StreamReader);
begin
  inherited Create;
  FStreamToPrint := AStreamToPrint;
end;

procedure TTextFilePrintDocument.OnBeginPrint(aPrintEventArgs: PrintEventArgs);
begin
  inherited OnBeginPrint(aPrintEventArgs);
  FPrintFont:=Font.Create('Arial'
, 10);
end;

procedure TTextFilePrintDocument.OnPrintPage(aPrintPageEventArgs: PrintPageEventArgs);
var
  lpp, yPos, leftMargin, topMargin: Double;
  count: integer;
  Line: string;
begin
  inherited OnPrintPage(aPrintPageEventArgs);
  count := 0
;
  leftMargin := aPrintPageEventArgs.MarginBounds.Left;
  topMargin := aPrintPageEventArgs.MarginBounds.Top;
  line := ''
;

  lpp := aPrintPageEventArgs.MarginBounds.Height  / FPrintFont.GetHeight(aPrintPageEventArgs.Graphics);
  Line := FStreamToPrint.ReadLine;
  aPrintPageEventArgs.HasMorePages := true;
  while (count < lpp) do
  begin
    if Count <> 0
 then
      Line := FStreamToPrint.ReadLine;
    if (System.String(Line) = NIL) then
    begin
      aPrintPageEventArgs.HasMorePages := false;
      break;
    end
    else
    begin
      yPos := topMargin + (count * FPrintFont.GetHeight(aPrintPageEventArgs.Graphics));
      aPrintPageEventArgs.Graphics.DrawString (line, FPrintFont, Brushes.Black, leftMargin, yPos, StringFormat.Create);
      inc(Count);
    end;
  end;
end;



constructor TPreviewSampleForm.Create;
begin
  inherited Create;
  AOpenFileDialog := System.Windows.Forms.OpenFileDialog.Create;
  InitializeComponents;
end;


procedure TPreviewSampleForm.PreviewClick(sender: System.Object; eventArgs:System.EventArgs);
var
  StreamToPrint: StreamReader;
  TextFilePrintDocument: TTextFilePrintDocument;
  Dlg: PrintPreviewDialog;
begin
  if (FFileName = ''
) and (AOpenFileDialog.ShowDialog = DialogResult.OK) then
    FFileName := AOpenFileDialog.FileName;
  if FFileName <> ''
 then
  begin
    StreamToPrint := StreamReader.Create(FFileName);
    try
      TextFilePrintDocument := TTextFilePrintDocument.Create(StreamToPrint);
      Dlg := PrintPreviewDialog.Create;
      Dlg.Document := TextFilePrintDocument;
      Dlg.FindForm.StartPosition := FormStartPosition.CenterScreen;
      Dlg.ShowDialog;
    finally
      StreamToPrint.Close
    end;
  end;
end;

procedure TPreviewSampleForm.InitializeComponents;
begin
  self.PreviewButton := System.Windows.Forms.Button.Create;
  self.SuspendLayout;

  // PreviewButton

  with PreviewButton do
  begin
    Location := System.Drawing.Point.Create(168
, 40);
    Name := 'PreviewButton'
;
    TabIndex := 0
;
    Text := 'Preview..'
;
    Add_Click(PreviewClick);
    Parent := Self;
  end;

  // TPreviewSampleForm

  self.AutoScaleBaseSize := System.Drawing.Size.Create(5
, 13);
  self.ClientSize := System.Drawing.Size.Create(292
, 273);

  self.Name := 'PreviewSample'
;
  self.Text := '.NET Preview sample'
;
  self.ResumeLayout(false);
end;

var
 PreviewSampleForm: TPreviewSampleForm;

begin
 PreviewSampleForm := TPreviewSampleForm.Create;
 Application.Run(PreviewSampleForm);
end.
반응형