Click here to Skip to main content
13,553,626 members
Click here to Skip to main content
Add your own
alternative version


59 bookmarked
Posted 20 Apr 2005

How to print text in C#

, 20 Apr 2005
Rate this:
Please Sign up or sign in to vote.
How printing works in Multipad, a Notepad clone.


Multipad is my Notepad clone. It also has the typical Page Setup, Print Preview and Print menu items. Read on if you want to know how printing works in Multipad. It is best to download the source code and take a look at it while reading the article.

The PrintDocument

PrintDocument is a .NET class which glues together the page settings, the printer settings, the data to print and the print logic. For Multipad, I derived a class from PrintDocument called MultipadPrintDocument. It has properties to set the text (which can contain Environment.NewLines) and the font.

MultipadPrintDocument implements the virtual methods OnBeginPrint() and OnPrintPage(). OnBeginPrint() sets the pointer to the current character (_offset) to 0 and the current page number to 1.

OnPrintPage() has one parameter of type PrintPageEventArgs. When the system calls OnPrintPage(), we have to typeset the page using the Graphics object in the PrintPageEventArgs parameter. We typeset the page by printing lines of text until the page is full or until we reach the end of the text. The PrintPageEventArgs parameter has a property MarginBounds which contains the page size. Unfortunately, the dimensions are expressed in hundredths of an inch. In .NET, there is no GraphicsUnit which represents a hundredth of an inch. Because we're going to measure strings in GraphicsUnit.Document (1/300th of an inch), we convert the page dimensions by multiplying them with 3. Now we're ready to start printing the lines of the text.

First, we create a StringBuilder which will hold the text of a single line. We also create a GenericTypographic StringFormat object. It's very important to use GenericTypographic because otherwise, MeasureString() and DrawString() wouldn't behave as expected. We also set the tab stops: if a line of text contains tabs, the text will be formatted correctly (the tabs will not be replaced with spaces, they will act as real tabs). Finally, we set the PageUnit property of the Graphics object to GraphicsUnit.Document.

Before we start filling the page with lines, we check to see if there is enough space to print at least four lines: one line of text and three lines for the page number (two empty lines above the page number). If there isn't enough room, we simply leave the page blank. This situation should rarely occur.

Now we're ready to break up the text in lines. We read the text string one character at a time. We add the character to the line buffer (the StringBuilder object), except if the character is a NewLine or Eos (end of string). Note that NewLine is "\r\n" in Windows or "\n" in Unix, so we have to keep in mind that we don't simply skip one character but Environment.NewLine.Length characters (yes, we strive to perfection). If the character is a space or a tab, we save this position because when the line is full, we don't want to break the line in the middle of a word, no, we will print the line up to the last tab or space. For example, if we have the line "The quick brown ... lazy dog." and the line overflows at the 'd' of "dog", we will begin the next line with "dog" instead of "og". If the last character is a space or tab, we continue to add these characters. This way, the next line will never start with white space. If the line overflows or we encounter a NewLine or Eos, we print the text in the line buffer. Then we increment the y position of the next line and empty the line buffer. If there's still room for a new line of text and we still have text to print, we continue the loop; if not, we exit the loop, print the page number at the bottom of the page, increment the page number and set the property HasMorePages of the PrintPageEventArgs parameter to true if there's still text to print, otherwise we set it to false.

Using MultipadPrintDocument in your own code

If you want to use MultipadPrintDocument in your own code, it's best to rename the class and its constructor to something more appropriate. Then add a variable of type XXXPrintDocument to your form and implement the menu items as follows:

void OnFilePrint(Object sender, EventArgs e)
    PrintDialog pd = new PrintDialog();
    _printdocument.Text = _multipadbox.Text;
    _printdocument.Font = _multipadbox.Font;
    pd.Document = _printdocument;

void OnFilePrintPreview(Object sender, EventArgs e)
    PrintPreviewDialog ppd = new PrintPreviewDialog();
    _printdocument.Text = _multipadbox.Text;
    _printdocument.Font = _multipadbox.Font;
    ppd.Document = _printdocument;

void OnFilePageSetup(Object sender, EventArgs e)
    PageSetupDialog psd = new PageSetupDialog();
    psd.Document = _printdocument;


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Mike Finnegan
Belgium Belgium
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralMy vote of 3 Pin
yoke15-Sep-12 17:35
memberyoke15-Sep-12 17:35 
GeneralMy vote of 5 Pin
manoj kumar choubey26-Feb-12 21:22
membermanoj kumar choubey26-Feb-12 21:22 
Questiondifferent lines with different Font, size etc. Pin
sunrise0074-Jul-11 3:22
membersunrise0074-Jul-11 3:22 
AnswerRe: different lines with different Font, size etc. Pin
Mike Finnegan6-Jul-11 21:30
memberMike Finnegan6-Jul-11 21:30 
GeneralThanks Pin
Justin Porter4-Aug-08 5:33
memberJustin Porter4-Aug-08 5:33 
GeneralNice code Pin
Mickey_Inside30-Dec-06 4:20
memberMickey_Inside30-Dec-06 4:20 
GeneralCool. Pin
steve_99999999999999999999910-Aug-06 4:56
membersteve_99999999999999999999910-Aug-06 4:56 
GeneralRe: Cool. Pin
q12345678910-Aug-06 21:56
memberq12345678910-Aug-06 21:56 
GeneralA question about printing Pin
TimothyP11-Apr-06 11:49
memberTimothyP11-Apr-06 11:49 
GeneralRe: A question about printing Pin
q12345678911-Apr-06 23:05
memberq12345678911-Apr-06 23:05 
GeneralPrint Setup Pin
Pheonix Blade1-Mar-06 20:48
memberPheonix Blade1-Mar-06 20:48 
GeneralRe: Print Setup Pin
q1234567892-Mar-06 2:23
memberq1234567892-Mar-06 2:23 
GeneralRe: Print Setup Pin
webstorm10-Apr-07 8:29
memberwebstorm10-Apr-07 8:29 
GeneralRe: Print Setup Pin
Wolfram Steinke11-Apr-07 12:39
memberWolfram Steinke11-Apr-07 12:39 
GeneralRe: Print Setup Pin
Xeor8228-Nov-07 7:15
memberXeor8228-Nov-07 7:15 
GeneralPreview Pin
Rom200029-Aug-05 23:42
memberRom200029-Aug-05 23:42 
GeneralRe: Preview Pin
Anonymous31-Aug-05 1:15
sussAnonymous31-Aug-05 1:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02-2016 | 2.8.180515.1 | Last Updated 21 Apr 2005
Article Copyright 2005 by Mike Finnegan
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid