Reusing MSHTML

MSHTML was introduced in Microsoft Internet Explorer 4.0. It is the main HTML component of the Windows Internet Explorer browser and can be used in other applications. It hosts Microsoft ActiveX Controls and supports the OLE Control '96 (OC96) specification for windowless controls.

MSHTML itself is an Active Document, so it can be hosted by implementing the Active Document interfaces in an application. MSHTML can also be customized by aggregation to create a special-purpose HTML Active Document. Applications that contain MSHTML supply their own toolbars and menu UI. The container can also override the default context menus.

You can also use MSHTML without UI activation to make use of the MSHTML ability to parse HTML. By loading HTML, you can use the object model to access the underlying HTML and modify any elements. Component Object Model (COM) objects hosted by MSHTML (such as ActiveX Controls) also have the ability to access the Dynamic HTML (DHTML) Object Model.

To integrate Internet browsing into an application, it is recommended that you host the WebBrowser Control. The WebBrowser control implements support for in-place linking and navigation, in addition to MSHTML.

To customize printing and the Print Preview feature introduced in Microsoft Internet Explorer 5.5, use the IDM_PRINT and IDM_PRINTPREVIEW commands to pass the URL of a custom print template to MSHTML. Print templates give you control over the way MSHTML prints a document; they also offer control over the UI features provided in print preview mode. For additional information on providing customized Print Preview, see the Print Template Reference.

  • Hosting MSHTML
    • Hosting MSHTML as an Active Document
    • Aggregating MSHTML
  • Replacing the MSHTML User Interface
  • Substituting User Preferences
  • Loading HTML and Referenced Data
    • Loading an HTML Page
    • Downloading Objects in a Page
    • Resolving Hyperlinks
  • Automating MSHTML
  • Using Scripts Within MSHTML
  • Sending and Receiving Commands
  • Terminology
  • Related topics

Hosting MSHTML

MSHTML can be hosted to form an integral part of an application. This can be done in two ways:

  • Host MSHTML as an Active Document. MSHTML is an Active Document, and can be hosted in an application that implements the Active Document hosting interfaces. In this mode of operation, MSHTML supplies its own UI for context menus to the containing application, although the container can replace the UI, if required, by implementing additional interfaces.
  • Aggregate MSHTML to create an Active Document. If a host needs to provide extra services and functionality, but still needs to be an Active Document for use within another application, it can do so by aggregating MSHTML. This permits the host to take advantage of the MSHTML implementation of Active Document server interfaces without having to reimplement them, while still allowing the host to wrap MSHTML to provide additional functionality and its own UI.

Hosting MSHTML as an Active Document

As an Active Document, MSHTML follows the standard OLE mechanisms for negotiating with the container for menu merging and displaying its toolbars. MSHTML supports only the single-view implementation of Active Documents. Commands can be sent and received using the IOleCommandTarget interface that is also part of the Active Document specification. The standard NULL command set is supported as well as a set of extended commands specific to MSHTML.

A host of MSHTML can turn off the MSHTML menus and toolbars and supply its own UI. The host can also intercept any of the MSHTML UI, such as context menus and message boxes. For more information about intercepting UI, see Replacing the MSHTML User Interface. For more information about implementing an Active Document host, see Active documents.

Aggregating MSHTML

If your application is using MSHTML to implement an Active Document that customizes MSHTML behavior, a host can aggregate with MSHTML to create a new class. MSHTML is designed to support aggregation. Overriding a small number of interfaces can customize much of the MSHTML behavior.

Creating a new Active Document

The minimum interfaces that must be supplied by an aggregator are IOleObject and the IPersist interfaces.

These interfaces supply the object's class identifier (CLSID) and USERCLASSTYPE properties (through IOleObject::GetUserClassID, IOleObject::GetUserType, and IPersist::GetClassID methods). The aggregator should supply its own implementations to differentiate the new object from MSHTML.

Some common functionality that can be customized by aggregation:

Other functionality can be customized by supplying services to MSHTML.

Supplying services and ambient properties when aggregating

An aggregator can supply ambient properties to MSHTML without having to implement a full client site for hosting MSHTML. The site object normally supplies ambient properties, but a site object has a number of other interfaces that are not trivial to implement. Using this technique, the aggregator can let the container's client site pass through to MSHTML while the aggregator still supplies ambient properties.

Replacing the MSHTML User Interface

If MSHTML is integrated into an application, it might be desirable to have the application supply its own menus, toolbars, and other UI. To do this, the host can supply optional services to MSHTML that allow the host to replace the MSHTML UI. In implementing these interfaces, a host knows that MSHTML is the component being hosted and has knowledge of the MSHTML command set.

When replacing the MSHTML UI, the host turns off the MSHTML menus and toolbars and can replace them. This does not involve any negotiation. A host of MSHTML can display message boxes, Help UI, and all in-place active UI on behalf of MSHTML by implementing two interfaces, IDocHostUIHandler and IDocHostShowUI.

To replace the menus, toolbars, and other UI for MSHTML, the host should implement the IDocHostUIHandler interface. MSHTML obtains this interface by passing IID_IDocHostUIHandler to the QueryInterface method of the host's client site object. If the host does not implement a client site, the host can query the MSHTML document object for the ICustomDoc interface and call the ICustomDoc::SetUIHandler method to set the MSHTML UI handler.

When the IDocHostUIHandler interface is present, MSHTML delegates a number of IOleInPlaceObject and IOleInPlaceActiveObject methods directly to it, allowing a host to hook into methods such as IOleInPlaceActiveObject::TranslateAccelerator and IOleInPlaceActiveObject::ResizeBorder. Returning S_OK on the IDocHostUIHandler::ShowUI method called by MSHTML will cause MSHTML to hide its menus and toolbars and not call the IOleInPlaceFrame methods for menu merging and border space negotiation.

To supply message boxes and Help UI, the host should implement the IDocHostShowUI interface. MSHTML obtains this interface by calling the host's client site QueryInterface, requesting IID_IDocHostShowUI. The site object implements both IOleDocumentSite and IOleClientSite.

Substituting User Preferences

Because MSHTML can be used in a number of different host environments, each host environment must be able to set different default user preferences in the registry. MSHTML allows its host to specify a special registry key under which to store the default preferences.

MSHTML calls IDocHostUIHandler::GetOptionKeyPath on the host at initialization to allow the host to specify the registry location for the preference settings. MSHTML then uses this registry key to store and get the settings for its preference property pages. If the host returns S_FALSE for this method, or if the returned registry key path is NULL or empty, MSHTML reverts to its own default set of options.

Loading HTML and Referenced Data

The topics in this section describe how a host can control the loading of HTML documents and objects within them, and define how hyperlinks are navigated.

Loading an HTML Page

MSHTML can load pages from URLs or from files. A host can load and display the page at a specific URL by constructing a URL moniker using the CreateURLMoniker function call and then calling the MSHTML implementation of IPersistMoniker::Load. The MSHTML implementation of IPersistMoniker is specifically designed to support the loading of data asynchronously over slow links.

For more information about these interfaces, see About URL Monikers.

When a page is loaded, MSHTML calls IDocHostUIHandler::TranslateUrl to assist in resolving URLs. If desired, a host can implement a version of this method to provide additional control. This method is not called when downloading items within the page, such as images.

MSHTML can also load and save HTML through its implementation of the IPersistStreamInit and IPersistFile interfaces. Both implementations operate asynchronously.

Because MSHTML loads documents asynchronously, it might not be possible to gain immediate access to the object model of the requested document. To determine when the requested document has completely loaded, a hosting application should implement the IPropertyNotifySink::OnChanged method. Use the standard connection point protocol to advise MSHTML of the availability of this outgoing interface.

When the ready state of the document changes, MSHTML calls the host's implementation of IPropertyNotifySink::OnChanged. The following code example shows how to get the ready state from the document as the ready state changes.

STDMETHODIMP CApp::OnChanged(DISPID dispID)
{
    if (DISPID_READYSTATE == dispID)
    {
        READYSTATE rs = READYSTATE_UNINITIALIZED;
        GetReadyState(m_pDoc, &rs);
        if (READYSTATE_COMPLETE == rs)
        {
            BOOL fRet = PostThreadMessage(GetCurrentThreadId(),
                                          WM_USER_STARTWALKING,
                                          (WPARAM)0,
                                          (LPARAM)0);
        }
    }
}

HRESULT GetReadyState(IHTMLDocument* pDoc, READYSTATE* pReadyState)
{
    VARIANT vResult = {0};
    EXCEPINFO excepInfo;
    UINT uArgErr;
    DISPPARAMS dp = {NULL, NULL, 0, 0};

    HRESULT hr = pDoc->Invoke(DISPID_READYSTATE, IID_NULL, LOCALE_SYSTEM_DEFAULT,
                              DISPATCH_PROPERTYGET, &dp, &vResult, &excepInfo, &uArgErr);

    if (FAILED(hr))
        return hr;

    *pReadyState = READYSTATE( V_I4( & vResult ) );
    VariantClear(&vResult);
    return S_OK;
}

For details on how to load an HTML document asynchronously, see WalkAll Sample Source Page.

Downloading Objects in a Page

A host can control how objects within a Web page are downloaded, such as by suppressing the download of frames or scripts. To do this, the host must implement IOleClientSite and the DISPID_AMBIENT_DLCONTROL property. When IDispatch::Invoke is called with the dispidMember parameter set to DISPID_AMBIENT_DLCONTROL, the host can specify download options. The following code shows how to handle the call to IDispatch::Invoke. For more information and a list of download options, see Download Control.

HRESULT CHostWindow::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
    DISPPARAMS *pdispparams, VARIANT *pvarResult,
    EXCEPINFO *pexcepinfo, UINT *puArgErr)
{
    HRESULT hr = DISP_E_MEMBERNOTFOUND;

    if (dispidMember == DISPID_AMBIENT_DLCONTROL)
    {
        pvarResult->vt = VT_I4;
        pvarResult->lVal =  DLCTL_NO_FRAMEDOWNLOAD | DLCTL_NO_SCRIPTS;
        hr = S_OK;
    }

    return hr;
}

If a user clicks a link within an HTML page viewed in MSHTML, MSHTML calls the HlinkNavigate function (after implementing an IHlink interface). If the host does not implement IHlinkFrame, this function launches a separate application to follow the hyperlink.

Hosts that you want to act as browsers (and navigate within the same frame) can implement IHlinkFrame on the frame object. The HlinkNavigate function calls IHlinkFrame::Navigate, allowing a browser application to hide the previous instance of MSHTML and create, load, and show a new instance of MSHTML (or other Active Document) to display the new page.

For more information on hyperlinking, see Hyperlinks.

Because the WebBrowser Control has built-in support for hyperlinking, hosting the WebBrowser Control is the preferred solution here.

Automating MSHTML

MSHTML can be automated using IDispatch and IConnectionPointContainer-style automation interfaces. These interfaces enable a host to automate MSHTML through the object model.

Using Scripts Within MSHTML

MSHTML is responsible for loading and running scripts that appear within HTML. Because scripting uses the ActiveX Scripting interfaces, any ActiveX script engine can be hosted by MSHTML.

Sending and Receiving Commands

Because MSHTML is an Active Document, it communicates with its host using the IOleCommandTarget interface. With this interface, the following details are communicated to the hosting frame:

  • Menu/Toolbar enabling—The common menus and toolbar buttons found on the host (Cut, Copy, Paste, and so on) are enabled and disabled by sending MSHTML commands and queries.
  • MSHTML commands—Common functions, such as Refresh, Stop, and Hide Toolbars, are sent by the host to MSHTML through commands.
  • Status bar updates—Progress and status bar text information is communicated to the hosting frame by MSHTML through commands.

In addition to the standard command group, MSHTML supports a group of MSHTML-specific commands that provide simple access to a number of MSHTML-specific features. For more information, see the OLECMDID enumeration.

Terminology

Active Document—Also known as an OLE Document Object or Doc Object. An Active Document is a contained object; the container provides the frame and some basic UI. In such containers, the Active Document can be interchanged with other Active Documents while the containing frame and its UI remain constant. Examples of Active Document containers include the Office Binder and Microsoft Internet Explorer 3.0, where the Active Document could change to Microsoft Word or Microsoft Excel while maintaining the same outer frame application. An Active Document is similar to an OLE Embedding scenario or an ActiveX control, but its interfaces are designed to support an object that is at the top level and takes up the entire content area of the frame. There are specific interfaces required to support Active Document functionality. For more information, see Active documents.

ActiveX control—Also known as an OLE Control. An ActiveX control is a contained mini-application. It can (optionally) maintain state, draw itself, persist itself, have its own window, respond to automation methods, throw events, take keyboard focus, respond to mouse and keyboard input, and show merged menu and toolbar UI. Most of the control interfaces are documented in the MSDN Online site. Support was added to Internet Explorer 4.0 to take advantage of new interfaces that improve the performance of ActiveX Controls and make them suitable for the Internet. For more details, see Building ActiveX Controls for Internet Explorer.

ActiveX Scripting—A standard set of interfaces that allows for language-independent script integration to applications. Any scripting engine—such as Microsoft Visual Basic Scripting Edition (VBScript), Microsoft JScript, or a third-party scripting language, for example—that supports the standard interfaces can be integrated with an ActiveX scripting host such as MSHTML.

Aggregation—A kind of run-time inheritance. By aggregating, an object can extend and enhance the functionality of another object but still take advantage of the functionality and interfaces of the aggregated object. Objects can be designed to be aggregated or not. MSHTML is designed to be aggregated.

Ambient—A property owned by the container and supplied to an ActiveX object through the IDispatch interface on its hosting site.

Automation—A set of standards to allow an object to be programmed by scripts. Every object that can be automated can have methods and properties that can be used by a script, as well as events that can trigger scripts to be run.

Command—A simple action sent to an ActiveX object through the IOleCommandTarget interface. Commands usually correspond to user-level commands, such as the commands on menus, and can be enabled or disabled by the command target. A command can be sent to the frame, the container site, MSHTML, or a control.

Container—The ActiveX object that owns the site obtained through IOleClientSite::GetContainer (can be null). From the container, the contained objects can be enumerated through IOleContainer::EnumObjects. This concept of containment should not be confused with the concept of containment used for scripting and supplied by automation interfaces. Some contained automation objects are not contained ActiveX objects, and some contained ActiveX objects cannot be automated.

Dispatch Interface—An interface inheriting from IDispatch that is used to access named automation properties and methods of an object from a script.

Document Window—The document window, with toolbar space, supplied to an ActiveX object through IOleInPlaceSite::GetWindowContext. (In the multiple document interface [MDI] it is the document window, and in the single document interface [SDI] it is NULL.) MSHTML currently ignores the document window.

Event Interface—A callback interface attached to an object using IConnectionPointContainer. This is used by script engines to get notification of events thrown by objects.

Frame—The outer application frame, with menu and toolbar space, supplied to an ActiveX object through IOleInPlaceSite::GetWindowContext. This is the object with which MSHTML negotiates for menu and toolbar space and also for links.

MSHTML—An Active Document that is capable of rendering HTML and laying out contained ActiveX Controls. In this document, it refers to an instance of the MSHTML COM object that implements IOleObject, IOleDocument, IOleDocumentView, and many other interfaces.

Service—Functionality supplied by the host to an ActiveX object through the IServiceProvider interface on the container site. Each service is identified by a service identifier (SID), allowing access to interfaces and methods.

Site—The object supplied by a container to a contained object through IOleObject::SetClientSite. Containers of an ActiveX object must supply a site before doing anything else. MSHTML gets much of its information about its geometry, activation, and ambient properties from its container site. MSHTML supplies a site for each ActiveX control it hosts.

Type Info—A structure used to specify properties, methods, and events. It can be obtained from a dispatch interface through IDispatch or an object that supplies IProvideClassInfo*.

X Object—An object that MSHTML wraps around each hosted control to supply common, per-control, container-owned properties and events. MSHTML aggregates the X object to the control, if possible, and merges types with the control.

Introduction to ActiveX Controls