2008-09-05 15 views
2

J'ai écrit un plugin Active X pour IE7 qui implémente IObjectWithSite en plus d'autres interfaces nécessaires (notez IOleClient). Cette interface est interrogée et appelée par IE7. Au cours de la SetSite() appeler je récupère un pointeur vers l'interface du site de IE7 que je peux utiliser pour récupérer l'interface IHTMLDocument2 en utilisant l'approche suivante:Comment puis-je récupérer l'interface IPIEHTMLDocument2 sur IE Mobile

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

J'ai essayé une approche similaire sur PIE et en utilisant le code suivant, cependant , même l'interface IPIEHTMLWindow2 ne peut être acquise, donc je suis coincé:

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

Utilisation de l'interface IServiceProvider ne fonctionne pas non plus, donc je l'ai déjà testé cela.

Des idées?

Répondre

3

J'ai trouvé le code suivant dans le code Google Gears, here. J'ai copié les fonctions dont je pense que vous avez besoin ici. Celui dont vous avez besoin est en bas (GetHtmlWindow2), mais les deux autres sont également nécessaires. J'espère n'avoir rien manqué, mais si j'ai fait ce dont vous avez besoin, c'est probablement sur le lien.

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

Eh bien, je connaissais déjà le code des engrenages. Le mécanisme utilise une solution de contournement en effectuant un appel de méthode explicite dans le plugin gears depuis le chargeur d'engrenages pour définir l'objet window et l'utiliser comme interface de site à la place de IUnknown fourni par IE Mobile dans l'appel SetSite. En ce qui concerne le code des engrenages, les ingénieurs de Google sont conscients du même problème que je pose et ont trouvé cette solution de contournement que j'ai décrite.

Cependant, je crois qu'il doit y avoir une autre façon plus "officielle" de traiter ce problème, car définir explicitement le site sur un contrôle/plugin Active X n'est pas très bon. Je vais demander directement à l'équipe MS IE Mobile et je vous tiendrai informé dès que j'aurai une solution. C'est peut-être un bug dans IE Mobile qui est la chose la plus probable que je puisse imaginer, mais qui sait ...

Mais merci quand même pour votre réponse;))