The SPropValue structure aggregates the information that defines a MAPI property (in MAPI, an SPropValue object is a property). It contains both the name of the property (in the form of a property tag), and its value. You can also use a SPropValue structure to hold several MAPI properties—by treating it as an array, and indexing into it by using a subscript. For more information, see the code example below.


struct { 
  ULONG     ulPropTag;
  ULONG     dwAlignPad;
  union _PV Value;
} SPropValue, FAR *LPSPropValue;


  • ulPropTag
    Property tag for the property. Property tags are codes expressed as 32-bit unsigned integers, that contain the property's unique identifier (Property ID) in the high-order 16 bits, and the property's Type in the low-order 16 bits.

    For example, consider the "Importance" message envelope property. Its Property ID is 0x0017, and its Data Type is PT_LONG (which maps to a hexadecimal value of 0003). Its Property Tag is a combination of these two: 0x00170003. This hexadecimal value is defined as the constant PR_IMPORTANCE, in the mapitags.h header file.

    For a list of all of the possible data types, see MAPI Property Data Types. For a mapping of data types to their associated numerical values, look in the file mapidefs.h. For a list of values that can be used for many common MAPI properties, look in the file mapitags.h.

  • dwAlignPad
    Reserved for MAPI—do not use.
  • Value
    The value of the property. This information is contained in a PV union. The member of the union that is used is dictated by the property tag, which contains the property's type in the low-order 16 bits.

    For a list of all of the possible union members, see MAPI Property Data Types.


SPropValue is the structure tag that names the structure definition, and is used to declare variables of type SPropValue. LPSPropValue is another structure tag, and it is used to declare pointers to variables of type SPropValue.

When you treat a SPropValue structure as an array to hold several MAPI properties, CE MAPI automatically creates a variable of type SPropTagArray, which is a structure that aggregates an array of LPSPropValue pointers, along with their count.

Property Identifier values are group into ranges, which group MAPI properties according to the way they are used. For more information, see the Remarks section in MAPI Properties.

The Type indicates the format for the property's value. In the MAPIDefs.h header file, MAPI defines constants for each of the property types that it supports.

The dwAlignPad member is used as padding to ensure proper alignment on computers that require 8-byte alignment for 8-byte values. Developers who write code on such computers should use memory allocation routines that allocate the SPropValue arrays on 8-byte boundaries.


The following code example demonstrates how to you can set and add MAPI properties to a message by using a pointer an SPropValue structure (an LPSPropValue).

HRESULT DemoMAPIProps(IMessage * pMsg)
   HRESULT                    hr = E_FAIL;
   LPSPropValue rgpMsgProperties = NULL;  // A structure for holding a MAPI property. This is treated as an array of MAPI properties.
   int          cbMsgProperties  = 0;     // The size of the array of properties (measured as a count of bytes).
   int          cMsgProperties   = 4;     // The number of properties for the message (for example, four)
   LPWSTR       pszSubject       = L"This is actually a MAPI message";

   cbMsgProperties = sizeof(SPropTagArray) + 
                        cMsgProperties * (sizeof(SPropValue) + 
                            (wcslen(pszSubject) + 3) * sizeof(WCHAR));

   hr = MAPIAllocateBuffer(cbMsgProperties, (LPVOID FAR *)&rgpMsgProperties);  // Allocate memory for the properties.
   memset(rgpMsgProperties, 0, cbMsgProperties);                               // Erase the allocated memory.

   rgpMsgProperties[0].ulPropTag   = PR_SUBJECT;   // Set values for the properties.
   rgpMsgProperties[0].Value.lpszW = pszSubject;

   rgpMsgProperties[1].ulPropTag   = PR_MESSAGE_FLAGS;
   rgpMsgProperties[1].Value.ul    = MSGFLAG_FROMME | MSGFLAG_UNSENT;

   rgpMsgProperties[2].ulPropTag   = PR_MSG_STATUS;
   rgpMsgProperties[2].Value.ul    = MSGSTATUS_RECTYPE_SMTP;

   rgpMsgProperties[3].ulPropTag   = PR_IMPORTANCE;
   rgpMsgProperties[3].Value.ul    = IMPORTANCE_HIGH;

   hr = pMsg->SetProps(cMsgProperties, rgpMsgProperties, NULL);  // Add the properties to the message.
   hr = MAPIFreeBuffer((void *)rgpMsgProperties);                // Free resources.

   // The body of the message must be streamed into the property, since it can be so large.
   LPSTREAM pStream = NULL; // A pointer to an IStream interface.
   hr = pMsg->OpenProperty(PR_BODY, NULL, 0, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN *)&pStream);

   LPWSTR pszBody  = L"Text in Body of Message.";
   ULONG cbBody    = 0;
   ULONG cbWritten = 0;

   cbBody = (wcslen(pszBody) + 1) * sizeof(WCHAR);
   hr = pStream->Write(pszBody, cbBody, &cbWritten);

   pStream = NULL;

   hr = pMsg->SubmitMessage(0);

   pMsg = NULL;

   hr = S_OK;
   return hr;

Notice how using brackets allows you to treat the structure as a collection of properties. Also notice how to combine multiple flag values to set the PR_MESSAGE_FLAGS property.


Header mapidefs.h
Windows Embedded CE Windows CE 3.0 and later
Windows Mobile Pocket PC 2002 and later, Smartphone 2002 and later

External Resources

For a list of all the possible data types, see MAPI Property Data Types.

For a mapping of data types to their associated numerical values (as used in Property Tags), look in the header file mapidefs.h.

For a list of values that can be used for many common MAPI properties, look in the file header mapitags.h.


See Also


MAPI Structures

Other Resources