概要
本分步指南介紹了如何打印 RichTextBox 控件的內容。 RichTextBox 控件沒有提供任何打印 RichTextBox 內容的方法。您可以擴展 RichTextBox 類以使用 EM_FORMATRANGE 消息將 RichTextBox 控件的內容發送到一個輸出設備(如打印機)。返回頁首
創建 RichTextBoxPrintCtrl 控件
下面的示例介紹了如何擴展 RichTextBox 類,以及如何使用 EM_FORMATRANGE 打印 RichTextBox 控件的內容。- 在 Visual C# .NET 中,新建一個名為 RichTextBoxPrintCtrl 的類庫項目。默認情況下創建 Class1.cs。
- 將 Class1.cs 的名稱改為 RichTextBoxPrintCtrl.cs。
- 在解決方案資源管理器中,右鍵單擊“引用”,然后單擊“添加引用”。
- 在“添加引用”對話框中,雙擊“System.Drawing.dll”和“System.Windows.Forms.dll”,然后單擊“確定”。
- 將 RichTextBoxPrintCtl.cs 中的現有代碼替換為以下代碼:
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(); } } }
- 在“生成”菜單中,單擊“生成解決方案”以創建 RichTextBoxPrintCtrl.dll。
測試控件
- 在 Visual C# .NET 中創建一個新的 Windows 應用程序項目。默認情況下將創建出 Form1.cs。
- 將一個按鈕控件從工具箱拖入 Form1。將 Name 屬性更改為 btnPageSetup,並將 Text 屬性更改為頁面設置。
- 將另一個按鈕控件從工具箱拖入 Form1。將 Name 屬性更改為 btnPrintPreview,並將 Text 屬性更改為打印預覽。
- 將另一個按鈕控件從工具箱拖入 Form1。將 Name 屬性更改為 btnPrint,並將 Text 屬性更改為打印。
- 在工具箱中,雙擊“PrintDialog”、“PrintPreviewDialog”、“PrintDocument”和“PageSetupDialog”以將這些控件添加到 Form1 中。
- 將 PrintDialog1、PrintPreviewDialog1 和 PageSetupDialog1 控件的 Document 屬性修改為 PrintDocument1。
- 在“工具”菜單上,單擊“自定義工具箱”。
- 在“.NET Framework 組件”選項卡上,單擊“瀏覽”,單擊以選中“RichTextBoxPrintCtrl.dll”,然后單擊“確定”。
- 將 RichTextBoxPrintCtrl 從工具箱拖入 Form1。
- 在解決方案資源管理器中,右鍵單擊 Form1.cs,然后單擊查看代碼。
- 將以下代碼添加到 InitializeComponent 方法中:
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);
- 將下面的代碼添加到 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; }
- 在“調試”菜單上,單擊“啟動”以運行該應用程序。Form1 將顯示出來。
- 在 RichTextBoxPrintCtrl 中鍵入一些文本。
- 單擊“頁面設置”以設置頁面設置。
- 單擊“打印預覽”以查看頁面的打印預覽。
- 單擊“打印”以打印“RichTextBoxPrintCtrl”的內容。