Eric Hartwell's InfoDabble

 
Welcome to Eric Hartwell's InfoDabble
About | Site Map
Home Tech Notes Apollo 17: Blue Marble Apollo 17 Flight Journal   Calendars About me  
 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
Creative Commons License

Unless otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License

 

Site Map | About Me