IE Mobile で IPIEHTMLDocument2 インターフェイスを取得するにはどうすればよいですか
-
09-06-2019 - |
質問
私は、他の必要なインターフェイス (IOleClient がないことに注意してください) に加えて、IObjectWithSite を実装する IE7 用の Active X プラグインを作成しました。このインターフェイスは、IE7 によってクエリされ、呼び出されます。SetSite() 呼び出し中に、次の方法で IHTMLDocument2 インターフェイスを取得するために使用できる IE7 のサイト インターフェイスへのポインターを取得します。
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) ですが、他の 2 つも同様に必要です。何も見逃していないことを願っていますが、必要なものはおそらくリンクにあるはずです。
#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 プラグインへの明示的なメソッド呼び出しを実行してウィンドウ オブジェクトを設定し、それを SetSite 呼び出しで IE Mobile によって提供される IUnknown の代わりにサイト インターフェイスとして使用するという回避策に基づいています。Gears コードに関しては、Google のエンジニアは私が尋ねているのと同じ問題を認識しており、私が説明したこの回避策を考え出しました。
ただし、Active X コントロール/プラグイン上でサイトを明示的に設定するのはあまり優れた方法ではないため、この問題に対処する別のより「公式」な方法が必要であると私は考えています。今すぐ MS IE Mobile チームに直接問い合わせる予定です。解決策が得られたらお知らせします。私が想像できる最も可能性の高いのは IE Mobile のバグかもしれませんが、誰にもわかりません...
しかしとにかく、ご返答いただきありがとうございます ;))