Can't access mail item in ATL/COM C++ Outlook Addin

593 views Asked by At

I am trying to get the mail information and do some actions based on the values when the user hits the send button in Outlook. Therefore I use this function:

VOID WINAPI CConnect::ItemSend(IDispatch * Item, bool Cancel)

In the OnConnection event handler I call

DispEventAdvise((IDispatch*)m_Application, &__uuidof(Outlook::ApplicationEvents));

It is implemented in the Header-File like this:

public IDispEventSimpleImpl<1, CConnect, &__uuidof(Outlook::ItemEvents)>

public:

VOID WINAPI ItemSend(IDispatch * Item, bool Cancel);

BEGIN_SINK_MAP(CConnect)
SINK_ENTRY_INFO(1, __uuidof(Outlook::ItemEvents), 0x0000F002, ItemSend, &fiMailItemEvents)
END_SINK_MAP()

This is working just like it should, but inside the function I try to get the mail item I always get an exception. This is my code for accessing the item:

CComPtr<Outlook::_MailItem> mail;
Item->QueryInterface(IID__MailItem, (void**)&mail);

What am I doing wrong? Thanks in advance

1

There are 1 answers

2
Aurora On BEST ANSWER

There are a couple of caveats in your code, which could lead to problems:

  • Your ItemSend() method differs from the one in Outlook's type library. It should be declared as ItemSend(IDispatch* Item, VARIANT_BOOL* Cancel).
  • The pointer to the event dispinterface's IID in your IDispEventSimpleImpl template declaration points to Outlook::ItemEvents. However, you are interested in handling events from Outlook::ApplicationEvents.
  • Although not crucial, your call to DispEventAdvise() casts the application interface pointer to IDispatch*, whereas the function expects an IUnknown* parameter. You may also omit the second parameter.

The following class demonstrates how to handle the ItemSend event accordingly. Since you are implementing the IDTExtensibility2 interface, you'll need to move the initialization and cleanup routines to its OnConnection and OnDisconnection methods respectively.

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

class CConect : 
    public ATL::IDispEventSimpleImpl<1, CConect, &(__uuidof(Outlook::ApplicationEvents))>
    {
public:
    CConect(Outlook::_ApplicationPtr piApp)
    {
        m_piApp = piApp;
        DispEventAdvise((IUnknown*)m_piApp);        
    }

    virtual ~CConect()
    {
        DispEventUnadvise((IUnknown*)m_piApp);
    }

    void __stdcall OnItemSend(IDispatch* Item, VARIANT_BOOL* Cancel)
    {
        CComPtr<Outlook::_MailItem> mail;
        HRESULT hr = Item->QueryInterface(__uuidof(Outlook::_MailItem), (void**)&mail);
    }

    BEGIN_SINK_MAP(CConect)
        SINK_ENTRY_INFO(1, __uuidof(Outlook::ApplicationEvents), 0x0000F002, OnItemSend, &fiMailItemEvents)     
    END_SINK_MAP()

private:

    Outlook::_ApplicationPtr m_piApp;
};