Outlook 2000 exposes a new method that allows an application to programmatically obtain the currently selected item in an Outlook folder. This article demonstrates how you can use automation to retrieve information about the currently selected item from Visual C++ using MFC.
- Start Visual C++ and create a new MFC EXE dialog-based application called AutoOutlook.
- Add a button to your dialog.
- Double-click the button to add a handler for it, and add the following code to the handler:
// Start Outlook
// If it is already running, you will get the same instance
_Application olApp;
_Explorer olExp;
Selection olSel;
LPDISPATCH olSelectedItem; // Since you don't know what type to expect, just use an IDispatch*
COleException e;
COleVariant covOptional((long) DISP_E_PARAMNOTFOUND, VT_ERROR);
if (!olApp.CreateDispatch("Outlook.Application", &e))
{
CString strError;
strError.Format("CreateDispatch() failed with error 0x%08lx", e.m_sc);
AfxMessageBox(strError, MB_SETFOREGROUND);
return;
}
// Logon, which will work correctly even if you are already logged on.
NameSpace olNs(olApp.GetNamespace("MAPI"));
olNs.Logon(covOptional, covOptional, covOptional, covOptional);
// Get the ActiveExplorer so that you can get the selection;
olExp = olApp.ActiveExplorer();
// Get the Selection object
olSel = olExp.GetSelection();
// Since more than one object can be selected at any one time, you loop through them
// one at a time
for (long i = 1; i <= olSel.GetCount(); i++)
{
COleVariant covIndex;
covIndex.vt = VT_I4;
covIndex.lVal = i;
olSelectedItem = olSel.Item(covIndex); // Get the selected item
DisplayInfo(olSelectedItem); // Call your function for displaying the information
}
olNs.Logoff();
olNs.ReleaseDispatch();
olApp.ReleaseDispatch();
- Add a new member function to the CAutoOutlookDlg class called DisplayInfo in AutoOutlookDlg.h:
void DisplayInfo(LPDISPATCH olItem);
- Add the DisplayInfo function to AutoOutlookDlg.cpp:
void CAutoOutlookDlg::DisplayInfo(LPDISPATCH olItem)
{
// You need to determine the message class
WCHAR *rgszNames = L"MessageClass\0";
int cNames = 1;
DISPID dispID;
DISPPARAMS dispParams;
CString strMessageClass;
COleVariant covResult;
HRESULT hr;
dispParams.cArgs = 0;
dispParams.cNamedArgs = 0;
dispParams.rgvarg = NULL;
dispParams.rgdispidNamedArgs = NULL;
// You need to find out what the dispatch ID of "MessageClass" is, so you call
// GetIDsOfNames() on the LPDISPATCH that points the the current item.
hr = olItem->GetIDsOfNames(IID_NULL, &rgszNames, cNames, GetThreadLocale(), &dispID);
if (FAILED(hr))
return; // if you failed, exit
// Request the MessageClass from the LPDISPATCH the you have.
hr = olItem->Invoke(dispID, IID_NULL, GetThreadLocale(), DISPATCH_PROPERTYGET, &dispParams, &covResult, NULL, NULL);
if (FAILED(hr))
return; // if you failed, exit
strMessageClass = covResult.bstrVal; // Move the message class into a CString (easier to work with)
if (strMessageClass == "IPM.Appointment") // A calendar entry was selected
{
_AppointmentItem olAppointmentItem;
olAppointmentItem = (_AppointmentItem) olItem;
AfxMessageBox(olAppointmentItem.GetSubject());
AfxMessageBox(olAppointmentItem.GetBody());
}
else if (strMessageClass == "IPM.Contact") // A contact was selected
{
_ContactItem olContactItem;
olContactItem = (_ContactItem) olItem;
AfxMessageBox(olContactItem.GetFullName());
AfxMessageBox(olContactItem.GetEmail1Address());
}
else if (strMessageClass == "IPM.Note") // An email message was selected
{
_MailItem olMailItem;
olMailItem = (_MailItem) olItem;
AfxMessageBox(olMailItem.GetSubject());
AfxMessageBox(olMailItem.GetBody());
}
else if (strMessageClass == "IPM.Activity") // A journal entry was selecetd
{
_JournalItem olJournalItem;
olJournalItem = (_JournalItem) olItem;
AfxMessageBox(olJournalItem.GetSubject());
AfxMessageBox(olJournalItem.GetBody());
}
else if (strMessageClass == "IPM.StickyNote") // A note was selected
{
_NoteItem olNoteItem;
olNoteItem = (_NoteItem) olItem;
AfxMessageBox(olNoteItem.GetSubject());
AfxMessageBox(olNoteItem.GetBody());
}
else if (strMessageClass == "IPM.Task") // A task was selected
{
_TaskItem olTaskItem;
olTaskItem = (_TaskItem) olItem;
AfxMessageBox(olTaskItem.GetSubject());
AfxMessageBox(olTaskItem.GetPercentComplete());
}
else
{
AfxMessageBox("This is a custom item, this sample does not support this");
}
}
- Bring up the ClassWizard (Control-W), click the Automation tab and choose From a type library under the Add Class menu.
- In the dialog box that comes up, navigate to the directory where Outlook is installed, and choose the Outlook 2000 type library MSOUTL9.OLB. Select all the items it finds, and click OK to have ClassWizard generate MFC wrapper classes for all of them.
- Add the following code just before the implementation of your button handler:
#include "msoutl9.h"
// Ole-initialization class.
class OleInitClass {
public:
OleInitClass() {
OleInitialize(NULL);
}
~OleInitClass() {
OleUninitialize();
}
};
// This global class calls OleInitialize() at
// application startup, and calls OleUninitialize()
// at application exit...
OleInitClass g_OleInitClass;
- Start Outlook 2000 and select an item in a folder.
- Compile and run the project.
- Click on the button you created. A message box appears showing some information about the item that you selected.
Keywords : kbole kbAutomation kbMFC kbOutlookObj kbVC kbVC500 kbVC600 kbGrpDSO kbOffice2000 kboutlook2000
Version : WINDOWS:2000; winnt:5.0,6.0
Platform : WINDOWS winnt
Issue type : kbhowto