如何在 IE Mobile 上检索 IPIEHTMLDocument2 界面
-
09-06-2019 - |
题
我为 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。关于齿轮代码,谷歌工程师意识到了我所问的同样问题,并提出了我所描述的解决方法。
然而,我相信必须有另一种更“官方”的方法来处理这个问题,因为在 Active X 控件/插件上明确设置站点并不是很好。我现在将直接询问 MS IE Mobile 团队,一旦找到解决方案,我会立即通知您。这可能是 IE Mobile 中的一个错误,这是我能想象到的最有可能的事情,但谁知道呢......
但无论如何感谢您的回复;))
不隶属于 StackOverflow