Exoware ....   Tech Notes    About Exoware    Home
 

Quality solutions, on time, and on budget

 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:

  1. November, 1998 - original version
  2. December, 1999 - minor edits


Send mail to webmaster@exoware.com with questions or comments about this web site.
Copyright © 1997-2005 Exoware. Last modified: March 16, 2005