How To Use CDOEX to Create, Configure, and Send a Message in VC++ (286037)



The information in this article applies to:

  • Microsoft Exchange 2000 Server
  • Collaboration Data Objects for Exchange 2000
  • Microsoft Visual C++, 32-bit Enterprise Edition 6.0
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • Microsoft Visual C++, 32-bit Learning Edition 6.0

This article was previously published under Q286037

SUMMARY

This article demonstrates how to send a MIME formatted message using Collaboration Data Objects for Exchange 2000 (CDOEX) in Visual C++. The sample code below builds a message with an HTML body, inline graphics, an attachment, and a custom MIME header. It also demonstrates how to request a delivery receipt.

MORE INFORMATION

To send a MIME formatted message using CDOEX, follow these steps:
  1. In Visual C++, create a new Win32 Application project.
  2. Add a new file called main.cpp and paste the following code:
    #include <stdio.h>
    #include <comdef.h>
    
    #include <cdoex.h>
    #include <cdoex_i.c>
    using namespace CDO;
    
    #define CHECKHRES(hRes) (CheckHRes(hRes,"",__FILE__,__LINE__))
    
    BOOL CheckHRes(HRESULT hRes,char *szErrorMsg,char *szFile,int iLine);
    
    HRESULT DoCDOEX();
    
    HRESULT SetField(ADOFields* pFields,VARIANT FieldName,VARIANT Value);
    
    void main(void)
    {
       DoCDOEX();
    }
    
    HRESULT DoCDOEX()
    {
       HRESULT  hRes = S_OK;
       IConfiguration *pConfiguration = NULL;
       IMessage *pMsg = NULL;
       Fields *pConfigFields = NULL;
       Fields *pMessageFields = NULL;
       IBodyPart *pAttach1 = NULL;
       IBodyPart *pAttach2 = NULL;
       IBodyPart *pHTML = NULL;
       char szHTML[1024];
    
       //TODO: Modify the following strings to match 
       //valid addresses and files on your system.
       _variant_t vFrom = "Administrator@mydomain.com";
       _variant_t vTo = "Administrator@mydomain.com";
       _variant_t vCC = (_bstr_t)"user1@mydomain.com;user2@mydomain.com";
       _variant_t vGIFPath = "c://mygif.gif";
       _variant_t vGIFName = "mygif.gif";
       _variant_t vBMPPath = "c://mybmp.bmp";
    
    
    
       hRes = CoInitialize(NULL);
    
       hRes = CoCreateInstance(
          CLSID_Message,
          NULL,
          CLSCTX_INPROC_SERVER,
          IID_IMessage,
          (void**)&pMsg);
       if (!CHECKHRES(hRes)) goto Cleanup;
          
       hRes = CoCreateInstance(
          CLSID_Configuration,
          NULL,
          CLSCTX_INPROC_SERVER,
          IID_IConfiguration,
          (void**)&pConfiguration);
       if (!CHECKHRES(hRes)) goto Cleanup;
    
       if (pMsg && pConfiguration)
       {
          //First, we set our configuration options on the message.
          hRes = pConfiguration->get_Fields(&pConfigFields);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //Declare that we want this mail sent through Exchange.
          hRes = SetField(
             pConfigFields,
             (_variant_t)cdoSendUsingMethod,
             (_variant_t)(LONG)cdoSendUsingExchange);
          if (!CHECKHRES(hRes)) goto Cleanup;
          
          //We must set this to a valid mailbox on the Server.
          //If the mailbox does not exist, 
          //  we get error CDO_E_BAD_SENDER = 0x80040233.
          //If we don't have permission to use this mailbox, 
          //  we get 0x80070005 - Access Denied.
          hRes = SetField(
             pConfigFields,
             (_variant_t)cdoSendEmailAddress,
             vFrom);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //This can be set to any address, valid or not.
          //Usually it is the same as cdoSenEmailAddress.
          hRes = SetField(
             pConfigFields,
             (_variant_t)cdoSendUserReplyEmailAddress,
             vFrom);
          if (!CHECKHRES(hRes)) goto Cleanup;
          
          hRes = pConfigFields->Update();
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          hRes = pMsg->put_Configuration(pConfiguration);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
    //Now we can address the mail.
    
          //The following call duplicates setting cdoSendEmailAddress.
    //      hRes = pMsg->put_From((_bstr_t)vFrom);
    //      if (!CHECKHRES(hRes)) goto Cleanup;
    
          //To and CC are ';' delimited strings.
          hRes = pMsg->put_To((_bstr_t)vTo);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          hRes = pMsg->put_CC((_bstr_t)vCC);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //TODO: Uncomment this to request a read receipt.
    //      hRes = pMsg->put_MDNRequested((_variant_t)true);
    //      if (!CHECKHRES(hRes)) goto Cleanup;
    
          hRes = pMsg->put_Subject((_bstr_t)"This is a subject!");
          if (!CHECKHRES(hRes)) goto Cleanup;
    
    
    //Now, we create the message body and attachments.
    
          //TODO: To generate an HTMLBody directly from a web page, 
          //use this call instead of the put_HTMLBody 
          //and AddRelatedBodyPart calls.
    //      hRes = pMsg->CreateMHTMLBody(
    //         (_bstr_t)"http://www.microsoft.com",
    //         cdoSuppressNone,
    //         NULL,
    //         NULL);
    //      if (!CHECKHRES(hRes)) goto Cleanup;
    
          sprintf(szHTML,
             "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">" 
             "<HTML>"
             "  <HEAD>"
             "    <TITLE>This is a title</TITLE>"
             "  </HEAD>"
             "  <BODY>"
             "   <p>This is a lovely photograph I took while "
             "I was vactioning in Kauai.</p>"
             "   <p><IMG src=\"%s\"></p>"
             "   <p>My Picture</p>" 
             "  </BODY>"
             "</HTML>",
             (char *)(_bstr_t)vGIFName);
    
          hRes = pMsg->put_HTMLBody((_bstr_t)szHTML);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          hRes = pMsg->AddRelatedBodyPart(
             (_bstr_t)vGIFPath,
             (_bstr_t)vGIFName,
             cdoRefTypeLocation,
             NULL,
             NULL,
             &pAttach1);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //Add an extra attachment.
          hRes = pMsg->AddAttachment((_bstr_t)vBMPPath,NULL,NULL,&pAttach2);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //Add some keywords.
          hRes = pMsg->put_Keywords((_bstr_t)"frog,blender");
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          hRes = pMsg->get_Fields(&pMessageFields);
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //TODO: Uncomment this to request a delivery reciept.
          /*
          hRes = SetField(
               pMessageFields,
             (_variant_t)"http://schemas.microsoft.com/exchange/deliveryreportrequested",
               (variant_t)true);
            if (!CHECKHRES(hRes)) goto Cleanup;
          */ 
    
          //Let's add a custom header value here.
          hRes = SetField(
             pMessageFields,
             (_variant_t)"urn:schemas:mailheader:MyCustomHeader",
             (variant_t)"MyValue");
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          hRes = pMessageFields->Update();
          if (!CHECKHRES(hRes)) goto Cleanup;
    
          //Send the message.
          hRes = pMsg->Send();
          if (!CHECKHRES(hRes)) goto Cleanup;
    
       }
    
    Cleanup:
       if (pHTML) pHTML->Release();
       if (pConfigFields) pConfigFields->Release();
       if (pMessageFields) pMessageFields->Release();
       if (pAttach1) pAttach1->Release();
       if (pAttach2) pAttach2->Release();
       if (pConfiguration) pConfiguration->Release();
       if (pMsg) pMsg->Release();
    
       CoUninitialize();
       return hRes;
    }
    
    HRESULT SetField(ADOFields* pFields,VARIANT FieldName,VARIANT Value)
    {
       HRESULT hRes = S_OK;
       Field *pField = NULL;
    
       hRes = pFields->get_Item(FieldName,&pField);
       if (!CHECKHRES(hRes)) goto Cleanup;
       hRes = pField->put_Value(Value);
       if (!CHECKHRES(hRes)) goto Cleanup;
       if (pField) pField->Release();
       pField = NULL;
    Cleanup:
       return hRes;
    }
    
    BOOL CheckHRes(HRESULT hRes,char *szErrorMsg,char *szFile,int iLine)
    {
       if (FAILED(hRes))
       {
          printf(
             "%s\nhRes = %x\nIn file %s\nOn line %d",
             szErrorMsg,
             hRes,
             szFile,
             iLine);
       }
       return SUCCEEDED(hRes);
    }
    					
  3. Update the "TODO" sections of the code as appropriate.
  4. Compile and execute the project.
  5. Check the recipient's mailbox to see that the message was sent.

Modification Type:MinorLast Reviewed:8/25/2005
Keywords:kbhowto KB286037