Neste artigo vou mostrar como imprimir o conteúdo de um controle RichTextBox em aplicações VB .NET. |
Este artigo foi baseado no original encontrado em : https://support.microsoft.com/pt-br/kb/811401 e acessado em agosto de 2016.
O controle RichTextBox não fornece um método para imprimir seu conteúdo. No entanto, você pode estender a classe RichTextBox para usar a mensagem EM_FORMATRANGE.
Nota: EM_FORMATRANGE é uma estrutura que o controle usa para formatar a saida para um dispositivo. (FORMATRANGE structure (Windows) - MSDN - Microsoft)
Você pode então enviar o conteúdo de um RichTextBox para um dispositivo de saída, como uma impressora.
Neste tutorial vou mostrar um exemplo prático implementando o código mostrado no artigo da Microsoft.
Recursos usados :
Criando o projeto Class Library no Visual Studio 2015 Community
Abra o VS 2015 Community e clique em New Project;
Selecione o template Class Library e informe o nome RichTextBoxPrintCtrl;
Altere o nome do arquivo Class1.vb para RichTextBoxPrintCtrl;
Na janela Solution Explorer clique com o botão direito do mouse em References e em seguida em Add Reference;
Na caixa de diálogo Add Reference selecione Assemblies e marque os namespaces System.Drawing e System.Windows.Forms;
Inclua o
código abaixo no arquivo RichTextBoxPrintCtrl.vb :
Option Explicit On Imports System.Windows.Forms Imports System.Runtime.InteropServices Imports System.Drawing.Printing Namespace RichTextBoxPrintCtrl Public Class RichTextBoxPrintCtrl Inherits RichTextBox ' Converte a unidade que usada pelo .NET framework (1/100 inch) ' e a unidade que é usada pelas chamadas da API Win32 (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 ' Primeiro caractere do intervalo (0 para inicio do doc) Public cpMax As Integer ' Último caractere do intervalo (-1 para o fim do doc) End Structure <StructLayout(LayoutKind.Sequential)> Private Structure FORMATRANGE Public hdc As IntPtr ' Atual DC para desenhar Public hdcTarget As IntPtr ' Alvo DC para determinar a formatação do texto Public rc As RECT ' Região do DC para desenhar(em twips) Public rcPage As RECT ' Região de toda a DC (tam. da página) (em twips) Public chrg As CHARRANGE ' Intervalo de texto para desenhar 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 ' Renderiza o conteudo do RichTextBox para impressão ' Retorna o último caractere impresso +1 (a impressão inicia deste ponto para a próxim pagina) 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 ' Calcula a área para renderizar e imprimir 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 ' Calcula o tamanho a pagina 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 o ponteiro da estrutura FORMATRANGE na memória 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) ' Libera a memória alocada Marshal.FreeCoTaskMem(lparam) ' Libera o manipulador de contexto do dispositivo obtido na chamada anterior e.Graphics.ReleaseHdc(hdc) ' Retorna o ultimo caractere +1 da impressora Return res.ToInt32() End Function End Class End Namespace |
Observe que esta classe herda (Inherits) da classe RichTextBox e usa a estrutura EM_FORMATRANGE para implementar a impressão do seu conteúdo.
Salve e compile o projeto para gerar na pasta \bin\Debug o arquivo : RichTextBoxPrintCtrl.dll que iremos usar para testar a nossa implementação.
Criando o projeto Windows Forms para imprimir o conteúdo do RichTextBox
No menu File clique em Add -> New Project;
Selecione o template Windows Forms Application e informe o nome RichTextBox_Impressao;
Agora vamos incluir uma referência ao nosso arquivo dll criado no projeto Class Library.
Clique com o botão direito sobre a ToolBox e a seguir clique em Choose Items;
Na janela Choose ToolBox Items clique na guia .NET Framework Components e a seguir clique em Browse;
Localize o arquivo RichTextBoxPrintCtrl.dll na pasta bin\Debug do projeto e selecione o arquivo e clique em Abrir;
Será incluída uma referência à DLL conforme mostrada na figura abaixo. Selecione a referência e clique em OK;
Agora o componente estará aparecendo na ToolBox. Arraste o componente para o formulário como mostra a figura abaixo:
A seguir inclua também no formulário os seguintes controles :
Na janela de propriedades, modifique a propriedade Document do PrintDialog1, PrintPreviewDialog1e PageSetupDialog1 para PrintDocument1.
Exemplo:
Disponha os controles conforme o leiaute da figura abaixo:
Inclua o código abaixo no evento Click dos botões :
1- Configurar Página
Private
Sub btnConfigurar_Click(sender As Object, e As EventArgs) Handles
btnConfigurar.Click PageSetupDialog1.ShowDialog() End Sub |
2- Visualizar Impressão
Private
Sub btnVisualizar_Click(sender As Object, e As EventArgs) Handles
btnVisualizar.Click PrintPreviewDialog1.ShowDialog() End Sub |
3- Imprimir
Private Sub btnImprimir_Click(sender As Object, e As EventArgs) Handles btnImprimir.Click
If PrintDialog1.ShowDialog() = DialogResult.OK Then
PrintDocument1.Print()
End If
End Sub
|
No evento Click do botão Imagem vamos definir o código para incluir uma imagem no controle RichtTextBox conforme abaixo:
Private Sub btnImagem_Click(sender As Object, e As EventArgs) Handles btnImagem.Click
If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
picImagem.Load(OpenFileDialog1.FileName)
Clipboard.SetImage(picImagem.Image)
picImagem.Image = Nothing
Me.RichTextBoxPrintCtrl1.Paste()
End If
End Sub
|
Agora no evento Click do botão Iniciar Dados inclua o código abaixo para preencher o controle com alguns dados:
Private Sub btnIniciar_Click(sender As Object, e As EventArgs) Handles btnIniciar.Click
With RichTextBoxPrintCtrl1
.BackColor = Color.White
.Clear()
.BulletIndent = 10
.SelectionFont = New Font("Georgia", 18, FontStyle.Bold)
.SelectedText = "Macoratti .net " & vbLf
.SelectionFont = New Font("Verdana", 16)
.SelectionBullet = True
.SelectionColor = Color.DarkBlue
.SelectedText = "Quase Tudo" + vbLf
.SelectionFont = New Font("Verdana", 14)
.SelectionColor = Color.Orange
.SelectedText = "Para VB.NET" + vbLf
.SelectionFont = New Font("Verdana", 12)
.SelectionColor = Color.Green
.SelectedText = "C# , ASP .NET " + vbLf
.SelectionColor = Color.Red
.SelectedText = "e outros recursos da plataforma .NET" + vbLf
.SelectionBullet = False
.SelectionFont = New Font("Tahoma", 10)
.SelectionColor = Color.Black
.SelectedText = "http://www.macoratti.net" & vbLf
End With
End Sub
|
Finalmente inclua o código abaixo no formulário onde
Private verificaImpressao As Integer
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
verificaImpressao = 0
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
' imprime o conteudo do RichTextBox.
' armazena o ultimo caractere impresso
verificaImpressao = RichTextBoxPrintCtrl1.Print(verificaImpressao, RichTextBoxPrintCtrl1.TextLength, e)
' verifica se há mais paginas
If verificaImpressao < RichTextBoxPrintCtrl1.TextLength Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
End Sub
|
Agora é só alegria...
Executando o projeto, iniciando os dados e incluindo uma imagem ao clicar no botão para Visualizar Impressão iremos obter o seguinte resultado:
Pegue o projeto completo aqui : RichTextBoxPrintCtrl.zip
"Verdadeiramente ele (Jesus) tomou sobre
si as nossas enfermidades, e as nossas dores levou sobre si; e nós o reputávamos
por aflito, ferido de Deus, e oprimido."
Isaías 53:4
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
Visual Basic .NET - Implementando um array de controles - Macoratti.net