반응형
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.
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.
반응형