Is it safe to ignore the result of DispEventUnadvise?

0

I'm writing a BHO using ATL and I'm using DispEventUnadvise as part of my SetSite function to disconnect from Internet Explorer.

This is my code:

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);
}

Many times DispEventUnadvise returns0x80040200 which corresponds to a number of different HRESULTs, but I think it's corresponding to EVENT_E_FIRST but I'm not sure, the documentation for DispEventUnadvise doesn't document its error codes.

The failing assert in ATLENSURE_SUCCEEDED causes my BHO to crash, so I need to remove it, but is it safe to completely disregard the return value from DispEventUnadvise or should I check for 0x80040200 and otherwise still call ATLENSURE_SUCCEEDED?

Update

This is my class' header, it includes the Sink Map:

// FooBho.h : Declaration of the CFooBho

#pragma once
#include "resource.h"       // main symbols

#include <ShlGuid.h> // IID_IWebBrowser2, DIID_DWebBrowserEvents2, etc.
#include <exdispid.h> // DISPID_DOCUMENTCOMPLETE, etc.
#include <MsHTML.h>

#include "Bho_i.h"

using namespace ATL;

const int DispatchInterface1 = 1;

class ATL_NO_VTABLE FooBho :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<FooBho, &CLSID_FooBho>,
    public IObjectWithSiteImpl<FooBho>,
    public IDispatchImpl<IFooBho, &IID_IFooBho, &LIBID_BhoLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
    public IDispEventImpl<DispatchInterface1, FooBho, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>
{
private:

    CComPtr<IWebBrowser2> webBrowser;
    bool                  isAdvised;

public:
    FooBho()
    {
    }

DECLARE_REGISTRY_RESOURCEID(IDR_FOOBHO)

DECLARE_NOT_AGGREGATABLE(FooBho)

BEGIN_COM_MAP(FooBho)
    COM_INTERFACE_ENTRY(IFooBho)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()

    STDMETHOD(SetSite)(IUnknown *site) override;

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }

#pragma region DIID_DWebBrowserEvents2

    BEGIN_SINK_MAP(FooBho)
        SINK_ENTRY_EX(DispatchInterface1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
    END_SINK_MAP()

    void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* dispatch, VARIANT* uri);

#pragma endregion

private:

    long RemoveImages(IHTMLDocument2* document);

};

OBJECT_ENTRY_AUTO(__uuidof(FooBho), FooBho)
c++
com
atl
asked on Stack Overflow Sep 13, 2014 by Dai • edited Sep 13, 2014 by Dai

2 Answers

3

The error code stands for CONNECT_E_NOCONNECTION, which is presumably returned by internal IConnectionPointContainer::FindConnectionPoint call. That is, there is no connection point, something is wrong with the sink map, which you did not include.

There are other things wrong in your code snippet. Use of ATLENSURE_SUCCEEDED is incorrect. It throws exception which you are supposed to catch before returning from COM method.

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

Error code safe to ignore would be code telling "you were not advised to Unadvise".

answered on Stack Overflow Sep 13, 2014 by Roman R. • edited Sep 13, 2014 by Roman R.
0

Try to provide second parameter to DispEventUnadvise pointing to uuid of 'Events' interface, like

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

This way I solved the same problem (with same error code) in CANoe application

answered on Stack Overflow Sep 19, 2017 by Tomas

User contributions licensed under CC BY-SA 3.0