【问题标题】:Comparing objects with IDispatch to get main frame only (BHO)将对象与 IDispatch 进行比较以仅获取主框架 (BHO)
【发布时间】:2010-03-07 23:53:44
【问题描述】:

我不知道有没有人熟悉 BHO(Browser Helper Object),但是 c++ 方面的专家也可以帮助我。

在我的 BHO 中,我只想在主框架上运行 OnDocumentComplete() 函数 - 第一个容器,而不是当前页面内的所有 Iframe。 (另一种方法是仅在这是主框架时才放置一些代码)。

我找不到如何跟踪何时填充的主框架。

在谷歌搜索后发现每一帧都有“IDispatch* pDisp”,我必须将它与指向第一个的指针进行比较。

这是主要功能:

STDMETHODIMP Browsarity::SetSite(IUnknown* pUnkSite)
{
    if (pUnkSite != NULL)
    {
        // Cache the pointer to IWebBrowser2.
        HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
        if (SUCCEEDED(hr))
        {
            // Register to sink events from DWebBrowserEvents2.
            hr = DispEventAdvise(m_spWebBrowser);
            if (SUCCEEDED(hr))
            {
                m_fAdvised = TRUE;
            }
        }
    }
    else
    {
        // Unregister event sink.
        if (m_fAdvised)
        {
            DispEventUnadvise(m_spWebBrowser);
            m_fAdvised = FALSE;
        }

        // Release cached pointers and other resources here.
        m_spWebBrowser.Release();
    }

    // Call base class implementation.
    return IObjectWithSiteImpl<Browsarity>::SetSite(pUnkSite);
}

这是我想知道它是否是主窗口(框架)的地方:

void STDMETHODCALLTYPE Browsarity::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
  // as you can see, this function get the IDispatch *pDisp which is unique to every frame.
  //some code
}

我在微软论坛上问了这个问题,我得到了答案,但没有解释如何实际实现:http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/7c433bfa-30d7-42db-980a-70e62640184c

【问题讨论】:

    标签: c++ bho


    【解决方案1】:

    jeffdav 的建议是,通过QueryInterface() 测试pDisp 是否支持IWebBrowser2,如果支持,请检查它是否与您存储在SetSite() 中的对象相同。
    QueryInterface() rules 只要求 QIIUnknown 始终产生相同的指针值,因此您必须另外将 QIIUnknown 相比较并比较结果指针。

    这将导致OnDocumentComplete() 中出现类似的情况:

    IWebBrowser2* pBrowser = 0;
    IUnknown *pUnk1=0, *pUnk2=0;
    if(   SUCCEEDED(pDisp      ->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser))
       && SUCCEEDED(pDisp      ->QueryInterface(IID_IUnknown,     (void**)&pUnk1))
       && SUCCEEDED(m_spBrowser->QueryInterface(IID_IUnknown,     (void**)&pUnk2))
       && (pUnk1 == pUnk2)) 
    {
        // ... top-level
    }
    

    ...或者如果您使用 ATL(如 m_spWebBrowser 建议的那样):

    CComQIPtr<IWebBrowser2> spBrowser(pDisp);
    if(spBrowser && spBrowser.IsEqualObject(m_spWebBrowser)) {
        // ...
    }
    

    【讨论】:

    • 谢谢!帮助我解决了类似的问题(我正在比较错误的接口指针)。 IE对象模型一团糟……
    【解决方案2】:

    请注意,我没有对此进行测试,我只是在重写 msdn 上的人所说的内容。

    在 ::SetSite 中,您会得到一个 IUnknown 指针。在它上面调用 IUnknown::QueryInterface(就像你已经在做的那样),而是使用 IID_IDISPATCH。将此指针保存在某处,此指针是顶层框架。

    在 ::OnDocumentComplete 中,您将获得一个 IDispatch 指针,将此指针与之前保存的 ptr 进行比较,瞧,如果有匹配项,您就在顶层。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-20
      • 2012-01-21
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 2018-04-06
      相关资源
      最近更新 更多