C# - Editor de Texto com RichTextBox e PrintDocument - II
No artigo de hoje vou mostrar como podemos criar um pequeno editor de textos usando os recursos do controle RichTextBox na linguagem C#. Veremos também como imprimir e visualizar a impressão do texto usando o PrintDocument. |
Na primeira parte do artigo eu criei o projeto defini a interface com o usuário e implementei a maior parte das funcionalidades do editor de texto.
Neste artigo eu vou implementar as funcionalidades para exibir as configurações da impressora, visualizar a impressão e imprimir o texto carregado no editor.
Recursos usados:
Implementando as opções de impressão do texto
Abra projeto RichTextBox_Imprimir criado no artigo anterior usando o VS Community 2013 clique em Open Project e selecione o projeto abrindo-o.
Nesta parte iremos trabalhar com os componentes :
Configurações da Impressora
Nesta opção exibimos as configurações da impressora padrão. Esta rotina atribui o componente PrintDialog ao documento a ser impresso: prntdlg1.Document = prntdoc1;
Nota: Quando você cria uma instância de PrintDialog , as propriedades read/write são definidas para os valores iniciais os quais são:
Propriedade Valor Inicial AllowSomePages false AllowPrintToFile true AllowSelection false Document null (Nothing no VB) PrinterSettings null (Nothing no VB) PrintToFile false ShowHelp false ShowNetwork true O diálogo é exibido usando o componente ShowDialog de maneira que o usuário pode definir as suas opções de impressão e decidir se imprime ou não o documento.
private void mnuConfiguracoesImpressora_Click(object sender, EventArgs e)
{
ConfiguracoesImpressora();
}private void toolStripConfigImpressora_Click(object sender, EventArgs e)
{
ConfiguracoesImpressora();
}private void ConfiguracoesImpressora() { try { this.prntdlg1.Document = this.prntdoc1; prntdlg1.ShowDialog(); } catch(Exception ex) { MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Visualizar Impressão
Nesta opção usamos o componente PrintPreviewDialog para visualizar a impressão.
O componente PrintPreview também dispara o evento PrintPage mas ao invés de direcionar para a impressora a saída é direcionada para a tela de visualização.
private void mnuVisualizarImpressão_Click(object sender, EventArgs e)
{
visualizaImpressao();
} private void toolStripVisualizar_Click(object sender, EventArgs e) { visualizaImpressao(); }private void visualizaImpressao() { //visualiza a impressao try { string strTexto = this.rtxtb1.Text; leitor = new StringReader(strTexto); PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog(); var prn = printPreviewDialog1; prn.Document = this.prntdoc1; prn.Text = "Macoratti - Visualizando a impressão"; prn.WindowState = FormWindowState.Maximized; prn.PrintPreviewControl.Zoom = 1; prn.FormBorderStyle = FormBorderStyle.Fixed3D; prn.ShowDialog(); } catch (Exception ex) { MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Imprimir
Para realizar a impressão do documento usamos o método Print do componente PrintDocument.
Para concluir a impressão precisamos definir o código no evento PrintPage.
O evento PrintPage é automaticamente chamado pelo sistema para imprimir a página selecionada. O evento é do tipo PrintPageEventArgs e contém o contexto do dispositivo e.Graphics usado para imprimir para a impressora.
A propriedade PageBounds da classe PrintPageEventArgs representa um retângulo da página inteira , já a propriedade MarginBounds representa um retângulo da área do interior das margens conforme mostra a figura ao lado. Ambas as propriedades são usadas na unidade de 100 dpi, de maneira que um formato carta de 8.5 x 11 polegadas terá sempre um retângulo PageBounds de medida igual a {0, 0, 850, 1100}. Com uma margem padrão de 1 polegada , o retângulo MarginBounds terá as seguintes medidas {100, 100, 650, 900}.
A margem é útil porque muitas impressoras não podem imprimir a partir do início das bordas das páginas. Para evitar a perda de impressão nestes casos o objeto Graphics que você manuseia quando você imprime, inicia a impressão no topo superior esquerdo da área de impressão da página.Neste exemplo efetuamos a leitura de cada linha de texto do controle RichTextBox usando um StringReader que nos dá a habilidade de tratar uma string como um stream e tomar vantagem da função ReadLine para ler cada linha de texto no controle.
Podemos calcular a posição das linhas baseadas nas margens e na altura da fonte, e com o objetivo de prever a altura da fonte para a impressora nós passamos a ela o contexto do dispositivo da impressora na função GetHeight (printFont.GetHeight(ev.Graphics()), pois a altura da fonte na tela em pixels é diferente da fonte na impressora.
O atributo HasMorePages da classe PrintPageEventArg é continuamente verificado de maneira que o evento PrintPage é disparado se existirem mais linhas do que a página atual pode suportar.
private void mnuImprimir_Click(object sender, EventArgs e) { Imprimir(); }
private void toolStripImprimir2_Click(object sender, EventArgs e)
{
Imprimir();
}private void Imprimir() { prntdlg1.Document = prntdoc1;
string strTexto = this.rtxtb1.Text; leitor = new StringReader(strTexto); if (prntdlg1.ShowDialog() == DialogResult.OK) { this.prntdoc1.Print(); } }
private void prntdoc1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { float linhasPorPagina = 0; float Posicao_Y = 0; int contador = 0;
//defina as margens e o valor minimo float MargemEsquerda = e.MarginBounds.Left - 50; float MargemSuperior = e.MarginBounds.Top- 50;
if (MargemEsquerda < 5) MargemEsquerda = 20;
if (MargemSuperior < 5) MargemSuperior = 20; //define a fonte string linha = null; Font FonteDeImpressao = this.rtxtb1.Font; SolidBrush meupincel = new SolidBrush(Color.Black); //StreamReader leitor = null;
//Calcula o numero de linhas por página usando as medidas das margens linhasPorPagina = e.MarginBounds.Height / FonteDeImpressao.GetHeight(e.Graphics);
// Vamos imprimir cada linha implementando um StringReader linha = leitor.ReadLine();
while (contador < linhasPorPagina) { // calcula a posicao da proxima linha baseado na altura da fonte de acordo com o dispositivo de impressão Posicao_Y = (MargemSuperior + (contador * FonteDeImpressao.GetHeight(e.Graphics))); // desenha a proxima linha no controle richtextbox e.Graphics.DrawString(linha, FonteDeImpressao, meupincel, MargemEsquerda, Posicao_Y, new StringFormat()); //conta a linha e incrementa uma unidade contador += 1; linha = leitor.ReadLine(); }
// se existir mais linhas imprime outra página if ((linha != null)) { e.HasMorePages = true; } else { e.HasMorePages = false; } meupincel.Dispose(); }
Ajuda
Na opção Ajuda exibimos o formulário form2.cs que contém o seguinte leiaute e é composto pelos controles: PictureBox, GroupBox, Label, LinkLabel e Button.
Para incluir o formulário no projeto clique no menu PROJECT -> Add Windows Forms; (Abaixo a direita vemos o código do form2.cs)
private void lnkurl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { lnkurl.LinkVisited = true; System.Diagnostics.Process.Start("http://www.macoratti.net"); }
private void btnFechar_Click(object sender, System.EventArgs e) { this.Close(); }
Abaixo temos o código do formulário form1.cs que chama o método Sobre() para exibir o formulário form2.cs acima:
private void mnuSobre_Click(object sender, EventArgs e)
{
Sobre();
}private void toolStripAjuda_Click(object sender, EventArgs e)
{
Sobre();
}private void Sobre() { try { Form2 frm2 = new Form2(); frm2.ShowDialog(); if (frm2.DialogResult == DialogResult.OK) { frm2.Dispose(); } } catch (Exception ex) { MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Sair
A opção Sair solicita ao usuário a confirmação para encerrar ou não a aplicação.
private void sairToolStripMenuItem_Click(object sender, EventArgs e)
{
Sair();
}private void toolStripSair_Click(object sender, EventArgs e)
{
Sair();
}private void Sair()
{
if(MessageBox.Show("Deseja sair da aplicação ?","Sair",MessageBoxButtons.YesNo,MessageBoxIcon.Question)== System.Windows.Forms.DialogResult.Yes)
{
Application.Exit();
}
}
E assim temos as funcionalidades do nosso editor implementadas e prontas para serem usadas. Eu poderia continuar incluindo mais funcionalidades como o Refazer (Redo), Desfazer (Undo), etc. , mas deixo como exercício para você.
Executando o projeto temos uma visão do nosso editor em funcionamento abaixo:
Pegue o projeto completo aqui : RichTextBox_Imprimir.zip
E
Deus limpará de seus olhos toda a lágrima; e não haverá mais morte, nem pranto,
nem clamor, nem dor; porque já as primeiras coisas são passadas.
Apocalipse 21: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 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: