HOWTO: Using Recipients Collection RawTable with Active Msg/VC++
ID: Q175368
|
The information in this article applies to:
-
Collaboration Data Objects (CDO), versions 1.0, 1.0a, 1.1
SUMMARY
The Collaboration Data Objects Library (formally known as Active Messaging,
versions noted above) contains a bug that prevents the successful execution
of the GetItem() method of any object that has this method. This is
documented in the Microsoft Knowledge Base Article:
Q173850
PRB: #Import Does not Include Index Parameter Error from VC5
The article documents the problem, and indicates that context-specific
workarounds are available. The following article covers one of these
workarounds and can be used as a template for any Collection that includes
a RawTable property.
MORE INFORMATION
The code sample below instantiates an Active Messaging Session, logs on to
that Session, grabs the first Message it finds in your Inbox, and then uses
the RawTable Method off of the Recipients Collection to get a pointer to
the underlying Extended MAPI IMAPITable, which contains information about
the Recipients of this Message.
To demonstrate that we have this information, it also collects the names of
the Recipients into a string and subsequently displays the string in a
MessageBox.
Code Sample Follows:
#import "olemsg32.dll" no_namespace
#include <stdio.h>
#include <assert.h>
#include <tchar.h>
#define INITGUID
#define USES_IID_IMAPITable
#define USES_IID_IMAPITableData
#include "mapidefs.h"
#include "MAPIGUID.H"
// Arbitrary Maximum # of recipients we will process
#define MAX_RECIPS 500
void dump_com_error(_com_error &e)
{
_tprintf(_T("Oops - hit an error!\n"));
_tprintf(_T("\a\tCode = %08lx\n"), e.Error());
_tprintf(_T("\a\tCode meaning = %s\n"), e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
_tprintf(_T("\a\tSource = %s\n"), (LPCTSTR) bstrSource);
_tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
}
// If this is placed in the scope of the smart pointers, they must be
// explicitly Release(d) before CoUninitialize() is called. If any
// reference count is non-zero, a protection fault will occur.
struct StartOle {
StartOle() { CoInitialize(NULL); }
~StartOle() { CoUninitialize(); }
} _inst_StartOle;
void main(int argc, char *argv[])
{
TCHAR szNames[MAX_RECIPS * 20];
try
{
SessionPtr pSession("MAPI.Session");
pSession->Logon();
FolderPtr pFolder = pSession->Inbox;
MessagesPtr pMessages = pFolder->Messages;
MessagePtr pMessage = pMessages->GetFirst();
if (pMessage!=NULL)
{
RecipientsPtr pRecipColl=pMessage->Recipients;
LPMAPITABLE lpRecipsTable = NULL;
IUnknown* lpRecipsObj = NULL;
HRESULT hr = S_OK;
int iNumRows = 0;
// Get an IUnknown Interface to the Recipient Obj
(IUnknown*)lpRecipsObj = pRecipColl->RawTable;
// From this point down to (but not including) the Logoff, we
// are using pure Extended MAPI functionality except for refering
// to the field names by their constants as defined in the Active
// Messaging Library. (aka - ActMsgPR_DISPLAY_NAME)
//
// Get an Interface to the IMAPITable from that interface
hr = lpRecipsObj->QueryInterface(IID_IMAPITable,
(void**)&lpRecipsTable);
// Make sure we got a table back
if(lpRecipsTable)
{
LPSRowSet lpRows = NULL; // Table
LPSRow lpRow = NULL; // 1 row from table
LPSPropValue lpProp = NULL; // 1 Prop (column) from row
SizedSPropTagArray(1, Columns) =
{
1, // number of properties
{
ActMsgPR_DISPLAY_NAME
}
};
// Set the columns to just ActMsgPR_DISPLAY_NAME
hr = lpRecipsTable->SetColumns((LPSPropTagArray)&Columns, 0);
// If you care to use TBLVU32 to view you IMAPITable, insert
// the code commented after the end of the program at this
// point.
// Set BookMark to beginning of table
hr = lpRecipsTable->SeekRow(BOOKMARK_BEGINNING,0,NULL);
// Find out how many rows are in the table.
ULONG lCount = 0;
hr = lpRecipsTable->GetRowCount(0, &lCount);
// Get all of the rows.
hr = lpRecipsTable->QueryRows(lCount, 0, &lpRows);
// Get number of rows returned
iNumRows = lpRows->cRows;
// Loop through the rows and collect the names for later use
for (int iIndex =0; iIndex < iNumRows; iIndex++)
{
lpRow = &lpRows->aRow[iIndex];
lpProp = &lpRow->lpProps[0];
if(lpProp->ulPropTag == ActMsgPR_DISPLAY_NAME)
{
// append the name and a ";" to the string of names
strcat(&szNames[0], lpProp->Value.lpszA);
strcat(&szNames[0], ";");
}
}
}
char sNumRecips[35];
sprintf(sNumRecips, "There are %d Recipients", iNumRows);
MessageBox(NULL, szNames, sNumRecips, MB_OK);
}
// Logoff the Active Messaging MAPI Session
pSession->Logoff();
}
catch (_com_error &e)
{
dump_com_error(e);
}
}
/*
#ifdef _DEBUG
// Prepare to show the table with tblvu32.dll
HINSTANCE hInstTableVu = LoadLibrary("tblvu32.dll");
ULONG (PASCAL *lpfnViewMAPITable)(LPMAPITABLE FAR *, HWND);
(FARPROC&)lpfnViewMAPITable = GetProcAddress(hInstTableVu,
"ViewMapiTable");
lpfnViewMAPITable((LPMAPITABLE FAR *)&lpRecipsTable, NULL);
FreeLibrary (hInstTableVu);
#endif _DEBUG
*/
REFERENCES
This sample assumes that Collaboration Data Objects (CDO) version 1.1 is
installed on your system. For additional information on obtaining the
Active Messaging library, please see the following article in the Microsoft
Knowledge Base:
Q171440
Where to Acquire the Collaboration Data Objects Libraries
For additional information about Collaboration Data Objects versus Active
Messaging, please see the following article in the Microsoft Knowledge
Base:
Q176916
INFO: Active Messaging and Collaboration Data Objects (CDO)
Additional query words:
Keywords : kbActMsg kbCDO100a kbCDO110 kbMsg kbVC kbGrpMsg
Version : WINDOWS:1.0,1.0a,1.1
Platform : WINDOWS
Issue type : kbhowto