How To Create a Message With an Attachment and Send It Using MAPI/VC++ (200174)



The information in this article applies to:

  • Microsoft Extended Messaging Application Programming Interface (MAPI)

This article was previously published under Q200174

SUMMARY

This article demonstrates how to make and send a message. It also shows how to add an attachment to the message that is to be sent.

MORE INFORMATION

The following code creates a MAPI session, logs on to the private message store, creates a new message, sets properties on the message, and then sends it.

The recipient for the message is selected from the typical address dialog box displayed by Exchange or Outlook mail clients.

The following code has been compiled using the Ignore all default libraries option on the Link tab of the project Settings dialog box. The following libraries must be used as well:
  • Mapi32.lib
  • Version.lib
  • Edkdebug.lib
  • Edkmapi.lib
  • Edkutils.lib
  • Addrlkup.lib
  • Edkguid.lib
  • Rulecls.lib
  • Msvcrt.lib
#include <edk.h>
HRESULT SetMessageProp ( LPMAPISESSION m_pSession,
                        LPMESSAGE lpMessage);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR pszCmd,
                   int nCmdShow)
{
   // Load strings, and register window classes.
   LPMDB           lpStore     = NULL;
   LPMAPISESSION   lpSession   = NULL;
   LPMESSAGE       lpMessage   = NULL;
   HRESULT         hr          = NULL;
   ULONG           cbEntryID   = 0;
   LPENTRYID       lpEntryID   = NULL;
   LPCIID          lpInterface = NULL;
   ULONG           ulFlags     = MAPI_BEST_ACCESS;
   ULONG           ulObjType   = 0;
   LPMAPIFOLDER    lpFolder    = NULL;
   ULONG           cbEIDFolder = 0;
   LPENTRYID       lpEIDFolder = NULL;
   CHAR            szFolder[MAX_PATH + 1] = {0};

   hr = MAPIInitialize(NULL);
   if (FAILED(hr))
   {
     return 1;
   }
   hr = MAPILogonEx(0,"", NULL,
                 MAPI_LOGON_UI | MAPI_NEW_SESSION |  MAPI_EXPLICIT_PROFILE,
                 &lpSession);

   if (FAILED(hr))
   {
      MessageBox(NULL,"MAPI Logon failed",NULL,MB_OK);
      goto cleanup;
   }

   if (FAILED(hr = HrOpenExchangePrivateStore(lpSession,&lpStore)))
   {
      MessageBox(NULL,"Message Store Not Opened",NULL,MB_OK);
      goto cleanup;
   }

   strcpy(szFolder, "Top of Information Store\\Outbox");
   hr = HrMAPIOpenFolderEx (lpStore,'\\',szFolder,&lpFolder);
   if (FAILED(hr))
   {
      MessageBox(NULL,"Outbox Could Not Be Opened",NULL,MB_OK);
      goto cleanup;
   }

   if (FAILED(hr = lpFolder->CreateMessage(NULL, MAPI_DEFERRED_ERRORS,               &lpMessage)))
   {
      MessageBox(NULL,"CreateMessage Fail",NULL,MB_OK);
      goto cleanup;
   }

   if (FAILED(hr = SetMessageProp(lpSession, lpMessage)))
      goto cleanup;

cleanup:

   if ( NULL != lpMessage )
   {
       lpMessage ->Release ( );
       lpMessage = NULL;
   }

   if (NULL != lpFolder)
   {
      lpFolder->Release();
      lpFolder = NULL;
   }
   if (lpSession)
   {
      lpSession->Logoff(0, 0, 0);
      ULRELEASE(lpSession);
   }
   MAPIUninitialize();
   return 0;
}

HRESULT SetMessageProp ( LPMAPISESSION lpSession,
                         LPMESSAGE lpMessage)
{
   HRESULT hr = S_OK;
   enum {SUBJECT, CLASS, BODY, MSG_DEL, MSG_PROPS };
   LPADRBOOK        lpAdrBook = NULL;
   LPADRLIST        lpAdrList = NULL;
   LPATTACH             pAtt      = NULL;
   ULONG              ulAttNum;

   //  Display Address Dialog

   if (FAILED(hr = lpSession->OpenAddressBook(0L,NULL,0,&lpAdrBook)))
      goto Quit;

    LPSTR    rglpszDestTitles[1];
    ULONG    rgulDestComps[1];
    ULONG   m_hWnd1;
    rglpszDestTitles[0]        = "To";
    rgulDestComps[0]           = MAPI_TO;
    ADRPARM  adrparm;
    adrparm.cbABContEntryID    = 0;
    adrparm.lpABContEntryID    = NULL;
    adrparm.ulFlags            = DIALOG_MODAL;
    adrparm.lpReserved         = NULL;
    adrparm.ulHelpContext      = 0;
    adrparm.lpszHelpFileName   = NULL;
    adrparm.lpfnABSDI          = NULL;
    adrparm.lpfnDismiss        = NULL;
    adrparm.lpvDismissContext  = NULL;
    adrparm.lpszCaption        = "MAPI Dialog";
    adrparm.lpszNewEntryTitle  = "For this test dialog";
    adrparm.lpszDestWellsTitle = "Selected Recipients:";
    adrparm.cDestFields        = 0xffffffff;
    adrparm.nDestFieldFocus    = 0;
    adrparm.lppszDestTitles    = NULL;
    adrparm.lpulDestComps      = NULL;
    adrparm.lpContRestriction  = NULL;
    adrparm.lpHierRestriction  = NULL;
    m_hWnd1 = 0;

   if (FAILED(hr = lpAdrBook->Address(&m_hWnd1,&adrparm,&lpAdrList)))
      goto Quit;

//  Message properties tag array
   SPropValue lpPropValueArray2[MSG_PROPS];
   lpPropValueArray2[SUBJECT].ulPropTag = PR_SUBJECT;
   lpPropValueArray2[SUBJECT].Value.lpszA = "Testing IPM With Attachments";

// TO DO:Change this to your custom form class

   lpPropValueArray2[CLASS].ulPropTag = PR_MESSAGE_CLASS;
   lpPropValueArray2[CLASS].Value.lpszA = "IPM.Note";
   lpPropValueArray2[BODY].ulPropTag = PR_BODY;
   lpPropValueArray2[BODY].Value.lpszA = "Custom Text For Message";
   lpPropValueArray2[MSG_DEL].ulPropTag = PR_DELETE_AFTER_SUBMIT;
   lpPropValueArray2[MSG_DEL].Value.b = TRUE;

   if (FAILED(hr = lpMessage->ModifyRecipients(MODRECIP_ADD,lpAdrList)))
      goto Quit;

   if (FAILED(hr = lpMessage->CreateAttach( NULL, (ULONG)0, &ulAttNum,        &pAtt)))
      goto Quit;
   {

      enum {METHOD,RENDERING,PATH, FILENAME, DISPLAYNAME, NUM_ATT_PROPS};
      SPropValue    spvAttach[NUM_ATT_PROPS];
      spvAttach[METHOD].ulPropTag = PR_ATTACH_METHOD;
      spvAttach[METHOD].Value.l = ATTACH_BY_REFERENCE;

      spvAttach[RENDERING].ulPropTag = PR_RENDERING_POSITION;
      spvAttach[RENDERING].Value.l = -1;

      spvAttach[PATH].ulPropTag = PR_ATTACH_PATHNAME;
      spvAttach[PATH].Value.lpszA ="\\\\<server>\\<share>\\code.txt";

      spvAttach[FILENAME].ulPropTag = PR_ATTACH_FILENAME;
      spvAttach[FILENAME].Value.lpszA = "code.txt";

      spvAttach[DISPLAYNAME].ulPropTag = PR_DISPLAY_NAME;
      spvAttach[DISPLAYNAME].Value.lpszA = "Great code.txt";

      // Save the properties we have set on the attachment
      if (FAILED(hr = pAtt ->SetProps(
            NUM_ATT_PROPS,
            (LPSPropValue)&spvAttach,
            NULL)))
         goto Quit;

      if (FAILED(hr = pAtt->SaveChanges(0)))
         goto Quit;

   }

   if (FAILED(hr = lpMessage->SetProps(MSG_PROPS,lpPropValueArray2,NULL)))
      goto Quit;

   if (FAILED(hr = lpMessage->SubmitMessage(0L)))
      goto Quit;

   // Clean up and release all objects no longer needed in this
   // method. Be sure to return the value of hr to the caller.

Quit:

   if ( NULL != lpAdrBook )
   {
       lpAdrBook ->Release ( );
       lpAdrBook = NULL;
   }

   if ( NULL != lpAdrList )
   {
       MAPIFreeBuffer(lpAdrList);
       lpAdrList = NULL;
   }

   if ( NULL != pAtt )
   {
       pAtt ->Release ( );
       pAtt = NULL;
   }

   return hr;


}

Modification Type:MinorLast Reviewed:8/25/2005
Keywords:kbFAQ kbhowto kbMsg KB200174 kbAudDeveloper