Introduction

Recently it became necessary for me to create an application which was
alerted whenever new mail was received using Microsoft Outlook 2002/XP.

Although there are already several articles on hooking into Outlook, I found
that the automation implementation had changed considerably for Outlook 2002/XP
and Microsoft Visual Studio .NET 2003. The second problem was that amongst the
thousands of articles available, there are VERY few MFC or C++ ones. From my
research I only managed to find a single MSDN article (KB 309301) relating to
handling events using the .NET development environment. Unfortunately this was
for Excel. A little bit of playing around and I successfully managed to convert
this KB article to work with Outlook. Reading a bit about COM architecture also
helped out on this new topic to me.

Building the application

Firstly, we need to create our default application:

Start Visual Studio and select the 'File' menu, followed by 'New' and then
select 'MFC application'. For its type, select 'Dialog Based'. Enter
MFCOutlookEvent for its project name.

Select 'Class View' and right click inside the window to select 'Add Class'.
For your class type select 'MFC Class from TypeLib'. A type library is basically
an interface to expose the objects of a COM component.

Finally in order to initialize the use of the COM object, we must add the
following code to your CMFCOutlookEventApp.InitInstance(void)
function. Add it just above where you see
AfxEnableControlContainer();:

Compile/run

You should now be able to compile/run your project. To test it, run it, and
click 'Start'. It will automatically hook onto an existing instance of Outlook,
or if no instance is found, it will start a new one. When new mail is received a
trace entry will be placed into your 'Output' window of DevStudio saying
'HandleNewMail'.

Handling a new mail notification

You will probably wish to perform some form of operation whenever a new mail
item is received. To do this simply navigate to your
CAppEventListener.HandleNewMail(void) function and write whatever
code you desire.

Detailed explanation

On closer look at the CAppEventListener class you will notice a
few strange things. Firstly, in the header file there is the following code:

This is basically the unique GUID assigned to Outlook. To discover this,
takes a bit of delving around. Load Visual Studio, click 'Tools' followed by
'OLE/COM Object Viewer'. From here, navigate down to expand your 'Type
Libraries' section. You will probably have a huge list of available
applications. Locate 'Microsoft Outlook 10.0 Object Library' and double click
it. From here, locate 'coClass Application', expand this and highlight
'ApplicationEvents'. In the right hand view you should see the event GUID listed
above.

You will also notice several application event functions. Above each function
is a hexadecimal address. The NewMail() function which we were
interested in should have the following:

[id(0x0000f003), helpcontext(0x0050df85)]
void NewMail();

If you go back to Visual Studio and go to the
CAppEventlistener.Invoke function, you will see a switch statement,
and one of its cases is the exact same hexadecimal value (0x0000f003). This
function is our main event handler if you so desire, and will call the
appropriate function when the correct dispatch message arrives.

Not being an expert on COM, infact I only have about 2 hours experience so
far, I can't really go into too much further detail, plus the code serves its
purpose without knowing all the ins and outs! I hope this is of benefit to you
all.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

I am using Outlook 2003, I compiled your code. At the time I run it, I receives a "Can't open outlook!" message. Looks like "m_OutlookApplication.CreateDispatch( "Outlook.Application" )" cause the failure. Can you drop me a hint on what I miss here?
Thank you.

This error is raised because Outlook and your app are running in different security contexts. Check whether you're running one of them as an administrator or with system account then try to launch them in the same contexts and it should work for you.

do you know how to catch the mail item, after it was sent? or just after it was attach to the Outlook Folder?

My theory on this is to declare a message handler, (based on your example) change the event id ( where to get the list of the event ID?) and get the dispatch pointer and create a mailitem object from the dispatch.

3. my outlook express in already open. MFCOutlookevents application that is also running, in that time when ever i rec'd a new mail i am getting the message box from outlook express"A program is trying to access the email address..." what to do ?.

Is each hex value an event that you want to have access to? I do not see the hex value for the NewMail event. Can you explain the hex values in the first set of brackets and the hex values in the second set of brackets.

I'm not sure how you can add the stationry, but if you catch the send event (see a prvious comment on how to do that), you can create a CMailitem from the second argument and process from there... The CMailItem class has methods you can use, but I am sure if you did some more investigation, you could do a lot more.
I added these lines to the code in AppListener.cpp to catch an email before it was sent: case 0x0000f002: // ItemSend()
if(pDispParams->cArgs !=2)
return E_INVALIDARG;
else
{
// the second argument is the pointer to the mail item.
CMailItem Mail(pDispParams->rgvarg[1].pdispVal);
HandleSendMail(Mail);

What I try to make is to handle the situation, when the user clicks 'Send'. I want the e-mail to be saved on disk (as an *.msg file) and not sent and stored in Outbox. So, there is no user cancel - it's me who want to cancel automaticly the sending of e-mail.

Other than this it should be fairly straight forward. Id strongly advise that you study the Outlook Object Model in the COM explorer of visual studio before starting out. Try to discover the best objects to use and then just play around with them until you get the results you require. Alot of useful information, such as the IDs required etc can be found there.

Does this work with Outlook 2000 and Windows 2000? I also want to save the exported data from the inbox to a MSDE sql database. Must I convert the XML data into a dataset and then fill my sql tables with the data? Help!

i was wanderin is there any way of getting the event when mail is being sent,
for example user clicks send&receive and all outgoing mail contents are being scanned with my antivirus.. how can i do that ?

If you look in the outlook object model ApplicationEvents properties you will see that above NewMail() function there is an ItemSend() function that receives an IDispatch* Item object. Im assuming this is a pointer to the mail item being sent, as ive not had the chance to test this. Its hex value btw is f002.

To get a simple notification of the event you need to implement something like the following in your STDMETHODIMP CAppEventListener::Invoke function: