HOW TO:使用 Visual C# .NET 打印 RichTextBox 控件的內容

概要

本分步指南介紹瞭如何打印 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”的內容。

原文鏈接HOW TO:使用 Visual C# .NET 打印 RichTextBox 控件的內容

發佈了27 篇原創文章 · 獲贊 10 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章