打印 RichTextBox

创建 RichTextBoxPrintCtrl 控件

下面的示例介绍了如何扩展 RichTextBox 类,以及如何使用 EM_FORMATRANGE 打印 RichTextBox 控件的内容。

1.在 Visual C# .NET 中,新建一个名为 RichTextBoxPrintCtrl 的类库项目。默认情况下创建 Class1.cs。
2.将 Class1.cs 的名称改为 RichTextBoxPrintCtrl.cs。
3.在解决方案资源管理器中,右键单击“引用”,然后单击“添加引用”。
4.在“添加引用”对话框中,双击“System.Drawing.dll”和“System.Windows.Forms.dll”,然后单击“确定”。
5.将 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();
  }
 }
}
6.在“生成”菜单中,单击“生成解决方案”以创建 RichTextBoxPrintCtrl.dll。

回到顶端

测试控件

1.在 Visual C# .NET 中创建一个新的 Windows 应用程序项目。默认情况下将创建出 Form1.cs。
2.将一个按钮控件从工具箱拖入 Form1。将 Name 属性更改为 btnPageSetup,并将 Text 属性更改为页面设置
3.将另一个按钮控件从工具箱拖入 Form1。将 Name 属性更改为 btnPrintPreview,并将 Text 属性更改为打印预览
4.将另一个按钮控件从工具箱拖入 Form1。将 Name 属性更改为 btnPrint,并将 Text 属性更改为打印
5.在工具箱中,双击“PrintDialog”、“PrintPreviewDialog”、“PrintDocument”和“PageSetupDialog”以将这些控件添加到 Form1 中。
6.将 PrintDialog1PrintPreviewDialog1 和 PageSetupDialog1 控件的 Document 属性修改为PrintDocument1
7.在“工具”菜单上,单击“自定义工具箱”。
8.在“.NET Framework 组件”选项卡上,单击“浏览”,单击以选中“RichTextBoxPrintCtrl.dll”,然后单击“确定”。
9.将 RichTextBoxPrintCtrl 从工具箱拖入 Form1。
10.在解决方案资源管理器中,右键单击 Form1.cs,然后单击查看代码
11.将以下代码添加到 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);
12.将下面的代码添加到 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.在“调试”菜单上,单击“启动”以运行该应用程序。Form1 将显示出来。
14.在 RichTextBoxPrintCtrl 中键入一些文本。
15.单击“页面设置”以设置页面设置。
16.单击“打印预览”以查看页面的打印预览。
17.单击“打印”以打印“RichTextBoxPrintCtrl”的内容。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值