Direct communication with the HTML view

InfoDabble > Tech Notes > Exoware > Direct communication with the HTML view
Jump to: navigation, search
Exoware ..... Tech Note
Direct Communication with the HTML View Eric Hartwell - November 1998

When your COM object is executing inside a browser page, it has complete access to the HTML Document Object Model through the IWebBrowser2 interface. However, as far as IWebBrowser2 is concerned, the browser is running as a stand-alone application, so get_Application() returns IWebBrowser2, and get_Container() and get_Parent() return NULL.

Microsoft has built a hook into the DOM through the IDocHostUIHandler::GetExternal() method, which, when implemented, returns the host's IDispatch interface (see Q188015). Microsoft's WBCustomizer (Q183235) is a sample ATL COM object that implements the IDocHostUIHandler to perform certain user interface functions, such as turning off context menus and accelerator keys (which you probably want in your application anyway).

The sample program uses the WBCustomizerObj methods and adds the SetExternal method, which allows the host to pass a dispatch pointer to the COM object. This implementation simply saves the pointer as a member of the object's class.

STDMETHODIMP CMyHtmlDocUI::putref_SetExternal(LPDISPATCH pExternal)
{
    m_spExternal = pExternal;   // OK to set it to null
    return S_OK;
}

Now the COM object has a way to communicate directly with the host. In a MFC application, probably the simplest thing to do is to pass the IDispatch pointer of the View class (or Document, or Application):

void CMyHtmlView::OnInitialUpdate()
{
    CHtmlView::OnInitialUpdate();
 
    // Now attach the DocUI handler
    IMyHtmlDocUIPtr pDocUI(__uuidof(MyHtmlDocUI));
    m_pDocUI = pDocUI;                  // Keep a copy of the handler
    if (m_pDocUI)
    {
        m_pDocUI->AddRef();             // Remember we have it
        m_pDocUI->PutRefWebBrowser(m_pBrowserApp);
        m_pDocUI->PutEnableContextMenus((_variant_t)false);
        // Give the UI a pointer to this view class
        m_pDocUI->PutRefSetExternal(this->GetIDispatch(false));
    }

Once you add Automation methods and properties to your class through the Automation tab of the Class Wizard, the COM object can use the dispatch pointer to access them. (If you forgot to call EnableAutomation in your constructor, you'll get an assertion to remind you).

Finally, if you add a method that returns the COM object's IDispatch pointer, then the container can communicate directly with the object.

Resources

MSDN, Microsoft Knowledge Base, Site Builder Workshop, Platform SDK, etc.


Revisions

  • November, 1998 - original version
  • December, 1999 - minor edits