How to Create an HTML Editor Application

This tutorial describes how to use features found in Microsoft Internet Explorer 5.5 or later to create an HTML Editor Application. The application you create in this tutorial contains an editable region where users can type and format text using all of the standard formatting commands. For example, users can make the text bold or italic, change the font size, and make bulleted or numbered lists. A toolbar provides the formatting buttons, buttons for opening and saving files, and drop-down list boxes for font and block formatting selections. A menu allows alternate access to the functionality provided by the toolbar. As of Internet Explorer 6, you can also use the HtmlDlgSafeHelper object to change the face or color of the font.

With this HTML Editor Application, users can create HTML documents and save them to disk in either HTML or text format. If saved as an .htm file, the documents are viewable in Windows Internet Explorer or in the HTML Editor Application. Files saved as .txt can be viewed in any text editor.

This tutorial demonstrates how to do the following:

You can use this kind of application to allow "what you see is what you get" (WYSIWYG) content editing of Web sites by users. You can also use this type of application as an editor for an Internet e-mail program.

  • Requirements and Dependencies 
  • Implementation Steps 
    • Step 1: Create the HTML file 
    • Step 2: Create the Toolbars 
    • Step 3: Create the Text Formatting Functions 
    • Step 4: Create the File New, File Open, and File Save Functions 
    • Step 5: Create the Menu 
    • Step 6: Create the Splash Screen 
  • Final Wrap-up 
  • Related Topics

Requirements and Dependencies

Developers who want to create an HTML editor as described in this tutorial should be familiar with Microsoft JScript and Dynamic HTML (DHTML). Knowledge of element behaviors is also helpful.

The CommonDialog control used in this tutorial to display the Open and Save As dialog boxes is a licensed control that requires a valid design-time license. You can run the sample, but you cannot create this functionality unless you have Microsoft Visual Basic or Microsoft Visual InterDev installed on your development machine. For more information, see HOWTO: Set Up Internet Download for Comdlg32.ocx.

You can use any HTML development environment, such as Visual InterDev, to complete this tutorial. Visual InterDev is a good choice because it provides a design-time license for the CommonDialog control.

Most of the technology described in this tutorial is supported by Internet Explorer 5.5 or later, with the notable exception of the HtmlDlgSafeHelper object, which requires Internet Explorer 6.

This tutorial requires a number of dependent files in order to function properly, including icons for the toolbar buttons, and two HTML Components (HTCs). All of these files are included in the HTML Editor sample download. Before you get started with the tutorial, you need to download the HTML Editor sample. Follow the steps on the download page before continuing to Implementation Steps.

Implementation Steps

This section describes, step-by-step, how to create a WYSIWYG HTML Editor HTA.

  • Step 1: Create the HTML file 
  • Step 2: Create the Toolbars 
  • Step 3: Create the Text Formatting Functions 
  • Step 4: Create the File New, File Open, and File Save Functions 
  • Step 5: Create the Menu 
  • Step 6: Create the Splash Screen 

Step 1: Create the HTML file

The HTML file that you create in this step serves as the foundation for the features you add as the tutorial progresses.

  1. Create an HTML file. This file should contain the standard HTML tags, including HTML, HEAD, and BODY. You can also add a TITLE element in the HEAD section if you like. The following code sample shows what the HTML should look like.

    <HTML>
    <HEAD>
    <TITLE>HTML Editor</TITLE>
    </HEAD>
    <BODY STYLE="overflow:hidden; margin:0px">
    </BODY>
    </HTML>
    
  2. Add a DIV element in the BODY section. This DIV element is the container for the all of the UI elements in the application.

    <DIV  ID="oContainer" STYLE="background-color:threedface; border:1px solid #cccccc;
    position:relative; height:100%; top:0;">
    

    Place the closing DIV tag directly above the closing BODY tag.

  3. Add the DIV element that serves as the editing region. Place this DIV inside the oContainer DIV element and set the CONTENTEDITABLE attribute. Give the DIV element an ID value of oDiv and set the STYLE properties of the DIV. The following code shows you how to set all the necessary attributes of the DIV.

    <DIV 
    ID=oDiv 
    CONTENTEDITABLE
    STYLE="height:80%;background-color:white; overflow:auto; width:100%;"> 
    </DIV>
    
  4. Add a SCRIPT block in the HEAD section and create a function that is called when the application initializes. The doInit function sets the focus on the DIV and sets the UNSELECTABLE attribute for all elements of the document. Later in the tutorial, you will add more code to this function.

    <SCRIPT>
    window.onload=doInit
    function doInit(){
    // Ensure that all document elements except the content editable DIV are unselectable.
    for (i=0; i<document.all.length; i++)
     document.all(i).unselectable = "on";
    oDiv.unselectable = "off";
    // Clear any text in the Document window and set the focus.
    oDiv.innerHTML="";
    oDiv.focus();
    }
    </SCRIPT>
    
  5. Name the file something meaningful and save the page with an .htm extension in the directory where you downloaded the sample files.

Note  As you work through the tutorial, be careful not to name any of the files you create HTML_Editor, or you might overwrite the sample application. The sample application should be left as a reference to consult while working through this tutorial.

Step 2: Create the Toolbars

In this step, you use the WebControls Toolbar element behavior to add two toolbars. The toolbars contain ToolbarButton, ToolbarDropDownList, and ToolbarSeparator elements that implement common document editing functionality by using execCommand along with formatting commands like Bold and ForeColor.

  1. Declare the following namespace for the toolbar inside the opening HTML tag.

    xmlns:mytb
    
  2. Add the IMPORT statement, shown in the following example, between the opening HTML tag and the opening HEAD tag. The IMPORT statement points to the toolbar element behavior that uses the same namespace declared in the HTML element.

    <?IMPORT namespace="mytb" implementation="toolbar.htc">
    

    After you declare the namespace and add the IMPORT statement, all that is left to do to create a basic toolbar is to add the elements in the BODY section.

  3. Add the first Toolbar element and child elements in the BODY of the document, inside the oContainer DIV element, directly above the oDiv DIV element.

    Two Toolbar elements are used so that they display on two separate rows.

    The following example shows the oToolbar Toolbar element.

    <mytb:TOOLBAR STYLE="display:inline; width:100%" ID="oToolBar">
    <mytb:TOOLBARBUTTON IMAGEURL="UI_new.gif"
        title="New Document"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_open.gif"
        title="Open Document"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_save.gif"
        title="Save Document"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARDROPDOWNLIST id="oFontSize">
        <option value=1>1
        <option value=2>2
        <option value=3>3
        <option value=4 selected>4
        <option value=5>5
        <option value=6>6
        <option value=7>7
    </mytb:TOOLBARDROPDOWNLIST>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_bold.gif" 
        title="Bold"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_italic.gif"
        title="Italic" />
    <mytb:TOOLBARBUTTON IMAGEURL="UI_underline.gif"
        title="Underline" />
    <mytb:TOOLBARBUTTON IMAGEURL="UI_form-strike.gif" 
        title="StrikeThrough"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_superscript.gif"
        title="SuperScript"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_subscript.gif" 
        title="SubScript"/>
    </mytb:TOOLBAR>
    </nobr>
    
  4. Add the second Toolbar and child elements, shown in the following example, in the BODY of the document, directly below the first Toolbar element.

    Note  The order of the elements in the HTML source code dictates the order of the elements displayed on the rendered page. Be careful to add each element in its proper place to ensure proper rendering.

    <nobr>
    <mytb:TOOLBAR STYLE="display:inline; width:100%" ID="oToolBar2">
    <mytb:TOOLBARBUTTON IMAGEURL="UI_tool-cut.gif"
        title="Cut"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_form-copy.gif"
        title="Copy"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_paste.gif"
        title="Paste"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_undo.gif"
        title="Undo"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_redo.gif"
        title="Redo"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_numberlist.gif"
        title="InsertOrderedList"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_bulletlist.gif"
        title="InsertUnorderedList"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_outdent.gif"
        title="Outdent"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_indent.gif"
        title="Indent"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_leftalign.gif"
        title="JustifyLeft"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_centeralign.gif"
        title="JustifyCenter"/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_rightalign.gif"
        title="JustifyRight"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_tool_vertical.gif"
        title="Vertical Alignment"/>
    <mytb:TOOLBARSEPARATOR/>
    <mytb:TOOLBARBUTTON IMAGEURL="UI_fontcolor.gif"
        title="Font Color" />
    <mytb:TOOLBARBUTTON IMAGEURL="UI_backcolor.gif"
        title="HighLight"/>
    </mytb:TOOLBAR> 
    

At this point, you have an application that is beginning to look like an editor, although the toolbar buttons will not function until you add the code to implement the functionality behind the buttons. Your application should look like the following example.

Code example: http://samples.msdn.microsoft.com/workshop/samples/author/editing/HTML_Editor/StepTwo.htm

Step 3: Create the Text Formatting Functions

The functions created in this step are from the ToolbarButton elements created in the last step. These include a function that executes most of the formatting commands used in this sample as well as functions to change the fontSize property and to change the alignment of the text.

You also create the HtmlDlgSafeHelper object and write functions that use this object to display the color dialog box and change the ForeColor or BackColor, based on the user's selection. You also write functions that utilize the HtmlDlgSafeHelper object to retrieve an array of fonts and an array of block formats installed on the user's system, populate ToolbarDropDownList elements on the ToolbarButton with these arrays, and change the font or format of the selection in the editable region based on the user's selection.

Create all of the functions in this step in the SCRIPT block.

  1. Create a function called callFormatting with a single input parameter that calls the execCommand method. The parameter passes the appropriate Command Identifiers to the function based on which ToolbarButton is clicked.

    function callFormatting(sFormatString){
    document.execCommand(sFormatString);
    }
    
  2. Add an onclick event to each of the toolbar buttons that use the callFormatting function. Use the following Bold ToolbarButton element as an example, and then replace the Bold Command Identifier with the appropriate Command Identifier in the list that follows the example.

    <mytb:TOOLBARBUTTON IMAGEURL="UI_bold.gif" 
    title="Bold"
    <!--This is the line to add --> 
    onclick="callFormatting('Bold');"/>
    
    

    The ToolbarButtons that call this method are: Bold, Italic, Underline, StrikeThrough, SuperScript, SubScript, Cut, Copy, Paste, Undo, Redo, InsertOrderedList, Insert, UnorderedList, Outdent, Indent, JustifyLeft, JustifyCenter, and JustifyRight.

    As you can see, most of the formatting functionality is accomplished with one simple line of code using the execCommand method and the proper Command Identifier. For clarity, the ToolbarButton titles match the Command Identifier that is passed to the function.

    Use this example as a check point for your application. Both applications should look and function the same way. You can use the source code of the example to compare to your application.

    Code example: http://samples.msdn.microsoft.com/workshop/samples/author/editing/HTML_Editor/StepThree_A.htm

  3. Create a function called changeFontSize to change the fontSize property based on the value chosen in the oFontSize ToolbarDropDownList.

    function changeFontSize(){
    var sSelected=oToolBar.getItem(6).getOptions().item(oToolBar.getItem(6).getAtt
    ribute("selectedIndex"));
    document.execCommand("FontSize", false, sSelected.value);
    }
    
  4. Add an onchange event to the oFontSize ToolbarDropDownList element that calls the changeFontSize function.

    onchange="changeFontSize();"
    
  5. Create a function called VerticalMode that uses the writingMode property to toggle the alignment of the editable region from vertical alignment to horizontal alignment.

     function VerticalMode(){
    if (oDiv.style.writingMode == 'tb-rl')
        oDiv.style.writingMode = 'lr-tb';
    else
        oDiv.style.writingMode = 'tb-rl';
    }
    
  6. Add an onclick event to the Vertical Alignment ToolbarButton element that calls the VerticalMode function.

    onclick="VerticalMode();"
    
  7. Add the object element at the top of the BODY section to create the HtmlDlgSafeHelper object. You must have Internet Explorer 6 or later to complete this step and subsequent steps.

    
     <OBJECT ID=dlgHelper CLASSID="clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b"
     WIDTH="0px" HEIGHT="0px"></OBJECT>
    
  8. Create a function called getSystemFonts that uses the fonts collection of the Dialog Helper object to return an array of the names of all of the fonts installed on the user's system and then creates a ToolbarDropDownList element on the Toolbar and populates the OPTION elements with the names of the fonts. The code in this function also detects the onchange event and calls a function called ChangeFont.

    function getSystemFonts(){
        var a=dlgHelper.fonts.count;
        var fArray = new Array();
        var oDropDown = oToolBar.createDropDownListAt("4");
        oDropDown.setAttribute("id","FontNameList");
        for (i = 1;i < dlgHelper.fonts.count;i++){ 
            fArray[i] = dlgHelper.fonts(i);
            var aOptions = oDropDown.getOptions();  
            var oOption = document.createElement("OPTION");
            aOptions.add(oOption);  
            oOption.text = fArray[i];
            oOption.Value = i;
        }
        // Attaching the onchange event is necessary in order to detect when a
        // user changes the value in the drop-down list box.
            oDropDown.setAttribute("onchange",ChangeFont);
    }
    
  9. Add a call to the getSystemFonts function to the end of the doInit function so that the ToolbarDropDownList element is populated when the application initializes.

    getSystemFonts();
    
  10. Create a function called ChangeFont that uses the execCommand method and the FontName command to change the fontFamily of the selection in the editable region.

    function ChangeFont(){  
    var sSelected=oToolBar.getItem(4).getOptions().item(oToolBar.getItem(4).getAtt
    ribute("selectedIndex"));
    document.execCommand("FontName", false, sSelected.text);
    }
    
  11. Create a function called getBlockFormats that uses the fonts collection of the HtmlDlgSafeHelper object to return an array of the names of all of the block formats installed on the user's system and then creates a ToolbarDropDownList on the Toolbar and populates the OPTION elements with the names of the block formats. The code in this function also detects the onchange event and calls a function called ChangeFormat.

    function getBlockFormats(){
        var a=dlgHelper.blockFormats.count;
        var fArray = new Array();
        var oDropDown = oToolBar.createDropDownListAt("5");
        oDropDown.setAttribute("id","FormatList");
        for (i = 1;i < dlgHelper.blockFormats.count;i++)
        { 
            fArray[i] = dlgHelper.blockFormats(i);
            var aOptions = oDropDown.getOptions();  
            var oOption = document.createElement("OPTION");
            aOptions.add(oOption);  
            oOption.text = fArray[i];
            oOption.Value = i;
        } 
        // Attach the onchange event
        oDropDown.setAttribute("onchange",ChangeFormat);
    }
    
    
  12. Add a call to the getBlockFormats function to the doInit function so that the ToolbarDropDownList element is populated when the application initializes.

    getBlockFormats();
    
  13. Create a function called ChangeFormat that uses the execCommand method and the FormatBlock command to change the block format of the selection in the editable region.

    function ChangeFormat(){
    var sSelected=oToolBar.getItem(5).getOptions().item(oToolBar.getItem(5).getAtt
    ribute("selectedIndex"));
    document.execCommand("FormatBlock", false, sSelected.text);
    }               
    
  14. Create a global variable called sInitColor and set it equal to null. This variable holds the color that is chosen by the user when the color dialog box displays. The application "remembers" this choice and it will be the selected color the next time the color dialog box displays.

    var sInitColor = null;
    
  15. Create a function called callColorDlg that calls the ChooseColorDlg method of the HtmlDlgSafeHelper object. The ChooseColorDlg method displays the color dialog box, returns the user's color selection in sColor, then applies the color choice using the ForeColor or the BackColor command, according to what is passed in sColorType.

    function callColorDlg(sColorType){
    if (sInitColor == null) 
        // Display color dialog box
        var sColor = dlgHelper.ChooseColorDlg();
    else
        var sColor = dlgHelper.ChooseColorDlg(sInitColor);
        // Change decimal to hex
        sColor = sColor.toString(16);
        // Add extra zeroes if hex number is less than 6 digits
    if (sColor.length < 6) {
        var sTempString = "000000".substring(0,6-sColor.length);
        sColor = sTempString.concat(sColor);
    }
        // Change color of the selected text
        document.execCommand(sColorType, false, sColor);
        sInitColor = sColor;
        oDiv.focus();
    }
    

At this point, you can use the application to create and format an HTML document, creating WYSIWYG HTML Web pages. Use this example as a check point for your application. Both applications should look and function the same way. You can use the source code of the example to compare to your application.

Code example: http://samples.msdn.microsoft.com/workshop/samples/author/editing/HTML_Editor/StepThree_B.htm

To become a fully functional editing application, the next step is to provide a way to save documents, to open existing documents, and to create new documents.

Step 4: Create the File New, File Open, and File Save Functions

The CommonDialog control is an Microsoft ActiveX control that provides an easy way to display the Open and Save As dialog boxes. After you declare the CommonDialog object, you can write one line of code that displays a dialog box.

Note  The CommonDialog control is a licensed control that is available only to developers with Visual Basic or Visual InterDev installed on their development machine. If you do not have a license to use the CommonDialog control, skip to Step 5: Create the Menu.

  1. Create a global variable called sPersistValue.

    var sPersistValue
    

    This variable holds the value of the innerHTML property of oDiv when the div is saved. This value is then compared to the value of innerHTML property of oDiv in the checkForSave function to determine whether to prompt the user to save the current document before opening an existing document or creating a new document. This variable must be declared before the functions that use it. The easiest way to ensure this is to place the variable declaration at the beginning of the script block.

  2. Create a function called checkForSave that determines whether the contents of the editable region have changed and optionally uses the showModalDialog method to display a modal dialog box that asks the user whether to save the changes to the current document before proceeding. For information on using modal dialog boxes, see Creating and Using Modal Dialog Boxes.

    This function is called by the NewDocument and LoadDocument functions. The dCheckForSave.htm file is provided for you in the sample directory.

    function checkForSave()
    {if ((oDiv.innerHTML!=sPersistValue)&&(oDiv.innerHTML !=""))
      var checkSave=showModalDialog('dcheckForSave.htm','','dialogHeight:125px;dialo
    gWidth:250px;scroll:off');
    else
      var checkSave=false;
    return checkSave
    }
    
  3. Create a function called NewDocument that calls the checkForSave function. If the document in the editable region has changed, then the SaveDocument function is called before a new document is created by clearing the innerHTML property of oDiv.

    function NewDocument(){
        var answer = checkForSave();
        if (answer) {var sCancel = SaveDocument();
            if (sCancel) return;
            oDiv.innerHTML="";}
        if (answer==false)
            oDiv.innerHTML="";
        oDiv.focus();
    }
    
  4. Add an onclick event to the New Document Toolbar element that calls the NewDocument function.

    onclick="NewDocument();"
    
  5. Create the CommonDialog OBJECT in the BODY section, directly below the dlgHelper OBJECT.

    <OBJECT ID="cDialog" WIDTH="0px" HEIGHT="0px"
        CLASSID="CLSID:F9043C85-F6F2-101A-A3C9-08002B2F49FB"
        CODEBASE="http://activex.microsoft.com/controls/vb5/comdlg32.cab">
    </OBJECT>
    
  6. Create a function called LoadDocument that displays a Open dialog box, and then opens a FileSystemObject to read the contents of the file chosen by the user and display it in the editable region.

    function LoadDocument(){
    // Setting CancelError to true and using try/catch allows the user to
    // click cancel on the save as dialog without causing a script error.
        cDialog.CancelError=true;
        try{
            var answer = checkForSave();
            // The user has clicked yes in the modal dialog box called in the
            // checkForSave function.
                if (answer) {var sCancel = SaveDocument();
                // The user has clicked cancel in the save as dialog box; exit
                // function.
                if (sCancel) return; 
                cDialog.Filter="HTM Files (*.htm)|*.htm|Text Files (*.txt)|*.txt"
                cDialog.ShowOpen();
                var ForReading = 1;
                var fso = new ActiveXObject("Scripting.FileSystemObject");
                var f = fso.OpenTextFile(cDialog.filename, ForReading);
                var r = f.ReadAll();
                f.close();
                oDiv.innerHTML=r;
                // This variable is used in the checkForSave function to see
                // if there is new content in the div. 
                sPersistValue=oDiv.innerHTML;
    
                }
                // The user has clicked no in the modal dialog box called in
                // the checkForSave function.
                if (answer==false)
                {cDialog.Filter="HTM Files (*.htm)|*.htm|Text Files (*.txt)|*.txt"
                cDialog.ShowOpen();
                var ForReading = 1;
                var fso = new ActiveXObject("Scripting.FileSystemObject");
                var f = fso.OpenTextFile(cDialog.filename, ForReading);
                var r = f.ReadAll();
                f.close();
                oDiv.innerHTML=r;
                sPersistValue=oDiv.innerHTML;
    }
                oDiv.focus();
            }
            catch(e){
            var sCancel="true";
            return sCancel;}
    }
    
  7. Add an onclick event to the Open Document Toolbar element that calls the LoadDocument function. The Open Document Toolbar element should look like the following example.

    <mytb:TOOLBARBUTTON  IMAGEURL="UI_open.gif"
    title="Open Document"
    onclick="LoadDocument();" />
    
  8. Create a function called SaveDocument that displays the Save As dialog box and then opens a FileSystemObject to write the contents of the document in the editable region to the file chosen by the user.

    function SaveDocument(){
    // Setting CancelError to true and using try/catch allows the user to click cancel on the save
    // as dialog without causing a script error.
        cDialog.CancelError=true;
        try{
            cDialog.Filter="HTM Files (*.htm)|*.htm|Text Files (*.txt)|*.txt"
            cDialog.ShowSave();
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            var f = fso.CreateTextFile(cDialog.filename,  true);
            f.write(oDiv.innerHTML);
            f.Close();
            sPersistValue=oDiv.innerHTML;}
        catch(e){
            var sCancel="true";
            return sCancel;}
        oDiv.focus();   
      } 
    
  9. Add an onclick event to the Save Document Toolbar element that calls the SaveDocument function.

  10. To enable users of the HTML Editor access to the Open and Save As dialog boxes on a computer without a license for the CommonDialog control, you must generate a license package file (LPK). To create this file, follow the procedures outlined in HOWTO: Use Licensed ActiveX Controls in Internet Explorer and HOWTO: Set Up Internet Download for Comdlg32.ocx. After you have created the .lpk file and followed the instructions for creating the licensing object as outlined in these articles, you have an .lpk file in the sample directory, and the licensing object is declared in the BODY of the sample application, as in the following example.

    <OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">
        <PARAM NAME="LPKPath" VALUE="comdlg.lpk">
    </OBJECT>
    

    You will also have a CODEBASE attribute for the cDialog object, as in the following example.

     CODEBASE="http://activex.microsoft.com/controls/vb5/comdlg32.cab"
    
  11. In most cases, HTML pages do not have access to the local file systems of client machines. For purposes of this sample it means that the user cannot open and save local files as long as the application is an HTML file. This is by design for security reasons. Because HTAs can do anything that other locally accessed applications can do, HTAs do not have this limitation. For more information, see Introduction to HTML Applications (HTAs).

    Add the HTA element in the HEAD section directly below the title element.

    <HTA:APPLICATION ID="oHTA"
         APPLICATIONNAME="HTML Editor"
         BORDER="thick"
         BORDERSTYLE="raised"
         CAPTION="yes"
         ICON="netpad.ico"
         MAXIMIZEBUTTON="yes"
         MINIMIZEBUTTON="yes"
         SHOWINTASKBAR="yes"
         SINGLEINSTANCE="yes"
         SYSMENU="yes"
         VERSION="1.0"
         WINDOWSTATE="normal"/> 
    
  12. Give the file a meaningful name and save the page with an .hta extension in the directory where you downloaded the sample files.

Note  Do not name the file HTML_Editor, or you will overwrite the sample application.

At this point, the application is fully functional. All of the button routines are operational and the application should work as a full-featured WYSIWYG HTML content editor. Use this example as a check point for your application. Both applications should look and function the same way. You can use the source code of the example to compare to your application.

Code example: http://samples.msdn.microsoft.com/workshop/samples/author/editing/HTML_Editor/StepFour.hta

The next steps outline how to create a menu and splash screen to add a professional look to the application.

Step 5: Create the Menu

The menu you create in this step implements a subset of the functionality provided by the ToolbarButton elements. You can extend the menu to include any of the items on the ToolbarButton, as well as any other functions you want to provide your users.

  1. Declare the namespace for the menu inside the opening HTML tag. The HTML tag should look like the following example.

    <HTML xmlns:mytb
          xmlns:mymenu>
    
  2. Add the IMPORT statement that points to the menu element behavior and that uses the same namespace declared in the HTML element.

    <?IMPORT namespace="mymenu" implementation="menu.htc">
    

    After you declare the namespace and add the IMPORT statement, all that is left to do to create a menu is to add the markup tags.

  3. Add the menu elements and child elements to the BODY of the sample application, directly above the oToolBar ToolbarButton element. Explicitly set the background color of the menu so that it won't be affected by individual desktop settings.

    <mymenu:menu id="File" 
    backcolor="threedface" onsubmenu_click="CallMenuFunction();">File
    <mymenu:menu id="new" backcolor="threedface">New</mymenu:menu>
    <mymenu:menu id="open" backcolor="threedface">Open</mymenu:menu>
    <mymenu:menu id="save" backcolor="threedface">Save</mymenu:menu>
    <mymenu:menu id="exit" backcolor="threedface">Exit</mymenu:menu>
    </mymenu:menu>
    <mymenu:menu id="Edit" backcolor="threedface" 
    onsubmenu_click="CallMenuFunction();">Edit
    <mymenu:menu id="cut" backcolor="threedface">Cut Ctrl+X</mymenu:menu>
    <mymenu:menu id="copy" backcolor="threedface">Copy Ctrl+C</mymenu:menu>
    <mymenu:menu id="paste" backcolor="threedface">Paste Ctrl+V</mymenu:menu>
    </mymenu:menu>
    <mymenu:menu id="Format" backcolor="threedface" onsubmenu_click="CallMenuFunction();">Format
    <mymenu:menu id="bold" backcolor="threedface">Bold</mymenu:menu>
    <mymenu:menu id="italic" backcolor="threedface">Italic</mymenu:menu>
    <mymenu:menu id="underline" backcolor="threedface">Underline</mymenu:menu>
    <mymenu:menu id="fontColor" backcolor="threedface">Font Color</mymenu:menu>
    <mymenu:menu id="highlight" backcolor="threedface">HighLight</mymenu:menu>
    </mymenu:menu>
    <mymenu:menu id="Help" backcolor="threedface" 
    onsubmenu_click="CallMenuFunction();">Help
    <mymenu:menu id="about" backcolor="threedface">About</mymenu:menu>
    </mymenu:menu>
     <nobr>
    
  4. Create a function called CallMenuFunction that uses a switch statement to call the formatting functions created in Step 3: Create the Text Formatting Functions. The switch operates on the value of the ID attribute of the menu items.

    function CallMenuFunction(){
    var menuChoice = event.result;
    switch(menuChoice){
     case "open":   
      LoadDocument();
      break;
     case "new":
      NewDocument();
      break;
     case "save":
      SaveDocument();
      break;
     case "exit":
      window.close();
      break;
     case "cut":
      callFormatting('Cut');
      break;
     case "copy":
      callFormatting('Copy');
      break;
     case "paste":
      callFormatting('Paste');
      break;
     case "bold":
      callFormatting('Bold');
      break;
     case "underline":
      callFormatting('Underline');
      break;
     case "italic":
      callFormatting('Italic');
      break;
     case "fontColor":
      callColorDlg('ForeColor');
      break;
     case "highlight":
      callColorDlg('BackColor');
      break;
     case "about":
      goContext(); 
      break;
     default:
      break;
                }
    }
    
  5. Add an event called onsubmenu_click to the opening tag of each of the top-level menus: File, Edit, Format, and Help. This event calls the CallMenuFunction function.

    <mymenu:menu id="File" onsubmenu_click="CallMenuFunction();">
    

Step 6: Create the Splash Screen

A splash screen adds a professional look to any application and is easy to implement using the HTML+TIME default behavior.

  1. Declare the namespace for the HTML+TIME element behavior inside the opening HTML tag.

    xmlns:t ="urn:schemas-microsoft-com:time"
    
  2. Add the IMPORT statement that uses the same namespace declared in the HTML element.

    <?IMPORT namespace="t" implementation="#default#time2">
    
  3. Add the style element in the HEAD element, directly above the title element.

    <style>
            .time           { behavior: url(#default#time2) }
    </style>
    
  4. Create a global variable called oPopup and use it to create a new pop-up window using the createPopup method. This variable must be declared before the functions that use it; therefore, place the variable declaration at the beginning of the script block.

    var oPopup = window.createPopup();
    
  5. Create a function called goContext that displays the pop-up window.

    
    function goContext()
    {var oPopupBody = oPopup.document.body;
    
    oPopupBody.innerHTML = oContext.innerHTML;
    oPopup.show(175, 125, 400, 300, document.body);
    document.body.onmousedown = oPopup.hide;
    }
    
  6. Add the HTML+TIME element in the BODY section, directly below the OBJECT elements. The pop-up window displays for 5 seconds and then disappears.

    <t:animate dur="5" onend="oPopup.hide();"/>
    
  7. Add the div elements that serve as the display for the splash screen directly below the HTML+TIME element.

    <DIV ID="oContext" STYLE="display:none">
    <DIV STYLE="position:absolute; top:0; left:0; width:400px;
                 height:300px; border:1px solid black; background:#eeeeee; "> 
    <DIV STYLE="padding:20px; background:white; border-bottom:5px solid
    #cccccc">
    <img src="htmledlogo.gif" align="absmiddle"></div>
    <DIV STYLE="padding:20px; font-size:8pt; line-height:1.5em;
    font-family:verdana; color:black;">This HTML Editor is created
    entirely using DHTML technologies and is provided as an example for developers using 
    Internet Explorer 6.
    <br>
    <br>
    <br>
    <br><center>
    &#169;2001 Microsoft Corporation. All rights reserved. </center>
    </DIV>
    </DIV>
    </DIV>
    
  8. Add a call in the goContext function to the doInit function so the splash screen displays when the application initializes. The doInit function should look like the following example.

    function doInit(){
    for (i=0; i<document.all.length; i++)
     document.all(i).unselectable = "on";
     oDiv.unselectable = "off";
     oDiv.innerHTML="";
     oDiv.focus();  
     getSystemFonts();
     getBlockFormats();
     goContext(); 
    }
    

Congratulations! You now have a fully functioning HTML Editor Application, which should look and act like the example.

Code example: http://samples.msdn.microsoft.com/workshop/samples/author/editing/HTML_Editor/HTML_Editor.hta

Final Wrap-up

In this tutorial, you discovered how to use Internet Explorer 6 features to create a real-time, WYSIWYG HTML Editor Application that can open and save files from the file system and which takes advantage of the rich, scriptable editing that Internet Explorer 6 offers.

Applying WYSIWYG editing to HTML can help users create Web pages effectively without knowing HTML. Additionally, you can use the HTML Editor Application as an online editor for an Internet e-mail program.

You can add many features to this application. For example, one extension could be a routine to synchronize the state of the toolbar buttons with the formatting of the current selection so that the buttons change state as the user navigates through the content in the editable region. Another possible extension of this application would be to include the ability to insert images from a file.