How to print the content of a RichTextBox control by using Visual C# .NET or Visual C# 2005

For a Microsoft Visual Basic .NET version of this article, see 811401.
SUMMARY
This step-by-step article describes how to print the content of a RichTextBox control. The RichTextBox control does not provide any method to print the content of the RichTextBox. You can extend the RichTextBox class to use EM_FORMATRANGE message to send the content of a RichTextBox control to an output device such as printer.

Create RichTextBoxPrintCtrl Control

The following sample describes how to extend the RichTextBox class, and how to use EM_FORMATRANGE to print the content of the RichTextBox control.
  1. In Visual C# .NET or Visual C# 2005, create a new Class Library project that is named RichTextBoxPrintCtrl. By default, Class1.cs is created.
  2. Change the name of Class1.cs to RichTextBoxPrintCtrl.cs.
  3. In Solution Explorer, right-click References, and then click Add Reference.
  4. In the Add Reference dialog box, double-click System.Drawing.dll and System.Windows.Forms.dll, and then click OK.
  5. Replace the existing code in RichTextBoxPrintCtrl.cs with the following code:
    using System;using System.Windows.Forms;using System.Drawing;using System.Runtime.InteropServices;using System.Drawing.Printing;namespace RichTextBoxPrintCtrl{	public class RichTextBoxPrintCtrl:RichTextBox	{		//Convert the unit used by the .NET framework (1/100 inch) 		//and the unit used by Win32 API calls (twips 1/1440 inch)		private const double anInch = 14.4;		[StructLayout(LayoutKind.Sequential)] 			private struct RECT		{			public int Left;			public int Top;			public int Right;			public int Bottom;		}		[StructLayout(LayoutKind.Sequential)]			private struct CHARRANGE		{			public int cpMin;         //First character of range (0 for start of doc)			public int cpMax;           //Last character of range (-1 for end of doc)		}		[StructLayout(LayoutKind.Sequential)]			private struct FORMATRANGE		{			public IntPtr hdc;             //Actual DC to draw on			public IntPtr hdcTarget;       //Target DC for determining text formatting			public RECT rc;                //Region of the DC to draw to (in twips)			public RECT rcPage;            //Region of the whole DC (page size) (in twips)			public CHARRANGE chrg;         //Range of text to draw (see earlier declaration)		}		private const int WM_USER  = 0x0400;		private const int EM_FORMATRANGE  = WM_USER + 57;				[DllImport("USER32.dll")]		private static extern IntPtr SendMessage (IntPtr hWnd , int msg , IntPtr wp, IntPtr lp); 		// Render the contents of the RichTextBox for printing		//	Return the last character printed + 1 (printing start from this point for next page)		public int Print( int charFrom, int charTo,PrintPageEventArgs e)		{			//Calculate the area to render and print			RECT rectToPrint; 			rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);			rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);			rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);			rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);			//Calculate the size of the page			RECT rectPage; 			rectPage.Top = (int)(e.PageBounds.Top * anInch);			rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);			rectPage.Left = (int)(e.PageBounds.Left * anInch);			rectPage.Right = (int)(e.PageBounds.Right * anInch);			IntPtr hdc = e.Graphics.GetHdc();			FORMATRANGE fmtRange;			fmtRange.chrg.cpMax = charTo;				//Indicate character from to character to 			fmtRange.chrg.cpMin = charFrom;			fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering			fmtRange.hdcTarget = hdc;              //Point at printer hDC			fmtRange.rc = rectToPrint;             //Indicate the area on page to print			fmtRange.rcPage = rectPage;            //Indicate size of page			IntPtr res = IntPtr.Zero;			IntPtr wparam = IntPtr.Zero;			wparam = new IntPtr(1);			//Get the pointer to the FORMATRANGE structure in memory			IntPtr lparam= IntPtr.Zero;			lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));			Marshal.StructureToPtr(fmtRange, lparam, false);			//Send the rendered data for printing 			res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);			//Free the block of memory allocated			Marshal.FreeCoTaskMem(lparam);			//Release the device context handle obtained by a previous call			e.Graphics.ReleaseHdc(hdc);			//Return last + 1 character printer			return res.ToInt32();		}	}}
  6. On the Build menu, click Build Solution to create RichTextBoxPrintCtrl.dll.

Test the Control

  1. In Visual C# .NET or Visual C# 2005, create a new Windows Application project. By default, Form1.cs is created.

    Note The code should be changed in Visual Studio 2005. When you create a Windows Forms project, Visual C# adds one form to the project by default. This form is named Form1. The two files that represent the form are named Form1.cs and Form1.designer.cs. You write your code in Form1.cs. The Designer.cs file is where the Windows Forms Designer writes the code that implements all the actions that you performed by adding controls.For more information about the Windows Forms Designer in Visual C# 2005, visit the following Microsoft Web site:
  2. Drag a Button control from the toolbox to Form1. Change the Name property to btnPageSetup, and the Text property to Page Setup.
  3. Drag another Button control from the toolbox to Form1. Change the Name property to btnPrintPreview, and the Text property to Print Preview.
  4. Drag another Button control from the toolbox to Form1. Change the Name property to btnPrint, and the Text property to Print.
  5. In the toolbox, double-click PrintDialog, PrintPreviewDialog, PrintDocument, and PageSetupDialog to add these controls to Form1.
  6. Modify the Document properties of the PrintDialog1, the PrintPreviewDialog1, and the PageSetupDialog1 controls to PrintDocument1.
  7. On the Tools menu, click Customize Toolbox.
  8. On the .NET Framework Components tab, click Browse, click to select RichTextBoxPrintCtrl.dll, and then click OK.
  9. Drag RichTextBoxPrintCtrl from the toolbox to Form1.
  10. In Solution Explorer, right-click Form1.cs, and then click View Code.
  11. Append the following code to the InitializeComponent method:
    		this.printDocument1.BeginPrint += new System.Drawing.Printing.PrintEventHandler(this.printDocument1_BeginPrint);		this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);		this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click);		this.btnPrintPreview.Click += new System.EventHandler(this.btnPrintPreview_Click);		this.btnPageSetup.Click += new System.EventHandler(this.btnPageSetup_Click);
  12. Add the following code to the class Form1:
    		private int checkPrint;		private void btnPageSetup_Click(object sender, System.EventArgs e)		{			pageSetupDialog1.ShowDialog();		}		private void btnPrintPreview_Click(object sender, System.EventArgs e)		{			printPreviewDialog1.ShowDialog();		}		private void btnPrint_Click(object sender, System.EventArgs e)		{			if (printDialog1.ShowDialog() == DialogResult.OK)				printDocument1.Print();		}		private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)		{			checkPrint = 0;		}		private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)		{			// Print the content of RichTextBox. Store the last character printed.			checkPrint = richTextBoxPrintCtrl1.Print(checkPrint, richTextBoxPrintCtrl1.TextLength, e);			// Check for more pages			if (checkPrint < richTextBoxPrintCtrl1.TextLength)				e.HasMorePages = true;			else				e.HasMorePages = false;		}
  13. On the Debug menu, click Start to run the application. Form1 is displayed.
  14. Type some text in RichTextBoxPrintCtrl.
  15. Click Page Setup to set the page settings.
  16. Click Print Preview to view the print preview of the page.
  17. Click Print to print the content of RichTextBoxPrintCtrl.
REFERENCES
For additional information, see the following topic in the Microsoft .NET Framework SDK Documentation:
RichTextBox Class
http://msdn2.microsoft.com/en-us/library/system.windows.forms.richtextbox(vs.71).aspx

Properties

Article ID: 812425 - Last Review: 11/13/2007 09:46:36 - Revision: 3.4

Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# 2005 Express Edition

  • kbprint kbwindowsforms kbinheritance kbctrl kbcontrol kbhowtomaster kbhowto KB812425
Feedback