如何在IE Mobile上检索IPIEHTMLDocument2接口
时间:2020-03-05 18:48:11 来源:igfitidea点击:
我为IE7编写了一个Active X插件,该插件除了实现一些其他必要的接口(请注意,没有IOleClient)之外还实现了IObjectWithSite。该接口由IE7查询和调用。在SetSite()调用期间,我检索了指向IE7站点接口的指针,可以使用它通过以下方法来检索IHTMLDocument2接口:
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 */ }
我也使用以下代码在PIE上尝试了类似的方法,但是,即使IPIEHTMLWindow2接口也无法获取,所以我陷入了困境:
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 */ }
使用IServiceProvider接口也不起作用,因此我已经对此进行了测试。
有任何想法吗?
解决方案
回答
我在这里的Google Gears代码中找到了以下代码。我在这里复制了我认为我们需要的功能。我们需要的一个在底部(GetHtmlWindow2),但另外两个也是必需的。希望我什么都没错过,但是如果我做了什么,我们可能需要在链接上。
#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 }
回答
好吧,我已经知道了齿轮代码。 Gears使用的机制基于一种变通方法,该解决方案是通过从Gears加载器对gears插件执行显式方法调用来设置窗口对象并将其用作站点接口,而不是由IE Mobile在SetSite调用中提供的IUnknown。关于齿轮代码,Google工程师知道我要问的相同问题,并提出了我所描述的解决方法。
但是,我认为必须存在另一种"官方"方式来解决此问题,因为在Active X控件/插件上显式设置站点不是很好。我现在要直接询问MS IE Mobile团队,一旦获得解决方案,我们将立即通知我们。这可能是IE Mobile中的错误,这是我能想到的最有可能发生的事情,但是谁知道...
但是无论如何,谢谢回复;))