building a simple word processor around an extended richtextbox control

36
Building a Simple Word Processor Around an Extended RichTextBox Control Introduction This article describes an easy approach to building a simple word processor around an extended version of the RichTextBox (RTB) control. Microsoft has made available an extended version of the RTB control that greatly eases the

Upload: baneeishaquek

Post on 07-Feb-2016

28 views

Category:

Documents


0 download

DESCRIPTION

ggh

TRANSCRIPT

Page 1: Building a Simple Word Processor Around an Extended RichTextBox Control

Building a Simple Word Processor Around an Extended RichTextBox Control

IntroductionThis article describes an easy approach to building a simple word processor around an extended version of the RichTextBox (RTB) control. Microsoft has made available an extended version of the RTB control that greatly eases the requirements for printing the control s text or RTF content. This article and the sample application will use this �extended version of the RTF control to demonstrate the following word processor related functions:

Page 2: Building a Simple Word Processor Around an Extended RichTextBox Control

Opening Text, RTF, HTML, or other text files into a RTB control Saving Text, RTF, HTML, or other text files from an RTB control Implementation of the Page Setup dialog control Implementation of the Print Preview dialog control Implementation of the Print dialog control Setting font properties on selected text or RTF within the RTB control Searching for and highlighting text contained within the RTB control Searching for and replacing text contained within the RTB control Adding indentation to sections of an RTB s content �Adding bullets to sections of an RTB s content �Implementing Undo/Redo within an RTB Implementing Select All, Cut, Copy, and Paste in an RTB control Embedding images into an RTB control Setting page and font colors Implementing alignment options in an RTB control Whilst this project will not lead you to drop MS Word, it is a decent little word processor, and to that end, you may find a use for it. I have always kept one of these on hand, and have frequently tailored them to do things like provide a custom tool for viewing reports, error logs, and things of that nature when I wanted to integrate that feature into a product so that I could use it in lieu of doing something like shelling out a text file into Notepad. Doing so allows me to control the appearance of the application, the caption in the title bar of the form, etc.

Page 3: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 1: The editor application in useGetting StartedIn order to get started, unzip the attachment, and load the solution into Visual Studio 2005. Examine the Solution Explorer, and note the files contained in the project:

Page 4: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 2: The Solution Explorer showing the project files

First, note that there are two separate projects contained in the solution. The first project is a class library entitled, ExtendedRichTextBox . That library contains a single � �control class, RichTextBoxPrintCtrl . This control class was provided by Microsoft � �as an alternative to the basic RichTextBox control; the class inherits from the RichTextBox control class but adds to that base class additional support for printing the control s content. The approach provided by the control is far simpler than the �traditional approach used based upon the manipulation of the graphics context of the control.The second solution is the editor application itself (RichTextEditor). This application uses the extended rich text box control, and then to that, adds in all of the normal document manipulation techniques (such as font selection, indentation, and file IO support). Aside from the main application s form (frmMain), this project also includes �two additional forms, one to search for a string within the RTB s content, and one to �search for and replace strings within the RTB. These forms are frmFind and frmReplace.

Page 5: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 3: Editor application Find dialog

Figure 4: Editor application Find and Replace dialog

In addition to the form classes mentioned, the solution also contains a folder entitled Graphics ; this folder contains all of the image files used to support the � �

application s menus and toolbar.�Project ReferencesAside from the default references, there are a couple of additional references added. Most notably, the extended rich text box control library is added to allow for the use of the extended rich text box control. Figure 5 shows the references as they exist in the project.

Page 6: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 5: Project references

The Code: The Main Form ClassThe main form class (frmMain) is pretty easy to follow. It begins with a couple of Imports statements, followed by the class declaration. The code is divided by purpose into four separate regions, which are:Declarations Menu methods Toolbar methods Printing The imports and the class declaration looks like this: Imports System.DrawingImports System.Drawing.Image

Public Class frmMainThe class declaration is plain enough, and does not inherit from or implement any base class or interface. I would emphasis here again that making use of Microsoft s extended� rich text box control greately reduces the amount of code necessary to support all of the methods used within this application.The declarations section is also very simple; the section contains the variables used throughout the application. The content is as follows: #Region "Declarations"

Page 7: Building a Simple Word Processor Around an Extended RichTextBox Control

Private currentFile As String Private checkPrint As Integer

#End RegionThe currentFile variable is used to keep track of the path and file name of the file � �loaded into the extended rich text box control; it is updated whenever the user opens a file, creates and saves a file, or saves a file with a new name and/or file extension.The checkPrint variable is used by the streamlined printing process recommended � �by Microsoft in the article describing the use of the extended rich text box control. It is used to determine if additional pages exist when the document is sent to the printer (in support of multi-page printing).The next section of code is the primary block of code used by this application. The

Menu Methods region contains all of the subroutines evoked in response to the � �selection of a menu option. The Toolbar Methods region follows the Menu � � �Methods region, but all of the subroutines in the toolbar controls' section call the �subroutines defined in the Menu Methods region of the code unless the code is so � �trivial (one line) that it is just as simple to make the call directly; for that reason, this document will not describe the contents of the Toolbar Methods region specifically.� �The first block of code in the menu region is used to create a new file: Private Sub NewToolStripMenuItem_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles NewToolStripMenuItem.Click

If rtbDoc.Modified Then Dim answer As Integer answer = MessageBox.Show("The current document has not" & _ " been saved, would you like to " & _ "continue without saving?", "Unsaved Document", _ MessageBoxButtons.YesNo, MessageBoxIcon.Question)

If answer = Windows.Forms.DialogResult.Yes Then rtbDoc.Clear() Else Exit Sub End If Else rtbDoc.Clear() End If

currentFile = "" Me.Text = "Editor: New Document" End SubIn this subroutine, prior to clearing the current document, the status of the current document is checked by using the control's Modified test; if the document has been � �

Page 8: Building a Simple Word Processor Around an Extended RichTextBox Control

modified while it has been open, the test will return true. If the document has been modified, the user is queried with a message box to determine whether or not they want to save (or lose) the modifications made to the current file prior to clearing the file. If they choose to save the changes, the subroutine is exited; else, the document is cleared, and the changes are lost. If the document has not been modified, the subroutine will clear the document without notifying the user. Whenever the document is cleared, the title of the control is updated to indicate that a new (unsaved) document is the current document, and the currentFile variable is set to contain an empty string.� �

Figure 6: Confirmation dialog shown after user requests a new document without saving changesThe next subroutine is used to open an existing file into the rich text box control: Private Sub OpenToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles OpenToolStripMenuItem.Click

If rtbDoc.Modified Then

Dim answer As Integer answer = MessageBox.Show("The current document has not" & _ " been saved, would you like to continue " & _ "without saving?", "Unsaved Document", _ MessageBoxButtons.YesNo, MessageBoxIcon.Question)

If answer = Windows.Forms.DialogResult.No Then Exit Sub Else OpenFile() End If Else OpenFile() End If

End SubThis subroutine works in a manner similar to the new subroutine discussed in the � �previous section. If the file has not been modified or if the user decides not to save the current modifications, the subroutine calls an OpenFile subroutine, which in turn exposes a File Open dialog used to allow the user to navigate to the file they wish to open. The OpenFile subroutine is next, and contains this code:

Page 9: Building a Simple Word Processor Around an Extended RichTextBox Control

Private Sub OpenFile()

OpenFileDialog1.Title = "RTE - Open File" OpenFileDialog1.DefaultExt = "rtf" OpenFileDialog1.Filter = "Rich Text Files|*.rtf|" & _ "Text Files|*.txt|HTML Files|" & _ "*.htm|All Files|*.*" OpenFileDialog1.FilterIndex = 1 OpenFileDialog1.ShowDialog()

If OpenFileDialog1.FileName = "" Then Exit Sub

Dim strExt As String strExt = System.IO.Path.GetExtension(OpenFileDialog1.FileName) strExt = strExt.ToUpper()

Select Case strExt Case ".RTF" rtbDoc.LoadFile(OpenFileDialog1.FileName, RichTextBoxStreamType.RichText) Case Else Dim txtReader As System.IO.StreamReader txtReader = New System.IO.StreamReader(OpenFileDialog1.FileName) rtbDoc.Text = txtReader.ReadToEnd txtReader.Close() txtReader = Nothing rtbDoc.SelectionStart = 0 rtbDoc.SelectionLength = 0 End Select

currentFile = OpenFileDialog1.FileName rtbDoc.Modified = False Me.Text = "Editor: " & currentFile.ToString()

End Sub

Page 10: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 7: Open File dialog

The first part of the FileOpen subroutine is used to configure and display the Open File dialog box; this code sets up the filters for the files types (rich text, text, or HTML), sets the dialog box title, and a selects an extension filter (RTF). Once this is done, the dialog box is displayed. If the user okays the dialog box without specifying a file name, the subroutine will exit. If a file name exists, the code extracts the file extension from the file name, places the extension in a local string variable, converts it to upper case, and does a Select Case statement on the string variable. If the file selected by the user is an RTF file, the subroutine calls the control s LoadFile method and passes it the file name and �format. If the file is not an RTF file, a stream reader is instanced and passed the path to the file, the control is then fed the content of the file by means of the stream reader s �ReadToEnd method. The reader is then closed and disposed of, and the cursor is moved to the beginning of the document and the selection length is set to zero (if you do not do this, the whole document will initialize as entirely selected). After the file is loaded, the

currentFile variable is updated to contain the current file path and name, the � �modified property of the control is set to false, and the caption bar is updated to show the name of the file currently under edit in the rich text box control.The next item up is the Save menu option; it contains the following code:� � Private Sub SaveToolStripMenuItem_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _

Page 11: Building a Simple Word Processor Around an Extended RichTextBox Control

Handles SaveToolStripMenuItem.Click

If currentFile = "" Then SaveAsToolStripMenuItem_Click(Me, e) Exit Sub End If

Dim strExt As String strExt = System.IO.Path.GetExtension(currentFile) strExt = strExt.ToUpper()

Select Case strExt Case ".RTF" rtbDoc.SaveFile(currentFile) Case Else ' to save as plain text Dim txtWriter As System.IO.StreamWriter txtWriter = New System.IO.StreamWriter(currentFile) txtWriter.Write(rtbDoc.Text) txtWriter.Close() txtWriter = Nothing rtbDoc.SelectionStart = 0 rtbDoc.SelectionLength = 0 rtbDoc.Modified = False End Select

Me.Text = "Editor: " & currentFile.ToString()

End SubThe Save function first checks to see if the currentFile variable is empty; if it � � � �is, the content of the rich text box control has not been saved previously, and the subroutine will call the Save As menu option to provide the user with an interface to� � define a file name and storage location for the current unnamed file. If the file is named (and has a current storage location), the subroutine will check the file extension and, by means of a Select Case statement, determine the appropriate method for storing the file, and will then save the content to the file location. This all works very similar to the approach used to open the file. However, instead of opening a file, the approach is used to call the rich text box control s SaveFile method if the file is a rich text file, or to �instance a stream writer and write the file content out as text to the file location if the file is plain text or HTML.With both the file open and file save methods used, if the file is anything other than a rich text file, the application will attempt to open or save it with a stream reader or stream writer; this will allow the application to work with any text file, not just RTF, TXT, or HTML files. That would permit you to use it with custom file types, or other things such as license files or error log files.The next subroutine addresses the Save As menu option; its code is as follows:� �

Page 12: Building a Simple Word Processor Around an Extended RichTextBox Control

Private Sub SaveAsToolStripMenuItem_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles SaveAsToolStripMenuItem.Click

SaveFileDialog1.Title = "RTE - Save File" SaveFileDialog1.DefaultExt = "rtf" SaveFileDialog1.Filter = "Rich Text Files|*.rtf|" & _ "Text Files|*.txt|HTML Files" & _ "|*.htm|All Files|*.*" SaveFileDialog1.FilterIndex = 1 SaveFileDialog1.ShowDialog()

If SaveFileDialog1.FileName = "" Then Exit Sub

Dim strExt As String strExt = System.IO.Path.GetExtension(SaveFileDialog1.FileName) strExt = strExt.ToUpper()

Select Case strExt Case ".RTF" rtbDoc.SaveFile(SaveFileDialog1.FileName, _ RichTextBoxStreamType.RichText) Case Else Dim txtWriter As System.IO.StreamWriter txtWriter = New System.IO.StreamWriter(SaveFileDialog1.FileName) txtWriter.Write(rtbDoc.Text) txtWriter.Close() txtWriter = Nothing rtbDoc.SelectionStart = 0 rtbDoc.SelectionLength = 0 End Select

currentFile = SaveFileDialog1.FileName rtbDoc.Modified = False Me.Text = "Editor: " & currentFile.ToString()

End Sub

Page 13: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 8: File menu optionsBy now, this should look pretty familiar; in the code, a Save as file dialog box is configured and displayed to the user. The dialog will permit the user to save the file as RTF, TXT, or HTML. If the user saves the file as RTF, the control s SaveFile method �is used to store the contents of the file whilst preserving the RTF formatting. If the user selects another option, the file will be saved as plain text using a text writer. In either case, after the file is saved, the currentFile variable is updated, the application s � � �title bar is updated, and the document s Modified property is set to False.�The next item in the code is the menu s Exit call. It is used to terminate the application. �Prior to closing the application, this subroutine checks to see if the current document has been modified and, if it has, it alerts the user and asks whether or not the document should be saved prior to closing it and the application. The code is as follows: Private Sub ExitToolStripMenuItem_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles ExitToolStripMenuItem.Click

If rtbDoc.Modified Then

Dim answer As Integer answer = MessageBox.Show("The current document has not been" & _

Page 14: Building a Simple Word Processor Around an Extended RichTextBox Control

" saved, would you like to continue without saving?", _ "Unsaved Document", MessageBoxButtons.YesNo, _ MessageBoxIcon.Question)

If answer = Windows.Forms.DialogResult.No Then Exit Sub Else Application.Exit() End If Else Application.Exit() End If

End SubThe next menu option addressed is the edit menu s Select All function. Select All � � �is a method embedded in the rich text box control, and therefore it may be called directly without writing any additional code to make the Select All happen; to use it, just call it as follows: Private Sub SelectAllToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles SelectAllToolStripMenuItem.Click

Try rtbDoc.SelectAll() Catch exc As Exception MessageBox.Show("Unable to select all document content.", _ "RTE Select", MessageBoxButtons.OK, _� MessageBoxIcon.Error) End Try

End SubFollowing the edit menu s Select All function, we have the cut, copy, and paste � � �subroutines. Just as the Select All method exists within the rich text box control, so do these, and so you can call them directly in a manner similar to that used in Select All. For that reason, I am not going to show them here, but you can see the calls made in the example application if you d care to take a look at them.�

Page 15: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 9: Edit menu optionsNext up is the menu option used to select the current font. This code merely uses a standard font dialog box to set the rich text box control s SelectionFont property to the �font selected by the user through the font dialog. The code used to do this is as follows: Private Sub SelectFontToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles SelectFontToolStripMenuItem.Click

If Not rtbDoc.SelectionFont Is Nothing Then FontDialog1.Font = rtbDoc.SelectionFont Else FontDialog1.Font = Nothing End If

FontDialog1.ShowApply = True If FontDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then rtbDoc.SelectionFont = FontDialog1.Font End If

Page 16: Building a Simple Word Processor Around an Extended RichTextBox Control

End Sub

Figure 10: Font dialog in useSimilarly, the font color menu option is used to display a standard color dialog to the user; if the user selects a color from the dialog, the ForeColor property of the document will be updated to contain the selected color. As the rich text box control works primarily with selected text (that is, what you change in terms of selecting a font or changing a color), this function will alter the color of the selected text only. If no text is selected, the color at the insertion point will hold the fore color selection, and typing from the insertion point will show text in the newly selected color. Private Sub FontColorToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles FontColorToolStripMenuItem.Click

ColorDialog1.Color = rtbDoc.ForeColor If ColorDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then rtbDoc.SelectionColor = ColorDialog1.Color End If

End SubThe next three sections of code are the subroutines used to set the selected text s bold, �italic, or underline properties. Each section is set up to work such that, if the selected text is bold, selecting the bold option will remove the bolding (or italics, or underline). (As they all basically work the same, I am only showing bold here.)

Page 17: Building a Simple Word Processor Around an Extended RichTextBox Control

Private Sub BoldToolStripMenuItem_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles BoldToolStripMenuItem.Click If Not rtbDoc.SelectionFont Is Nothing Then Dim currentFont As System.Drawing.Font = rtbDoc.SelectionFont Dim newFontStyle As System.Drawing.FontStyle If rtbDoc.SelectionFont.Bold = True Then newFontStyle = FontStyle.Regular Else newFontStyle = FontStyle.Bold End If

rtbDoc.SelectionFont = New Font(currentFont.FontFamily, _ currentFont.Size, newFontStyle) End If End SubThe Normal font menu option returns the selected text to a normal, unadorned � �format: Private Sub NormalToolStripMenuItem_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles NormalToolStripMenuItem.Click If Not rtbDoc.SelectionFont Is Nothing Then Dim currentFont As System.Drawing.Font = rtbDoc.SelectionFont Dim newFontStyle As System.Drawing.FontStyle newFontStyle = FontStyle.Regular

rtbDoc.SelectionFont = New Font(currentFont.FontFamily, _ currentFont.Size, newFontStyle) End If End SubThe menu option used to set the page color is used to expose a color dialog box to the user; if the user selects a color form the dialog, the back color of the rich text box control is set to that color. The code to support this function is as follows: Private Sub PageColorToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles PageColorToolStripMenuItem.Click ColorDialog1.Color = rtbDoc.BackColor If ColorDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then rtbDoc.BackColor = ColorDialog1.Color End If End Sub

Page 18: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 11: Color dialog in useThe undo and redo functions are used to back up or restore changes made to the content of the control during an edit; the rich text box control supports the undo and redo function directly, so all you need to do in order to add undo and redo support is merely evoke the method directly from the control, make the call, test to determine whether or not the control can execute the undo or redo request, and, if it is supported, call the method: Private Sub mnuUndo_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles mnuUndo.Click If rtbDoc.CanUndo Then rtbDoc.Undo() End Sub

Private Sub mnuRedo_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles mnuRedo.Click If rtbDoc.CanRedo Then rtbDoc.Redo() End SubThe next three sections of code address setting the document s horizontal alignment �property to support left, centered, or right justification of the selected text. Each of these alignment control options is directly supported by the control: Private Sub LeftToolStripMenuItem_Click_1(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles LeftToolStripMenuItem.Click rtbDoc.SelectionAlignment = HorizontalAlignment.Left End Sub

Private Sub CenterToolStripMenuItem_Click_1(ByVal sender _

Page 19: Building a Simple Word Processor Around an Extended RichTextBox Control

As System.Object, ByVal e As System.EventArgs) _ Handles CenterToolStripMenuItem.Click rtbDoc.SelectionAlignment = HorizontalAlignment.Center End Sub

Private Sub RightToolStripMenuItem_Click_1(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles RightToolStripMenuItem.Click rtbDoc.SelectionAlignment = HorizontalAlignment.Right End Sub

Figure 12: Alignment optionsAdding and removing bullets is also directly supported by the control. The BulletIndent property sets the gap between the bullet and the text, and the SelectionBullet property merely instructs the control to add or remove the bullet from the selected text: Private Sub AddBulletsToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles AddBulletsToolStripMenuItem.Click rtbDoc.BulletIndent = 10 rtbDoc.SelectionBullet = True End Sub

Private Sub RemoveBulletsToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles RemoveBulletsToolStripMenuItem.Click rtbDoc.SelectionBullet = False End Sub

Page 20: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 12: Bullet optionsSetting the indentation level for the selected text is also directly supported by the control: Private Sub mnuIndent0_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles mnuIndent0.Click rtbDoc.SelectionIndent = 0 End Sub

Figure 13: Indentation optionsThe application contains a separate dialog box used to find a text string within the current document. If the user selects the Find menu option, the application will create and display a new instance of the search form (frmFind.vb): Private Sub FindToolStripMenuItem_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles FindToolStripMenuItem.Click Dim f As New frmFind() f.Show() End Sub

Page 21: Building a Simple Word Processor Around an Extended RichTextBox Control

Similarly, if the user selects the Find and Replace menu option, the application will create and display a new instance of the find and replace form (frmReplace.vb): Private Sub FindAndReplaceToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles FindAndReplaceToolStripMenuItem.Click Dim f As New frmReplace() f.Show() End SubThe print document is set to contain the contents of the current rich text box control. In order to support print preview, page setup, and printing, given the modifications made to the extended rich text box control, all that needs to be done is to pass the print document to each of the related standard dialog boxes: Private Sub PreviewToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles PreviewToolStripMenuItem.Click PrintPreviewDialog1.Document = PrintDocument1 PrintPreviewDialog1.ShowDialog() End Sub

Private Sub PrintToolStripMenuItem_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles PrintToolStripMenuItem.Click PrintDialog1.Document = PrintDocument1 If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then PrintDocument1.Print() End If End Sub

Private Sub mnuPageSetup_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles mnuPageSetup.Click PageSetupDialog1.Document = PrintDocument1 PageSetupDialog1.ShowDialog() End SubThe next subroutine is a little more interesting; it is used to embed an image file into the extended rich text box document. This subroutine uses an open file dialog box set to filter the extensions used for bitmaps, JPEGs, and GIF files. The user may navigate to the file that they want to embed into the document (placing it at the insertion point defined by the cursor). Private Sub InsertImageToolStripMenuItem_Click(ByVal sender _ As System.Object, ByVal e As System.EventArgs) _ Handles InsertImageToolStripMenuItem.Click

OpenFileDialog1.Title = "RTE - Insert Image File"

Page 22: Building a Simple Word Processor Around an Extended RichTextBox Control

OpenFileDialog1.DefaultExt = "rtf" OpenFileDialog1.Filter = "Bitmap Files|*.bmp|JPEG Files|*.jpg|GIF Files|*.gif" OpenFileDialog1.FilterIndex = 1 OpenFileDialog1.ShowDialog()

If OpenFileDialog1.FileName = "" Then Exit Sub

Try Dim strImagePath As String = OpenFileDialog1.FileName Dim img As Image img = Image.FromFile(strImagePath) Clipboard.SetDataObject(img) Dim df As DataFormats.Format df = DataFormats.GetFormat(DataFormats.Bitmap) If Me.rtbDoc.CanPaste(df) Then Me.rtbDoc.Paste(df) End If Catch ex As Exception MessageBox.Show("Unable to insert image format selected.", "RTE � Paste", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try

End Sub

Page 23: Building a Simple Word Processor Around an Extended RichTextBox Control

Figure 15: Embedding an image fileOnce the user selects a file through the open file dialog, the subroutine will create an image using the Image.FromFile method. This image is then placed into the clipboard, and subsequently pasted into the document.The last section of the main form s code is contained in the printing region. The calls �used to print, due to the use of the extended rich text box control, are very simple: Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, _ ByVal e As System.Drawing.Printing.PrintEventArgs) _ Handles PrintDocument1.BeginPrint ' Adapted from Microsoft's example for extended richtextbox control ' checkPrint = 0 End SubThe BeginPrint subroutine is used to set the checkPrint variable back to zero at the � �start of each new print job.The PrintPage subroutine evokes the extended rich text box control s Print method to �send the entire or selected section of the current document to the printer. The call also checks to see if more than a single page exists, and it will continue to print until all of the pages have been passed to the printer. The code used to print is as follows:

Page 24: Building a Simple Word Processor Around an Extended RichTextBox Control

Private Sub PrintDocument1_PrintPage(ByVal sender As Object, _ ByVal e As System.Drawing.Printing.PrintPageEventArgs) _ Handles PrintDocument1.PrintPage ' Adapted from Microsoft's example for extended richtextbox control ' ' Print the content of the RichTextBox. Store the last character printed. checkPrint = rtbDoc.Print(checkPrint, rtbDoc.TextLength, e)

' Look for more pages If checkPrint < rtbDoc.TextLength Then e.HasMorePages = True Else e.HasMorePages = False End If End Sub

Figure 16: Print preview

Page 25: Building a Simple Word Processor Around an Extended RichTextBox Control

The print section wraps up the rest of the main form class.Code: The Find and Replace FormThe find and replace form is supported with the frmReplace class. The find class is defined in frmFind, but since it contains two subroutines (Find and Find Next) which are also contained in the Find and Replace form, I will only discuss the code contained in the Find and Replace form.The Find and Replace form supports four subroutines:Find Find Next Replace Replace All The Find subroutine is pretty straightforward, it will search the entire document for the first occurrence of the search term defined by the user on the form. It will search in one of two ways: with or without matching the case of the search term. Depending upon whether or not the user has checked the Match Case check box on the form, the application will search for the text using either the binary or text compare method. With the binary method, the search term must match exactly (including case); with the text compare method, the strings just need to match. The StartPosition integer value is � �set to the value returned from the InStr call; InStr is passed the starting position of 1, the entire body of the text contained in the rich text box control (as the article to search), the search term entered by the user, and the search compare method. InStr will return the index position of the found text if the text is in fact found. If nothing is found, it will return a zero. If the starting position value is zero, the user will be notified that the search term was not found, else, the application will highlight the found text in the document, pan to its location, and set the focus back to the main form (which in turn makes the highlighting visible to the user). Private Sub btnFind_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnFind.Click

Dim StartPosition As Integer Dim SearchType As CompareMethod

If chkMatchCase.Checked = True Then SearchType = CompareMethod.Binary Else SearchType = CompareMethod.Text End If

StartPosition = InStr(1, frmMain.rtbDoc.Text, _ txtSearchTerm.Text, SearchType)

If StartPosition = 0 Then MessageBox.Show("String: '" & txtSearchTerm.Text.ToString() & _ "' not found", "No Matches", _ MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

Page 26: Building a Simple Word Processor Around an Extended RichTextBox Control

Exit Sub End If

frmMain.rtbDoc.Select(StartPosition - 1, txtSearchTerm.Text.Length) frmMain.rtbDoc.ScrollToCaret() frmMain.Focus()

End SubThe Find Next function works in a manner consistent with the Find function; the only difference is that it sets the start position to the current position of the selection starting point within the document so that the Find Next function will not start at the beginning of the document each time it searches: Private Sub btnFindNext_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnFindNext.Click

Dim StartPosition As Integer = frmMain.rtbDoc.SelectionStart + 2 Dim SearchType As CompareMethod

If chkMatchCase.Checked = True Then SearchType = CompareMethod.Binary Else SearchType = CompareMethod.Text End If

StartPosition = InStr(StartPosition, frmMain.rtbDoc.Text, _ txtSearchTerm.Text, SearchType)

If StartPosition = 0 Then MessageBox.Show("String: '" & txtSearchTerm.Text.ToString() & _ "' not found", "No Matches", _ MessageBoxButtons.OK, MessageBoxIcon.Asterisk) Exit Sub End If

frmMain.rtbDoc.Select(StartPosition - 1, txtSearchTerm.Text.Length) frmMain.rtbDoc.ScrollToCaret() frmMain.Focus()

End SubThe Replace subroutine is quite simple. It merely tests to see if any text is selected and, if it is, it is replaced with the replacement text entered into the form by the user; it then moves to the next occurrence of the search term if one exists: Private Sub btnReplace_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnReplace.Click

Page 27: Building a Simple Word Processor Around an Extended RichTextBox Control

If frmMain.rtbDoc.SelectedText.Length <> 0 Then frmMain.rtbDoc.SelectedText = txtReplacementText.Text End If

Dim StartPosition As Integer = frmMain.rtbDoc.SelectionStart + 2 Dim SearchType As CompareMethod

If chkMatchCase.Checked = True Then SearchType = CompareMethod.Binary Else SearchType = CompareMethod.Text End If

StartPosition = InStr(StartPosition, frmMain.rtbDoc.Text,_ txtSearchTerm.Text, SearchType)

If StartPosition = 0 Then MessageBox.Show("String: '" & txtSearchTerm.Text.ToString() & _ "' not found", "No Matches", _ MessageBoxButtons.OK, MessageBoxIcon.Asterisk) Exit Sub End If

frmMain.rtbDoc.Select(StartPosition - 1, txtSearchTerm.Text.Length) frmMain.rtbDoc.ScrollToCaret() frmMain.Focus()

End SubThe Replace All function is a little different in that it uses the Replace method to replace every instance of the search term with the replacement term throughout the entire body of the text: Private Sub btnReplaceAll_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnReplaceAll.Click

Dim currentPosition As Integer = frmMain.rtbDoc.SelectionStart Dim currentSelect As Integer = frmMain.rtbDoc.SelectionLength

frmMain.rtbDoc.Rtf = Replace(frmMain.rtbDoc.Rtf, _ Trim(txtSearchTerm.Text), _ Trim(txtReplacementText.Text)) frmMain.rtbDoc.SelectionStart = currentPosition frmMain.rtbDoc.SelectionLength = currentSelect frmMain.Focus()

Page 28: Building a Simple Word Processor Around an Extended RichTextBox Control

End SubAgain, the frmFind class is the same as the Replace class with the exception being that it does not support the Replace and Replace All methods.Code: Rich Text Box Print ControlThe code in the class library contained in the RichTextBoxPrintCtrl class was developed at Microsoft; for a complete description of the contents of the class, please refer to this link in your Visual Studio 2005 Help files.SummaryThis article and sample application have attempted to demonstrate some of the available techniques useful in creating and managing text and text files through the use of the RichTextBox control. The control itself was modified using an approach recommended by Microsoft to greatly facilitate the ease with which one may print the contents of a text or rich text file. Further, the application provides an approach to inserting an image into a RichTextBox as a means of creating a more useful application based upon the RichTextBox control.LicenseThis article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.A list of licenses authors might use can be found here