Advanced Visual Basic .NET - Project 5

My Editor - OLE Automation

Project 5

Removing your old project and creating a new one

Run Visual Basis .NET and open your Solution (<your name>.sln).

Right-click on the DatabaseSnooper project in the Solution Explorer window and select Remove from the context menu.  Click the OK button when warned that DatabaseSnooper will be removed from the Solution.  Drop down the File menu and select New Project under the Add Project menu item.  When the Add New Project dialog appears, be sure that the Visual Basic Projects folder is open in the Project Types pane, and that the Windows Application template is selected in the Templates pane.  Type MyEditor in the Name textbox.  Then click the OK button.  This creates a new folder inside the \Visual Studio Projects\<Your Name> folder named MyEditor:

        ...My Documents\Visual Studio Projects\<Your Name>\MyEditor.

Note: When class is over, be sure to follow the instructions at the end of this project that tell you how to copy your project to your floppy diskette so you can take it home with you.

Rename the Form file and change it's Name and Text properties

With the form file (Form1.vb) selected in the Solution Explorer window, so that it's File properties are displayed in the Properties window, change the File Name property to frmEditor.vb (don't forget to include the .vb extension).

Now click on the form in the Designer window to display it's properties:

Setting the Startup Object

Right-click on the MyEditor project in your Solution Explorer window, click on the Properties item at the bottom of the context-menu.  In the MyEditor Property Pages dialog drop down the Startup object list and choose frmEditor and click the OK button.

Creating a Simple Editor that uses the Microsoft« Word spell checker

In this project we will create a simple word processor.  It will include a statusbar and the option to do spell checking.  But instead of creating our own spell checker, we will use the same spell checker that Microsoft Word uses by using OLE automation.  OLE is an acronym that stands for Object Linking and Embedding.  We will embed the functionality of the Microsoft Word spell checker into our application.  Here is an example illustration of the finished MyEditor application:

Adding a Statusbar to the form

Notice the statusbar at the bottom of the illustration above.  It has three panels.  Starting from the left end they are:

  1. A sunken panel that displays the path and name of the open file.
  2. A sunken panel that displays the status of the Capslock key.
  3. A raised panel that displays the Date, including the day of the week.

Instead of adding our statusbar by pulling it from the Control Toolbox, we will use code only to create and configure our statusbar.  To create a statusbar with three panels with code only, we will use object constructors.

Creating a Statusbar and three Panels

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

'Declare a StatusBar object reference variable
Private StatusBar1 As StatusBar
'Declare three StatusBarPanel object reference variables
Private Panel1 As StatusBarPanel
Private
Panel2 As StatusBarPanel
Private
Panel3 As StatusBarPanel

The above code creates the reference variables for a statusbar (StatusBar1) and three statusbar panels (Panel1, Panel2, and Panel3).  We will now make a custom CreateMyStatusBar procedure to hold the code that will create, configure, and display the statusbar.  At the bottom of the Code window, make a blank line above the End Class statement--and below the last End Sub statement--then type the following line of code and press enter to create a custom  CreateMyStatusBar procedure:

Private Sub CreateMyStatusBar()

Now we can use the object constructor (New) to create StatusBar1 and its three statusbar panels (Panel1, Panel2, and Panel3). Type the following code into your new CreateMyStatusBar procedure:

'Create the statusbar and three panels with their Object Constructors
StatusBar1 = New StatusBar()
Panel1 = New StatusBarPanel()

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

The above code creates the objects, now we can configure the panels and add them to StatusBar1.  Add the following code to the CreateMyStatusBar procedure, below the object constructor code above:

Configuring Panel1

'Display Panel1 with a sunken border style
Panel1.BorderStyle = StatusBarPanelBorderStyle.Sunken
'Initialize the text of Panel1.  We begin with no open file.
Panel1.Text = "New File"
'Align the contents of Panel1 to the left.  The HorizontalAlignment
'    enumeration has Left, Center, and Right elements.
Panel1.Alignment = HorizontalAlignment.Left
'Set the AutoSize property to use all remaining space on the StatusBar.  This
'    makes sure that Panel1 automatically stretches to fill any space that
'    the other two panel don't use.
Panel1.AutoSize = StatusBarPanelAutoSize.Spring

Configuring Panel2

'Display Panel2 with a sunken border style
Panel2.BorderStyle = StatusBarPanelBorderStyle.Sunken
'Center the contents of Panel2
Panel2.Alignment = HorizontalAlignment.Center
'Use the GetKeyState API call to determine the status of the Caps Lock
'    key.  We will need to add a private declaration for GetKeyState to the
'    Declarations section.  When the return value is 1, Caps Lock is on.
If GetKeyState(Keys.CapsLock) = 1 Then
    Panel2.
Text = "CAPSLOCK"
Else
    Panel2.
Text = "capslock"
End If
' Set the AutoSize property so that Panel2 resizes to fit its contents.
Panel2.AutoSize = StatusBarPanelAutoSize.
Contents

To use the GetKeyState API call in the code above, we need to declare it in the Declarations section.  Add the following line of code to the Declarations section:

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

Now continue adding the following code to the CreateMyStatusBar procedure:

Configuring Panel3

'Display Panel3 with a raised border style.
Panel3.
BorderStyle = StatusBarPanelBorderStyle.Raised

'Set the text of the Panel3 to the current day and date.

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

' Set the AutoSize property so that Panel3 resizes to fit its contents.

Panel3.
AutoSize = StatusBarPanelAutoSize.Contents

Putting the parts together and displaying the Statusbar

We are now ready to put all the pieces together and display the statusbar on the form.  Add the following code at the end of the CreateMyStatusBar procedure:

'Add the three Panels to the StatusBarPanelCollection of StatusBar1.
StatusBar1.Panels.Add(Panel1)
StatusBar1.
Panels.Add(Panel2)
StatusBar1.
Panels.Add(Panel3)

'Display the Panels in the StatusBar control.

StatusBar1.
ShowPanels = True
'Add StatusBar1 to the Controls collection of the form.
Me.Controls.Add(StatusBar1)

Last but not least add a call to our CreateMyStatusBar procedure to the frmEditor_Load event procedure so that the statusbar is created when the program starts:

'Create the StatusBar when the program starts.
CreateMyStatusBar()

Testing the program so far

Save the project now.  Run the program.  Is your statusbar displayed?  Fix any problems before going on.  

Adding a MainMenu control to the form

Menu Table
Level 1
Text
Level 2
Text
Name

&File

  (default name)
  &New mnuNew
  &Open mnuOpen
  &Save mnuSave
  (Insert Separator)  
  E&xit mnuExit
&Options   (default name)
  &Spell Check mnuSpell

Double-click on the MainMenu item on the Control toolbox to add a MainMenu control (MainMenu1) to the Component Tray.  Once added to your project, the MainMenu control appears in the Component Tray, like this:

Note: The Component Tray at the bottom of the screen is normally hidden when it is empty. 

To add MainMenu1 to the form, set the Menu property of the form to MainMenu1, like this:

After setting the Menu property to MainMenu1, click once on the MainMenu1 control in the Component Tray to select it.  Once ManuMenu1 is selected in the Component Tray, the new blank menu should appear in the upper left corner of the form, like this:

Place the cursor on the Type Here text by clicking on it, and the menu will look like this:

Type &File for the text value, leave the default name (MenuItem1) unchanged. Now place the cursor in the first menu entry on the File menu by clicking it:

Type &New as the text value, and in the Properties window type mnuNew for the name:

Use the Menu Table above to guide you, and complete the rest of the menu.  When you get to the addition of the separator (just below half way down the Menu Table), right-click on the menu item where the separator is to go and choose Insert Separator from the context menu:

To add the Options menu, click in the next 1st level menu item:

Adding a RichTextBox control to the Form

Use the illustration at the beginning of the project and add a RichTextBox control where shown.  Note: Unlike a regular TextBox control, a RichTextBox has extra support for Rich Text Documents that can contain formatted text (Bold, Underline, etc.) and multiple fonts within the same document.  Set it's properties, like this:

RichTextBox
Property Value
Name txtEditor
MultiLine True
Text (blank)

To make sure that the textbox is resized when the form is resized, add the following code to the frmEditor_Resize event procedure:

'Add 3 to Left and Top to shift the edge of the txtEditor
'    textbox 3 pixels away from the edge of the form.

txtEditor.
Left = 3
txtEditor.
Top = 3
'The Border of the form is 6 pixels wide, add to that the
'   3 pixels from the edge and we get 6 * 2 + 3 = 15
txtEditor.Width = Me.Width - 15
'The Caption bar of the form is 47 pixels high and the statusbar
'   is 30 pixels high so we get 47 + 30 + 3 = 80
txtEditor.Height = Me.Height - 80

Testing the program so far

Save the project now.  Run the program.  Try resizing the form (Note: There is a resize-grabber handle on the right end of the statusbar).  How does it look?  Does the txtEditor textbox stretch to fit the form?  Does the menu look good? 

Adding OpenFileDialog and SaveFileDialog controls to the Form

Scroll down the Control toolbox and add one (double-click once) OpenFileDialog control and SaveFileDialog control to the Component Tray:

  Once added, your Component Tray should look like this:

Using a SaveFileDialog control to help you save files

Why do the Open file and Save file dialogs that most applications use look very similar to each other (see the illustration below)?  The idea of a Common User Interface is an important driving force behind the development of windows applications.  In theory, if all applications work in a similar way, a user will be more productive and take less time learning how to use new applications.  To that end, the Save and Open file dialog boxes look and behave the same way between different applications.  In fact, the code that generates these dialog boxes exists inside a Dynamic Link Library (DLL) file that is part of the operating system.  So the Save file and Open file dialog boxes don't just look the same between different applications; they are the same!

When we use a SaveFileDialog dialog box, we are actually displaying the same Save dialog that most other applications will display.  This is how the SaveFileDialog dialog looks.  This should look familiar to you:

Here is the code that uses the SaveFileDialog control to create the above Save dialog box:

‘Assign the dialog’s Title property (this is displayed in the caption bar of the Save dialog)
SaveFileDialog1.Title = "Specify a Name for the File"
‘The Filter property lets you specify which file types will to be listed in the Save dialog.
'    The text after the
= sign and to the left of the | (vertical bar) is the text displayed in the
'    Save As Type dropdown listbox (shown above). The last part:
*.txt is the actual filter
‘    specification, which means only files with a TXT extension will be displayed.
SaveFileDialog1.Filter = "Text File (*.txt) | *.txt"
‘The AddExtension property makes sure that the .txt extension is automatically
'    added to any file name the user specifies.
SaveFileDialog1.AddExtension = True
‘By setting the OverwritePrompt property to true, a warning dialog will appear
'    if the user attempts to save over an existing file.
SaveFileDialog1.OverwritePrompt = True
‘The InitialDirectory property lets you specify the start up directory that is displayed
'    when the Save dialog first opens.
SaveFileDialog1.InitialDirectory = "C:\"
‘The ShowDialog method displays the Save dialog.  Any code that follows this
'    line of code will not be executed until the Save dialog is closed.
SaveFileDialog1.ShowDialog()

Type the above code into the mnuSave_Click event procedure.   The code above does not actually save a file.  All it does is use the SaveFileDialog to display the Save dialog where the user specifies the name of the file to be saved--or they can browse and select an existing file to overwrite it.  It is still up to us to write the code that will save the contents of the txtEditor textbox to the file that the user specifies.

Creating a System.IO.FileStream object to write to a file

We need to create a FileStream to do file input and output.  We can dynamically create a FileStream object by dimensioning an instance of it with it's object constructor, like this (do not type the following code yet):

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

Using the FileStream method of System.IO class to create the FileStream object requires two parameters:

  1. The File Name--the name of the file to be created or opened, which must include the full path and name of the file.
  2. The File Mode--which determines how the file is to be opened.  The File Mode options that are available include, Append, Create, CreateNew, Open, OpenOrCreate, and Truncate.

Once we have created a FileStream object--which gives us a connection to the file and determines how it is opened--we can create a StreamWriter object for the FileStream that makes writing to the file easy, like this:

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

The FStream parameter is the FileStream object we had just created.  Once the StreamWriter object is created we can write to the file with the StreamWriter's  Write method, like this:

    SWriter.Write(<String>)

To close the File once we are finished writing to it, we must use the Close methods of both the StreamWriter and FileStream objects, like this:

    SWriter.Close()
   
FStream.Close()

Type the following code below the code you had previously added to the mnuSave_Click event procedure:

‘Make sure the user specified a file name for the file to be created.  If the FileName property
'    is blank, the user either clicked the Cancel button or clicked Save without specifying a file
'    name in the Name text box of the SaveFileDialog control.
If SaveFileDialog1.FileName <> "" Then
    ‘Create a FileStream object that connects to the file and opens it in create mode.
    Dim FStream As _
       
New System.IO.FileStream(SaveFileDialog1.FileName, IO.FileMode.Create)
    ‘Create a StreamWriter object for the FileStream to make writing to the file easy.
    Dim SWriter As New System.IO.StreamWriter(FStream)
    ‘Write the contents of the txtEditor textbox to the file.
    SWriter.Write(txtEditor.Text)
    ‘Close the StreamWriter and FileStream.
    SWriter.Close()
    FStream.
Close()
    ‘Destroy the StreamWriter and FileStream objects. 
    SWriter = Nothing
    FStream
= Nothing
End If

Using an OpenFileDialog control to help you read from a file

The only significant difference between the OpenFileDialog and SaveFileDialog controls is that the text on the button of the OpenFileDialog says Open and the text on the button of the SaveFileDialog says Save.   Add the following code to the mnuOpen_Click event procedure to display an OpenFileDialog:

OpenFileDialog1.Title = "Choose a File to Open"
'List files with a .txt extension only.
OpenFileDialog1.Filter = "Text File (*.txt) | *.txt"
‘If the user types a filename the .txt extension is added
'    automatically if they don't include it.
OpenFileDialog1.AddExtension = True
‘The InitialDirectory property lets you specify the start up directory that is displayed
'    when the Open dialog first opens.
OpenFileDialog1.InitialDirectory = "C:\"
‘The ShowDialog method displays the Open dialog.  Any code that follows this
'    line of code will not be executed until the Open dialog is closed.
OpenFileDialog1.ShowDialog()

The OpenFileDialog has no OverwritePrompt property since the user is picking a file to be opened, not saved.

Creating a System.IO.FileStream object to read from a file

The FileStream object that we'll need to read from a file will be created exactly the same way we constructed the FileStream object to write to a file, except for the FileMode parameter.  Instead of using IO.FileMode.Create, we will use IO.FileMode.Open, like this (do not type the following code yet):

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

Instead of a StreamWriter which lets us write to a FileStream, we need to create a StreamReader so that we can read from a FileStream:

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

Now, reading the contents of the file into the txtEditor textbox is easy with the StreamReader's ReadToEnd method, like this:

    txtEditor.Text = SReader.ReadToEnd()

Type the following code below the code you had previously added to the mnuOpen_Click event procedure:

‘Make sure the user specified a file name for the file to be created.  If the FileName property
'    is blank, the user either clicked the Cancel button or clicked Save without specifying a file
'    name in the Name text box of the SaveFileDialog control.
If OpenFileDialog1.FileName <> "" Then
    ‘Create a FileStream object that connects to the file and determines how the file is opened.
    Dim FStream As _
        New
System.IO.FileStream(OpenFileDialog1.FileName, IO.FileMode.Open)
    ‘Create StreamReader object for the FileStream to make reading from the file easy.
    Dim SReader As New System.IO.StreamReader(FStream)
    ‘Read the contents of the file into the txtEditor textbox.
    txtEditor.Text = SReader.ReadToEnd()
    ‘Close the StreamReader and FileStream.
    SReader.Close()
   
FStream.Close()
    ‘Destroy the StreamReader and FileStream objects. 
    SReader = Nothing
   
FStream = Nothing
End If

Testing the program so far

Before testing the project, click on the Save All button on the toolbar to save it.  Now run the program and type something into the Editor Text textbox, and save it to a file with the Save menu item.  Then use the Open menu item and open the file.  Does it work?  Use the open menu item and find an existing text file on the hard drive and open it.

Updating the Caps Lock panel on the StatusBar

The Caps Lock key status panel on the statusbar needs to be updated when the user toggles on or off the Caps Lock key.  We added the following code to our CreateMyStatusBar procedure, to update the Caps Lock key status panel when the statusbar is first displayed:

'Use the GetKeyState API call to determine the status of the Caps Lock
'    key.  When the return value is 1, Caps Lock is on.
If GetKeyState(Keys.CapsLock) = 1 Then
    Panel2.
Text = "CAPSLOCK"
Else
    Panel2.
Text = "capslock"
End If

All we need to do is add the above code to an event procedure that is triggered whenever the Caps Lock key is pressed.  The first event procedure that comes to mind is the KeyPress event procedure of the txtEditor textbox.  But remember that the KeyPress event procedure actually happens before the key that was typed sends it's code to the operating system for processing.  So the GetKeyState API call--which gets it's information directly from the operating system--would happen too soon if we put the above code into the KeyPress event procedure of txtEditor.  How about the KeyUp event procedure?  The KeyUp event procedure happens after the operating system has processed the key stroke, so it should be ideal.  Add the following code to the txtEditor_KeyUp event procedure:

'Don't waste processing time by making the GetKeyState API call
'    unless the user had actually pressed the Caps Lock key.
If e.KeyValue = Keys.CapsLock Then
    'Use the GetKeyState API call to determine the status of the Caps Lock
    '    key.  When the return value is 1, Caps Lock is on.
    If GetKeyState(Keys.CapsLock) = 1 Then
        Panel2.
Text = "CAPSLOCK"
    Else
        Panel2.
Text = "capslock"
    End If
End If

Spell Checking with the Microsoft Word spell checker

Microsoft Word is an ActiveX (OLE server) application.  This means that it was written and compiled so that most, if not all, of its functionality is exposed.  You can write applications that launch Word, open and modify documents, and do everything that Word does, all from within your own applications.  In order to access the exposed functionality of Microsoft Word, we must set a reference to the Microsoft Word 10.0 Object Library.  This object library contains declarations and definitions for all of the exposed classes that Microsoft Word contains.

Setting a Reference to the Microsoft Word 10.0 Object Library

Drop down the Project menu and select the Add Reference... item:

On the Add Reference dialog box, click on the COM (Component Object Model) tab to display all the COM libraries.  Note: The Component Object Model (COM) and its related COM-based technologies of DCOM, COM+, MTS and ActiveX« comprise the most widely-used component software model in the world.  For more information on COM, I suggest you visit http://www.microsoft.com/com/about.asp

Scroll down the Component Name list and select the Microsoft Word ##.0 Object Library item (where ##.0 is the version number) and click the Select button to add it to the Selected Components listbox at the bottom of the dialog (In the example below we are using the Microsoft Word 10.0 Object Library):

Now click the OK button to close the Add Reference dialog.

Creating a Word Object Reference variable

Just as we did with the statusbar, we will use an object constructor at run-time to access the exposed functionality of Microsoft Word.  Add the following dimension statement to the Declarations section at the top of the code window:

Dim WordObj As

When typing a dimension statement, as soon as you type As and a space a dropdown list of available class types appears (Note: If you are using the Microsoft Word 11.0 Object Library or higher the Word item may not appear in the class list as shown in the illustration below.  If that is the case, add the following Imports line at very top of your code window (above the Public Class MyEditor line):

        Imports Microsoft.Office.Interop

Only add the above Imports statement if the Word item is not available in the class list as shown below.

Normally the Word class would not be listed here.  But because we set a reference to the Microsoft Word XX.0 Object Library in the previous step, a Word class is now available.  After selecting Word, type a dot (.) to see a list of classes that the Word object contains:

Select ApplicationClass so that you will have access to all the exposed functionality of the Microsoft Word application.  Your finished line of code in the Declarations section should look like this (Note: If you want this project to work with older versions of Microsoft Word, the following line should say Dim WordObj As Word.Application, and everywhere in the following code that you use ApplicationClass, use Application instead):

'Dimension a Word.ApplicationClass reference variable
Dim WordObj As Word.ApplicationClass

Using the Microsoft Word Spell Checker from within our application

We will use an object constructor to create an instance of Word, like this:

'Make sure that WordObj is not already referencing an
'    instance of Microsoft Word.
If WordObj Is Nothing Then
     'Use the Word.ApplicationClass object constructor to
     '    create an instance of Microsoft Word.
    WordObj = New Word.ApplicationClass()
End If

To avoid accidentally creating multiple instances of Word, it's always a good idea to make sure that your reference variable (WordObj) is not already referencing something.  The key word Nothing is the state of an unassigned reference variable.  By making sure that WordObj Is Nothing before using the object constructor, we avoid launching Word multiple times unnecessarily.  Add the above code to the mnuSpell_Click event procedure.  

Once we've used our object constructor above (New), an instance of Word is created--The Microsoft Word application is actually launched in the background.  Now let's look at some of the commands and capabilities that Word has exposed for our use.  The following five steps let us spell check any text in our txtEditor textbox:

  1. We begin by adding a new document to our instance of Word:

'Use the Add method of the Documents class
'    to add a new blank document to Word.
WordObj.Documents.Add()

  1. Next we copy the contents of the txtEditor textbox to the new blank word document:

'Use the TypeText method of the Selection class to copy the contents
'    of the txtEditor textbox to the new blank document.
WordObj.Selection.TypeText(txtEditor.Text)

  1. Now we can check the text for spelling errors with the CheckSpelling method of the Item collection (which is a collection of all the documents):

'Use the CheckSpelling method of the Item collection to check the
'    spelling of the text in the new document. 
WordObj.Documents.Item(WordObj.Documents.Count).CheckSpelling()

In the above line of code, the Count property of the Documents collection is equal to the index value of the new document we added in step 1 above.  Note: In Microsoft Word it is possible to have multiple documents open at the same time.  When we added a new document with the WordObj.Documents.Add() call in step 1, our new document was added to the end of the Item collection of existing documents.  For example, if there were already 3 documents open, the new document we added would be document number 4.  The WordObj.Documents.Count property would then be equal to 4, so it represents the index value of our new document----the first document in the Item collection is at index value 1 not 0

  1. Once the spell checking is complete, we must copy the spelling-corrected text back to the txtEditor textbox:

'Copy the spelling-corrected text from the document to the txtEditor textbox
txtEditor.Text = _
    WordObj.
Documents.Item(WordObj.Documents.Count).Content.Text

  1. To complete the process, we must close the new document that we had created.  Quit from Word, and disconnect the WordObj object reference variable by setting it to Nothing.  This allows our instance of Word to terminate.

'Close the document we created above without saving any changes to it.
WordObj.Documents.Close(Word.
wdSaveOptions.wdDoNotSaveChanges)
'Quit Microsoft Word
WordObj.Quit()
'Set the WordObj reference variable to Nothing so that our
'    instance of Word can terminate.
WordObj = Nothing

Add the code from steps 1 through 5 to the mnuSpell_Click event procedure, below any code you previously added to it.

Testing the program so far

Before testing the project, click on the Save All button on the toolbar to save it.  Now run the program and type a single line of text into the Editor Text textbox and deliberately make a couple of spelling errors.  Note: Do Not try spell checking a large document on your first test!  Then drop down the Options menu and choose the Spell Check item.  Does it work?

Implementing the New menu item

In it's simplest version, the code for the mnuNew_Click event procedure would include this single line of code:

'Clear the contents of the txtEditor textbox.
txtEditor.Clear()

But what if the user had just typed a 5 page document and had not yet saved it?  Clearing the txtEditor textbox unconditionally when the New menu item selected is not very user-friendly.  To properly implement the New menu item, you must do the following before clearing the txtEditor textbox:

Required Enhancements

Putting the Filename in the Status Bar

Make sure that Panel1 displays the filename and path of the currently open file.

More Spell Checking Options

Spell Checking Selected Text

A textbox control has a SelectedText property that stores any text that is selected in a textbox, or blank if no text is selected.  We can easily modify our spell checking procedure so that only selected text is spell check, or all the text is spell checked if no text is selected (this is a modification the code in the mnuSpell_Click event procedure):

'Make sure that WordObj is not already referencing an
'    instance of Microsoft Word.
If WordObj Is Nothing Then
     'Use the Word.ApplicationClass object constructor to
     '    create an instance of Microsoft Word.
    WordObj = New Word.ApplicationClass()
End If

WordObj.Documents.Add()
'If the SelectedText property is not blank, spell check
'    only the selected text.
If txtEditor.SelectedText <> "" Then
    'Copy only the SelectedText to the Word document
    WordObj.Selection.TypeText(txtEditor.SelectedText)
    WordObj.
Documents.Item(WordObj.Documents.Count).CheckSpelling()
    'Copy the spelling-corrected text over the SelectedText
    txtEditor.SelectedText =  _
        WordObj.
Documents.Item(WordObj.Documents.Count).Content.Text
Else
    'Copy all the text from txtEditor to the Word document
    WordObj.Selection.TypeText(txtEditor.Text)
    WordObj.
Documents.Item(WordObj.Documents.Count).CheckSpelling()
    txtEditor.
Text =  _
        WordObj.
Documents.Item(WordObj.Documents.Count).Content.Text
End If
'Close the document we created above without saving any changes to it.
WordObj.Documents.Close(Word.WdSaveOptions.wdDoNotSaveChanges)
WordObj.
Quit()
WordObj =
Nothing

Counting Spelling Errors

Before actually going to all the trouble of spell-checking a document, here is a method of counting and displaying the number of spelling errors in a document (Put this code into the Click event procedure of a new Count Spelling Errors menu item):

'Stores the number of spelling errors
Dim iErrCount As Integer
'Make sure that WordObj is not already referencing an
'    instance of Microsoft Word.
If WordObj Is Nothing Then
     'Use the Word.ApplicationClass object constructor to
     '    create an instance of Microsoft Word.
    WordObj = New Word.ApplicationClass()
End If

WordObj.Documents.Add()
WordObj.
Selection.TypeText(txtEditor.Text)
'The Count property of the SpellingErrors class of the
'    ActiveDocument class is equal to the number of
'    spelling errors found.
iErrCount = WordObj.ActiveDocument.SpellingErrors.Count()
'Close the document we created above without saving any changes to it.
WordObj.Documents.Close(Word.WdSaveOptions.wdDoNotSaveChanges)
WordObj.
Quit()
WordObj =
Nothing
'If iErrCount > 0, display the number spelling errors found.
If iErrCount > 0 Then
    MessageBox.
Show("This document contains: " &  _
            iErrCount
& " spelling errors!")
Else
    MessageBox.
Show("No spelling errors found.")
End If


To copy a Project folder from your Solution on the Hard Drive to a floppy diskette, follow these steps:

  1. Exit Visual Basic .NET and insert the floppy diskette, that you want to copy the Project folder to, into drive A:
  2. Select the My Documents item on the Start Menu to open the My Documents folder.
  3. In the My Documents folder, double-click the Visual Studio Projects folder to open it.
  4. Double-click on your Solution folder to open it (it should have your name).
  5. Open the Project folder that you want to copy, by double-clicking on it.

Deleting the Obj and Bin folders from inside the Project folder before copying it.

  1. Inside the Project folder, delete the Obj and Bin folders--these folders are created automatically when you open a project.  You do not need to copy them, or their contents, to your floppy diskette.
  2. Hit the Backspace key once--or click the Back button on the toolbar.  This moves you from inside the Project folder to back inside your Solution folder.
  3. Right-click on the Project folder and selected: 31/2" Floppy A: on the Send To fly-out menu.  This copies the Project folder to your floppy diskette.