문제

나는 다른 필수 인터페이스 외에 IObjectWithSite를 구현하는 IE7용 Active X 플러그인을 작성했습니다(IOleClient는 없음).이 인터페이스는 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)에 있지만 나머지 두 개도 필요합니다.제가 놓친 것이 없었기를 바라지만, 필요한 내용을 모두 작성했다면 아마도 해당 링크에 있을 것입니다.

#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가 사용하는 메커니즘은 창 개체를 설정하고 SetSite 호출에서 IE Mobile이 제공하는 IUnknown 대신 이를 사이트 인터페이스로 사용하기 위해 Gears 로더에서 Gears 플러그인에 대한 명시적 메서드 호출을 수행함으로써 해결 방법을 기반으로 합니다.기어 코드와 관련하여 Google 엔지니어들은 제가 묻는 것과 동일한 문제를 알고 있으며 제가 설명한 이 해결 방법을 생각해 냈습니다.

그러나 Active X 컨트롤/플러그인에서 사이트를 명시적으로 설정하는 것은 그다지 좋지 않기 때문에 이 문제를 처리하는 또 다른 "공식적인" 방법이 있어야 한다고 생각합니다.지금 MS IE 모바일 팀에 직접 문의하고 해결책을 찾는 대로 알려드리겠습니다.IE Mobile의 버그일 가능성이 가장 높지만, 누가 알겠습니까?

하지만 어쨌든 귀하의 답변에 감사드립니다;))

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top