VB .NET - Atualizando o conteúdo de um RichTextBox com o Word/Wordpad


 Neste artigo vou mostrar como podemos atualizar o conteúdo de controle RichTextBox usando o Word ou WordPad.

O componente RichTextBox é similar com o controle TextBox mas fornece características mais avançadas que podemos explorar. Dentre elas temos a formatação de texto, cores e fontes. Da mesma forma que o controle TextBox o controle RichTextBox é baseado na classe TextBoxBase a qual é baseada na classe Control.

Ao acessar textos no controle RichTextBox temos duas opções:

  1. text - Trata o texto no formato normal
  2. rtf - Trata o texto no formato Rich Text Format

Além disto o controle RichTextBox fornece métodos para abrir e salvar arquivos e procurar strings:

 - LoadFile - permite carregar um arquivo .RTF existente ou um arquivo Texto no controle. Você pode também carregar dados de um stream de dados já aberto.

- SaveFile - permite salvar para RTF ou ASCII texto. Você também pode salvar para um stream de dados aberto.

- Find -  permite localizar strings específicas no texto do controle

Você também pode inicializar o controle para dados armazenados em memória.  Se o texto no interior do controle contiver links para sítios web , você pode usar a propriedade DetectUrls para exibir o link apropriadamente no texto; pode também tratar o evento LinkClicked para realizar tarefas associada com o link.

A propriedade SelectionProtected permite proteger o texto no controle de manipulações por parte do usuário. Com o texto protegido você pode gerenciar o evento Protected para determinar quando o usuário tentou modificar o texto ou alertar o usuário que o texto esta protegido.

Eu já abordei o controle RichTextBox em diversos artigos (veja as referências) por isso neste artigo eu apenas vou mostrar como podemos abrir um arquivo RTF  usando o Word e após alterar o texto salvar essas alterações no arquivo RTF exibido no controle RichTextBox.

Vamos então realizar as seguintes tarefas:

  1. Inserir um texto em um controle RichTextBox
  2. Salvar o conteúdo do controle RichTextBox para um arquivo temporário
  3. Iniciar um processo para o Word ou WordPad para abrir este arquivo
  4. Editar o texto no Word/WordPad , fechar a janela e salvar o arquivo
  5. No processo de fechamento disparar um evento exit e chamar um método para atualizar o conteúdo do RichTextBox

Isso pode parecer uma tarefa simples de fazer mas se você não tomar cuidado pode perder os cabelos com ela.

Observe que estamos realizando uma atualização cross-thread e estamos tratando de um processo exit em uma outra thread.

Sem tomar os devidos cuidado você pode se deparar com a mensagem de erro abaixo:

"Crossthread operation not valid : Control 'rtbTexto' accessed from a thread other than the thread it was created on."

Recursos usados:

Criando o projeto no Visual Studio 2013 Express

Abra o VS Express 2013 for Windows desktop e clique em New Project;

A seguir selecione a linguagem Visual Basic e o template Windows Forms Application;

Informe o nome Atualizando_RTF_Word e clique no botão OK;

A seguir vamos incluir a partir da ToolBox os seguintes controles no formulário form1.vb do projeto:

Disponha os controles conforme o leiaute da figura abaixo:

A seguir vamos declarar as seguintes variáveis formulário form1.vb:

Private WithEvents WordProcess As New Process
Public strNomeArquivoTemp As String = "
C:\dados\DemoMac.rtf"
Private Delegate Sub AtualizaRichTextBox(ByVal strNomeArquivo As String)

Neste código estamos fazendo o seguinte:

Como o processo WordProcess será executado em uma thread diferente da execução do formulário e queremos atualizar o controle RTF do formulário, para evitar uma exception temos que definir um delegate para realizar esta atualização. (Poderíamos usar um BackgroundWorker)

Definindo o código do Projeto

Vamos iniciar definindo o código do evento Click do botão de comando Editar Texto conforme abaixo:

Private Sub btnEditar_Click(sender As Object, e As EventArgs) Handles btnEditar.Click
        Try
            'Salva o conteudo do rich textbox em um arquivo temporario
            rtbTexto.SaveFile(strNomeArquivoTemp, RichTextBoxStreamType.RichText)
            'Abre o arquivo no Wordpad ou Word
            AbrirEditor(strNomeArquivoTemp)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

O código salva o conteúdo do RichTextBox em um arquivo temporário e chama o método AbrirEditor() cujo código é dado  a seguir:

 Private Sub AbrirEditor(ByVal strNomeArquivo As String)
        Try
            'Abre a janela do WordPad/Word
            WordProcess.EnableRaisingEvents = True
            WordProcess.StartInfo.FileName = strNomeArquivo
            WordProcess.Start()
        Catch ex As System.Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

 

O código inicia um novo processo (thread) para o Word e abre o arquivo com o conteúdo do RichTextBox.

Quando o processo do Word for finalizado temos que disparar um evento chamado WordProcess_Exited que deverá chamar a rotina AtualizaTextBox para atualizar o conteúdo do controle RichTextBox que esta em outra thread.

A seguir temos o código que realiza esta tarefa :

 Private Sub WordProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles WordProcess.Exited
        Try
            'Invoca o método para atualizar o conteudo do Rich Text Box
            Dim delAtualizaRichText As AtualizaRichTextBox = AddressOf AtualizaTextBox
            Me.Invoke(delAtualizaRichText, New Object() {"C:\Dados\DemoMac.rtf"})
        Catch ex As System.Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

A seguir temos o código do método AtualizaTextBox() :

Private Sub AtualizaTextBox(ByVal strNomeArquivo As String)
  Try
     'Atualiza o conteudo do Rich Text com o conteudo do arquivo temporario
     rtbTexto.LoadFile(strNomeArquivo, RichTextBoxStreamType.RichText)
  Catch ex As Exception
     MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
  End Try
End Sub

Para mostrar que apenas abrindo e fechando o Word em um processo separado não seria possível atualizar o conteúdo do RichTextBox sem usar um delegate eu inclui no evento Click de botão Abrir no WordPad o código que abre o WordPad com o texto do RichTextBox.

    Private Sub btnAbrirWordPad_Click(sender As Object, e As EventArgs) Handles btnAbrirWordPad.Click
        Try
            Dim valor As System.Diagnostics.ProcessStartInfo
            valor = New System.Diagnostics.ProcessStartInfo("wordpad.exe", strNomeArquivoTemp)
            System.Diagnostics.Process.Start(valor)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

 

Executando o projeto teremos o seguinte resultado:

1- Abrindo o Word com o conteúdo do RichTextBox e alterando sua formatação

2- Atualizar o conteúdo no RichtTextBox após salvar o texto no Word e encerrar o processo do Word:

Se você abrir o texto no WordPad poderá alterá-lo mas o conteúdo do RichTextBox não será atualizado com o código que usamos no artigo para o evento Click do botão Abrir no WordPad.

Pegue o projeto completo aqui: Atualizando_RTF_Word.zip

João 6:35 Declarou-lhes Jesus. Eu sou o pão da vida; aquele que vem a mim, de modo algum terá fome, e quem crê em mim jamais terá sede.

João 6:36 Mas como já vos disse, vós me tendes visto, e contudo não credes.

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:


José Carlos Macoratti