visual studio – Outlook COM based C++ Addin to Capture Sent Items


I am trying to add a record to log file when Email is sent from outlook using com addins. I intialized an interface and registered for Outlook::ApplicationEvents using DispEventAdvise method. The program fails to execute the Onsend Method. I build the addin and tried to load in Outlook. I am unable to trigger the sent email function.

// Connect.h : Declaration of the CConnect

#pragma once    
#include "TestAddin2_i.h"
#include "resource.h"
#include <iostream>
#include <fstream>
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h> 
#include <Ole2.h>
#import "C:\Program Files\Microsoft Office\root\Office16\MSOUTL.OLB" raw_interfaces_only, raw_native_types, named_guids, auto_rename

_ATL_FUNC_INFO fiMailItemEvents = { CC_STDCALL, VT_EMPTY, 1, {VT_DISPATCH | VT_BYREF} };

#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif


typedef IDispatchImpl<_IDTExtensibility2, &__uuidof(_IDTExtensibility2), &__uuidof(__AddInDesignerObjects), /* wMajor = */ 1> IDTImpl;

#include <fstream>

void LogMessage(const char* message) {
    std::ofstream file("C:/Users/Windows/Desktop/log.txt", std::ios_base::app);
    if (file.is_open()) {
        file << __TIME__ <<" " <<  message << '\n';
        file.close();
    }
}

class ATL_NO_VTABLE CConnect :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CConnect, &CLSID_Connect>,
    public IDispatchImpl<IConnect, &IID_IConnect, &LIBID_TestAddin2Lib, 1,0>,
    public IDispEventSimpleImpl<1, CConnect, &__uuidof(Outlook::ApplicationEvents)>,
    public IDTImpl
{
public:

    LPDISPATCH m_spApplication;

    CConnect()
    {
    }

    STDMETHOD(Invoke)(DISPID dispidMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexceptinfo, UINT *puArgErr)
    {
        HRESULT hr=DISP_E_MEMBERNOTFOUND;

        if (DISP_E_MEMBERNOTFOUND == hr)
            hr = IDTImpl::Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexceptinfo, puArgErr);

        return hr;
    }
    DECLARE_REGISTRY_RESOURCEID(IDR_CONNECT)

    BEGIN_COM_MAP(CConnect)
        COM_INTERFACE_ENTRY(IConnect)   
        COM_INTERFACE_ENTRY(_IDTExtensibility2)
    END_COM_MAP()


    BEGIN_SINK_MAP(CConnect)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ApplicationEvents), 0x0000F005, OnSend, &fiMailItemEvents)
    END_SINK_MAP()

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }
    STDMETHOD(OnConnection)(LPDISPATCH Application, ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, SAFEARRAY** custom)
    {
        LogMessage("Addin Loaded");
        if (Application)
        {
            LogMessage("Addin Loaded and DispEventAdvise");
            HRESULT hrAdvise = DispEventAdvise(Application, &__uuidof(Outlook::ApplicationEvents));
            LogMessage("Starting to check addin load");
            if (SUCCEEDED(hrAdvise)) {
                LogMessage("Registration of DispEventAdvice Successfull");
            }
            else {
                LogMessage("Failed to register DispEvent");
            }
        }
        return S_OK;
    }
    STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode, SAFEARRAY** custom)
    {
        return S_OK;
    }

    STDMETHOD(OnAddInsUpdate)(SAFEARRAY * * custom)
    {
        return S_OK;
    }
    STDMETHOD(OnStartupComplete)(SAFEARRAY * * custom)
    {
        return S_OK;
    }
    STDMETHOD(OnBeginShutdown)(SAFEARRAY * * custom)
    {
        return S_OK;
    }

    STDMETHOD(OnSend)(VARIANT_BOOL Cancel) {
        LogMessage("Item Sent Successfully");
        return S_OK;
    }
};
OBJECT_ENTRY_AUTO(__uuidof(Connect),CConnect)
class ATL_NO_VTABLE CConnect :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CConnect, &CLSID_Connect>,
    public IDispatchImpl<IConnect, &IID_IConnect, &LIBID_TestAddin2Lib, 1,0>,
    public IDispEventSimpleImpl<1, CConnect, &__uuidof(Outlook::ApplicationEvents)>,
    public IDTImpl
{
public:

    LPDISPATCH m_spApplication;

    CConnect()
    {
    }

    STDMETHOD(Invoke)(DISPID dispidMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexceptinfo, UINT *puArgErr)
    {
        HRESULT hr=DISP_E_MEMBERNOTFOUND;

        if (DISP_E_MEMBERNOTFOUND == hr)
            hr = IDTImpl::Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexceptinfo, puArgErr);

        return hr;
    }
    DECLARE_REGISTRY_RESOURCEID(IDR_CONNECT)

    BEGIN_COM_MAP(CConnect)
        COM_INTERFACE_ENTRY(IConnect)   
        COM_INTERFACE_ENTRY(_IDTExtensibility2)
    END_COM_MAP()


    BEGIN_SINK_MAP(CConnect)
    SINK_ENTRY_INFO(1, __uuidof(Outlook::ApplicationEvents), 0x0000F005, OnSend, &fiMailItemEvents)
    END_SINK_MAP()

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }
    STDMETHOD(OnConnection)(LPDISPATCH Application, ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, SAFEARRAY** custom)
    {
        LogMessage("Addin Loaded");
        if (Application)
        {
            LogMessage("Addin Loaded and DispEventAdvise");
            HRESULT hrAdvise = DispEventAdvise(Application, &__uuidof(Outlook::ApplicationEvents));
            LogMessage("Starting to check addin load");
            if (SUCCEEDED(hrAdvise)) {
                LogMessage("Registration of DispEventAdvice Successfull");
            }
            else {
                LogMessage("Failed to register DispEvent");
            }
        }
        return S_OK;
    }
    STDMETHOD(OnSend)(VARIANT_BOOL Cancel) {
        LogMessage("Item Sent Successfully");
        return S_OK;
    }
};
OBJECT_ENTRY_AUTO(__uuidof(Connect),CConnect)

Leave a Reply

Your email address will not be published. Required fields are marked *