您的位置:首页 > 编程语言 > C#

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

2010-01-05 19:52 567 查看
本分步指南介绍了如何打印 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 中的现有代码替换为以下代码:

[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();
}

}
}

[/code]

在“生成”菜单中,单击“生成解决方案”以创建 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 中。

PrintDialog1PrintPreviewDialog1PageSetupDialog1 控件的 Document 属性修改为 PrintDocument1

在“工具”菜单上,单击“自定义工具箱”。

在“.NET Framework 组件”选项卡上,单击“浏览”,单击以选中“RichTextBoxPrintCtrl.dll”,然后单击“确定”。

RichTextBoxPrintCtrl 从工具箱拖入 Form1。

在解决方案资源管理器中,右键单击 Form1.cs,然后单击查看代码

将以下代码添加到 InitializeComponent 方法中:

[code]		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);

[/code]

将下面的代码添加到 Form1 类:

[code]		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;
}

[/code]

在“调试”菜单上,单击“启动”以运行该应用程序。Form1 将显示出来。

在 RichTextBoxPrintCtrl 中键入一些文本。

单击“页面设置”以设置页面设置。

单击“打印预览”以查看页面的打印预览。

单击“打印”以打印“RichTextBoxPrintCtrl”的内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐