Print with RichTextBox

Solved
danmor Posted messages 31 Status Member -  
arion320 Posted messages 219 Registration date   Status Member Last intervention   -
Hello everyone

Happy New Year

I'm starting off well with this question

Does anyone have a good way to print with VB 2005? I've tried a lot but nothing works.
There's always an error somewhere that I can't find.
Do you have a good method that works well? If you could help me, that would be nice.

See you
Configuration: Windows XP Internet Explorer 7.0

2 answers

  1. Nico# Posted messages 328 Registration date   Status Member Last intervention   102
     
    Hello,

    1.

    Create a class RichTextBoxPrintCtrl that inherits from RichTextBox.
    2.

    Use the RichTextBoxPrintCtrl class in your upgraded project.

    To create a class that inherits from the RichTextBox class

    1.

    Use Visual Basic 2005 to create a new Class Library project named RichTextBoxPrintCtrl.

    By default, Class1.vb is created.
    2.

    Rename the Class1.vb file to RichTextBoxPrintCtrl.vb.
    3.

    In Solution Explorer, right-click on References, and then click on Add Reference.
    4.

    In the Add Reference dialog, double-click on System.Drawing.dll, then on System.Windows.Forms.dll.
    5.

    To add the references, click OK.
    6.

    Delete the existing code in RichTextBoxPrintCtrl.vb.
    7.

    Add the following code to RichTextBoxPrintCtrl.vb :

    Option Explicit On

    Imports System
    Imports System.Windows.Forms
    Imports System.Drawing
    Imports System.Runtime.InteropServices
    Imports System.Drawing.Printing

    Namespace RichTextBoxPrintCtrl
    Public Class RichTextBoxPrintCtrl
    Inherits RichTextBox

    ' Convert the unit that is used by the .NET framework
    ' (1/100 inch) and the unit that is used by Win32 API calls
    ' (twips 1/1440 inch)
    Private Const AnInch As Double = 14.4

    Private WithEvents m_PrintDocument As Printing.PrintDocument
    Private intCharactersToPrint As Integer
    Private intCurrentPosition As Integer

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure RECT
    Public Left As Integer
    Public Top As Integer
    Public Right As Integer
    Public Bottom As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure CHARRANGE
    ' First character of range (0 for start of doc)
    Public cpMin As Integer
    ' Last character of range (-1 for end of doc)
    Public cpMax As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure FORMATRANGE
    ' Actual DC to draw on
    Public hdc As IntPtr
    ' Target DC for determining text formatting
    Public hdcTarget As IntPtr
    ' Region of the DC to draw to (in twips)
    Public rc As Rect
    ' Region of the whole DC (page size) (in twips)
    Public rcPage As Rect
    ' Range of text to draw (see above declaration)
    Public chrg As CHARRANGE
    End Structure

    Private Const WM_USER As Integer = &H400
    Private Const EM_FORMATRANGE As Integer = WM_USER + 57

    Private Declare Function SendMessage Lib "USER32" Alias _
    "SendMessageA" (ByVal hWnd As IntPtr, ByVal msg As Integer, _
    ByVal wp As IntPtr, ByVal lp As IntPtr) As IntPtr

    Public Sub SelPrint()

    'print only the selected text if any is selected
    If Me.SelectionLength > 0 Then
    intCharactersToPrint = Me.SelectionStart + Me.SelectionLength
    intCurrentPosition = Me.SelectionStart
    Else
    'otherwise print the entire document
    intCharactersToPrint = Me.TextLength
    intCurrentPosition = 0
    End If

    m_PrintDocument.Print()

    End Sub
    ' Render the contents of the RichTextBox for printing
    ' Return the last character printed + 1 (printing starts from
    ' this point for the next page)
    Private Function Print(ByVal charFrom As Integer, _
    ByVal charTo As Integer, ByVal e As PrintPageEventArgs) As Integer

    ' Mark starting and ending character
    Dim cRange As CHARRANGE
    cRange.cpMin = charFrom
    cRange.cpMax = charTo

    ' Calculate the area to render and print
    Dim rectToPrint As RECT
    rectToPrint.Top = e.MarginBounds.Top * AnInch
    rectToPrint.Bottom = e.MarginBounds.Bottom * AnInch
    rectToPrint.Left = e.MarginBounds.Left * AnInch
    rectToPrint.Right = e.MarginBounds.Right * AnInch

    ' Calculate the size of the page
    Dim rectPage As RECT
    rectPage.Top = e.PageBounds.Top * AnInch
    rectPage.Bottom = e.PageBounds.Bottom * AnInch
    rectPage.Left = e.PageBounds.Left * AnInch
    rectPage.Right = e.PageBounds.Right * AnInch

    Dim hdc As IntPtr = e.Graphics.GetHdc()

    Dim fmtRange As FORMATRANGE
    ' Indicate character from to character to
    fmtRange.chrg = cRange
    ' Use the same DC for measuring and rendering
    fmtRange.hdc = hdc
    ' Point at printer hDC
    fmtRange.hdcTarget = hdc
    ' Indicate the area on page to print
    fmtRange.rc = rectToPrint
    ' Indicate whole size of page
    fmtRange.rcPage = rectPage

    Dim res As IntPtr = IntPtr.Zero

    Dim wparam As IntPtr = IntPtr.Zero
    wparam = New IntPtr(1)

    ' Move the pointer to the FORMATRANGE structure in
    ' memory
    Dim lparam As IntPtr = 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 the last + 1 character printed
    Return res.ToInt32

    End Function
    Public ReadOnly Property PrintDocument() As Printing.PrintDocument
    Get
    If m_PrintDocument Is Nothing Then
    m_PrintDocument = New Printing.PrintDocument
    End If

    Return m_PrintDocument
    End Get
    End Property

    Private Sub m_PrintDocument_PrintPage(ByVal sender As _
    Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
    Handles m_PrintDocument.PrintPage
    ' Print the content of the RichTextBox.
    ' Store the last character printed.

    intCurrentPosition = Me.Print(intCurrentPosition, _
    intCharactersToPrint, e)

    ' Look for more pages by checking
    If intCurrentPosition < intCharactersToPrint Then
    e.HasMorePages = True
    Else
    e.HasMorePages = False
    End If

    End Sub
    End Class
    End Namespace

    8.

    To create RichTextBoxPrintCtrl.dll, click on Build Solution in the Build menu.

    To use the RichTextBoxPrintCtrl class in your upgraded project

    1.

    Open your upgraded Windows application project in Visual Basic 2005.
    2.

    From the toolbox, drag a PrintDialog component onto the form containing the RichTextBox control.
    3.

    In the Tools menu, click on Customize Toolbox.
    4.

    Click on .NET Framework Components, browse for RichTextBoxPrintCtrl.dll, and then click OK.
    5.

    From the toolbox, drag a RichTextBoxPrintCtrl control onto the form.
    6.

    Set the properties of RichTextBoxPrintCtrl to match those of your original RichTextBox control.
    7.

    Remove the RichTextBox control, then rename the RichTextBoxPrintCtrl control to match the name of your original RichTextBox control.
    8.

    Double-click on the form to open the code editor.
    9.

    Add the following code to the Button_Click event handler (or wherever you called SelPrint in the original code):

    ' NOTE: Replace "Button1" with the name of your actual Print button
    Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click

    'associate the correct printdocument to the printdialog
    PrintDialog1.Document = Me.RichTextBoxPrintCtrl1.PrintDocument

    If PrintDialog1.ShowDialog() = DialogResult.OK Then
    Me.RichTextBoxPrintCtrl1.SelPrint()
    End If
    End Sub
    0
  2. danmor Posted messages 31 Status Member
     
    Thank you, but I'm getting a printer violation error directly

    I already have this effective DLL in another one of my projects and it's the same problem

    Thank you for your help, but I will have to check all my programs that use a printer and see what the problem is, and thank you again
    0
    1. chiffre
       
      Thank you for these details for printing..

      This works very well, I have a few codes to add...

      Thank you
      number
      0