free web page counters

Windows Mobile Pocket PC Smartphone Programming

==>Click here for the SiteMap<==. Original contents with decent amount of source codes.

Thursday, March 02, 2006

How to retrieve/get TO, CC, BCC recipient address of an email through CEMAPI (C++) in Windows Mobile device?

====>SiteMap of this Blog<===

How to retrieve/get TO, CC, BCC recipient address of an email through CEMAPI (C++) in Windows Mobile device?

Whenever you deal with email application through MAPI (or, CEMAPI, the trimmed version in Windows Mobile devices), quite possibly you need to load TO addresses, CC addresses from a given email message (or BCC addresses in case the message is in "draft" folder or "Sent Item" folder) . For example, when developing a mail transport, you not only need to synchronize the account's inbox with the remote server, but also have to deal with outgoing messages. Inevitably, you have to know TO/CC/BCC of any outgoing message.

Intuitive thought is to query them as corresponding properties from the message object IMessage using its GetProps method. Although the CEMAPI documentation is scarce, one can still find such properties from the header files:

  • PR_DISPLAY_BCC
  • PR_DISPLAY_CC
  • PR_DISPLAY_TO

Unfortunately all of three properties returned me empty strings, at least in Pocket PC 2003 devices. Time to take a google search to see whether other people ran into the same issue. I did find two fellow clueless guys, who posted the question but got no useful answers:

So I had to take the more complex approach, using the recipient table. Every message has a recipient table. Each record in the recipient table is a recipient, and has a couple of properties/columns. As with any other MAPI stuff, an email address is a property, a recipient's name is also a property, and an address type (TO/CC/BCC) is also a property.

So I changed my simple code to a slightly longer one:

  • opening the recipient table by calling GetRecipientTable,
  • setting the interested properties by calling SetColumns,
  • iterating through the table record-by-record by calling QueryRows

Heck! This seemingly perfect and innocent code still did not work. After a debug, I soon realized that SetColumns returns a COM error meaning not implemented. Not surprisingly, CEMAPI is not the full-fleged MAPI in the desktop world, and here we tasted a slight bitterness.

So the natural solution is to loop though all the properties for each record, and figure out the type of each property. The number of the properties for each recipient is SRow.cValues, and the type of each property is specified in SPropValue.ulPropTag. Below is a code snippet:

  // the hack is to loop through all rows without limiting the columns
  HRESULT hr = pMessage->GetRecipientTable(0, &pRecipientTable);
  EXIT_ON_FAILED(hr);

  // iterate all the recipients
  while (TRUE) {
    hr = pRecipientTable->QueryRows(1, 0, &pRows);
    if (FAILED(hr) || !pRows || pRows->cRows != 1) break;

    // nProps is the number of columns in the recipient table
    int nProps = pRows->aRow[0].cValues;
    ULONG ulReceipType = 0;

    // loop through all the properties
    for (int ii = 0; ii < nProps; ii++) {

      ULONG ulPT = pRows->aRow[0].lpProps[ii].ulPropTag;
      
      switch (ulPT) {
      case PR_EMAIL_ADDRESS:
        // This is the email address
        szReceipEmail = pRows->aRow[0].lpProps[ii].Value.LPSZ;
        break;
      case PR_RECIPIENT_TYPE:
        // this is the recipient type: TO/CC/BCC
        ulReceipType = pRows->aRow[0].lpProps[ii].Value.ul;
        break;
      case PR_DISPLAY_NAME:
        // this is the display name
        szReceipName = pRows->aRow[0].lpProps[ii].Value.LPSZ;
        break;
      default:
        break;
      }  // switch
    }
  }


Category: [Outlook / Transport / MAPI]

====>SiteMap of this Blog<===




[ [permalink] ]

5 Comments:

At October 23, 2006 10:50 PM, Anonymous Anonymous said...

I am not able to retrive the recipient list through IMessage::GetRecipientTable().
It is returning MAPI_E_NO_RECIPIENTS.

For offlinen mails this is working fine.
Could you help me in finding the solution for this problem.

 
At October 23, 2006 10:52 PM, Anonymous Anonymous said...

I am not able to retrive the recipient list through IMessage::GetRecipientTable().
It is returning MAPI_E_NO_RECIPIENTS.

For offline mails this is working fine.
Could you help me in finding the solution for this problem.

 
At August 09, 2007 2:06 AM, Anonymous Anonymous said...

Hello Lao K,

I'm trying to add a menu item to the inbox of the email application on Pocket PC 2003 SE and higher. But, I'm wondering if it is actually possible. Is it? If possible, how to?
The purpose of this menu item is to grab information (subject, content, To, Cc, Bcc) of the selected or opened email and take this information to another application (a .NET application).
I hope you can help me and appreciate your effort!!
Thank you in advance,
Luk.

 
At December 21, 2007 3:11 AM, Anonymous Anonymous said...

Hi,
Great Work.. Great Article... Helped me a lot.
-ravi

 
At March 13, 2008 2:27 AM, Blogger Andy said...

I have similar code, but all the sudden I am getting MAPI_E_NO_RECIPIENTS. Is there some sort of direction to look next. The interesting thing is it worked for PPC 2003 and not now, but still works for Mobile 6.

 

Post a Comment

<< Home