Introduction
It's very hard when we are coding for some project and we require the functionality that we can think of for each part, but if we try to think of them together, we just can't logically arrange the parts.
I got the main idea to write this article when I was coding for one project and we were in need of a textbox which can check the spelling and it can underline the wrong word. But, the main requirement was that it should be achieved using Microsoft's Word Interop.
This article will show you how to use Word's spell check functionality and underline the wrong word in the textbox.
When the user starts to type in the textbox and presses the spacebar, our functionality will check the last typed word against Word's spell check functionality to verify the word. If it is wrong, that word will be underlined. And when the user right clicks on the underlined wrong word, user will see the menu with available options for that wrong word. Once the user will select the option from the menu, it will be replaced with the right word.
Code Exploring
To implement spell check functionality, you can write code directly on Form or you can create user control. If you want to create a user control to incorporate this functionality, you must user Richtextbox
as the base class, since we are going to implement spell check functionality in Richtextbox
.
Step 1: Add a new Class file under solution
We are going to create a control which will incorporate the functionality. So, add class (.vb) file under the solution. Add as I mentioned above, use RichTextBox
as the base class.
Public Class SpellCheckTextBox
Inherits RichTextBox
Step 2: Add reference
Now our class is ready, but we will need the reference of Microsoft Word's DLL. So, we will have to add a reference of Microsoft Word Object library. To add the reference, right click on Solution -> Add reference -> COM tab and select Microsoft Word object library.
Now that a reference has been added to the project, we can use namespace for Office.
Imports Microsoft.Office
Step 3: Start writing Events
First event that you need to add is Textbox
's KeyUp
event. This is because, when the user will start typing, we will identify the space and when the user presses spacebar it means that he/she has finished the word and we will need to verify it.
Write this code under KeyUp
event of Textbox
.
If (Me.Text.Length = 0) Then
Me.SelectionFont = New Font(Me.SelectionFont.FontFamily, _
Me.SelectionFont.Size, FontStyle.Regular)
Me.Refresh()
End If
If (e.KeyValue = 32) Then
Dim m_strRecentWord As String = String.Empty
Dim m_intLastIndex As Integer = Me.Text.Substring_
(0, Me.SelectionStart - 1).LastIndexOf(" ")
Dim m_intLength As Integer = Me.SelectionStart - m_intLastIndex - 2
m_strRecentWord = Me.Text.Substring(m_intLastIndex + 1, m_intLength)
m_strRecentWord = m_strRecentWord.Trim()
If (m_strRecentWord.Length > 0 And IsWrongWord_
(m_strRecentWord) = True) Then
Me.SelectionStart = m_intLastIndex + 1
Me.SelectionLength = m_intLength
Me.SelectionFont = New Font(Me.SelectionFont.FontFamily, _
Me.SelectionFont.Size, FontStyle.Underline)
Me.SelectionStart = Me.SelectionStart + Me.SelectionLength + 1
Me.Refresh()
End If
End If
Once the word is verified against Word's spell check functionality, if it is wrong then underline the word as a wrong word. In Richtextbox
, if we want to change the format for a specific area, we need to change the selected text only.
Now, our wrong word(s) are underlined in Richtextbox
. And our next step will be to replace it with a selection from the menu by right clicking on that wrong word.
We will achieve this by MouseDown
event of RichTextbox
. When we right click on a wrong word, our job is to pick that right clicked word. To select the right clicked word, we are using the GetCharIndexFromPosition
function to get the index of right clicked character in the RichTextBox
. Once, we get the index of that character, we will find the space from this index to the right and left.To do that, we will split the content of RichTextBox
in three parts. Here is the code which will explain it all. Just paste this code in MouseDown
event of RichTextBox
.
If (Me.SpellCheck = False) Then
If (e.Button = Windows.Forms.MouseButtons.Right) Then
Dim m_objContextMenuStrip As New ContextMenuStrip
Dim m_intClickIndex As Int16 = _
Me.GetCharIndexFromPosition(New Point(e.X, e.Y))
Dim m_strInitialString As String = Me.Text.Substring_
(0, m_intClickIndex)
Dim m_intStartIndex As Int16 = Me.Text.Length - 1
If (Me.Text.IndexOf(" ", m_intClickIndex) <> -1) Then
m_intStartIndex = Me.Text.IndexOf(" ", m_intClickIndex)
End If
Dim m_intLastIndex As Int16 = m_strInitialString.LastIndexOf(" ")
Dim m_strWord As String = Me.Text.Substring_
(m_intLastIndex + 1, m_intStartIndex - m_intLastIndex)
If (m_strWord.Length > 0) Then
Dim m_doc As Word.Document = m_app.Documents.Add()
Dim m_listOfAlternateWords As Word.SpellingSuggestions = _
m_app.GetSpellingSuggestions(m_strWord)
If m_listOfAlternateWords.Count > 0 Then
m_objContextMenuStrip.Items.Clear()
Dim m_word As Integer
For m_word = 1 To m_listOfAlternateWords.Count
Dim Item As New ToolStripMenuItem()
Item.Name = m_listOfAlternateWords.Item(m_word).Name
Item.Text = Item.Name
Item.Tag = New Int16() {m_intLastIndex, m_intStartIndex}
AddHandler Item.Click, AddressOf ToolStripMenuItem_Click
m_objContextMenuStrip.Items.Add(Item)
Next
If (m_objContextMenuStrip.Items.Count > 0) Then
m_objContextMenuStrip.Show(Me, New Point(e.X, e.Y))
End If
End If
End If
m_objContextMenuStrip = Nothing
End If
End If
So, now we have the right clicked word. Send it to get the options from Word's spell check functionality. If there are multiple results, it means that word has suggestions. So, create a menu and use all the suggestions as menu items. We, are using Tag
property of each menu item to store the starting and ending index of right clicked word. So, these two indexes will be used to replace the right clicked word with the selected option from the menu.
Here are some functions which I have used while coding.
Private Function IsWrongWord(ByVal m_strWord As String) As Boolean
Dim m_listOfAlternateWords As Word.SpellingSuggestions = _
m_app.GetSpellingSuggestions(m_strWord)
If (m_listOfAlternateWords.Count > 0) Then
Return True
Else
Return False
End If
End Function
Private Sub UnderLineWrongWords()
Me.SelectionStart = 0
Dim m_range As Word.Range
m_range = m_app.ActiveDocument.Range
m_range.InsertAfter(Me.Text)
Dim m_spellCollection As Word.ProofreadingErrors = _
m_range.SpellingErrors
Dim m_intWord As Integer
Dim m_font As Font = Me.SelectionFont
Dim m_strIndex As Int16 = 0
For m_intWord = 1 To m_spellCollection.Count
Me.Find(m_spellCollection.Item(m_intWord).Text, _
m_strIndex, RichTextBoxFinds.WholeWord)
RichTextBoxFinds.WholeWord, RichTextBoxFinds.WholeWord)
m_strIndex = Me.Text.IndexOf(m_spellCollection.Item_
(m_intWord).Text, m_strIndex)
Me.SelectionFont = New Font(m_font.FontFamily, m_font.Size, _
FontStyle.Underline)
Next
Me.SelectionStart = Me.SelectionStart + Me.SelectionLength + 1
Me.Refresh()
End Sub
Private Sub SpellChecking()
If (Me.Text.Length > 0) Then
m_app.Visible = False
m_app.WindowState = 0
Dim m_template As Object = Missing.Value
Dim m_newTemplate As Object = Missing.Value
Dim m_documentType As Object = Missing.Value
Dim m_visible As Object = False
Dim m_optional As Object = Missing.Value
Dim m_doc As Word.Document = m_app.Documents.Add_
(m_template, m_newTemplate, m_documentType, m_visible)
m_doc.Words.First.InsertBefore(Me.Text)
Dim m_we As Word.ProofreadingErrors = m_doc.SpellingErrors _
m_doc.CheckSpelling(m_optional, m_optional, m_optional, _
m_optional, m_optional, m_optional, m_optional, m_optional, _
m_optional, m_optional, m_optional, m_optional)
Dim m_first As Object = 0
Dim m_last As Object = m_doc.Characters.Count - 1
Me.Text = m_doc.Range(m_first, m_last).Text
Dim m_saveChanges As Object = False
Dim m_originalFormat As Object = Missing.Value
Dim m_routeDocument As Object = Missing.Value
m_app.Quit(m_saveChanges, m_originalFormat, m_routeDocument)
Me.SelectionStart = 0
Me.SelectionLength = Me.Text.Length
Me.SelectionFont = New Font(Me.SelectionFont.FontFamily, _
Me.SelectionFont.Size, FontStyle.Regular)
Me.Refresh()
Me.SelectionStart = Me.Text.Length
m_app = New Word.Application()
m_doc = m_app.Documents.Add()
End If
End Sub
When we select any option from the menu, we will replace the wrong word with the selected option by using Tag
property of the menu item. Here is the code. Paste this in menu item click event.
Dim m_item As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
Dim m_pointArray As Int16() = CType(m_item.Tag, Int16())
Dim m_strFirstPart As String = String.Empty
If (m_pointArray(0) > 0) Then
m_strFirstPart = Me.Text.Substring(0, m_pointArray(0)) + " "
End If
Dim m_strMiddlePart As String = Me.Text.Substring(m_pointArray(0) + 1, _
m_pointArray(1) - m_pointArray(0))
Dim m_strLastPart As String = Me.Text.Substring(m_pointArray(1) + 1)
Me.SelectionStart = m_pointArray(0) + 1
Me.SelectionLength = m_strMiddlePart.Length
Me.SelectionFont = New Font(Me.SelectionFont.FontFamily, _
Me.SelectionFont.Size, FontStyle.Regular)
Me.SelectedText = m_item.Text + " "
Me.Refresh()
It is also possible that somebody pastes the text in RichTextBox
, so here, our underline functionality will be not used. So, we have to call the same functionality in the Leave
event of RichTextBox
. So, write this code in Leave
event of RichTextBox
.
UnderLineWrongWords()
Call SpellChecking()
Mark that we are calling the spellcheck dialogue of Word when we underline the wrong word. We have already covered this function above.
At the end override the Dispose
method.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (m_app Is Nothing) Then
Dim m_saveChanges As Object = False
Dim m_originalFormat As Object = Missing.Value
Dim m_routeDocument As Object = Missing.Value
m_app.Quit(m_saveChanges, m_originalFormat, m_routeDocument)
m_app = Nothing
End If
End If
MyBase.Dispose(disposing)
End Sub
So, here is the way to incorporate Word's spell check in our application.