Microsoft KB Archive/175368

= HOWTO: Use CDO (1.x)/VC++ with Recipients Collection RawTable Property =

Article ID: 175368

Article Last Modified on 6/6/2005

-

APPLIES TO


 * Microsoft Collaboration Data Objects 1.1
 * Microsoft Collaboration Data Objects 1.2
 * Microsoft Collaboration Data Objects 1.21

-



This article was previously published under Q175368



SUMMARY
This article discusses how to use VC++ with the CDO (1.x) to return an IMAPITable from the Recipients Collection RawTable property. Although this article demonstrates only the RawTable of the Recipients Collection, it can be used as a model for usage of the RawTable property of other CDO (1.x) objects that support RawTable as well. The contents of this article can also be used to resolve the problem noted in the Microsoft Knowledge Base Article:

173850 PRB: #Import Does not Include Index Parameter Error from VC5



MORE INFORMATION
The code sample below instantiates a CDO (1.x) 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:
// To the Developer: // There are a couple of sections of this code with action items marked // "TO DO:" for you to resolve before it will successfully run.

// TO DO: // If you are using CDO (1.0, 1.0a) unremark the next line: // #import  no_namespace // If you are using CDO (1.1) unremark the next line: // #import  no_namespace // If you are using CDO (1.2, 1.21) unremark the next line: // #import  no_namespace

#import "olemsg32.dll" no_namespace

#include    #include     #include 

#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 {      // TO DO: // Create a MAPI.Session pointer // For CDO (1.0, 1.0a, 1.1) uncomment the next line // SessionPtr pSession("MAPI.Session"); // For CDO (1.2, 1.21) uncomment the next line // _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 CDO // (1.x) Library. //          // If you are using CDO (1.1), preface the constants used below // with "ActMsg" instead of "Cdo". //          // Example - Change CdoPR_DISPLAY_NAME to          //                  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 {               CdoPR_DISPLAY_NAME }           };

// Set the columns to just CdoPR_DISPLAY_NAME hr = lpRecipsTable->SetColumns((LPSPropTagArray)&Columns, 0);

// If you care to use TBLVU32 to view the 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 == CdoPR_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 CDO (1.x) 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 */

