This documentation is archived and is not being maintained.

How to: Create a Simple Mail Item

Last modified: October 10, 2010

Applies to: Office 2010 | Outlook 2010 | Visual Studio

MAPI can be used to create and send a message that requests a read receipt. When a read receipt is requested, the messaging system generates and returns a read report to the sender when the recipient opens the message.

For information about how to download, view, and run the code from the MFCMAPI application and CreateOutlookItemsAddin project referenced in this topic, see How to: Install the Samples Used in This Section.

To create and send a message requesting a read receipt

  1. Create an outgoing message. For information about how to create an outgoing message, see Handling an Outgoing Message.

  2. Add the PR_READ_RECEIPT_REQUESTED (PidTagReadReceiptRequested) property and set it to true.

  3. Add the PR_CONVERSATION_INDEX (PidTagConversationIndex) property.

  4. Add the PR_REPORT_TAG (PidTagReportTag) property.

  5. Send the message by calling the IMessage::SubmitMessage method.

The AddMail function in the Mails.cpp source file of the CreateOutlookItemsAddin project demonstrates these steps. The AddMail function takes parameters from the Add Mail dialog box that is displayed when you click the Add Mail command on the Addins menu in the MFCMAPI sample application. The DisplayAddMailDialog function in Mails.cpp displays the dialog box and passes the values from the dialog box to the AddMail function. The DisplayAddMailDialog function does not relate directly to creating a mail item using MAPI, so it is not listed here. The AddMail function is listed below.

Note that the lpFolder parameter passed to the AddMail method is a pointer to an IMAPIFolder interface that represents the folder where the new message will be created. Given the lpFolder parameter that represents an IMAPIFolder interface, the code calls the IMAPIFolder::CreateMessage method. The CreateMessage method returns a success code and a pointer to a pointer to an IMessage : IMAPIProp interface. Most of the AddMail function code handles the work of setting properties in preparation for calling the IMAPIProp::SetProps method. If the call to the SetProps method succeeds, a call to the IMAPIProp::SaveChanges method commits the changes to the store and creates a new mail item. Then, if requested, the IMessage::SubmitMessage method is called to send the message.

The AddMail function uses two helper functions to build values for the PR_CONVERSATION_INDEX and PR_REPORT_TAG properties: the BuildConversationIndex and AddReportTag functions. The BuildConversationIndex function, located in CreateOutlookItemsAddin.cpp, does the same work that the built-in MAPI ScCreateConversationIndex function does when a parent conversation index is not passed to it. The format of the conversation index buffer that these functions generate is documented in PidTagConversationIndex Canonical Property. The AddReportTag function, located in Mails.cpp, in turn calls the BuildReportTag function to build a structure for the PR_REPORT_TAG property. For information about the structure that the BuildReportTag function builds, see PidTagReportTag Canonical Property.

The following is the complete listing of the AddMail function.

            LPMAPIFOLDER lpFolder,
            LPWSTR szBody, // PR_BODY_W
            LPWSTR szRecipientName, // Recipient table
            BOOL bHighImportance, // PR_IMPORTANCE
            BOOL bReadReceipt, // PR_READ_RECEIPT_REQUESTED
            BOOL bSubmit,
            BOOL bDeleteAfterSubmit)
   if (!lpFolder) return MAPI_E_INVALID_PARAMETER;
   HRESULT hRes = S_OK;
   LPMESSAGE lpMessage = 0;

   // Create a message and set its properties
   hRes = lpFolder->CreateMessage(0,
   if (SUCCEEDED(hRes))
      // Because the properties to be set are known in advance, 
      // most of the structures involved can be statically declared 
      // to minimize expensive MAPIAllocateBuffer calls.
      SPropValue spvProps[NUM_PROPS] = {0};
      spvProps[p_PR_MESSAGE_CLASS_W].ulPropTag          = PR_MESSAGE_CLASS_W;
      spvProps[p_PR_ICON_INDEX].ulPropTag                 = PR_ICON_INDEX;
      spvProps[p_PR_SUBJECT_W].ulPropTag                = PR_SUBJECT_W;
      spvProps[p_PR_BODY_W].ulPropTag                   = PR_BODY_W;
      spvProps[p_PR_IMPORTANCE].ulPropTag               = PR_IMPORTANCE;
      spvProps[p_PR_MESSAGE_FLAGS].ulPropTag             = PR_MESSAGE_FLAGS;
      spvProps[p_PR_MSG_EDITOR_FORMAT].ulPropTag         = PR_MSG_EDITOR_FORMAT;
      spvProps[p_PR_MESSAGE_LOCALE_ID].ulPropTag         = PR_MESSAGE_LOCALE_ID;
      spvProps[p_PR_INTERNET_CPID].ulPropTag            = PR_INTERNET_CPID;
      spvProps[p_PR_CONVERSATION_INDEX].ulPropTag         = PR_CONVERSATION_INDEX;
      spvProps[p_PR_MESSAGE_CLASS_W].Value.lpszW = L"IPM.Note";
      spvProps[p_PR_ICON_INDEX].Value.l = 0x103; // Unsent Mail
      spvProps[p_PR_SUBJECT_W].Value.lpszW = szSubject;
      spvProps[p_PR_CONVERSATION_TOPIC_W].Value.lpszW = szSubject;
      spvProps[p_PR_BODY_W].Value.lpszW = szBody;
      spvProps[p_PR_IMPORTANCE].Value.l = bHighImportance?IMPORTANCE_HIGH:IMPORTANCE_NORMAL;
      spvProps[p_PR_READ_RECEIPT_REQUESTED].Value.b = bReadReceipt?true:false;
      spvProps[p_PR_MESSAGE_FLAGS].Value.l = MSGFLAG_UNSENT;
      spvProps[p_PR_MESSAGE_LOCALE_ID].Value.l = 1033; // (en-us)
      spvProps[p_PR_INETMAIL_OVERRIDE_FORMAT].Value.l = NULL; // Mail system chooses default encoding scheme
      spvProps[p_PR_DELETE_AFTER_SUBMIT].Value.b = bDeleteAfterSubmit?true:false;
      spvProps[p_PR_INTERNET_CPID].Value.l = cpidASCII;

      hRes = BuildConversationIndex(

      if (SUCCEEDED(hRes))
         hRes = lpMessage->SetProps(NUM_PROPS, spvProps, NULL);
         if (SUCCEEDED(hRes))
            hRes = AddRecipient(lpMAPISession,
            AddInLog(true,L"CallMenu: AddRecipient - returned hRes = 0x%08X\n",hRes);
            if (SUCCEEDED(hRes))
               if (bReadReceipt)
                  hRes = AddReportTag(lpMessage);

               if (SUCCEEDED(hRes))
                  hRes = lpMessage->SaveChanges(KEEP_OPEN_READWRITE);
                  if (SUCCEEDED(hRes) && bSubmit)
                     hRes = lpMessage->SubmitMessage(NULL);
      if (spvProps[p_PR_CONVERSATION_INDEX].Value.bin.lpb)
         delete[] spvProps[p_PR_CONVERSATION_INDEX].Value.bin.lpb;
   if (lpMessage) lpMessage->Release();
   return hRes;