Modifying Documents in Edit Mode
This article explains how to use editing commands to change a document in the MSHTML Editor. It includes a sample C++ application and a sample Web page, using Microsoft JScript, that demonstrate these commands. The article also provides source code for the samples.
This article is divided into the following topics:
- Prerequisites and Requirements
- Overview of Editing commands
- The Sample Specifications
- Issuing Editing Commands
- Related Topics
To understand and use this tutorial, you will need:
- Microsoft Internet Explorer 5.5 or later installed.
- A good understanding of C++, the Component Object Model (COM), and the Active Template Library (ATL).
- Header files and libraries for Internet Explorer 5.5 or later for use in your development environment; in particular, you'll need Mshtml.h and Mshtmcid.h.
- An understanding of Visual Basic.
- An understanding of scripting languages.
The MSHTML Editor provides a full complement of commands that enable you to modify a document. The commands to edit a document operate on the current selection. They enable you to perform many tasks, including:
- Cutting, copying, pasting or deleting the selection.
- Changing font size or color.
- Inserting new elements.
- Finding text.
- Changing between overwriting and insertion mode.
- Creating or removing hyperlinks.
- Indenting and negative-indenting blocks.
You can find a list of the available commands in MSHTML Command Identifiers.
The commands can be used from C++, Visual Basic, and script. The commands also work in browse mode, though you can't edit the text in browse mode. When you execute a command, it becomes a part of the Editor's undo list, if applicable. The MSHTML Editor provides some keyboard shortcuts to execute commands: the most important ones are copy, cut, paste, bold, and italic.
- How each of the features behaves.
- How to use IOleCommandTarget::Exec and execCommand to execute editing commands.
There are two samples for this tutorial. One is an executable application developed in C++; one is a simple Web page. The specifications are similar:
- The samples are simple editor implementations with buttons and input boxes to execute commands.
- The first button turns the MSHTML Editor on and off.
- Each of the rest of the buttons executes one of the selection editing commands. Some commands have edit boxes for input.
The source code for this sample is included in a Microsoft Visual C++ 6.0 workspace. The C++ sample uses ATL to provide COM support, standard implementations of some of the standard interfaces, and "smart" interface pointers that handle their own reference counting. The project source code can be downloaded at the Editing Commands Sample Source Page.
Many of the interface pointers in the sample are wrapped by the CComQIPtr class. CComQIPtr is a "smart" pointer class. Besides automatic reference counting, it provides overloaded operators to make working with COM easier. CComQIPtr includes an overloaded assignment operator (operator=) which performs an automatic QueryInterface during assignment. For instance, the sample's QueryInterface call to initialize its IOleCommandTarget pointer looks like this:
// m_spWebBrowser is an already initialized pointer to an IWebBrowser2 interface. // m_spOleCmdTarg is a declared but uninitialized CComQIPtr for an IOleCommandTarget interface. m_spOleCmdTarg = m_spWebBrowser;
The scripting sample implements the same functionality as the C++ sample. However, the scripting sample cannot retrieve current values in the Editor (like font size). It uses a div tag with a contentEditable attribute set to "On" for its editable region.
The editing commands can be executed in C++ using the IOleCommandTarget::Exec method with command identifiers taken from the CGID_MSHTML command group. These commands are defined in mshtmcid.h. You can obtain an IOleCommandTarget interface by calling QueryInterface on either the IWebBrowser2 or IHTMLDocument2 interface.
// Assume pWebBrowser is a valid pointer to the IWebBrowser2 interface IOleCommandTarget* pCmdTarg; pWebBrowser->QueryInterface(IID_IOleCommandTarget, (void**)&pCmdTarg);
Here is how you can bold the current selection using IOleCommandTarget::Exec
// Bold the current selection hr = pCmdTarg->Exec(&CGID_MSHTML, IDM_BOLD, MSOCMDEXECOPT_DODEFAULT, NULL, NULL);
The last two arguments to IOleCommandTarget::Exec, which are NULL in this example, are in and out parameters of type VARIANT. For some commands, use them to provide information to (and read information from) the method. The following example changes the font color of the current selection to red.
// Declare a VARIANT data type and initialize it VARIANT vIn; BSTR bstrRed = SysAllocString(L"Red"); V_VT(&vIn) = VT_BSTR; // Sets the type to BSTR V_BSTR(&vIn) = bstrRed; // Alternatives: Using hexidecimal values for the color red // Option 1: // V_VT(&vIn) = VT_BSTR; // Sets the type to BSTR // V_BSTR(&vIn) = L"#ff0000"; // Option 2: // V_VT(&vIn) = VT_I4; // Sets the type to long // V_I4(&vIn) = 0x0000ff; // NOTE: byte order is reversed // Change the font color of the current selection hr = pCmdTarg->Exec(&CGID_MSHTML, IDM_FORECOLOR, MSOCMDEXECOPT_DODEFAULT, &vIn, NULL); SysFreeString(bstrRed); // Deallocates bstrRed
// Declare a VARIANT data type and initialize it VARIANT vOut; VariantInit(&vOut); // Retrieve the font color of the current selection hr = pCmdTarg->Exec(&CGID_MSHTML, IDM_FORECOLOR, MSOCMDEXECOPT_DODEFAULT, NULL, &vOut);
The color will be returned as a long integer, a VARIANT of type VT_I4. In hexadecimal format, this number is the RGB color value with its byte order reversed. For example, the color "indigo," which is expressed as #4B0082 in script, would have the hexadecimal value 0x82004B.
In Visual Basic and script, the editing commands can be executed using the execCommand method. The first argument to this method is a string corresponding to one of the command identifiers used with IOleCommandTarget::Exec.
The following example makes the current selection bold by using execCommand in JScript.
document.execCommand("Bold", false, null);
The final argument to execCommand is a variable (null the previous example) that enables you to provide information to the method, such as font color.
document.execCommand("ForeColor", false, "red");
You cannot use execCommand to retrieve property values like you can with IOleCommandTarget::Exec.