2

IObjectWithSite を実装する IE7 用の Active X プラグインを作成しましたが、その他の必要なインターフェイスもいくつかあります (IOleClient がないことに注意してください)。このインターフェイスは、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 インターフェイスを使用しても機能しないため、既にテスト済みです。

何か案は?

4

2 に答える 2

3

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
}
于 2008-09-15T14:32:04.847 に答える
2

さて、私はすでにギアコードを知っていました。gearsが使用するメカニズムは、gearsローダーからgearsプラグインへの明示的なメソッド呼び出しを実行してウィンドウオブジェクトを設定し、SetSite呼び出しでIE Mobileによって提供されるIUnknownの代わりに、それをサイトインターフェイスとして使用することによる回避策に基づいています。ギアコードに関して、Googleのエンジニアは私が尋ねているのと同じ問題を認識しており、私が説明したこの回避策を考え出しました。

ただし、Active Xコントロール/プラグインにサイトを明示的に設定することはあまり優れていないため、この問題に対処する別の「公式」な方法が必要だと思います。今すぐMSIEMobileチームに直接質問し、解決策が得られたらお知らせします。それは私が想像できる最も可能性の高いものであるIEモバイルのバグかもしれませんが、誰が知っていますか...

しかし、とにかくあなたの応答に感謝します;))

于 2008-09-16T11:11:18.160 に答える