|  | Click Here!

Search the site:
EXPERT SEARCH

| Programming Languages
| Databases
| Security
| Web Services
| Network Services
| Middleware
| Components
| Operating Systems
| User Interfaces
| Groupware & Collaboration
| Content Management
| Productivity Applications
| Hardware
| Fun & Games

EarthWeb sites
Crossnodes
Datamation
Developer.com
DICE
EarthWeb.com
EarthWeb Direct
ERP Hub
Gamelan
GoCertify.com
HTMLGoodies
Intranet Journal
IT Knowledge
IT Library
JavaGoodies
JARS
JavaScripts.com
open source IT
RoadCoders
Y2K Info

# Chapter 26

# RTFEditor

by Evangelos Petroutsos

CONTENTS

- Using OCX Controls with VBScript
  - The RTFEditor Application
  - The Rich Textbox Control
  - Designing the User Interface
  - The Code Behind the Scenes
  - Saving and Recalling RTF Documents
- Review

## Using OCX Controls with VBScript

You've seen examples of ActiveX controls, which were designed specifically for VBScript and Web applications. Controls are not new to the Windows environment, though. They are the basic building blocks of the Windows user interface and as such existed long before VBScript, and were called OCX controls. If you have programmed in the Windows environment, you are familiar with OCX controls. ActiveX is a new specification for building controls that can be used both on the desktop and within a browser. Eventually, all the existing OCX controls will be converted to ActiveX format and you'll be able to use them on your Web pages or desktop applications written in most languages, like Visual Basic or Visual C++. As of this writing, however, there aren't many ActiveX controls. Over the next year, numerous ActiveX controls will become available from Microsoft and other companies. They will be more flexible than the existing ones, and you'll find in them all the functionality you want to incorporate into your VBScript applications.

This chapter covers some of the old OCX controls in Web page design. OCX controls aren't meant to be used with VBScript, but they work and you'll get a good idea of the kind of functionality they can add to your applications. To follow the examples of this and the following chapter, you must have certain OCX controls installed on your system. Windows programming languages, such as Visual Basic and Visual C++, will automatically install these OCX controls on your system. If you don't have one of these programming tools installed on your system, you should wait for the ActiveX versions of these controls or consider purchasing Visual Basic. The upcoming version of Visual Basic (version 5.0) will be an ideal complement to VBScript. You should also check Microsoft's Workshop site (`www.microsoft.com/workshop`) for new ActiveX controls and updates.

### The RTFEditor Application

The first OCX control discussed is the Rich Textbox control. The Rich Textbox control is in a small but very flexible word processor that combines the functionality of a Textbox control with formatting capabilities. If you want the Textbox control to display multiple fonts and styles, the Rich Textbox control is what you need. The application we are going to build in this chapter is called RTFEditor, and you can find it in this chapter's folder on the CD-ROM. Apart from showing you how to use the Rich Textbox control to build a word processor, the RTFEditor application demonstrates how to use command buttons and the Popup Menu control to build a user interface with menus. As long as HTML layouts can't have a menu structure of their own similar to the one you see on practically every Windows application, you'll have to use the Popup Menu control to creatively provide your users with the means to interact with your applications.

The RTFEditor application, shown in Figure 26.1, is a functional word processor that runs from within Internet Explorer's environment. Users can type text and edit it using the common editing operations (such as cut and paste) and the editing keys common to any text editing application in the Windows environment (like Home and Ctrl-C). In addition, they can use the menus behind the command buttons to format the text.

Figure 26.1 : RTFEditor is a functional word processing application that can be placed on a Web page and operated from within Internet Explorer 3.0.

The command buttons at the bottom of the page act as triggers for popup menus, with the various formatting options. The popup menus that correspond to each command button are shown in Figure 26.2. We have included a few very basic formatting commands to demonstrate the capabilities of the Rich Textbox control, and you can add more formatting options on your own. Even with the basic functionality we've built into it, RTFEditor is a functional application that provides most of the functionality of a word processor needed by the average user on a daily basis.

Figure 26.2 : The options of the RTFEditor application's popup menus.

You can open the RTFEditor application and familiarize yourself with it. Every time the RTFEditor page is loaded, Internet Explorer 3.0 will issue a warning to the effect that the application contains controls that might not be safe for your system, shown in Figure 26.3. This warning means that the page contains controls that Internet Explorer can handle, but they are not ActiveX controls and have not been verified for safety on the Web. The controls we are going to use are common Windows controls, and you can safely put them on your pages; so click the Yes to All button to continue. You just have to live with the inconvenience of seeing this message every time the page is loaded.

Figure 26.3 : By default, Internet Explorer will warn you with this message box each time it's about to load a Web page with an OCX control.

NOTE
You can bypass this warning through the safety settings of Internet Explorer, but we don't recommend changing the browser's settings while you surf the Web. If you follow the procedure outlined here, make sure you restore the original settings before you load other people's pages. To change the safety level of Internet Explorer, open the Options dialog box by selecting Options from the View menu. Then click the Security tab and on the new page click Safety Level to bring up the Safety Level window of Figure 26.4.

Figure 26.4 : The Safety Level settings let you specify how Internet Explorer will handle potential security and safety problems.

Click the None radio button and then click the OK button twice to close the Options dialog box. Now you can load the pages of this and the next chapter without the inconvenience of the warning of Figure 26.2.

You're now ready to look at the application. First, however, let's review the Rich Textbox control, its properties, and its methods that we are going to use in the example.

### The Rich Textbox Control

Let's start by looking at the various properties of the control that we'll use in building the RTFEditor application. The basic property of the Rich Textbox control is its `RTFText` property. RTF stands for rich text format and is a language for describing formatted documents, not unlike HTML. Like HTML, RTF was designed to create portable formatted documents that can be displayed on different systems. The RTF language uses tags to describe the document's format. For example, the tag for italics is `\i`, and its scope is delimited with the next character formatting tag (which in most cases is the `\plain` tag, which restores the text style to plain). The following RTF line will produce a sentence with a few words in italics:

>     RTF is a language for creating \i portable formatted\plain documents

The equivalent HTML code would be

>     RTF is a language for creating <I>portable formatted</I> documents

RTF, however, is much more complicated than HTML because RTF was meant to be used internally by applications. Just as you need a browser to view HTML documents, you need an RTF-capable application to view RTF documents. WordPad, for instance, supports RTF and can save a document in RTF format and read RTF files. But you're not expected to supply your own RTF code to produce a document.

To demonstrate the principles of RTF and how to create portable documents in RTF, let's create a simple formatted document with WordPad and then look at the source code. Start WordPad, enter some text, and format it any way you can with the program's tools. Figure 26.5 shows the same document contained in the Rich Textbox control of Figure 26.1, after it was copied from the RTFEditor application (with the Ctrl-C keystroke) and pasted into a Word document (with the Ctrl-V keystroke). The text was actually transferred in RTF format, which shows you that RTF is indeed a universal language, at least in the Windows environment. If you can exchange RTF files with other types of operating systems, you'll realize that RTF is indeed a universal file format for exchanging formatted files. You can also try to modify the text in Word, copy it, and paste it into the RTFEditor's window.

Figure 26.5 : The Rich Textbox control lets you exchange formatted documents with other Windows applications, like Word.

Now you can save the text in RTF format too. Select the Save As command from the File menu, and in the dialog box that will be displayed on the screen select Rich Text Format. Then save the file as `Document.rtf`. (You don't have to supply the extension.) You can find the RTF code for the document of Figure 26.5 in the folder with this chapter's examples on the CD-ROM. If you open this file with a text editor (any application that can't interpret RTF code), you'll see the actual code that produced the document:

>     {\rtf1\ansi\deff0\deftab720{\fonttbl{\f4\fnil MS Sans Serif;}{\b\fnil\fcharset2 Symbol;}

>     {\b\ System;}{\f4\fnil Times New Roman;}{\f4\fnil\fprq2 Verdana;}{\f11\fnil\fprq2 Impact;}

>     {\f11\fnil\fprq2 Comic Sans MS;}}

>     {\colortbl\red0\green0\blue0;\red16\green16\blue255;\red255\green16\blue16;}

>     \deflang1033\pard\qc\plain\f4\ RTFEditor Features\plain\f4\

>     \par \pard\plain\f4\

>     \par \plain\f4\ Character Formatting\plain\f4\ :

>     \par Regular, \plain\f4\ Bold\plain\f4\ , \plain\f4\ Italics,\plain\f4\

>     \plain\f4\ Underline\plain\f4\  and \plain\f4\ combinations

>     \par \plain\f4\

>     \par \plain\f4\ Paragraph Formatting\plain\f4\

>     \par Left aligned paragraphs

>     \par \pard\qc\plain\f4\ Centered paragraphs

>     \par \pard\qr\plain\f4\ Right aligned paragraphs

>     \par \pard\plain\f4\ Font and Sizes\plain\f4\

>     \par Mix \plain\f11\ various\plain\f4\  \plain\f11\ fonts\plain\f4\

>     and \plain\f4\ sizes\plain\f4\

>     \par \plain\f4\ Text\plain\f4\  \plain\f4\ and background colors\plain\f4\

>     \par \pard\plain\f4\

>     \par }

If you look carefully at the RTF code, you'll be able to see where the text and the formatting tags are. The `\par` tag inserts a paragraph similar to the `<P>` tag in HTML. The `\bold` tag delimits text to be displayed in bold. The file's header holds information about the fonts used in the document. The designation `f4` corresponds to the Verdana font and appears quite frequently in the text.

The RTF format makes it possible to format text on a Rich Textbox control. But producing cryptic text as in the RTF code segment shown previously to display a few lines of formatted text isn't VBScript's way of doing things. Indeed, the Rich Textbox control simplifies this process by providing a number of properties for formatting the text.

#### Text Manipulation Properties

The Rich Textbox control has many properties, the most important of them being the ones that manipulate the selected text. All these properties start with the prefix `Sel`. `SelText` is the selected text. To assign the selected text to a variable, use the statement

>     SText=RichTextbox1.SelText

where `RichTextbox1` is the name of the control. You can also modify the selected text by assigning a new value to the `SelText` property. The statement

>     RichTextbox1.SelText=UCase(RichTextbox1.SelText)

converts the selected text to uppercase. If you assign a string to the `SelText` property, the selected text in the control will be replaced. The statement

>     RichTextbox1.SelText="replacement string"

will replace the current selection on the `RichTextbox1` control with the string `"replacement string"`. If no text was selected, the same statement will insert the string at the location of the pointer. It is possible, therefore, to automatically insert text by assigning a string to the `SelText` property. This technique is quite useful in displaying some initial text on the control.

To simplify the manipulation and formatting of the text on the control, there are two additional properties, the `SelStart` and `SelLength` properties, which report the position of the first selected character in the text and the length of the selection respectively. You can also set the values of these properties to select a piece of text from within your code. One obvious use of these properties is to select (and highlight) the entire text:

>     RichTextBox1.SelStart=0

>     RichTextBox1.SelLength=Len(RichTextBox1.Text)

The `Text` property returns the text on the control, just like the `Text` property of the TextBox control.

#### Text Formatting Properties

The properties for formatting the selected text are `SelBold`, `SelItalic`, and `SelUnderline`. You can read the value of these properties to check the formatting of the selected text from within your code or set them to change the formatting accordingly. The statements

>     RichTextbox1.SelBold=True

>     RichTextbox1.SelItalic=True

turn on the bold and italic attributes of the selected text. Again, if no text is selected, the attributes are set for the character at the current location of the pointer. By setting the character formatting properties accordingly, the user is in effect changing the style of the text he or she is about to type.

The character formatting properties are used as toggles. Every time the user clicks the Bold button (or selects Bold from the application's menu), the following code is executed:

>     RichTextbox1.SelBold=NOT RichTextbox1.SelBold

If the selected text is in bold, it's turned back to normal; if it's normal, it's turned to bold. As you have noticed, there is no property to reset the text style back to normal. To do so, you must manually set all three properties to `False`:

>     RichTextbox1.SelBold=False

>     RichTextbox1.SelItalic=False

>     RichTextbox1.SelUnderline=False

The `SelAlignment` property lets you read or change the alignment of one or more paragraphs, and it can have one of the following values:

> `0` (Default) Left aligns selected paragraph(s)
> `1` Right aligns selected paragraph(s)
> `2` Centers selected paragraph(s)

Notice that the user doesn't have to actually select the entire paragraph to be aligned. Placing the pointer anywhere on the paragraph to be reformatted or selecting a few characters in the paragraph will do, because there is no way to align part of the paragraph only.

To change the font and style of the selected text, use the properties `SelFontName` and `SelFontSize`. The following statements will render the selected text in Verdana font, 24 points:

>     RICHTEXT.SelFontName = "Verdana"

>     RICHTEXT.SelFontSize = 24

You must supply a font name that exists on the client computer, or a similar font will be substituted. As of now, it's not possible for VBScript to read the names of the fonts installed on the client computer and present them to the viewer to select one.

Finally, there are two properties for creating bulleted items: the `SelBullet` property-and controlling the text's baseline, the `SelOffset` property. If the `SelBullet` property is set to `True`, the selected paragraphs are formatted with a bullet style, similar to the `UL` tag in HTML. To create a list of bullet items, select them with the pointer and assign the value `True` to the `SelBullet` property. To restore a list of bullet items to normal text, select the items and assign the value `False` to the `SelBullet` property.

The `SelOffset` property determines whether the selected characters appear on, above, or below the normal text baseline. Normally, text appears on the baseline. You can raise its baseline to create superscripts (you must also reduce its size a point or two) or lower it to create subscripts. To lower the baseline of the selected text, assign a negative number to the `SelOffset` property. This value must be expressed in twips. (A twip corresponds to one-twentieth of a point, and there are 72 points in an inch.)

As you have realized, creating a functional, even fancy, word processor based on the Rich Textbox control is quite simple. You must provide a convenient user interface that lets the user select text and apply attributes and styles to it, and then set the control's properties accordingly. This is exactly what this chapter's application does.

### Designing the User Interface

The RTFEditor's user interface is rather simple because VBScript doesn't provide the elaborate menu structures you need to build an application of this type. The commands for manipulating the text are placed in Popup Menu controls, which are activated by clicking the various command buttons below the Rich Textbox control. As usual, we'll start with the design of the layout and then look at the code.

To create the layout of Figure 26.1, create a new HTML document and place a Rich Textbox control on it with the Insert ActiveX control command of the Edit menu. When the Insert ActiveX Control window (shown in Figure 26.6) appears on the screen, locate the item Microsoft Rich Textbox Control and click the OK button.

Figure 26.6 : The Insert ActiveX Control window can be used to insert OCX controls on an HTML document.

Although it's possible to add this control to the Control Pad's toolbox and then draw a new control directly on the HTML layout, Internet Explorer will refuse to load the control at runtime. Instead, it will display the error message shown in Figure 26.7. This is a stubborn message you can't avoid no matter what your settings for safety and security are. The only way to avoid this message is to place the OCX control directly on the HTML document, with the Insert ActiveX Control command. When the application is loaded, you'll be warned that the document contains a control that may not be safe for your system, but it will at least give you the option to load the unsafe control.

Figure 26.7 : If you place a Rich Textbox control directly on a layout, Internet Explorer will refuse to load it.

When the Edit ActiveX Control window appears, adjust the size of the control and set the default font. You must also set its `Scrollbars` property to 2 (`Vertical`) or 3 (`Both`) so that the users will be able to quickly move to any location in a long document. After you have adjusted the size and the properties of the control, VBScript will insert an object definition like the following one in the HTML file:

>     <OBJECT ID="RichTextBox1" WIDTH=100 HEIGHT=51

>      CLASSID="CLSID:3B7C8860-D78F-101B-B9B5-04021C009402">

>         <PARAM NAME="_Version" VALUE="65536">

>         <PARAM NAME="_ExtentX" VALUE="2646">

>         <PARAM NAME="_ExtentY" VALUE="1323">

>         <PARAM NAME="_StockProps" VALUE="69">

>         <PARAM NAME="BackColor" VALUE="-2147483643">

>         <PARAM NAME="ScrollBars" VALUE="2">

>         <PARAM NAME="TextRTF" VALUE="{\rtf1\ansi\deff0\deftab720

>     	{\fonttbl{\f4\fnil MS Sans Serif;}{\b\fnil\fcharset2 Symbol;}{\b\ System;}

>     	{\f4\fnil\fprq2 MS Sans Serif;}}

>     {\colortbl\red0\green0\blue0;}

>     \deflang1033\pard\plain\f4\

>     \par }

>     ">

>     </OBJECT>

The `TextRTF` property contains some initial settings for the control's RTF text. The last parameter must be deleted or you will not be able to read the RTF code of the document on the control. (The `TextRTF` property will always return its initial value.) As you will see later in the chapter, we are going to add a command that displays the RTF description of the document on the control.

There's another property you must add manually to this definition, and this is the `RightMargin` property. This property determines the right margin of the text on the control and should be slightly less than the `_ExtentX` property. The right margin isn't specified as the distance of the text from the right edge of the control. Instead, it's the distance of the text's right margin from the left edge of the control. You should make it smaller than the `_ExtentX` property to accommodate the vertical scrollbar that will be attached to the control when the text's length exceeds the length of the Rich Textbox control.

You can also specify a right margin larger than the control's width. In this case, the users will be able to type lines longer than the control's width. Just make sure that a horizontal scrollbar will be attached to the control so that the user will be able to scroll the text right and left. The exact values of these two properties for the RTFEditor example are

>     <PARAM NAME="_ExtentX" VALUE="14000">

>     <PARAM NAME="RightMargin" VALUE="12500">

Next place the command buttons below the Rich Textbox control. Because you are not working on an HTML layout control, where you can visually place the various controls and align them, you must edit the HTML file manually and create a table structure for aligning the command buttons. Because HTML lacks the tags for precise placement of the elements on a Web page, using a table to align them is a very common practice. The table in which the Rich Textbox and command button controls will be placed has two rows and five columns. The Rich Textbox control takes up the entire first row (all five columns), and the command buttons take up the second row of the table. Each one is placed in its own cell. The command buttons are aligned perfectly with the Rich Textbox control, even when the user resizes the browser's window. Here's the modified HTML document with all the controls:

>     <HTML>

>     <HEAD>

>     <TITLE>New Page</TITLE>

>     </HEAD>

>     <BODY>

>     <TABLE>

>     <TR>

>     <TD COLSPAN=5>

>         <OBJECT ID="RichTextBox1" WIDTH=500 HEIGHT=280

>          CLASSID="CLSID:3B7C8860-D78F-101B-B9B5-04021C009402">

>             <PARAM NAME="_Version" VALUE="65536">

>             <PARAM NAME="_ExtentX" VALUE="14000">

>             <PARAM NAME="_ExtentY" VALUE="7408">

>             <PARAM NAME="_StockProps" VALUE="69">

>             <PARAM NAME="BackColor" VALUE="-2147483643">

>             <PARAM NAME="ScrollBars" VALUE="3">

>             <PARAM NAME="RightMargin" VALUE="12500">

>         </OBJECT>

>     </TR>

>     <TR>

>     <TD>

>         <OBJECT ID="FontMenu" WIDTH=96 HEIGHT=32

>          CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57">

>             <PARAM NAME="Caption" VALUE="Font">

>             <PARAM NAME="Size" VALUE="2540;846">

>             <PARAM NAME="FontName" VALUE="Verdana">

>             <PARAM NAME="FontHeight" VALUE="180">

>             <PARAM NAME="FontCharSet" VALUE="0">

>             <PARAM NAME="FontPitchAndFamily" VALUE="2">

>             <PARAM NAME="ParagraphAlign" VALUE="3">

>             <PARAM NAME="FontWeight" VALUE="0">

>         </OBJECT>

>     <TD>

>         <OBJECT ID="CharacterMenu" WIDTH=96 HEIGHT=32

>          CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57">

>             <PARAM NAME="Caption" VALUE="Character">

>             <PARAM NAME="Size" VALUE="2540;846">

>             <PARAM NAME="FontName" VALUE="Verdana">

>             <PARAM NAME="FontHeight" VALUE="180">

>             <PARAM NAME="FontCharSet" VALUE="0">

>             <PARAM NAME="FontPitchAndFamily" VALUE="2">

>             <PARAM NAME="ParagraphAlign" VALUE="3">

>             <PARAM NAME="FontWeight" VALUE="0">

>         </OBJECT>

>     <TD>

>         <OBJECT ID="ParagraphMenu" WIDTH=96 HEIGHT=32

>          CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57">

>             <PARAM NAME="Caption" VALUE="Paragraph">

>             <PARAM NAME="Size" VALUE="2540;846">

>             <PARAM NAME="FontName" VALUE="Verdana">

>             <PARAM NAME="FontHeight" VALUE="180">

>             <PARAM NAME="FontCharSet" VALUE="0">

>             <PARAM NAME="FontPitchAndFamily" VALUE="2">

>             <PARAM NAME="ParagraphAlign" VALUE="3">

>             <PARAM NAME="FontWeight" VALUE="0">

>         </OBJECT>

>     <TD>

>         <OBJECT ID="TextMenu" WIDTH=96 HEIGHT=32

>          CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57">

>             <PARAM NAME="Caption" VALUE="Text Color">

>             <PARAM NAME="Size" VALUE="2540;846">

>             <PARAM NAME="FontName" VALUE="Verdana">

>             <PARAM NAME="FontHeight" VALUE="180">

>             <PARAM NAME="FontCharSet" VALUE="0">

>             <PARAM NAME="FontPitchAndFamily" VALUE="2">

>             <PARAM NAME="ParagraphAlign" VALUE="3">

>             <PARAM NAME="FontWeight" VALUE="0">

>         </OBJECT>

>     <TD>

>         <OBJECT ID="PageMenu" WIDTH=96 HEIGHT=32

>          CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57">

>             <PARAM NAME="Caption" VALUE="Page Color">

>             <PARAM NAME="Size" VALUE="2540;846">

>             <PARAM NAME="FontName" VALUE="Verdana">

>             <PARAM NAME="FontHeight" VALUE="180">

>             <PARAM NAME="FontCharSet" VALUE="0">

>             <PARAM NAME="FontPitchAndFamily" VALUE="2">

>             <PARAM NAME="ParagraphAlign" VALUE="3">

>             <PARAM NAME="FontWeight" VALUE="0">

>         </OBJECT>

>     </TABLE>

>     </OBJECT>

>     <OBJECT ID="IEPOP1" WIDTH=0 HEIGHT=0

>          CLASSID="CLSID:7823A620-9DD9-11CF-A662-00AA00C066D2">

>             <PARAM NAME="_ExtentX" VALUE="0">

>             <PARAM NAME="_ExtentY" VALUE="0">

>         </OBJECT>

>         <OBJECT ID="IEPOP2" WIDTH=0 HEIGHT=0

>          CLASSID="CLSID:7823A620-9DD9-11CF-A662-00AA00C066D2">

>             <PARAM NAME="_ExtentX" VALUE="0">

>             <PARAM NAME="_ExtentY" VALUE="0">

>         </OBJECT>

>     </BODY>

>     </HTML>

This is the `RTFEdit.htm` file in this chapter's folder on the CD. Notice that it contains two Popup Menu controls too, the IEPOP1 and IEPOP2 controls. Each command button causes a menu to pop up on the screen, and this is the IEPOP1 control. One of the options in the Font menu is Size, which leads to a second popup menu, the IEPOP2.

### The Code Behind the Scenes

Now we are ready to look at the code. Each one of the command buttons at the bottom of the page triggers a Popup Menu control, which contains the corresponding options. Because we are using a single Popup Menu control, we must adjust its contents dynamically and keep track of which menu is displayed with a global variable. Here is the `Click` event of the Paragraph menu:

>     Sub ParagraphMenu_Click()

>         WhichMenu="PARAGRAPH"

>         IEPOP1.Clear

>         IEPOP1.AddItem "Left"

>         IEPOP1.AddItem "Right"

>         IEPOP1.AddItem "Center"

>         IEPOP1.Popup

>     End Sub

First this code sets the `WhichMenu` global variable, so that we'll know later which menu was opened and which option on this menu was selected. The `Click` events of the Character, Paragraph, Text Color, and Page Color menus are quite similar. They just use a different value for the `WhichMenu` variable and assign different content to the menu. After the menu's options are added, the menu is displayed with the Popup method.

Once a user has made a selection, the `Click` event of the IEPOP1 control is triggered, and this is where all the action takes place. The IEPOP1 Menu control is also used to implement a shortcut menu on the Rich Textbox control. Every time the user right-clicks the editor's window, the shortcut menu of Figure 26.8 is displayed.

Figure 26.8 : This shortcut menu contains the most commonly used commands for text manipulation.

The shortcut menu is displayed every time the user right-clicks the editor's window, an action that is signaled to the program by the control's `MouseDown` event. Here's the handler for this event:

>     Sub RichTextBox1_MouseDown(Button, Shift, x, y)

>         If Button<>2 then Exit Sub

>         IEPOP1.Clear

>         WhichMenu="EDITOR"

>         IEPOP1.AddItem "Copy"

>         IEPOP1.AddItem "Cut"

>         IEPOP1.AddItem "Paste"

>         IEPOP1.AddItem "Delete"

>         IEPOP1.AddItem "Select All"

>         IEPOP1.AddItem "Show RTF Code"

>         IEPOP1.Popup

>     End Sub

Any selection the user makes on the IEPOP1 control is reported to the application by means of the control's `Click` event. The IPEOP1 control's `Click` event is the lengthier subroutine, where all the action takes place:

>     Sub IEPOP1_Click(item)

>         Select Case WhichMenu

>         Case "FONT":

>             If item=1 then RichTextBox1.SelFontName="Verdana"

>             If item=2 then RichTextBox1.SelFontName="Impact"

>             If item=3 then RichTextBox1.SelFontName="Comic Sans MS"

>             If item=5 then

>                 IEPOP2.Clear

>                 IEPOP2.AddItem "10 points"

>                 IEPOP2.AddItem "12 points"

>                 IEPOP2.AddItem "14 points"

>                 IEPOP2.AddItem "16 points"

>                 IEPOP2.AddItem "18 points"

>                 IEPOP2.Popup

>             End If

>         Case "CHAR":

>             If item=1 Then

>                 RichTextBox1.SelBold=0

>                 RichTextBox1.SelItalic=0

>                 RichTextBox1.SelUnderline=0

>             End If

>             If item=2 then RichTextBox1.SelBold=NOT RichTextBox1.SelBold

>             If item=3 then RichTextBox1.SelItalic=NOT RichTextBox1.SelItalic

>             If item=4 then RichtextBox1.SelUnderline=NOT RichtextBox1.SelUnderline

>         Case "PARAGRAPH":

>             RichTextBox1.SelAlignment=item-1

>         Case "TEXT":

>             If item=1 then RichTextBox1.SelColor=&H000000

>             If item=2 then RichTextBox1.SelColor=&HFFFFFF

>             If item=3 then RichTextBox1.SelColor=&HFf1010

>             If item=4 then RichTextBox1.SelColor=&H1010FF

>             If item=5 then RichTextBox1.SelColor=&H10Ff10

>         Case "PAGE":

>             If item=1 then RichTextBox1.BackColor=&HFFFFFF

>             If item=2 then RichTextBox1.BackColor=&H000000

>             If item=3 then RichTextBox1.BackColor=&HA0A0A0

>             If item=4 then RichTextBox1.BackColor=&HFFFF01

>             If item=5 then RichTextBox1.BackColor=&H40F0F0

>         Case "EDITOR":

>             If item=1 then TempText=RichTextBox1.SelText

>             If item=2 then

>                 TempText=RichTextBox1.SelText

>                 RichTextBox1.SelText=""

>             End If

>             If item=3 then RichTextBox1.SelText=TempText

>             If item=4 then RichTextBox1.SelText=""

>             If item=5 then

>                 RichTextBox1.SelStart=0

>                 RichTextBox1.SelLength=Len(RichTextBox1.Text)

>             End If

>             If Item=6 Then

>                 MsgBox RichTextBox1.TextRTF

>             End If

>         End Select

>     End Sub

This subroutine is a big `Select Case` statement, which examines the value of the `WhichMenu` variable and carries out the action depending on the selected option. If the user selected an option from the Character menu (`WhichMenu="PARAGRAPH"`), the code sets the `SelBold`, `SelItalic`, and `SelUnderline` properties accordingly. If the user selected an option to change the color of the text or the page on which the text is displayed, the code sets the `TextColor` and `BackColor` properties.

Most of the code is straightforward, with the exception of the Size selection of the Font menu. This option leads to another submenu, with various font sizes. The program adds a number of options (font sizes) to the IEPOP2 control and then displays it. When the user makes a selection from this menu, the following subroutine is executed:

>     Sub IEPOP2_Click(item)

>         RichTextBox1.SelFontSize=10+(item-1)*2

>     End Sub

Here, we use the index of the selected item in the IEPOP2 control to set the font size of the selected text.

The last segment of the `IEPOP1_Click()` subroutine we'd like to discuss is the implementation of the editor's shortcut menu. The Copy, Cut, and Paste commands don't use the Clipboard to temporarily store some text. Instead, the copied text is stored in a global variable, `TempText`, which is then pasted onto the control with the Paste command. This approach isolates the RTFEditor application from the rest of the system and all the editing is done locally. It is possible to exchange data with other applications, however, with the Ctrl-X (cut), Ctrl-C (copy), and Ctrl-V (paste) keystrokes. This functionality is built into the controls and Windows itself, and you don't have to do anything about it.

The last option in the shortcut menu displays the RTF code of the document in a message box, as shown in Figure 26.9. This option is included for your experimentation with RTF code, and you should use it with very small documents. If the editor's window contains many lines of code, the message box will overflow and not display anything.

Figure 26.9 : The last command in the shortcut menu displays the document's RTF code in a message box.

### Saving and Recalling RTF Documents

RTFEditor is a practical tool, but what good is an editor if it can't store the documents into disk files and recall them later? Indeed, this application lacks two very important functions, which we are going to add momentarily. Even without the benefit of storing files on disk, you have learned how to present nicely formatted information to the user. You can use a word processor to produce the RTF code and then place it on a RichTextbox control. With some programming effort, you can allow the users to annotate the document, right on their screens. You can also place a RichTextbox control on a Web page and collect information from your viewers. To do so, you can copy the `TextRTF` property to a hidden textbox and submit it to the server. Or you can use it in conjunction with Exchange, to let users create formatted e-mail messages. The Rich Textbox control comes in very handy for developing intranet applications. Once the commands for saving and opening files are implemented, RTFEditor will become a handy utility for your Web pages.

The Rich Textbox control provides two methods for saving and loading documents to and from files. These methods are called `SaveFile` and `LoadFile`, and they can save documents in RTF or text format. The syntax of the `SaveFile` method is

>     RichTextBox1.SaveFile filename, filetype

where `filename` is the full name of the file in which the document will be stored and `filetype` indicates whether the document will be stored in RTF format (`filetype=0`) or plain text (`filetype=1`). The syntax of the `LoadFile` method is similar:

>     RichTextBox1.LoadFile filename, filetype

The Open and Save As commands can be implemented with a single statement. But hardcoding the name of the file won't take you far. A well-behaved Windows application must prompt the user for the name of the file to be opened or saved on disk. This is done with another OCX control, the Common Dialogs control, which we'll explore in the next section.

#### The Common Dialogs Control

The Common Dialogs control is a peculiar one because it's not displayed on the layout at runtime. It's a control that provides its services to the applications, but it need not be displayed, just like the Timer control. The services provided by the Common Dialogs control are the common Windows 95 dialog boxes, like the Open and Save As dialog boxes, which let the user select a filename; the Color dialog box, which lets the user select a color; the Font dialog box, which lets the user select a font; and so on. After you learn how to display the Save As and Open dialog boxes, you can try substituting the Font popup menu of the RTFEditor application with the standard Font dialog box and the two color menus with the Choose Color dialog box. Figures 26.10 and 26.11 show the two Common Dialog boxes we use in our example: the Save As and Open dialog boxes.

Figure 26.10 : The Save As dialog box.

Figure 26.11 : The Open dialog box.

To call on the services of the Common Dialogs control, you must first place an instance of the control on the layout. Use the Insert ActiveX control command of the Edit menu, and in the Insert ActiveX control box that will appear (refer to Figure 26.6) locate the Common Dialogs control. Then click the OK button to place it on the layout. Notice that you can't adjust its size, because the Common Dialogs control remains hidden at runtime. However, you can set several properties to adjust its function on the layout, like the font to be used, a default filename to appear when the Open or Save As dialog boxes are displayed, and so on.

Control Pad will insert the following object definition in the HTML file for the Common Dialogs control:

>     <OBJECT ID="CommonDialog1" WIDTH=32 HEIGHT=32

>      CLASSID="CLSID:f9043C85-f6f2-101A-A3C9-08002B2f49FB">

>         <PARAM NAME="_Version" VALUE="65536">

>         <PARAM NAME="_ExtentX" VALUE="847">

>         <PARAM NAME="_ExtentY" VALUE="847">

>         <PARAM NAME="_StockProps" VALUE="0">

>     </OBJECT>

Once the Common Dialogs control has been placed on the layout, you can use its `Action` property to display any of the Windows dialog boxes. The `Action` property may have one of the following values:

> 1 | Displays the Open dialog box
> 2 | Displays the Save As dialog box
> 3 | Displays the Color dialog box
> 4 | Displays the Font dialog box
> 5 | Displays the Printer dialog box

Once you assign a value to the `Action` property, the corresponding dialog box will appear on the screen and the execution of the program will be suspended until the dialog box is closed. The user can traverse the entire structure of his or her hard disk and locate the desired filename. Once the Open or Save button has been clicked, the control is returned to your application, which can read the name of the file selected by the user (property `FileName`) and use it to open the file or store the current document.

#### The Open and Save As Commands

Let's see how the File Open and File Save options were added to the application. The new project is called RTFEditor1. (We didn't want to add to the RTFEditor application and make it more complicated than necessary.) Open the `RTFEditor.htm` file with the ActiveX Control Pad and save it as RTFEditor1. First, you must edit the HTML file to add a sixth command button, as shown in Figure 26.12. This entails some adjustments to the table because there will be six rows now. You can open `RTFEditor1.htm` and look at the source code. It's quite similar to the RTFEditor application, and we need not repeat the HTML code here.

Figure 26.12 : The improved RTFEditor application can save and load documents to and from the local disk with the File menu's options.

The new command button functions just like the others. Each time the command button is clicked, a Popup Menu control with the following options is displayed: New File, Load File, and Save File. Here's how the three options are added to the menu from within the `IEPOP1_Click()` subroutine:

>     Sub FileMenu_Click()

>         WhichMenu="FILE"

>         IEPOP1.Clear

>         IEPOP1.AddItem "New File"

>         IEPOP1.AddItem "Open File"

>         IEPOP1.AddItem "Save File"

>         IEPOP1.Popup

>     End Sub

The New File command simply clears the contents of the textbox and is implemented with a single statement:

>     RichTextbox1.Text=""

The code of the File Open option in the popup menu causes the Open File Common Control dialog box to be displayed with the following lines:

>     CommonDialog1.Action=1

>     RichTextBox1.LoadFile CommonDialog1.FileName, 0

And the code of the File Save option is just as simple:

>     CommonDialog1.Action=2

>     RichTextBox1.SaveFile CommonDialog1.FileName, 0

To add file-handling capabilities to your application, insert the following `Case` statement in the existing `Select Case` structure:

>     Case "FILE":

>         If item=1 Then RichTextbox1.Text=""

>         If item=2 Then

>             CommonDialog1.Action=1

>             RichTextBox1.LoadFile CommonDialog1.FileName, 0

>         End If

>         If item=3 Then

>             CommonDialog1.Action=2

>             RichTextBox1.SaveFile CommonDialog1.FileName, 0

>         End If

The implementation of the file-related commands is quite simple, but it should be a bit lengthier. For example, what will happen if the user clicked the Cancel button? The Common Dialogs control returns an empty string. Here's a better way to implement the File Open command:

>     If item=2 Then

>         CommonDialog1.Action=1

>         Filename=CommonDialog1.FileName

>         If FileName="" Then Exit Sub

>         RichTextBox1.LoadFile CommonDialog1.FileName, 0

>     End If

Similar changes must be made to the File Save command's code so that the program will not attempt to save the current document under an invalid filename. In the case of the File Save command you can also prompt the users with an Input Box as to whether they want to save the current document in RTF (`filetype=0`) or text (`filetype=1`) format.

#### Safety Considerations

As we mentioned earlier, Internet Explorer will issue a warning every time it's about to load a page with an OCX control. OCX controls aren't unsafe for the client system, but they are not ActiveX controls, and they haven't been verified for security. The RTFEditor application could be considered doubly unsafe because it saves data on the local disk. People are very reluctant to allow an application that they ran into on the Internet to leave anything on their disk. Applications that make use of OCX controls are quite safe for an intranet environment, but you should think twice before placing them on public Web pages. When the ActiveX versions of these controls become available the situation will change. It's not known how these controls will handle security, but some mechanisms will be built into the controls to protect the viewers. Even a simple warning will help because the user will be able to control which application saves data to the local disk, and when.

## Review

Until all the existing controls are converted to ActiveX format, you can use the OCX controls to develop quite powerful utilities for the Web pages you plan to post on your intranet. The RichTextbox control, for example, provides all the functionality you need to build a simple word processor for everyone in the company. If you plan to use OCX controls on your pages, you should consider purchasing Visual Basic and consult the documentation for additional features of the various OCX controls. The Rich Textbox control, for example, provides methods for searching the text on the control, various ways of selecting text (from the location of the pointer to the end of the line, for example), a method for printing the text, and so on. One final suggestion is to customize each user's editor with cookies. For instance, you can provide a first-level menu that lets the users select the type of document they want to create, and you can bring up the RTFEditor application with a predefined template document, the user's settings (colors, font), the user's name, the current date, and so on. There are Microsoft Office applications that will do all that, but right now none of them can be invoked and customized from within a Web page as easily as the RTFEditor application-not to mention that the average user will find a custom editor like this one easier to learn and use.

Of course, the users of your applications that make use of regular OCX controls must be aware of the warning that Internet Explorer will issue and ignore it. This is more likely to happen in an intranet environment rather than the World Wide Web. We expect to see ActiveX versions of the OCX controls discussed in this and the following chapter shortly after this book hits the market.

The next chapter continues the exploration of OCX controls and how they can be used in Internet Explorer's environment by showing you how to build a spreadsheet application. The GraphData application uses the Grid OCX control to let the user enter data on a spreadsheet and then plots the data on the Graph control (which is actually an ActiveX control).

| Use of this site is subject certain Terms & Conditions. Copyright (c) 1996-1999 EarthWeb, Inc.. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Please read our privacy policy for details.