a_jam_sandwich
Junior Contributor
Help adapted C not working for RTB printing
Complies. Put on form & error;
the user control could not be loaded. Ensure that the library containing the control has been built ...
Tried to covert to
Complies. Put on form & error;
the user control could not be loaded. Ensure that the library containing the control has been built ...
C#:
namespace de.cortex.text.util
{
using System;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
// <doc>
// <desc>
// RichTextPrintDocument prints the content of a RichTextBox
// control as RTF formatted text to a printer.
//
// Usage:
// RichTextBox rtb = new RichTextBox();
// ... define content of rich text box control
// RichTextPrintDocument pd = new RichTextPrintDocument(rtb);
// ... define default page settings
// ... show standard or custom print dialog
// if (dlgResult == DialogResult.OK)
// pd.Print();
// </desc>
// </doc>
public class RichTextPrintDocument : PrintDocument
{
// internal data structures needed for EM_FORMATRANGE message
// send to RichTextBox control windows handle via SendMessage()
// The windows message handling is based on code posted by
// Martin Müller on 08.Feb.2002 in his RichTextBoxEx class.
[ 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;
public int cpMax;
}
[ StructLayout( LayoutKind.Sequential )]
private struct FORMATRANGE
{
public IntPtr hdc;
public IntPtr hdcTarget;
public RECT rc;
public RECT rcPage;
public CHARRANGE chrg;
}
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private const int WM_USER = 0x400;
private const int EM_FORMATRANGE = WM_USER+57;
private RichTextBox richTextBox = null;
private int textLength;
private int firstChar;
public RichTextPrintDocument(RichTextBox richTextBox) : base ()
{
this.richTextBox = richTextBox;
this.textLength = richTextBox.TextLength;
this.firstChar = 0; // start at the beginning of text
}
// Override the OnPrintPage to provide the document printing logic
protected override void OnPrintPage(PrintPageEventArgs ev)
{
base.OnPrintPage(ev);
// calculate and render as much text as will fit on the page
// and remember the last character printed for the next page
firstChar = FormatRange (ev, firstChar, textLength);
if (firstChar < textLength)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
}
// Override OnEndPrint to perform clean up after printing
protected override void OnEndPrint(PrintEventArgs ev)
{
base.OnBeginPrint(ev);
FormatRangeDone();
}
/// <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 int HundredthInchToTwips(int n)
{
return (int)(n*14.4);
}
/// <summary>
/// Calculate and render the contents of the RichTextBox for a printing
/// page
/// </summary>
/// <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>
private int FormatRange(PrintPageEventArgs ev, int charFrom, int charTo)
{
// build content of FORMATRANGE struct
CHARRANGE cr;
cr.cpMin=charFrom;
cr.cpMax=charTo;
RECT rc;
rc.top = HundredthInchToTwips(ev.MarginBounds.Top);
rc.bottom = HundredthInchToTwips(ev.MarginBounds.Bottom);
rc.left = HundredthInchToTwips(ev.MarginBounds.Left);
rc.right = HundredthInchToTwips(ev.MarginBounds.Right);
RECT rcPage;
rcPage.top = HundredthInchToTwips(ev.PageBounds.Top);
rcPage.bottom = HundredthInchToTwips(ev.PageBounds.Bottom);
rcPage.left = HundredthInchToTwips(ev.PageBounds.Left);
rcPage.right = HundredthInchToTwips(ev.PageBounds.Right);
IntPtr hdc = ev.Graphics.GetHdc();
FORMATRANGE fr;
fr.chrg = cr;
fr.hdc = hdc;
fr.hdcTarget = hdc;
fr.rc = rc;
fr.rcPage = rcPage;
// build SendMessage arguments
IntPtr res;
IntPtr wpar = new IntPtr(1);
IntPtr lpar = Marshal.AllocCoTaskMem( Marshal.SizeOf( fr ) );
Marshal.StructureToPtr(fr, lpar, false);
// let richTextBox control format its content for printing device
res = SendMessage(richTextBox.Handle, EM_FORMATRANGE, wpar, lpar);
// clean-up resources
Marshal.FreeCoTaskMem(lpar);
ev.Graphics.ReleaseHdc(hdc);
return res.ToInt32();
}
/// <summary>
/// Clean-up method after the print job is finished to release cached
/// information
/// </summary>
private void FormatRangeDone()
{
IntPtr wpar = new IntPtr(0);
IntPtr lpar = new IntPtr(0);
SendMessage(richTextBox.Handle, EM_FORMATRANGE, wpar, lpar);
}
}
}
Tried to covert to
Visual Basic:
Imports System
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class printRTF
Inherits PrintDocument
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
Private Structure CHARRANGE
Public cpMin As Integer
Public cpMax As Integer
End Structure
Private Structure sFORMATRANGE
Public hdc As IntPtr
Public hdcTarget As IntPtr
Public rc As RECT
Public rcPage As RECT
Public chrg As CHARRANGE
End Structure
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Private Const WM_USER As Integer = 1024
Private Const EM_FORMATRANGE As Integer = WM_USER + 57
Private richTextBox As richTextBox
Private textLength As Integer
Private firstChar As Integer
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'UserControl overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
#End Region
Public Function RichTextPrintDocument(ByVal tRichTextbox As richTextBox)
richTextBox = tRichTextbox
textLength = tRichTextbox.TextLength
firstChar = 0
End Function
Protected Overrides Sub OnPrintPage(ByVal e As System.Drawing.Printing.PrintPageEventArgs)
MyBase.OnPrintPage(e)
firstChar = FormatRange(e, firstChar, textLength)
If (firstChar < textLength) Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
End Sub
Protected Overrides Sub OnEndPrint(ByVal e As System.Drawing.Printing.PrintEventArgs)
MyBase.OnBeginPrint(e)
FormatRangeDone()
End Sub
Private Function HundredthInchToTwips(ByVal n As Integer) As Integer
Return CInt(n * 14.4)
End Function
Private Function FormatRange(ByVal e As PrintPageEventArgs, ByVal charFrom As Integer, ByVal charTo As Integer) As Integer
Dim cr As CHARRANGE
cr.cpMin = charFrom
cr.cpMax = charTo
Dim rc As 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)
Dim rcPage As 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)
Dim hdc As IntPtr = e.Graphics.GetHdc()
Dim fr As sFORMATRANGE
fr.chrg = cr
fr.hdc = hdc
fr.hdcTarget = hdc
fr.rc = rc
fr.rcPage = rcPage
Dim res As IntPtr
Dim wpar As IntPtr = New IntPtr(1)
Dim lpar As IntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr))
Marshal.StructureToPtr(fr, lpar, False)
res = SendMessage(richTextBox.Handle, EM_FORMATRANGE, wpar, lpar)
Marshal.FreeCoTaskMem(lpar)
e.Graphics.ReleaseHdc(hdc)
Return res.ToInt32()
End Function
Private Function FormatRangeDone()
Dim wpar As IntPtr = New IntPtr(0)
Dim lpar As IntPtr = New IntPtr(0)
SendMessage(richTextBox.Handle, EM_FORMATRANGE, wpar, lpar)
End Function
End Class