使用IDispatch比较对象以仅获取主框架(BHO)

时间:2010-03-07 23:53:44

标签: c++ bho

我不知道是否有人熟悉BHO(浏览器助手对象),但是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

2 个答案:

答案 0 :(得分:2)

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

这会在IUnknown

中产生类似的结果
OnDocumentComplete()

...或者如果您使用的是ATL(如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 } 所示):

m_spWebBrowser

答案 1 :(得分:1)

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

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

In :: OnDocumentComplete你得到一个IDispatch指针,将这个指针与之前保存的ptr和voíla进行比较,如果匹配你就在顶层。