Two Outlook COM Add-ins and connection points

gigasoft 21 Reputation points
2022-05-18T01:50:44.273+00:00

Hi, I have an application that requires that we install two Outlook COM add-ins. I want to send an event from one COM add-in to the other. So I chose to use ATL connection points. While I can use connection points without a problem in one add-in and capture events, I cannot seem to fire the same event to the other add-in. They are both COM DLL's and are loaded in the same process. I have done this before with other applications, but I seem not to be able to fire an event in one add-in and receive that connection point event in the other add-in within Outlook. Is this a security thing within Outlook? I have tried all the free threaded options, but it seems not to make a difference. Does anybody have any suggestions?

Thanks in advance.

Tom -

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,538 questions
Office Development
Office Development
Office: A suite of Microsoft productivity software that supports common business tasks, including word processing, email, presentations, and data management and analysis.Development: The process of researching, productizing, and refining new or existing technologies.
3,512 questions
{count} votes

3 answers

Sort by: Most helpful
  1. gigasoft 21 Reputation points
    2022-05-18T13:38:24.433+00:00

    Yep, I should have attached some code. Late night :)! I have attached some example code. It fails because if cannot find the connection point connection. I did try to go old school without ATL, but I get the same result.

    There is not any failure code, just cannot find connection.

    CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex); /// <<<< ALWAYS RETURNS 0 FAILS HERE

    The code ...

    //////////
    /// DLL  #1 (add-in #1)
    ////////////
    
    // Header
    
    class ATL_NO_VTABLE CSiteDown :
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CSiteDown, &CLSID_SiteDown>,
        public IConnectionPointContainerImpl<CSiteDown>,
        public IDispatchImpl<ISiteDown, &IID_ISiteDown, &LIBID_paddinLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
        public CProxy_ISiteDownEvents<CSiteDown>
    {
    public:
        CSiteDown()
        {
        }
    
        DECLARE_REGISTRY_RESOURCEID(115)
    
    
        BEGIN_COM_MAP(CSiteDown)
            COM_INTERFACE_ENTRY(ISiteDown)
            COM_INTERFACE_ENTRY(IDispatch)
            COM_INTERFACE_ENTRY(IConnectionPointContainer)
        END_COM_MAP()
    
        BEGIN_CONNECTION_POINT_MAP(CSiteDown)
            CONNECTION_POINT_ENTRY(__uuidof(_ISiteDownEvents))
        END_CONNECTION_POINT_MAP()
    
    
        DECLARE_PROTECT_FINAL_CONSTRUCT()
    
        HRESULT FinalConstruct()
        {
            return S_OK;
        }
    
        void FinalRelease()
        {
        }
    
    
    public:
    
        STDMETHOD(EnableErrorState)(VARIANT_BOOL vbEnable);
    
    };
    
    // CPP #1
    STDMETHODIMP CSiteDown::EnableErrorState(VARIANT_BOOL vbEnable)
    {
        AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
        Fire_EnableEvent(vbEnable);
        return S_OK;
    }
    
    // Events #1
    // Events_CP.h
    
    VOID Fire_EnableEvent(VARIANT_BOOL b)
    {
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        CComVariant* pvars = new CComVariant[2];
        int nConnections = m_vec.GetSize();
    
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            ///////////////////////////
            /// DOES NOT RECOGNIZE CONNECTION IN THE ADDIN #2
            ///////////////////////////
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);  ///  <<<< ALWAYS RETURNS 0  FAILS HERE
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                pvars[0].vt = VT_BOOL;
                pvars[0].boolVal = b;
                DISPPARAMS disp = { pvars, NULL, 1, 0 };
                pDispatch->Invoke(88, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
            }
        }
        delete[] pvars;
    }
    
    //////////
    /// DLL  #2 (add-in #2)
    ////////////
    
    // Header
    
    BEGIN_COM_MAP(CDown)
        COM_INTERFACE_ENTRY2(IDispatch, IRibbonCallback)
        COM_INTERFACE_ENTRY(_FormRegionStartup)
        COM_INTERFACE_ENTRY(IDown)
        COM_INTERFACE_ENTRY(_IDTExtensibility2)
        COM_INTERFACE_ENTRY(IRibbonExtensibility)
        COM_INTERFACE_ENTRY(IRibbonCallback)
        COM_INTERFACE_ENTRY_IID(__uuidof(paddinLib::_ISiteDownEvents), IExt)
    END_COM_MAP()
    
    CComPtr<paddinLib::ISiteDown> m_spDown;
    DWORD m_dwDownCookie;
    
    
    // CPP
    STDMETHODIMP CDown::Init()
    {
        if (m_spDown == nullptr)
        {
    
            HRESULT h = CoCreateInstance(
                paddinLib::CLSID_SiteDown, NULL, CLSCTX_ALL,
                paddinLib::IID_ISiteDown, reinterpret_cast<LPVOID*>(&m_spDown));
            if (SUCCEEDED(h) && m_spDown)
            {
                h = AtlAdvise(m_spDown, GetUnknown(), paddinLib::DIID__ISiteDownEvents, &m_dwDownCookie);
            }
        }
    
        return S_OK;
    }
    

  2. gigasoft 21 Reputation points
    2022-05-18T17:27:50.277+00:00

    I did a snippet for you. These are two huge add-ins with multiple com components. The key is that when I fire an event from add-in #1 it acts as if there are no connections that were successfully made in add-in #2.


  3. gigasoft 21 Reputation points
    2022-05-18T18:32:46.653+00:00

    I have done tons of these com components. I can definitely tell you it has something to do with Outlook. I will get to the bottom of this and I will let you know what the issue is.