VB.NET Imprimir RichTextBox
Publicado por: lasnv   en: 2012-04-17 19:17:17

Quienes como yo prefieren sacrificar algo de funcionalidad antes que gastar unos cuantos cientos de dolares en una licencia, saben que Visual Estudio Express es una típico caso en el que debido a que es gratuito muchas de los mejores controles de reportes e impresión no están disponibles.

Por suerte nos han dejado el control RichTextBox que puede renderizar documentos RTF.

Crear una dll para extender el namespace RichTextBox o descargar RichTextBoxPrintCtrl.zip que contiene la dll ya compilada y lista para ser usada, o el Proyecto en Visual Basic

Código para la .dll

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
 
        <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
            Public cpMin As Integer          ' First character of range (0 for start of doc)
            Public cpMax As Integer          ' Last character of range (-1 for end of doc)
        End Structure
 
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure FORMATRANGE
            Public hdc As IntPtr             ' Actual DC to draw on
            Public hdcTarget As IntPtr       ' Target DC for determining text formatting
            Public rc As Rect                ' Region of the DC to draw to (in twips)
            Public rcPage As Rect            ' Region of the whole DC (page size) (in twips)
            Public chrg As CHARRANGE         ' Range of text to draw (see above declaration)
        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
 
        ' Render the contents of the RichTextBox for printing
        '	Return the last character printed + 1 (printing start from this point for next page)
        Public 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
            fmtRange.chrg = cRange                 ' Indicate character from to character to 
            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 whole size of page
 
            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 last + 1 character printer
            Return res.ToInt32()
        End Function
 
    End Class
End Namespace

Una vez creado la dll debemos crear un proyecto nuevo en el cual vamos a usar la librería que acabamos de compilar.

Para usarla hay que pegar la dll en la carpeta |proyecto\bin\debug\ y luego añadir la referencia.
/App/upLoads/files/vb4(0).png

Para agregar la referencia hay que hacer click en el botón agregar luego en el botón examinar de la ventana resultante y buscar la ubicación de la dll y añadir la referencia. Una vez echo esto debemos ir al cuadro de herramientas y hacer click derecho "Elegir elementos" luego en el botón examinar y buscar y elegir la dll en cuestión.
/App/upLoads/files/vb5(0).png

Así debe quedar en la barra de herramientas.
/App/upLoads/files/vb6(0).png

Ahora debemos crear un WinForm similar a este.
/App/upLoads/files/vb8(0).png

Los controles que debe tener son los siguientes: RichTextBoxCtrlPrint, Botón Configurar pagina, Botón vista previa, Botón imprimir, PrintDialog, PrintPreviewDialog, PrintDocument, PageSetup.
/App/upLoads/files/vb7(0).png

Ahora es necesario cambiar la Propiedad "Document" de los controles PrintDialog, PrintPreviewDialog y PageSetup, esta propiedad se debe establecer con el nombre que se le haya asignado al control PrintDocument que por defecto es PrintDocument1.

Por ultimo se debe agregar el siguiente código al formulario:

Private checkPrint As Integer
 
    Private Sub PrintDocument1_BeginPrint(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
        checkPrint = 0
		'Evento BeginPrint del control PrintDocument1
    End Sub
 
    Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        checkPrint = RichTextBoxPrintCtrl1.Print(checkPrint, RichTextBoxPrintCtrl1.TextLength, e)
        If checkPrint < RichTextBoxPrintCtrl1.TextLength Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
        End If
		'Evento PrintPage del control PrintDocument1
    End Sub
 
    Private Sub btnPageSetup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPageSetup.Click
        PageSetupDialog1.ShowDialog()
		'Evento Click del boton Configurar pagina
    End Sub
 
    Private Sub btnPrint_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
        If PrintDialog1.ShowDialog() = DialogResult.OK Then
            PrintDocument1.Print()
        End If
		'Evento Click del boton Imprimir
    End Sub
 
    Private Sub btnPrintPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintPreview.Click
        PrintPreviewDialog1.ShowDialog()
		'Evento Click del Boton Vista previa
    End Sub

Bien eso es todo solo espero les sea útil.

DLL lista para ser usada RichTextBoxPrintCtrl.zip

Proyescto en Visual Basic Proyecto en Visual Basic

Publicado por: cdbx10   en: 2013-05-16 21:16:38

Según parece te esfuerzas en explicar del modo que se comprenda, buscaba algo similar, gracias


Publicado por: cdbx10   en: 2013-05-16 22:16:22

Mmmmmh no puedo agregar ese control RichTextBoxPrintCtrl en mi version actual de Framework o Visual Studio...


Visitante anonimo

Debes iniciar sesion para poder comentar
Iniciar sesión   Registrarse

Powered by Jean Paul Beard ® © 2014       Hosted on Web Hosting