Domanda

Ho scritto un plugin Active X per IE7 che implementa IObjectWithSite oltre ad alcune altre interfacce necessarie (non notare IOleClient).Questa interfaccia viene interrogata e richiamata da IE7.Durante la chiamata SetSite() recupero un puntatore all'interfaccia del sito di IE7 che posso utilizzare per recuperare l'interfaccia IHTMLDocument2 utilizzando il seguente approccio:

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

Ho provato un approccio simile anche su PIE utilizzando il seguente codice, tuttavia, anche l'interfaccia IPIEHTMLWindow2 non può essere acquisita, quindi sono bloccato:

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

Anche l'uso dell'interfaccia IServiceProvider non funziona, quindi l'ho già testato.

Qualche idea?

È stato utile?

Soluzione

Ho trovato il seguente codice nel codice di Google Gears, Qui.Ho copiato le funzioni che penso ti servano qui.Quello che ti serve è in fondo (GetHtmlWindow2), ma sono necessari anche gli altri due.Spero di non aver perso nulla, ma se ho fatto quello che ti serve probabilmente lo trovi nel 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
}

Altri suggerimenti

Beh, ero già a conoscenza del codice degli ingranaggi.Il meccanismo utilizzato da Gears si basa su una soluzione alternativa mediante l'esecuzione di una chiamata esplicita al metodo nel plug-in Gears dal caricatore di Gears per impostare l'oggetto finestra e utilizzarlo come interfaccia del sito anziché IUnknown fornito da IE Mobile nella chiamata SetSite.Per quanto riguarda il codice degli ingranaggi, gli ingegneri di Google sono a conoscenza dello stesso problema che sto chiedendo e hanno trovato questa soluzione alternativa che ho descritto.

Tuttavia, credo che ci debba essere un altro modo più "ufficiale" per affrontare questo problema poiché impostare esplicitamente il sito su un controllo/plugin Active X non è il massimo.Chiederò direttamente al team di MS IE Mobile e ti terrò informato non appena avrò una soluzione.Potrebbe trattarsi di un bug in IE Mobile, che è la cosa più probabile che riesco a immaginare, ma chi lo sa...

Ma grazie comunque per la tua risposta ;))

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top