Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to get TO, CC, BCC address list from IMessage object?

211 views
Skip to first unread message

Chang Kuang

unread,
Aug 14, 2003, 3:07:17 PM8/14/03
to
Hello,

After grabbing an IMessage object, how to get its TO, CC, BCC? I need to
get the whole list. The best is to recover the headers TO, CC, BCC in
the raw Mime message.

I successfully read its Sender and Subject by passing a PropTagArray
containing PR_SENDER_EMAIL_ADDRESS and PR_SUBJECT to IMessage->GetProps
method, but was unable to find a similar property for TO, CC and BCC.

Thanks,
Chang

Chang Kuang

unread,
Aug 14, 2003, 3:36:12 PM8/14/03
to
Just one clarification: I mean the messages in the draft folder.
Otherwise it won't have BCC header.

Fauzia Awan [MS]

unread,
Aug 14, 2003, 10:07:28 PM8/14/03
to

Hi Chang,
Try using the following properties
PR_DISPLAY_BCC
PR_DISPLAY_CC
PR_DISPLAY_TO


Fauzia Awan
Microsoft Developer Support - Messaging

This posting is provided "AS IS" with no warranties, and confers no rights.

Chang Kuang

unread,
Aug 15, 2003, 1:49:30 PM8/15/03
to
I tried these properties, but only got empty strings. Is it because I am
getting the message from Draft folder, rather than Inbox folder?
Whatever, the message indeed has TO, CC and BCC.

Fauzia Awan [MS]

unread,
Aug 15, 2003, 2:23:31 PM8/15/03
to

Hi,
These properties should be avaliable even in drafts folder. Is the message
saved in the draft folder before these properties are retrieved? Can you
post your code how you are retrieving these properties?

Dmitry Streblechenko

unread,
Aug 15, 2003, 3:45:26 PM8/15/03
to
These properties will be updated everytime message recipients are changed.
Make sure you save the message first - you should do that using Outlook
Object Model (MailItem.Save) rather than Extended MAPI.
Alo note that PR_DISPLAY_xxx will only give you a semicolon separated list
of display names; if you need any other attributes (name, address, entry id,
etc), you need to work with the recipients table - use
IMessage::GetRecipientsTable()

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool


"Chang Kuang" <chang...@hotmail.com> wrote in message
news:199%a.4$PQ5...@news.oracle.com...

Volker Bartheld

unread,
Aug 18, 2003, 4:51:34 AM8/18/03
to
Hi!

On Fri, 15 Aug 2003 10:49:30 -0700, Chang Kuang <chang...@hotmail.com>
wrote :


>I tried these properties, but only got empty strings. Is it because I am
> getting the message from Draft folder, rather than Inbox folder?

It doesn't matter from which folder you retrieve the message. As long as
the message existst, you should have access to its properties. You know
about Outlook Spy? Examine the message using that tool. If the props
_really_ are not there, something is wrong (or the handler from which
you access the message didn't set those props yet).

>> Try using the following properties
>> PR_DISPLAY_BCC
>> PR_DISPLAY_CC
>> PR_DISPLAY_TO

Maybe the code snippets below will help you a little bit (some class
definition are not included, they're from STL and rather self
explaining):

// static strings for email protocol and address types
static char *s_SZPROTO[MAIL_ENUMS::eNUM_PROTO]={"SMTP", "EX", "X400", "PROFS", "MHS"};
static char *s_SZADDRTYPES[MAIL_ENUMS::eNUM_ADDRTYPES]={"SENDER", "TO", "CC", "BCC"};

//////////////////////////////////////////////////////////////////////
// convert protocol string to integer identifier
//////////////////////////////////////////////////////////////////////
int GetProtocolNum(const char* pszProto)
{
assert(pszProto);

int i;
// the static array SZPROTO[] lists all email protocols
// (eSMTP, eEX, eX400, ePROFS, eMHS, eNUM_PROTO) available to
// outlook.
for(i=0; i<MAIL_ENUMS::eNUM_PROTO; i++) if(!strcmp(pszProto, s_SZPROTO[i])) return i; // search array and return protocol number
return -1; // "-1" means "not found"
}

//////////////////////////////////////////////////////////////////////
// get all recipients of an email
//////////////////////////////////////////////////////////////////////
HRESULT MAPI_GetRecipients(LPEXCHEXTCALLBACK pEECB, CRecipients& Rcpts)
{
#ifdef _DEBUGOUTPUT
OutputDebugString("MAPI_GetRecipients() ");
#endif // #ifdef _DEBUGOUTPUT

assert(pEECB);

HRESULT hr=MAPI_ERRS::E_NOERROR;
IMessage* pMessage=NULL;
IMAPITable* pRecipientsTable=NULL;
SRowSet* pRecipientRows=NULL;
char* pszRecipientEmail=NULL;
unsigned long ul;

IMailUser* pMailUser=NULL;
CMailUser MailUser;

enum {ePR_RECIPIENT_TYPE, ePR_ENTRYID, NUM_COLS};
static SizedSPropTagArray(NUM_COLS, PropRecipient) = {NUM_COLS, {PR_RECIPIENT_TYPE, PR_ENTRYID}}; // selects the recipient's type (TO, CC, ...) and Entry-ID

// get IMessage object, recipient table and query all rows for email addresses (selector is in PropRecipientNum)
if(FAILED(hr=pEECB->GetObject(NULL,(IMAPIProp**)(&pMessage)))) goto err; // get the object
if(FAILED(hr=pMessage->GetRecipientTable(0, &pRecipientsTable))) goto err;
if(FAILED(hr=HrQueryAllRows(pRecipientsTable, (SPropTagArray*)&PropRecipient, NULL, NULL, 0L, &pRecipientRows))) goto err;

for(ul=0; ul<pRecipientRows->cRows; ul++) // enumerate all recipients
{
if(PT_LONG!=(0xFFFF&pRecipientRows->aRow[ul].lpProps[ePR_RECIPIENT_TYPE].ulPropTag)) // recipient type must be long
{
hr=MAPI_ERRS::E_ADR_UNKNOWN;
goto err;
}
MailUser.m_Type=(enum MAIL_ENUMS::eADDRTYPES)pRecipientRows->aRow[ul].lpProps[ePR_RECIPIENT_TYPE].Value.l;
if(FAILED(hr=MAPI_GetStandardEmail(pEECB, &pRecipientRows->aRow[ul].lpProps[ePR_ENTRYID], MailUser))) goto err; // get the sender's email addy from user properties depending on SMTP, EX, ...
Rcpts.push_back(MailUser); // add the MailUser to list of recipients

#ifdef _DEBUGOUTPUT
OutputDebugString(s_SZADDRTYPES[MailUser.m_Type]);
OutputDebugString(":");
OutputDebugString(MailUser.m_sAddr.c_str());
OutputDebugString(" (");
OutputDebugString(s_SZPROTO[MailUser.m_Proto]);
OutputDebugString(") ");
#endif // #ifdef _DEBUGOUTPUT
} // for(unsigned long ul=0; ul<pRecipientRows->cRows; ul++)

#ifdef _DEBUGOUTPUT
OutputDebugString("\n");
#endif // #ifdef _DEBUGOUTPUT

err:
if(pMailUser) pMailUser->Release(); // free mail user

// free rows and table
if(pRecipientRows) FreeProws(pRecipientRows);
if(pRecipientsTable) pRecipientsTable->Release();
if(pMessage) pMessage->Release();

return hr;
} // HRESULT GetRecipientsEmail(LPEXCHEXTCALLBACK pEECB)


//////////////////////////////////////////////////////////////////////
// get standard email address of user and other properties
//////////////////////////////////////////////////////////////////////
HRESULT MAPI_GetStandardEmail(LPEXCHEXTCALLBACK pEECB, SPropValue* pEntryId, CMailUser& MailUser)
{
#ifdef _DEBUGOUTPUT
OutputDebugString("MAPI_GetStandardEmail() ");
#endif // #ifdef _DEBUGOUTPUT

assert(pEECB);
assert(pEntryId);

HRESULT hr=MAPI_ERRS::E_NOERROR;
IAddrBook* pAdrBook=NULL;
IMailUser* pMailUser=NULL;
SPropValue* pMailUserProp=NULL;
unsigned long ulObjType, ulCount=0;
int iProtocolNum;

enum {ePR_ADDRTYPE, ePR_EMAIL_ADDRESS, ePR_SMTP_ADDRESS, NUM_COLS};
static SizedSPropTagArray(NUM_COLS, PropMailUser) = {NUM_COLS, {PR_ADDRTYPE, PR_EMAIL_ADDRESS, 0x39FE001E}}; // 0x39FE001E==PR_SMTP_ADDRESS

// Note: OL might create the "A program is trying to access e-mail addresses you have stored in Outlook.
// Do you want to allow this?" messagebox (see http://support.microsoft.com/default.aspx?scid=kb;EN-US;262631 and
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;262701) here if the security update is installed.
// That behaviour affects OOM only (in contrast to E-MAPI) and can not be suppressed.

if(FAILED(hr=pEECB->GetSession(NULL, &pAdrBook))) goto err; // get the address book
if(FAILED(hr=pAdrBook->OpenEntry(pEntryId->Value.bin.cb, (LPENTRYID)pEntryId->Value.bin.lpb, NULL, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN *)&pMailUser))) goto err; // open the address book entry in pEntryId

// The following object types exist:
/*
#define MAPI_STORE ((ULONG) 0x00000001) // Message Store
#define MAPI_ADDRBOOK ((ULONG) 0x00000002) // Address Book
#define MAPI_FOLDER ((ULONG) 0x00000003) // Folder
#define MAPI_ABCONT ((ULONG) 0x00000004) // Address Book Container
#define MAPI_MESSAGE ((ULONG) 0x00000005) // Message
#define MAPI_MAILUSER ((ULONG) 0x00000006) // Individual Recipient
#define MAPI_ATTACH ((ULONG) 0x00000007) // Attachment
#define MAPI_DISTLIST ((ULONG) 0x00000008) // Distribution List Recipient
#define MAPI_PROFSECT ((ULONG) 0x00000009) // Profile Section
#define MAPI_STATUS ((ULONG) 0x0000000A) // Status Object
#define MAPI_SESSION ((ULONG) 0x0000000B) // Session
#define MAPI_FORMINFO ((ULONG) 0x0000000C) // Form Information
*/
if(MAPI_MAILUSER!=ulObjType) // should be a mail user object
{
hr=MAPI_ERRS::E_INVALID_OBJECT_TYPE;
goto err;
}

if(FAILED(hr=pMailUser->GetProps((LPSPropTagArray)&PropMailUser, 0, &ulCount, &pMailUserProp))) goto err;
if(MAPI_W_ERRORS_RETURNED==hr) hr=MAPI_ERRS::E_NOERROR; // delete a hr==0x40380 (not all properties retrieved) warning
if(PT_STRING8!=(0xFFFF&pMailUserProp[ePR_ADDRTYPE].ulPropTag)) // address type must be string8
{
hr=MAPI_ERRS::E_ADR_UNKNOWN;
goto err;
}

iProtocolNum=GetProtocolNum(pMailUserProp[ePR_ADDRTYPE].Value.lpszA); // convert protocol from string to number
MailUser.m_Proto=(MAIL_ENUMS::ePROTOCOLS)iProtocolNum; // save protocol (EX, SMTP, ...) for MailUser
switch(iProtocolNum) // switch for the possible protocols
{
case MAIL_ENUMS::eSMTP:
{
// plain SMTP message ("Friendly Name" <john...@company.com>) select PR_EMAIL_ADDRESS
if(PT_STRING8==(0xFFFF&pMailUserProp[ePR_EMAIL_ADDRESS].ulPropTag))
MailUser.m_sAddr=pMailUserProp[ePR_EMAIL_ADDRESS].Value.lpszA;
break;
}
case MAIL_ENUMS::eEX:
{
// exchange server EX message ("Administrator") select PR_SMTP_ADDRESS (0x39FE001E)
if(PT_STRING8==(0xFFFF&pMailUserProp[ePR_SMTP_ADDRESS].ulPropTag))
MailUser.m_sAddr=pMailUserProp[ePR_SMTP_ADDRESS].Value.lpszA;
break;
}
default:
{
// don't know for X400, PROFS, MHS, ...
hr=MAPI_ERRS::E_ADR_UNKNOWN;
goto err;
}
} // switch(iProtocolNum)

if(MailUser.m_sAddr.empty()) hr=MAPI_ERRS::E_ADR_UNKNOWN; // no email addr found - return error

err:
if(pMailUserProp) MAPIFreeBuffer(pMailUserProp);
if(pMailUser) pMailUser->Release();
if(pAdrBook) pAdrBook->Release();

return hr;
} // MAPI_GetStandardEmail(SPropValue* pEntryId, CMailUser& MailUser)

Good luck!


Volker

Chang Kuang

unread,
Aug 18, 2003, 2:36:34 PM8/18/03
to

> It doesn't matter from which folder you retrieve the message. As long as
> the message existst, you should have access to its properties. You know
> about Outlook Spy? Examine the message using that tool. If the props
> _really_ are not there, something is wrong (or the handler from which
> you access the message didn't set those props yet).

I know the cool OutlookSpy. The question my program is only intended for
Pocket PC, so I have to use cemapi. Not sure whether OutlookSpy has a
CE version.

>
> Maybe the code snippets below will help you a little bit (some class
> definition are not included, they're from STL and rather self
> explaining):

Thanks for your very helpful snippet. I will try to rewrite it based on
cemapi (hopefully all classes/methods are also available in cemapi)

- Chang

Volker Bartheld

unread,
Aug 19, 2003, 6:01:41 AM8/19/03
to
Hi!

On Mon, 18 Aug 2003 11:36:34 -0700, Chang Kuang <chang...@hotmail.com>
wrote :


>I know the cool OutlookSpy. The question my program is only intended for
> Pocket PC, so I have to use cemapi.

Ieeeeeeeeeeeeeeek. Seems you're on you own here... ;-)

>Not sure whether OutlookSpy has a
>CE version.

Hm... Dmitry - are you listening? ;-)

>> Maybe the code snippets below will help you a little bit (some class
>> definition are not included, they're from STL and rather self
>> explaining):

>Thanks for your very helpful snippet. I will try to rewrite it based on
>cemapi (hopefully all classes/methods are also available in cemapi)

OK. If you have any problems, don't hesitate to contact me at my email
address below. DON'T use the REPLY_TO in mentioned in the header of this
post.


Good luck!


Volker

Dmitry Streblechenko

unread,
Aug 19, 2003, 4:58:06 PM8/19/03
to
Nope, OutlookSpy does not support Pocket PC...

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool


"Volker Bartheld" <dr_ve...@freenet.de> wrote in message
news:bhsshd$2qv5i$1...@ID-78102.news.uni-berlin.de...

0 new messages