====== Wysiwyg printing ability on richtextbox ======
This allows you to print the contents of a RichTetBox in a WYSIWYG manner.
Create a new class that inherits RichTextBox and type in the code:
Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Drawing.Printing
Public Class RichTextBoxEx
Inherits RichTextBox
Private Structure STRUCT_RECT
Public left As Int32
Public top As Int32
Public right As Int32
Public bottom As Int32
End Structure
Private Structure STRUCT_CHARRANGE
Public cpMin As Int32
Public cpMax As Int32
End Structure
Private Structure STRUCT_FORMATRANGE
Public hdc As IntPtr
Public hdcTarget As IntPtr
Public rc As STRUCT_RECT
Public rcPage As STRUCT_RECT
Public chrg As STRUCT_CHARRANGE
End Structure
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Int32, ByVal wParam As Int32, ByVal lParam As IntPtr) As Int32
End Function
Private Const WM_USER As Int32 = &H400&
Private Const EM_FORMATRANGE As Int32 = WM_USER + 57
Public Function FormatRange(ByVal measureOnly As Boolean, _
ByVal e As PrintPageEventArgs, _
ByVal charFrom As Integer, _
ByVal charTo As Integer) As Integer
Dim cr As STRUCT_CHARRANGE
cr.cpMin = charFrom
cr.cpMax = charTo
Dim rc As 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)
Dim rcPage As 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)
Dim hdc As IntPtr
hdc = e.Graphics.GetHdc()
Dim fr As STRUCT_FORMATRANGE
fr.chrg = cr
fr.hdc = hdc
fr.hdcTarget = hdc
fr.rc = rc
fr.rcPage = rcPage
Dim wParam As Int32
If measureOnly Then
wParam = 0
Else
wParam = 1
End If
Dim lParam As IntPtr
lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr))
Marshal.StructureToPtr(fr, lParam, False)
Dim res As Integer
res = SendMessage(Handle, EM_FORMATRANGE, wParam, lParam)
Marshal.FreeCoTaskMem(lParam)
e.Graphics.ReleaseHdc(hdc)
Return res
End Function
Private Function HundredthInchToTwips(ByVal n As Integer) As Int32
Return Convert.ToInt32(n * 14.4)
End Function
Public Sub FormatRangeDone()
Dim lParam As New IntPtr(0)
SendMessage(Handle, EM_FORMATRANGE, 0, lParam)
End Sub
Private Structure STRUCT_CHARFORMAT
Public cbSize As Integer
Public dwMask As UInt32
Public dwEffects As UInt32
Public yHeight As Int32
Public yOffset As Int32
Public crTextColor As Int32
Public bCharSet As Byte
Public bPitchAndFamily As Byte
_
Public szFaceName As Char()
End Structure
End Class
And use this code to do the actual printing:
Private Sub ToolPrint_Click(sender As System.Object, e As System.EventArgs) Handles ToolPrint.Click
Dim printDoc As New Printing.PrintDocument()
AddHandler printDoc.BeginPrint, AddressOf printDoc_BeginPrint
AddHandler printDoc.PrintPage, AddressOf printDoc_PrintPage
AddHandler printDoc.EndPrint, AddressOf printDoc_EndPrint
printDoc.Print()
End Sub
Private m_nFirstCharOnPage As Integer
Private Sub printDoc_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs)
m_nFirstCharOnPage = 0
End Sub
Private Sub printDoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
m_nFirstCharOnPage = RTBe.FormatRange(False, e, m_nFirstCharOnPage, RTBe.TextLength)
If (m_nFirstCharOnPage < RTBe.TextLength) Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
End Sub
Private Sub printDoc_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs)
RTBe.FormatRangeDone()
End Sub