Microsoft KB Archive/175368

From BetaArchive Wiki
Knowledge Base

Article ID: 175368

Article Last Modified on 6/6/2005


  • 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


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


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 <mdisp32.tlb> no_namespace
   // If you are using CDO (1.1) unremark the next line:
   // #import <olemsg32.dll> no_namespace
   // If you are using CDO (1.2, 1.21) unremark the next line:
   // #import <cdo.dll> no_namespace

    #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];

       // 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");


        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,

          // Make sure we got a table back
            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

            // 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

      catch (_com_error &e)

    #ifdef _DEBUG
      // Prepare to show the table with tblvu32.dll
      HINSTANCE hInstTableVu = LoadLibrary("tblvu32.dll");

      (FARPROC&)lpfnViewMAPITable = GetProcAddress(hInstTableVu,

      lpfnViewMAPITable((LPMAPITABLE FAR *)&lpRecipsTable, NULL);
      FreeLibrary (hInstTableVu);
    #endif _DEBUG


This sample assumes that Collaboration Data Objects (1.1, 1.2, or 1.21) is installed on your system. For additional information on obtaining the CDO (1.x) library, please see the following article in the Microsoft Knowledge Base:

171440 Where to Acquire the CDO (1.x) Libraries

Keywords: kbhowto kbmsg KB175368