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
Fauzia Awan
Microsoft Developer Support - Messaging
This posting is provided "AS IS" with no warranties, and confers no rights.
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...
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
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
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 (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...