Mark Davis and Rick Jesse
DHTML Editing Component Support and Development Team
Updated: September 10, 1998
Questions
What is the Dynamic HTML Editing Component?
Who would benefit from using this component?
Where can software vendors obtain the component?
Where can I learn more about the DHTML Editing Component?
Where can I learn more about Dynamic HTML?
Will the DHTML Editing Component work with the Internet
Explorer 5 Developer Preview?
How do I use the DHTML Editing control?
How do I load HTML into the component from memory?
How do I access the Internet Explorer Document Object Model from the
DHTML Editing Component?
How do I insert new elements into a document?
How do I insert script into the document?
How do I use ExecCommand and QueryStatus?
How do I update my application's menus and toolbars based
on the current selection?
How do I implement my own commands?
How do I obtain the currently selected text?
How do I find the selected element or the element under the insertion
point?
How do I programatically set the position of the insertion point?
How do I trap an event such as ondoubleclick?
How do I sync document object model events in Visual Basic?
Why does my onclick event handler never get called?
How do I display a context menu?
How can I remove the underline from a hyperlink?
Does the DHTML Editing Component support drag-and-drop from an external
source?
How can I receive drop notifications?
How do I print programmatically?
What are the DESIGNTIMESP attributes that I see in an element's
outerHTML?
What are the licensing terms for the editing component?
How do I redistribute the DHTML Editing Component with my application?
The Microsoft Dynamic HTML (DHTML) Editing Component allows Web authors and application developers to add WYSIWYG DHTML editing capabilities to their Web sites and applications. The editing component uses Microsoft's Component Object Model (COM) technology to provide access to editing services such as basic HTML formatting, tables, undo/redo, find, and absolute positioning.
The DHTML Editing Component uses Internet Explorer to render HTML, so the editing environment is always in sync with the browsing environment. Web authors and developers can use any language, including Visual Basic, VBScript, JScript, C, C++, and Java to access editing services and provide a user interface for editing features. The DHTML Editing Component allows you to offer the following features:
Web authors and developers can also access the Document Object Model (DOM) to add sophisticated, custom editing features to their applications. In addition, you can edit pages created with Active Server Pages technology seamlessly, without changing the original server script. If you begin with existing HTML, the DHTML Editing Component will preserve your original formatting (the original white space and tags will remain).
Two types of components are available: the DHTML Editing DocObject, and the DHTML Editing ActiveX control. The ActiveX control provides many high-level features and can be used from development environments such as Visual Basic, Visual C++, Delphi, and Power Builder 6.0.
In addition to HTML authoring, help, and e-mail applications, any Win32® application that edits or outputs HTML could use the editing component for rich formatting or easy layout. In addition, corporate developers can include this control in their Visual Basic applications to build HTML-based forms for their application front-ends.
The DHTML Editing Component Software Development Kit (SDK) can be downloaded from this site. The SDK contains detailed documentation, samples, and headers for using the DTHML Editing Component.
See the Features page for a full list of features. For a developer's perspective on the DHTML Editing Component, read DHTML Editing Made Easy by Nancy Cluts, also on this site.
The key things you need to learn to become fluent in Dynamic HTML are the Dynamic HTML Object Model (DOM) and Cascading Style Sheets (CSS). See the DHTML, HTML & CSS area of the Web Workshop for overviews and detailed information about DHTML, CSS, and the DOM. For detailed specs on DHTML, DOM and CSS, visit the World Wide Web Consortium Web site (http://www.w3.org/ ).
The DHTML Editing control version 1.0 is intended for use with Microsoft Internet Explorer 4.0x and will not function correctly with the Internet Explorer 5 Developer Previews and betas.
The following HTML fragment shows how to insert the DHTML Editing control into a Web page:
<OBJECT CLASSID="clsid:683364AF-B37D-11D1-ADC5-006008A5848C" ID=DHTMLEdit HEIGHT=400 WIDTH=500> </OBJECT>
Note the use of the ID attribute, which allows the control to be accessed by name. See the HelloWld sample in the DHTML Editing Component SDK for an example of how to host the control on a Web page.
If you are using the control in a Visual Basic application, all you need to do is to add the control as a component to your project and it will be available in the component toolbox. See the VBDOM sample in the DHTML Editing Component SDK for an example of using the control in Visual Basic.
If you are hosting the control in a Microsoft Foundation Classes (MFC) application, insert the control into the project. A wrapper class for the control will be placed in your project and will be available in the resource editor. Either place the control on a dialog resource or create the control dynamically.
The DHTML Editing control's DocumentHTML property provides access to the contents of the currently loaded document. You can assign a BSTR containing HTML to the DocumentHTML property to load HTML from memory. If you are using the DocObject, you must create a Stream from an HGLOBAL and use IPersistStreamInit->Load(). Please see the documentation in the SDK for more information on using IPersistStreamInit. See the HelloWld Web sample in the DHTML Editing Component SDK for an example of how to load HTML using the control's DocumentHTML property.
The DHTML Editing control provides access to the underlying Internet Explorer Document Object Model through the Document property. This property returns the Document object of the currently loaded web page. The following JavaScript function demonstrates how to do this:
function ShowAll() { dom = DHTMLEdit.DOM; len = dom.all.length; str = ""; for ( i=0; i<len; i++ ) str += dom.all[i].tagName + "\n"; alert( str ); }
You can access the DOM from the DocObject by calling QueryInterface on the DocObject's IUnknown interface specifying IID_IHTMLDocument2:
IHTMLDocument2* pDom = NULL; lpUnk->QueryInterface(IID_IHTMLDocument2, (void **) &pDom);
Many commands are available that allow you to insert new HTML elements and apply formatting to existing HTML. They are invoked by calling the ExecCommand method with the appropriate command ID. Please refer to the documentation in the SDK for the comprehensive set of available commands. The following HTML demonstrates how to insert a table with default values:
<SCRIPT LANGUAGE=JavaScript SRC="DHTMLEd.js"> <!-- include the command ids for ExecCommand this file is in the inc directory of the SDK --> </SCRIPT> <SCRIPT LANGUAGE=JavaScript> function insertTable() { DHTMLEdit.ExecCommand(DECMD_INSERTTABLE, OLECMDEXECOPT_DONTPROMPTUSER, tableInfo); } </SCRIPT> <OBJECT ID=tableInfo CLASSID="clsid:47B0DFC7-B7A3-11D1-ADC5-006008A5848C"> <-- create the tableInfo object give it an id so we can reference it in the insertTable function &--gt </OBJECT>
You can also insert new HTML elements by accessing the Internet Explorer Document Object Model. The exact method will depend on how you want to insert the HTML. If you need to insert HTML elements relative to an existing element, the insertAdjacentHTML method is available on all elements. If you are replacing the user selection, you can create a TextRange object and call the pasteHTML method. This method can also be used to insert HTML at the current insertion point (caret). If you are modifying the HTML of an existing element, you can set the innerHTML or outerHTML properties, which are available on all elements. Note that the innerHTML property is only supported on block elements.
To insert a script element into a document, use the following technique:
Dim scriptElement As String ' The script in the element inserted below will be executed ' when the DHTMLEdit control's DocumentComplete event fires. ' It will display a modal dialog displaying the string ' "Document Loaded!" scriptElement = "<body> <script for=editor event=""DocumentComplete()""> alert(""Document Loaded!"");" </script>" ' Now inject the script into the document DHTMLEdit1.DOM.body.insertAdjacentHTML "AfterBegin", scriptElement
If the DHTML Editing control's SaveDocument method is called after executing this code, you'll see that the <SCRIPT> element is the first element after the initial <BODY> tag.
The ExecCommand method takes a numeric command ID and optional arguments, and typically operates on the current selection. QueryStatus is used to determine if a given command is valid for the current selection. ExecCommand and QueryStatus simplify the code necessary to update the user interface in your application. Use QueryStatus to enable and disable toolbars and menus; use ExecCommand to execute a command from a toolbar or menu.
The DHTML Editing control fires the DisplayChanged event whenever the editing context has changed (for example, when the user has selected an element). Use this event to update your menus and toolbars by calling QueryStatus. The VBEdit sample in the DHTML Editing Component SDK demonstrates this technique by updating its toolbar to reflect formatting of the current selection.
The DOM is the primary API for modifying a document. If no command ID is available for an operation you want to provide in your application, implement the functionality by using the DOM. You can use the DOM to insert and remove HTML elements and modify existing elements using element properties or the CSS Object Model.
The current selection is accessed through the DOM's Selection object. The Selection object has a type property that returns a value of "None", "Text", or "Control". If the type is "Text", you can call the Selection object's createRange method to obtain a TextRange object corresponding to the selection. The text can then be accessed through the TextRange object's text and htmlText properties. The following JavaScript function demonstrates this:
function ShowSelection() { sel = DHTMLEdit.DOM.selection; if ( "Text" == sel.type ) { range = sel.createRange(); alert( range.htmlText ); } else alert( "No text selected" ); }
The following is a an example of how to use the DOM Selection object and TextRanges to retrieve the selected element or the element directly under the insertion point:
' Assuming you have the DHTMLEdit control on ' a VB form and the control's name s DHTMLEdit1... ' Note that you should check the type of the selection. ' The Selection object's property "type" can return three values: ' "None" - nothing is selected (just blinking cursor) ' "Text" - text or mixed text is selected ' "Control" - a form control or image is selected Private Sub GetElementUnderInsertionPoint() Dim rg As IHTMLTxtRange Dim ctlRg As IHTMLControlRange ' branch on the type of selection and ' get the element under the caret or the site selected object ' print its outerHTML Select Case DHTMLEdit1.DOM.selection.Type Case "None", "Text" Set rg = DHTMLEdit1.DOM.selection.createRange ' collapse the range so that the scope of the ' range of the selection is the caret. That way the ' parentElement method will return the element directly ' under the caret. If you don't want to change the state of the ' selection, then duplicate the range and collapse it rg.collapse MsgBox rg.parentElement.outerHTML Case "Control" ' an element is site selected Set ctlRg = DHTMLEdit1.DOM.selection.createRange ' there can only be one site selected element at a time so the ' commonParentElement will return the site selected element MsgBox ctlRg.commonParentElement.outerHTML End Select End Sub
You can set the location of the insertion point programmtically by using TextRanges. The following code demonstrates how to set the insertion point at the end of the document:
Dim range As IHTMLTxtRange Set range = DHTMLEdit1.DOM.body.createTextRange() range.collapse False range.Select
The DHTML Editing control provides events for the mouse and keyboard. You can also sync events for specific elements in a document. For an example of how to sync document events in C++, see the CEdit sample in the DHTML Editing Component SDK.
You can sync Document events in Visual Basic using the WithEvents statement. You must include a reference in your Visual Basic project to mshtml.dll. See the VBDOM sample in the DHTML Editing Component SDK for a example of how to sync various DOM events on the document and specific elements in a document.
The onclick event does not fire in edit mode for the document object exposed through the control's DOM property, or any other HTML element within the document. However, the DHTML Editing control provides an onclick event handler that fires when the document or other elements are clicked on. Developers can handle the onclick event and find the element under the insertion point in their event handler.
When the user right-clicks within the DHTML Editing control's window, the ShowContextMenu event is fired. You can handle this event and provide a context menu by calling the control's SetContextMenu method. If the user selects a menu item, the ContextMenuAction is fired, indicating which item was chosen. The following JavaScript event handlers demonstrate this:
<SCRIPT LANGUAGE=JavaScript SRC="DHTMLEd.js"> </SCRIPT> <SCRIPT LANGUAGE=JavaScript FOR=DHTMLEdit EVENT=ShowContextMenu> menuStrings = new Array(); menuStates = new Array(); menuStrings[0] = "Grayed item"; menuStrings[1] = "Checked item"; menuStrings[2] = "Unchecked item"; menuStates[0] = OLE_TRISTATE_GRAY; menuStates[1] = OLE_TRISTATE_CHECKED; menuStates[2] = OLE_TRISTATE_UNCHECKED; DHTMLEdit.SetContextMenu( menuStrings, menuStates ); </SCRIPT> <SCRIPT LANGUAGE=JavaScript FOR=DHTMLEdit EVENT=ContextMenuAction(itemIndex)> alert( "You selected item " + itemIndex ); </SCRIPT>
The appearance of hyperlinks and other elements can be controlled through CSS attributes. The following is an example of a style sheet that removes the underline for all hyperlinks in a document:
<STYLE> A { text-decoration: none; } </STYLE>
You can override a style sheet by using inline styles on specific elements. For example, to remove the underline from a specific hyperlink, you could set the style attribute of the Anchor as follows:
<A href="http://www.microsoft.com" style="text-decoration: none">Look, no underline!</A>
The DHTML Editing DocObject and control register themselves as drop targets for the Clipboard format CF_HTML. When a drag operation is in progress involving this Clipboard format and the mouse is released on the DHTML Editing Component's window, the component will inject the HTML from the drop source's IDataObject into the current document at the point where the mouse is released. If the control's AbsoluteDropMode is set and the HTML is capable of being absolute positioned (such as with a table or button element), the HTML will be absolutely positioned. This is useful if you have implemented a toolbox or control palette and you are dragging controls onto the DHTML Editing control.
To participate in a drag/drop operation and receive drop notifications, you must host the DocObject and implement the IDocHostUIHandler::GetDropTarget method. See the Web Workshop for more information on IDocHostUIHandler.
The DHTML Editing control provides a method for printing. If you are hosting the DocObject, you can print a document using ExecCommand and the command ID IDM_TRIED_PRINT.
The DHTML Editing Component uses a number of attributes internally to maintain document state during an editing session. These attributes are filtered out upon saving a document. However, if the outerHTML of an element is accessed during an editing session, these attributes may be present. The DHTML Editing control provides a method for filtering these attributes from an arbitrary string of HTML. This method can be used for filtering the outerHTML of any element during editing.
The editing component is available for distribution free of charge. Because this component requires Internet Explorer 4.01, vendors will also need to license the Internet Explorer Administration Kit 4.01 to distribute Internet Explorer 4.01 with their products. For details, please see http://ieak.microsoft.com/ .
The DHTML Editing Component SDK documentation provides information on how to redistribute the necessary components with your application.