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.
Two Outlook COM Add-ins and connection points
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 -
3 answers
Sort by: Newest
-
-
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.
-
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; }