Search code examples
c++internet-explorerwindows-mobilepocketpc

How do I retrieve IPIEHTMLDocument2 interface on IE Mobile


I wrote an Active X plugin for IE7 which implements IObjectWithSite besides some other necessary interfaces (note no IOleClient). This interface is queried and called by IE7. During the SetSite() call I retrieve a pointer to IE7's site interface which I can use to retrieve the IHTMLDocument2 interface using the following approach:

IUnknown *site = pUnkSite; /* retrieved from IE7 during SetSite() call */
IServiceProvider *sp = NULL;
IHTMLWindow2 *win = NULL;
IHTMLDocument2 *doc = NULL;

if(site) {
    site->QueryInterface(IID_IServiceProvider, (void **)&sp);
    if(sp) {
        sp->QueryService(IID_IHTMLWindow2, IID_IHTMLWindow2, (void **)&win);
        if(win) {
            win->get_document(&doc);
        }
    }
}
if(doc) {
    /* found */
}

I tried a similiar approach on PIE as well using the following code, however, even the IPIEHTMLWindow2 interface cannot be acquired, so I'm stuck:

IUnknown *site = pUnkSite; /* retrieved from PIE during SetSite() call */
IPIEHTMLWindow2 *win = NULL;
IPIEHTMLDocument1 *tmp = NULL;
IPIEHTMLDocument2 *doc = NULL;

if(site) {
    site->QueryInterface(__uuidof(*win), (void **)&win);
    if(win) { /* never the case */
        win->get_document(&tmp);
        if(tmp) {
            tmp->QueryInterface(__uuidof(*doc), (void **)&doc);
        }
    }
}
if(doc) {
    /* found */
}

Using the IServiceProvider interface doesn't work either, so I already tested this.

Any ideas?


Solution

  • I found the following code in the Google Gears code, here. I copied the functions I think you need to here. The one you need is at the bottom (GetHtmlWindow2), but the other two are needed as well. Hopefully I didn't miss anything, but if I did the stuff you need is probably at the link.

    #ifdef WINCE
    // We can't get IWebBrowser2 for WinCE.
    #else
    HRESULT ActiveXUtils::GetWebBrowser2(IUnknown *site, IWebBrowser2 **browser2) {
      CComQIPtr<IServiceProvider> service_provider = site;
      if (!service_provider) { return E_FAIL; }
    
      return service_provider->QueryService(SID_SWebBrowserApp,
                                            IID_IWebBrowser2,
                                            reinterpret_cast<void**>(browser2));
    }
    #endif
    
    
    HRESULT ActiveXUtils::GetHtmlDocument2(IUnknown *site,
                                           IHTMLDocument2 **document2) {
      HRESULT hr;
    
    #ifdef WINCE
      // Follow path Window2 -> Window -> Document -> Document2
      CComPtr<IPIEHTMLWindow2> window2;
      hr = GetHtmlWindow2(site, &window2);
      if (FAILED(hr) || !window2) { return false; }
      CComQIPtr<IPIEHTMLWindow> window = window2;
      CComPtr<IHTMLDocument> document;
      hr = window->get_document(&document);
      if (FAILED(hr) || !document) { return E_FAIL; }
      return document->QueryInterface(__uuidof(*document2),
                                      reinterpret_cast<void**>(document2));
    #else
      CComPtr<IWebBrowser2> web_browser2;
      hr = GetWebBrowser2(site, &web_browser2);
      if (FAILED(hr) || !web_browser2) { return E_FAIL; }
    
      CComPtr<IDispatch> doc_dispatch;
      hr = web_browser2->get_Document(&doc_dispatch);
      if (FAILED(hr) || !doc_dispatch) { return E_FAIL; }
    
      return doc_dispatch->QueryInterface(document2);
    #endif
    }
    
    
    HRESULT ActiveXUtils::GetHtmlWindow2(IUnknown *site,
    #ifdef WINCE
                                         IPIEHTMLWindow2 **window2) {
      // site is javascript IDispatch pointer.
      return site->QueryInterface(__uuidof(*window2),
                                  reinterpret_cast<void**>(window2));
    #else
                                         IHTMLWindow2 **window2) {
      CComPtr<IHTMLDocument2> html_document2;
      // To hook an event on a page's window object, follow the path
      // IWebBrowser2->document->parentWindow->IHTMLWindow2
    
      HRESULT hr = GetHtmlDocument2(site, &html_document2);
      if (FAILED(hr) || !html_document2) { return E_FAIL; }
    
      return html_document2->get_parentWindow(window2);
    #endif
    }