2

我不知道是否有人熟悉 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

4

2 回答 2

2

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

这将导致这样的事情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)) {
    // ...
}
于 2010-03-08T00:12:47.530 回答
1

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

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

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

于 2010-03-08T00:13:30.657 回答