VB.NET - Criando um editor de textos com verificação ortográfica

 

Neste artigo vou criar um editor com o recurso de verificação ortográfica. Como ando meio preguiçoso não vou criar o meu próprio verificador ortográfico , mas vou usar um que já esta pronto e disponível. Adivinha da onde eu vou tirar este verificador ? Se pensou no Word , acertou...

 

Nota: Eu já criei um editor no VB.NET . leia o artigo VB.NET - Criando um Editor de Textos . Mas este vai ser diferente.

 

Pois bem vou criar um editor usando os recursos do verificador ortográfico do Word em minha aplicação. Para isto vou usar OLE - Object Linking and Embedding.

a - Inicie um novo projeto no Visual Studio.NET com as seguintes características (sinta-se a vontade para alterar a seu gosto.)

  1. Project Types : Visual Basic Projects
  2. Templates : Windows Application
  3. Name : MeuEditor
  4. Location : c:\vbnet\MeuEditor

- Selecione o arquivo form1.vb no Solution Explorer e na janela propriedades altere o nome do arquivo para MeuEditor.vb

 

- Clique no formulário e altere as propriedades Text  para Meu Editor e Name para frmEditor

 

-Clique com o botão direito do mouse sobre o projeto MeuEditor no Solution Explorer e selecione Properties no menu suspenso ; a seguir na janela MeuEditor Property Pages no item Startut Object selecione frmEditor e clique OK

 

O projeto MeuEditor vai conter uma barra de status e 3 paineis (panels) na parte inferior do formulário. Cada painel irá exibir a seguinte informação:

  1. Caminho e nome do arquivo aberto

  2. O status da tecla CapsLock

  3. A data e o dia da semana

Poderíamos facilmente incluir o controle statusbar no formulário arrastando-o a partir da TollBox mas vou criar o controle statusbar e os três controles panels via código. Veja abaixo:

Add this code to the Declarations section at the top of the code window:

'Declara uma varíavel objeto referênciando o objeto StatusBar
Private StatusBar1 As StatusBar
'Declara três variáveis do tipo StatusBarPanel
Private Panel1 As StatusBarPanel
Private
Panel2 As StatusBarPanel
Private
Panel3 As StatusBarPanel

Vamos criar uma rotina chamada CriaStatusBar que irá criar , configurar e exibir a statusbar no formulário.

Private Sub CreateMyStatusBar()

Agora podemos usar o construtor (New) para criar um objeto Statusbar1 e três panels (panel1, panel2 e panel3)

'Cria a status bar e os três objetos usando o construtor de cada classe

StatusBar1 = New StatusBar()
Panel1 = New StatusBarPanel()

Panel2 = New StatusBarPanel()
Panel3 =
New StatusBarPanel()

Vamos ter que configurar cada um dos controles , e vamos fazer isto via código sem depender da toolbox:

1- Configurando o Panel1

'Exibe o  Panel1 com o estilo de bordar com contornos
Panel1.BorderStyle = StatusBarPanelBorderStyle.Sunken

'Inicia o texto do .
Panel1.Text = "New File"
'Alinha o conteudo do  Panel1 a esquerda. (temos três opções : Left, Center, e Right ).
Panel1.Alignment = HorizontalAlignment.Left
'Define a propriedade  AutoSize property para usar todo o espaço disponívelo na StatusbarStatusBar.  This
Panel1.AutoSize = StatusBarPanelAutoSize.Spring

2- Configurando o Panel2

'Exibe o Panel2 com o estilo de borda
Panel2.BorderStyle = StatusBarPanelBorderStyle.Sunken
'Centra o conteúdo do  Panel2
Panel2.Alignment = HorizontalAlignment.Center

'Usamos a API  GetKeyState para determinar o status da tecla Caps Lock (retornando 1 Caps Lock esta ativa)
'Para que isto funcione você deve incluir uma declaração private na seção Declarations
If GetKeyState(Keys.CapsLock) = 1 Then
    Panel2.
Text = "CAPSLOCK"
Else
    Panel2.
Text = "capslock"
End If
' Define a propriedade Panel2 para redimensionar todo o seu conteúdo.
Panel2.AutoSize = StatusBarPanelAutoSize.
Contents

Nota: A chamada a API GetKeyState  é feita usando o código abaixo:

Private Declare Function GetKeyState Lib "user32.dll" Alias     "GetKeyState" (ByVal nVirtKey As Long) As Integer

 

3- Configurando o Panel3

'Exibe o  Panel1 com o estilo de bordar com contornos
Panel3.BorderStyle = StatusBarPanelBorderStyle.Raised
'Define o texto de  Panel3 como sendo o dia e data atual.

Panel3.
Text = System.DateTime.Today.ToLongDateString()

' Define a propriedade Panel2 para redimensionar todo o seu conteúdo.

Panel3.
AutoSize = StatusBarPanelAutoSize.Contents

4- Juntando todas as peças para exibir a barra de status no formulário.

'Inclui os três  Panels na coleção StatusBarPanelCollection do StatusBar1.
StatusBar1.Panels.Add(Panel1)
StatusBar1.
Panels.Add(Panel2)
StatusBar1.
Panels.Add(Panel3)

'Exibe os Panels no controle StatusBar.

StatusBar1.
ShowPanels = True
'Inclui StatusBar1 a coleção  Controls do formulário
Me.Controls.Add(StatusBar1)

5- A rotina acabou . Agora basta invocá-la através de uma chamada no evento Load do formulário:

'Cria a  StatusBar quando o programa carrega.
CriaStatusBar()

6- Vamos testar ??? Pressione F5 e você deverá obter:

 

 

Legal !!! Já temos a status bar e três panels vamos criar agora um menu no formulário. Inclua o componente MainMenu no formulário. Na toolbox clique duas vezes sobre MainMenu e defina a seguinte hierarquia de opções:

 

Menu
Nivel 1
Text0
Nivel 2
Texto
Name

&Arquivo

  (nome padrão)
  &Novo mnuNovo
  &Abrir mnuAbrir
  &Salvar mnuSalvar
  ( Separador)  
  S&air mnuSair
&Opções   (nome padrão)
  &Verificador mnuVerificador

Ao clicar no MainMenu para incluir no formulário na verdade o controle irá aparecer no Component Tray. Assim:

Nota: Quando o Component Tray esta vazio ele fica oculto. Para incluir MainMenu1 no formulário você também pode definir a propriedade Menu do formulário para MainMenu1: Assim:

Para inserir um separador entre as opções do menu clique sobre o local onde deseja colocar o separador com clique no menu suspenso na opção : Insert Separator

 

 

Vamos incluir um controle RichtTextBox ao formulário , afinal estamos criando um editor não é mesmo ??? Você sabe que o controle RichtextBox suporta textos formatados (negrito , sublinhado, múltiplas fontes) . Vamos definir as propriedades deste controle como a seguir:

RichTextBox
Property Value
Name rtbEditor
MultiLine True
Text (blank)

Para garantir que o controle será redimensionado quando o formulário o for inclua o seguinte código no evento Resize do formulário:

'Inclui 3 a Left e Top para mudar a margem do controle RichTextBox( txtEditor )
rtbEditor.Left = 3
rtbEditor.
Top = 3
'A bordar do form é iguala 6 de largura , incluindo isto a 3 pixel da margem temos: 6 * 2 + 3 = 15
rtbEditor.Width = Me.Width - 15
'O título (Caption) do form tem 47 pixels de largura e a statusbar tem 30 então vamos obter: 47 + 30 + 3 = 80
rtbEditor.Height = Me.Height - 80

Se você rodar o projeto agora vai obter o formulário a seguir :

 

No item Novo vamos implementar o código para limpar o texto do editor:

'Limpa o conteudo do rtbEditor.
txtEditor.Clear()

 

 

Agora eu vou incluir mais dois controles no formulário do projeto. Os controles OpenFileDialog e SaveDialog. Na barra de ferramentas selecione estes controles e clique duas vezes sobre cada um deles para incluí-los no formulário.  Podemos visualizar os controles no component Tray do formulário , conforme exibido nas figuras abaixo:

 

 

A intenção de incluir estes controles no projeto e abrir uma janela de diálogo para abrir arquivos e outra salvar arquivos .  A seguir o código que usa o controle SaveFileDialog para criar a janela de diálogo Salvar: Estaremos configurando as propriedades :

‘Atribuir um texto a propriedade Title property (O texto é exibido na barra de títulos da janela Save)
SaveFileDialog1.Title = "Informe o nome do arquivo"
‘A propriedade Filter permite que você determine que tipo de arquivo será listado na janela.
SaveFileDialog1.Filter = "Text File (*.txt) | *.txt"
‘A propriedade AddExtension faz com que a extensão .txt  seja automaticamente incluida a qualquer arquivo que o usuário escolher.
SaveFileDialog1.AddExtension = True
‘Definindo a propriedade OverwritePrompt como true, uma janela de alerta irá surgir se o usuário tentar sobrepor um arquivo existente SaveFileDialog1.OverwritePrompt = True
‘A propriedadse InitialDirectory permite que você especifique o diretório inicial que será exibido quando a janela abrir.
SaveFileDialog1.InitialDirectory = "C:\"
‘O método ShowDialog exibe a janela Save.
SaveFileDialog1.ShowDialog()

Podemos por o código acima no evento mnuSalvar_Click. Ele não esta completo pois não esta salvando o arquivo ainda apenas exibe janela Salvar Arquivo. Vamos usar o namespace System.IO.FileStream para escrever para um arquivo.

 

Precisamos criar um FileStream para realizar as operações de entrada e saída em um arquivo. Podemos criar o objeto FileStream dinamicamente através de uma instância do seu objeto construtor, assim :

    Dim FStream As New System.IO.FileStream(<NomeArquivo>, IO.FileMode.Create)

Percebeu que o método FileStream do namespace System.IO  precisa de dois parâmetros:

  1. O - FIle Name -nome do arquivo que será criado ou aberto
  2. O - File Mode - que determina como o arquivo será aberto. As opções são:
    • Append
    • Create
    • CreateNew
    • Open
    • OpenCreate
    • Truncate

 Após criar o objeto FileStream podemos criar um objeto StreamWriter para que o objeto FileStream possa escrever para o arquivo. O código é o seguinte:

    Dim SWriter As New System.IO.StreamWriter(FStream)

O parâmetro FStream é o objeto FileStream que acabamos de criar. Desde que o objeto StreamWrite seja criado nos podemos escrever para o arquivo usando o método Write; assim:0

    SWriter.Write(<String>)

Para concluir o código que incluímos no evento Click do menu Salvar iremos adicionar o seguinte código que vai Salvar o arquivo informado:

‘Verifique se um nome de arquivo foi informado. Se a propriedade FileName estiver em branco o usuário clicou no botão Cancelar ou clicou em Salvar sem definir um nome de arquivo..
If SaveFileDialog1.FileName <> "" Then
    ‘Cria um objeto FileStream que se comunica com o arquivo e abre no modo Create.
    Dim FStream As _
       
New System.IO.FileStream(SaveFileDialog1.FileName, IO.FileMode.Create)
    ‘Cria um objeto  StreamWriter para que o FileStream possa escrever no arquivo.
    Dim SWriter As New System.IO.StreamWriter(FStream)
    ‘Escreve o conteúdo do arquivo no richtexbox rtbtEditor .
    SWriter.Write(
rtbEditor.Text)
    ‘fecha o StreamWriter e FileStream.
    SWriter.Close()
    FStream.
Close()
    ‘Destroi os objetos StreamWriter e FileStream.
    SWriter = Nothing
    FStream
= Nothing
End If

Vamos a seguir usar o controle OpenFileDialog para poder ler a partir do arquivo. A única diferença entre os controles OpenFileDialog e SaveFileDialog e que o texto no botão do primeiro diz Abrir e no segundo diz Salvar. Inclua o código abaixo no evento Click do menu Abrir para que a janela de diálogo Abrir seja exibida:

OpenFileDialog1.Title = "Escolha um arquivo para abrir"
'Lista apenas os arquivos com extensão .txt.
OpenFileDialog1.Filter = "Text File (*.txt) | *.txt"
‘Se o usuário informar um nome de arquivo a extensão .txt  será incluida automaticamente se ele não informar.
OpenFileDialog1.AddExtension = True
‘A propriedade InitialDirectory permite abrir um diretório específico.
OpenFileDialog1.InitialDirectory = "C:\"
‘O método ShowDialog exibe a janela Abrir..
OpenFileDialog1.ShowDialog()

Nota : O controle OpenFileDialog não tem a propriedade OverwritePrompt , pois o usuário esta abrindo um arquivo.

Vamos criar um objeto System.IO.FileStream  para ler a partir de um arquivo. Sua criação é idêntica a que fizemos para escrever no arquivo com exceção do parâmetro FileMode . Iremos usar o modo : IO.FileMode.Open  . Assim :

    Dim FStream As New System.IO.FileStream(<File Name>, IO.FileMode.Open)

Como queremos ler vamos ter que criar um StreamReader para poder ler a partir de um FileStream. O código que faz isto é o seguinte:

    Dim SReader As New System.IO.StreamReader(FStream)

Agora podemos usar o método ReadToEnd par ler o conteúdo de um arquivo paro o RichtextBox rtbEditor.text.Assim

     rtbEditor.Text = SReader.ReadToEnd()

Para complementar o código já incluido no evento menuAbrir_click adicione o código abaixo:

‘Verifique se um nome de arquivo foi informado. Se a propriedade FileName estiver em branco o usuário clicou no botão Cancelar ou clicou em Salvar sem definir um nome de arquivo..‘
If
OpenFileDialog1.FileName <> "" Then
    ‘Cria um objeto FileStream que faz a conexão com o aruqivo e determina como o arquivo será aberto.
    Dim FStream As  New System.IO.FileStream(OpenFileDialog1.FileName, IO.FileMode.Open)
    ‘Cria um objeto StreamReader  para o FileStream ler do arquivo.
    Dim SReader As New System.IO.StreamReader(FStream)
    ‘Le o conteúdo do aruivo no editor.
     rtb
Editor.Text = SReader.ReadToEnd()
    ‘Fecha StreamReader e FileStream.
    SReader.Close()
   
FStream.Close()
    ‘Destroi os objetos StreamReader e FileStream
    SReader = Nothing
   
FStream = Nothing
End If

Agora salve o projeto e rode o programa , digite algo no editor e salve usando a opção Salvar do menu. A seguir abra o arquivo que você salvou . E então funciona ???

Atualizando o status da tecla Caps Lock

Para atualizar o status da tecla Caps Lock vamos usar o evento KeyUp pois ele ocorre depois que o pressionamento de uma tecla ocorreu. O evento KeyPress ocorre antes que a tecla pressionada envie o seu código para o sistema operacional e isto seria muito rápido . Vamos então colocar o código para refletir o estado da tecla Caps Lock no evento KeyUp do rtbEditor conforme abaixo:

If e.KeyValue = Keys.CapsLock Then
    'Usamos a API GetKeyState para determinar o statuso de  Caps Lock
    '   Retornando 1 Caps Lock esta ativa.
    If GetKeyState(Keys.CapsLock) = 1 Then
        Panel2.
Text = "CAPSLOCK"
    Else
        Panel2.
Text = "capslock"
    End If
End If

Verificando a ortografia com o  Microsoft Word

Finalmente chegamos ao mais interessante vamos usar o Word para fazer a verificação ortográfica no nosso editor. Para isto precisamos definir uma referência para a library Microsoft Word 10.0 Object . Este objeto contém as declarações e definições que iremos usar para implementar esta funcionalidade na nossa aplicação.

Para definir uma referência no menu Project  selecione a opção add Reference... :

Na janela Add Reference clique na aba COM para exibir as libraries COM.  Procure na lista de componentes o componente  Microsoft Word 10.0 Object Library , clique sobre ele de forma que ele aparece na em Selected Components e a seguir clique no botão Select :

Agora clique no botão OK para fechar a janela Add Reference.

Criando um referência a um Objeto Word

Estamos prontos para criar uma variável objeto do tipo Word. Inclua a seguinte linha de código na seção Declarations do projeto:

Dim objWord As Word.ApplicationClass

Não haverá perigo de você errar pois ao ir digitando uma lista de classes disponíveis irá surgir para guiá-lo.

A classe ApplicationClass expõe toda a funcionalidade do Word que iremos precisar.

Agora podemos usar o objeto construtor para criar uma instância do Word. O código a seguir deverá é o seguinte:

'Tenha certeza de que o objeto objWordjá não está referenciando uma instância do Word
If objWord
Is Nothing Then
     'Use o objeto construtor do objeto  Word.ApplicationClass para criar uma instância do Word
    objWord= New Word.ApplicationClass()
End If

Para evitar criar múltiplas instâncias do Word você deve sempre verificar se a variável objeto já não esta usando uma referência ao Word. Nothing é o estado de uma variável de referência que não esta sendo usada.

Ao criar a instância já temos o Word iniciando . Vamos então usar os recursos que ele disponibiliza. Vamos neste caso usar o verificador ortográfico no richtextbox rtbEditor. Iremos fazer assim :

  1. Começamos por incluir um novo documento a nossa instância do  Word:

'Use o método Add  da classe Documents cpara incluir um novo documento em branco
objWord.Documents.Add()

  1. Copie o conteúdo do rtbEditor para o documento em branco:

'Use o método TypeText da classe Selection para copiar o conteudo do editor rtbEditor para o novo documento.
objWord.Selection.TypeText(txtEditor.Text)

  1. Agora estamos pronto para fazer a mágica , ou seja , a verificação ortográfica . Iremos usar o método  CheckSpelling  da coleção e Item  (Que é uma coleção de todos os documentos):

'Use o método CheckSpelling da coleção  Item collection para verificar a ortografia do texto no novo documento. 
objWord.Documents.Item(objWord.Documents.Count).CheckSpelling()

Na linha de código acima a propriedade Count da coleção Documents é igual ao valor do índice do novo documento que incluimos.(O valor de index começa em 1 e não em 0)

  1. Assim que a verificação ortográfica terminar precisamos copiar o texto corrigido de volta o rtbEditor

'Copia o texto corrigido do comento para o editor  rtbEditor 
txtEditor.Text =  ObjWord.Documents.Item(objWord.Documents.Count).Content.Text

  1. Para encerrar precisamos fechar o documento Word criado . Vamos sair do Word e desconectar a variável objeto da referência a objWord definindo-a como Nothing.  Assim a instância do Word irá encerrar:

'Fecha o documento que criamos salvando as alterações.
objWord.Documents.Close(Word.wdSaveOptions.wdDoNotSaveChanges)
'Sai do Microsoft Word
objWord.Quit()
'Define a variável de referência objWord como igual a Nothing
objWord= Nothing

Para testar , salve projeto e rode o programa. Digite  uma linha de texto com erros e efetue a verificação ortográfica. Você verá o verificador em ação . Faça as correções e no final seu texto estará isento de erros de 'portugueis'.

Você vai comprovar que funciona. Só não recomendo usar textos muitos longos..

 

Para facilitar a sua vida pegue o código no formato texto clicando aqui. MeuEditor.zip ( basta copiar e colar no seu VB.NET)

 

Dica: Contando os erros de ortografia do texto.

Se quiser saber quantos erros foram corrigidos basta criar um novo item no menu e inserir o seguinte código no seu evento Click:

Dim iContadorErros As Integer
.
If objWord Is Nothing Then
   
objWord = New Word.ApplicationClass()
End If

objWord.Documents.Add()
objWord.
Selection.TypeText(rtbtEditor.Text)
'A propriedade Count da classe SpellingErrors da classe ActiveDocument é igual ao numero de correções feitas no texto.
iContadorErros = objWord.ActiveDocument.SpellingErrors.Count()
objWord.
Documents.Close(Word.WdSaveOptions.wdDoNotSaveChanges)
objWord.
Quit()
objWord =
Nothing

if
iContadorErros > 0 Then
    MessageBox.
Show("Este documentoe contém : "  &   iContadorErros  & " ortográficos !")
Else
    MessageBox.
Show("Não há erros ortográficos no texto.")
End If


Até o próximo artigo .net...

 

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti