C# Printing Problem (Richtextbox)

C# Printing Problem (RichTextBox)

got it..

on this Place:

if (printDialog.ShowDialog() == DialogResult.OK)
{
StringReader reader = new StringReader(eintragRichTextBox.Text);
documentToPrint.Print();
documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage);
}

I changed to:

if (printDialog.ShowDialog() == DialogResult.OK)
{
StringReader reader = new StringReader(eintragRichTextBox.Text);
documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage);
documentToPrint.Print();
}

Now it works fine..

Also if someone needs to print content of a RichTextBox, you can use my code..

Printing RichTextBox

You can print the content of your RuchTextBox by sending a EM_FORMATRANGE message to it.

This message is typically used to format the content of rich edit
control for an output device such as a printer.

To implement this solution, you can do these steps:

  • First create a RichtextBoxEx class that inherits from RichTextBox and implement a FormatRange method that its job is to print each page of your control contents. The complete code is listed below.
  • Then Create a Form and put a RichTextBoxEx, PrintDocument on it and handle BeginPrint, PrintPage and EndPrint events of PrintDocument and use following codes to perform print.

Please note

  1. Using this way, you can print the content of your control with all of formatting applied to text, that is better than printing all text in a black color with one font and size. Also you can set the font and size of content to be in one font and size and color.

  2. Creating RichtextBoxEx is just for encapsulation and is completely optional and if you want to use your existing control, simply you can use content of FormatRange method that I provided below and pass properties of your control to it to perform print.

RichTextBoxEx that supports Printing:

Here is the complete working code of what I described above. The code is extracted from the msdn article Getting WYSIWYG Print Results from a .NET RichTextBox article by Martin Müller.

public class RichTextBoxEx : RichTextBox
{
[StructLayout(LayoutKind.Sequential)]
private struct STRUCT_RECT
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}

[StructLayout(LayoutKind.Sequential)]
private struct STRUCT_CHARRANGE
{
public Int32 cpMin;
public Int32 cpMax;
}

[StructLayout(LayoutKind.Sequential)]
private struct STRUCT_FORMATRANGE
{
public IntPtr hdc;
public IntPtr hdcTarget;
public STRUCT_RECT rc;
public STRUCT_RECT rcPage;
public STRUCT_CHARRANGE chrg;
}

[DllImport("user32.dll")]
private static extern Int32 SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, IntPtr lParam);

private const Int32 WM_USER = 0x400;
private const Int32 EM_FORMATRANGE = WM_USER + 57;
private const Int32 EM_GETCHARFORMAT = WM_USER + 58;
private const Int32 EM_SETCHARFORMAT = WM_USER + 68;

/// <summary>
/// Calculate or render the contents of our RichTextBox for printing
/// </summary>
/// <param name="measureOnly">If true, only the calculation is performed, otherwise the text is rendered as well</param>
/// <param name="e">The PrintPageEventArgs object from the PrintPage event</param>
/// <param name="charFrom">Index of first character to be printed</param>
/// <param name="charTo">Index of last character to be printed</param>
/// <returns> (Index of last character that fitted on the page) + 1</returns>
public int FormatRange(bool measureOnly, PrintPageEventArgs e, int charFrom, int charTo)
{
// Specify which characters to print
STRUCT_CHARRANGE cr = default(STRUCT_CHARRANGE);
cr.cpMin = charFrom;
cr.cpMax = charTo;

// Specify the area inside page margins
STRUCT_RECT rc = default(STRUCT_RECT);
rc.top = HundredthInchToTwips(e.MarginBounds.Top);
rc.bottom = HundredthInchToTwips(e.MarginBounds.Bottom);
rc.left = HundredthInchToTwips(e.MarginBounds.Left);
rc.right = HundredthInchToTwips(e.MarginBounds.Right);

// Specify the page area
STRUCT_RECT rcPage = default(STRUCT_RECT);
rcPage.top = HundredthInchToTwips(e.PageBounds.Top);
rcPage.bottom = HundredthInchToTwips(e.PageBounds.Bottom);
rcPage.left = HundredthInchToTwips(e.PageBounds.Left);
rcPage.right = HundredthInchToTwips(e.PageBounds.Right);

// Get device context of output device
IntPtr hdc = default(IntPtr);
hdc = e.Graphics.GetHdc();

// Fill in the FORMATRANGE structure
STRUCT_FORMATRANGE fr = default(STRUCT_FORMATRANGE);
fr.chrg = cr;
fr.hdc = hdc;
fr.hdcTarget = hdc;
fr.rc = rc;
fr.rcPage = rcPage;

// Non-Zero wParam means render, Zero means measure
Int32 wParam = default(Int32);
if (measureOnly)
{
wParam = 0;
}
else
{
wParam = 1;
}

// Allocate memory for the FORMATRANGE struct and
// copy the contents of our struct to this memory
IntPtr lParam = default(IntPtr);
lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr));
Marshal.StructureToPtr(fr, lParam, false);

// Send the actual Win32 message
int res = 0;
res = SendMessage(Handle, EM_FORMATRANGE, wParam, lParam);

// Free allocated memory
Marshal.FreeCoTaskMem(lParam);

// and release the device context
e.Graphics.ReleaseHdc(hdc);

return res;
}

/// <summary>
/// Convert between 1/100 inch (unit used by the .NET framework)
/// and twips (1/1440 inch, used by Win32 API calls)
/// </summary>
/// <param name="n">Value in 1/100 inch</param>
/// <returns>Value in twips</returns>
private Int32 HundredthInchToTwips(int n)
{
return Convert.ToInt32(n * 14.4);
}

/// <summary>
/// Free cached data from rich edit control after printing
/// </summary>
public void FormatRangeDone()
{
IntPtr lParam = new IntPtr(0);
SendMessage(Handle, EM_FORMATRANGE, 0, lParam);
}
}

Example of Usage:

private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
// Start at the beginning of the text
firstCharOnPage = 0;
}

private void printDocument1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
// Clean up cached information
richTextBoxEx1.FormatRangeDone();
}

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
firstCharOnPage = richTextBoxEx1.FormatRange(false, e, firstCharOnPage, richTextBoxEx1.TextLength);
// check if there are more pages to print
if (firstCharOnPage < richTextBoxEx1.TextLength)
e.HasMorePages = true;
else
e.HasMorePages = false;
}

private void printToolStripButton_Click(object sender, EventArgs e)
{
//Print the contents here
printDocument1.Print();
}

Problem with Printing Content Of RichTextBox with Adorner Layers

I didn't find any way that works 100% for this problem, so I'm trying to transform all my adorner layers to actual images. I'll update the question once I get a 100% working solution.

WPF RichTexBox printing is creating unexpected line breaks

Because of the DocumentPaginator class takes context of the FlowDocument and split in into multiple pages to get desired result some of FlowDocument parameters should be configured before printing:

private void PrintCommand2(Object sender, RoutedEventArgs args)
{
var pd = new PrintDialog();
if (pd.ShowDialog() == true)
{
FlowDocument doc = richTB.Document;

// Save all settings that will be configured for printing.
double pageHeight = doc.PageHeight;
double pageWidth = doc.PageWidth;
double columnGap = doc.ColumnGap;
double columnWidth = doc.ColumnWidth;

// Make the FlowDocument page match the printed page.
doc.PageHeight = pd.PrintableAreaHeight;
doc.PageWidth = pd.PrintableAreaWidth;
doc.ColumnGap = 5;

// Set the minimum desired width of the column in the System.Windows.Documents.FlowDocument.
doc.ColumnWidth = doc.PageWidth - doc.ColumnGap - doc.PagePadding.Left - doc.PagePadding.Right;
pd.PrintDocument(((IDocumentPaginatorSource)doc).DocumentPaginator, "A Flow Document");

// Reapply the old settings.
doc.PageHeight = pageHeight;
doc.PageWidth = pageWidth;
doc.ColumnGap = columnGap;
doc.ColumnWidth = columnWidth;
}
}

With respect to Matthew MacDonald this way of the flow document content printing and more advanced techniques described in his book Pro WPF 4.5 in C# Windows Presentation Foundation in .NET 4.5 (Chapter 29).

RichTextBox takes too long to print results

Use StringBuilder and assign its result to the richTextBox1.Text:

  var sb = new StringBuilder();
foreach (string item in list)
{
sb.Append(item + "\r\n");
}
richTextBox1.Text += sb.ToString();

How do you print contents of a RichTextBox?

According MSDN discussion How to print RichEditBox content (RTF file), it's too much complex to print RichEditBox because if you want to print it you have to manually parse the RTF format & it's literally too much tough task. That's why even OneNote doesn't provide printing & Metro IE also provide poorest printing.

If you want to print text box content, I have created a helper class which simplifies printing text box content. You can add helper class via NuGet. If you want to enhance my existing helper class, fork on GitHub



Related Topics



Leave a reply



Submit