忽略DispEventUnadvise的结果是否安全?

时间:2014-09-13 02:10:40

标签: c++ com atl

我正在使用ATL写一个BHO,我正在使用DispEventUnadvise作为SetSite函数的一部分来断开与Internet Explorer的连接。

这是我的代码:

STDMETHODIMP FooBho::SetSite(IUnknown* site)
{
    if (site != nullptr)
    {
        if( this->webBrowser != nullptr )
        {
            this->webBrowser.Release();
        }
        // Cache the pointer to IWebBrowser2.
        HRESULT hr = site->QueryInterface(IID_IWebBrowser2, (void**) &this->webBrowser);
        ATLENSURE_SUCCEEDED(hr);

        // Register event-handler.
        hr = DispEventAdvise(this->webBrowser);
        ATLENSURE_SUCCEEDED(hr);

        this->isAdvised = true;
    }
    else
    {
        // Release cached pointers and other resources here.
        if( this->isAdvised )
        {
            HRESULT hr = DispEventUnadvise( this->webBrowser );
            ATLENSURE_SUCCEEDED(hr); // This assertion often fails when hr == 0x80040200 
            this->isAdvised = false;
        }

        this->webBrowser.Release();
    }

    // Return the base class implementation
    return IObjectWithSiteImpl<FooBho>::SetSite(site);
}

很多时候DispEventUnadvise会返回0x80040200,这对应于许多不同的HRESULT,但我认为它与EVENT_E_FIRST相对应,但我不确定{{1}的文档}没有记录其错误代码。

DispEventUnadvise中失败的断言导致我的BHO崩溃,所以我需要删除它,但完全忽略ATLENSURE_SUCCEEDED的返回值是否安全,或者我应该检查{{1} },否则仍然会调用DispEventUnadvise

更新

这是我的班级标题,它包含了水槽地图:

0x80040200

2 个答案:

答案 0 :(得分:3)

错误代码代表CONNECT_E_NOCONNECTION,可能是由内部IConnectionPointContainer::FindConnectionPoint调用返回的。也就是说,没有连接点,水槽地图有问题,你没有包含它。

您的代码段中还有其他问题。使用ATLENSURE_SUCCEEDED不正确。它抛出了从COM方法返回之前应该捕获的异常。

STDMETHODIMP FooBho::SetSite(IUnknown* site)
{
  _ATLTRY
  {
    // ...
    ATLENSURE_SUCCEEDED(...);
    // ...
  }
  _ATLCATCH(Exception)
  {
    return Exception;
  }
  return S_OK; 
}

可以忽略的错误代码是代码告诉&#34;您不会被告知Unadvise&#34;。

答案 1 :(得分:0)

尝试向 DispEventUnadvise 提供第二个参数,指向“事件”界面的uuid,例如

HRESULT hr = DispEventUnadvise(this->webBrowser, &DIID_DWebBrowserEvents2);

这样我在CANoe应用程序中解决了同样的问题(使用相同的错误代码)