Pregunta

Escribí un complemento Active X para IE7 que implementa IObjectWithSite además de algunas otras interfaces necesarias (tenga en cuenta que no hay IOleClient).Esta interfaz es consultada y llamada por IE7.Durante la llamada a SetSite() recupero un puntero a la interfaz del sitio de IE7 que puedo usar para recuperar la interfaz IHTMLDocument2 usando el siguiente enfoque:

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 */
}

También probé un enfoque similar en PIE usando el siguiente código; sin embargo, ni siquiera se puede adquirir la interfaz IPIEHTMLWindow2, así que estoy atascado:

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 */
}

Usar la interfaz IServiceProvider tampoco funciona, así que ya lo probé.

¿Algunas ideas?

¿Fue útil?

Solución

Encontré el siguiente código en el código de Google Gears, aquí.Copié las funciones que creo que necesitas aquí.El que necesitas está en la parte inferior (GetHtmlWindow2), pero los otros dos también son necesarios.Espero no haberme perdido nada, pero si hice lo que necesitas probablemente esté en el enlace.

#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
}

Otros consejos

Bueno, ya conocía el código de engranajes.El mecanismo que utiliza Gears se basa en una solución alternativa mediante la realización de una llamada explícita al método en el complemento Gears desde el cargador de Gears para configurar el objeto de ventana y usarlo como interfaz del sitio en lugar del IUnknown proporcionado por IE Mobile en la llamada SetSite.Con respecto al código de engranajes, los ingenieros de Google son conscientes del mismo problema que estoy preguntando y se les ocurrió esta solución que describí.

Sin embargo, creo que debe haber otra forma más "oficial" de abordar este problema, ya que configurar explícitamente el sitio en un control/complemento Active X no es muy bueno.Voy a preguntarle directamente al equipo de MS IE Mobile ahora y los mantendré informados una vez que obtenga una solución.Podría ser un error en IE Mobile, que es lo más probable que puedo imaginar, pero quién sabe...

Pero gracias de todos modos por tu respuesta ;))

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top