If you want to print text or graphics and have full control over the printing process, you should use the TPrinter class declared in the Printers unit.
In order to print with the TPrinter class, here's what you usually have to do:
Call the Printer function to obtain the global TPrinter instance.
Call the Printer BeginDoc method to begin a new print job.
Draw anything you want on the Printer Canvas.
Call the Printer NewPage method if you need to continue printing on a new page.
Call the Printer EndDoc method to end printing and to send the print job to the printer.
What follows is a short example of how to print a rectangle and a string using the TPrinter class and the global Printer object. The code uses the Printer PageWidth and PageHeight properties to determine the paper size so it can draw the page border.
procedure TMainForm.SimplePrintClick(Sender: TObject); begin Printer.BeginDoc; try Printer.Canvas.Font.Size := 36; Printer.Canvas.Rectangle(100, 100, Printer.PageWidth - 100, Printer.PageHeight - 100); Printer.Canvas.TextOut(150, 150, 'Printing with the TPrinter class!'); finally Printer.EndDoc; end; end;
The output of the above code is displayed in Figure 27-4.
Figure 27-4: Printing with the TPrinter class and the global Printer object
Now that you know how printing works, we can do something a bit more complex — print the entire contents of a TMemo component. This is actually a pretty simple feat, since you only have to do the following:
Determine the height of each line by calling the TextHeight method of the Printer Canvas.
Print all TMemo lines in a loop, using the simple TextOut method.
After a line is printed, test if the next line can be printed on the current page.
If the line cannot be printed on the current page, call the Printer NewPage method to create a new page and to continue printing on it.
The following listing shows how to print the entire contents of a TMemo, using the TMemo's font. Don't forget to read the comments because they explain in detail what's happening.
Listing 27-1: Printing the contents of a TMemo component
procedure TMainForm.MemoPrintClick(Sender: TObject); var i: Integer; yPos: Integer; lineHeight: Integer; begin { use the TMemo's font } Printer.Canvas.Font := Memo1.Font; { determine the line height } lineHeight := Printer.Canvas.TextHeight('W'); { start printing at the top of the page } yPos := 0; { start printing } Printer.BeginDoc; try for i := 0 to Pred(Memo1.Lines.Count) do begin { display the line at yPos } Printer.Canvas.TextOut(0, yPos, Memo1.Lines[i]); { increment the vertical position } Inc(yPos, lineHeight); { check if we can fit the next line into the page, and if we can't, create a new empty page } if yPos + lineHeight > Printer.PageHeight then begin { reset yPos to 0 to start painting at the top of the new page } yPos := 0; Printer.NewPage; end; // if yPos + lineHeight end; // for i finally Printer.EndDoc; end; // try..finally (Printer.BeginDoc) end;
The following figure shows the result of the above code.
Figure 27-5: Printing the contents of a TMemo component
Now that you know how to print an entire plain text file, we can start creating the TTextPrinter component, which supports margins and syntax highlighting.