سؤال

لقد كتبت مكونًا إضافيًا Active X لـ IE7 والذي ينفذ IObjectWithSite إلى جانب بعض الواجهات الضرورية الأخرى (لاحظ عدم وجود 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 لا يعمل أيضًا، لذلك قمت باختبار هذا بالفعل.

أيه أفكار؟

هل كانت مفيدة؟

المحلول

لقد وجدت الكود التالي في كود 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 لتعيين كائن window واستخدامه كواجهة موقع بدلاً من IUnknown الذي يوفره IE Mobile في استدعاء SetSite.فيما يتعلق برمز التروس، فإن مهندسي Google على دراية بنفس المشكلة التي أطرحها وتوصلوا إلى هذا الحل البديل الذي وصفته.

ومع ذلك، أعتقد أنه يجب أن تكون هناك طريقة "رسمية" أخرى للتعامل مع هذه المشكلة نظرًا لأن تعيين الموقع بشكل صريح على عنصر التحكم/البرنامج الإضافي Active X ليس أمرًا رائعًا.سأسأل فريق MS IE Mobile مباشرة الآن وسأبقيك على اطلاع بمجرد أن أحصل على الحل.قد يكون هناك خطأ في IE Mobile وهو الشيء الأكثر احتمالاً الذي يمكنني تخيله، ولكن من يدري...

لكن على كل حال شكرا لردك ;))

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top