none
MAPI: Set From Address in message after CreateMessage RRS feed

  • Question

  • Greetings,

    I am working on an C++ MFC Application, where a MAPI Integration is implemented. I am fetching Emails from Outlook, but also open, Forward and send emails.

    Until now we used only Outlook 2010. The user have several Exchange accounts connected and Monitors therefore different mail accounts. The user sets one of the mail accounts as "Main Account" in the application. If he sends an email from the application this "Main Account"-Address should be used as from address.

    With Outlook 2010 I opened, the corresponding outbox (OpenMsgStore) afterwards I create a message (CreateMessage from this outbox) set the properties, no sending address is set, addes attachments and SubmitMessage on the message itself.

    With changing to Outlook 2013 we saw, that the sending address is not set accordingly to the opened Outbox. It stays always the same. In some cases not even the personal accounts  address is used, the senders adress seems then to be randomly choosen.

    maybe someone knows the solution to set the from address?

    Help would be really appreciated, because now my users cannot really fit in the role without proper Senders Address in their mail.

    Kind regards

    Wolfgang

    OpenMsgStore

    OpenMsgStore)

    Thursday, September 10, 2015 11:28 AM

All replies

  • What code exactly do you use for creating and sending emails?

    Did you try to use OOM? Do you get the same results?

    Thursday, September 10, 2015 11:32 AM
  • What do you see in OutlookSpy or MFCMAPI for the messages in the Sent Items folder? Are messages created in the Outbox of the primary mailbox? Are other accounts opened as delegate Exchange stores?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, September 10, 2015 11:56 AM
  • void CAOMMapi::OpenOutbox() {
    	if (m_lpMAPISession!=NULL) {
    		if (m_lpMDB==NULL && m_vctMessageStoreEntryId[m_nStoreIndex]!=NULL && m_vctMessageStoreEntryId[m_nStoreIndex]->m_psBinaryEntryId!=NULL) {
    			if (SUCCEEDED(m_lpMAPISession->OpenMsgStore(0, m_vctMessageStoreEntryId[m_nStoreIndex]->m_psBinaryEntryId->cb, 
    				(LPENTRYID) m_vctMessageStoreEntryId[m_nStoreIndex]->m_psBinaryEntryId->lpb, NULL, MAPI_BEST_ACCESS, /*(LPMDB*) &lpMAPIProp*/&m_lpMDB))) {
    					
    				LPSPropValue lppPropArray = NULL;
    				ULONG cValues = 0;
    				m_lpOutbox= NULL;
    				//SizedSPropTagArray(2, rgTags) = {2,{PR_IPM_OUTBOX_ENTRYID, PR_OBJECT_TYPE}};
    				//// Now get the Drafts folder
    				//HRESULT hr = m_lpMDB->GetProps((LPSPropTagArray)&rgTags, MAPI_UNICODE, &cValues, &rgprops);
    				SizedSPropTagArray(2,sTags) = {2,	PR_IPM_OUTBOX_ENTRYID,PR_DISPLAY_NAME };
    
    				HRESULT hr = m_lpMDB->GetProps((LPSPropTagArray)&sTags,0,&cValues,&lppPropArray);
    				if(SUCCEEDED(hr) && lppPropArray != NULL) {
    					ULONG ulObjType=0;
    					hr = m_lpMDB->OpenEntry(lppPropArray[0].Value.bin.cb,
    					(LPENTRYID)lppPropArray[0].Value.bin.lpb, NULL, MAPI_MODIFY,
    					&ulObjType, (LPUNKNOWN*)&m_lpOutbox);
    					if (FAILED(hr)) {
    						CString strErrorMsg;
    						strErrorMsg.Format(IDS_ERROR_EMAIL_OPEN_OUTBOX,hr);
    						OutputError(strErrorMsg);
    					} else {
    						LPSPropValue lppPropArrayFolder = NULL;
    						SizedSPropTagArray(1,sTagsFolder) = {1,	PR_DISPLAY_NAME };
    						HRESULT hr = m_lpMDB->GetProps((LPSPropTagArray)&sTagsFolder,0,&cValues,&lppPropArrayFolder);
    						if(SUCCEEDED(hr) && lppPropArrayFolder != NULL) {
    												}
    					}
    					MAPIFreeBuffer(lppPropArray);
    				}
    			}
    		}
    	}
    }

    and to send:

    bool CAOMMapi::SendMail( CSendData* pSendData, CString cstrBody, std::vector<CString> vctAttachmentFiles/*=std::vector<CString>()*/, bool bOutlookForceSend/*=true*/) {
    	ASSERTION( pSendData != NULL ) return false;
    	bool retVal=false;
    	if (m_lpOutbox==NULL) {
    		OpenOutbox(); 
    	} 
    	if (m_lpOutbox!=NULL) {
    		IMessage *pNewMessage = NULL;
    
    		HRESULT hr = m_lpOutbox->CreateMessage(NULL, 0, &pNewMessage);
    		if(SUCCEEDED(hr) && pNewMessage!=NULL) {
    			//ENTRYID l_SentItemEntryId=GetSentItemsEntryId();
    			std::vector<CMapiAttachmentInfo> l_vctAttachmentInfo;
    			enum {SUBJECT, CLASS, /*BODY, *//*BODYHTML, */MSG_MOVE, EDITORFORMAT/*MSG_DEL*/, /*EMAIL_ADDRESS, */SENDER_NAME, MSG_PROPS };
    			LPSPropValue pPropValId=NULL;
    			hr = HrGetOneProp((LPMAPIPROP) m_lpMDB, PR_IPM_SENTMAIL_ENTRYID, &pPropValId);
    			if (SUCCEEDED(hr) && pPropValId!=NULL) {
    				CString cstrBodyHTML;
    				if( VollFormatHTML == (MeldungsFormat)theApp.m_ParameterStore.Get_DWORD( CParameterStore::dwEMoniMessageFormat )) {
    					cstrBodyHTML=cstrBody;
    				}
    				//  Message properties tag array
    				SPropValue lpPropValueArray2[MSG_PROPS];
    
    				lpPropValueArray2[SUBJECT].ulPropTag = PR_SUBJECT;
    				CString str = pSendData->GetSubject();
    				lpPropValueArray2[SUBJECT].Value.lpszW = str.GetBuffer();
    
    				lpPropValueArray2[CLASS].ulPropTag = PR_MESSAGE_CLASS;
    				lpPropValueArray2[CLASS].Value.lpszW = _T("IPM.Note");
    [BODYHTML].Value.lpszW = cstrBodyHTML.GetBuffer();
    				lpPropValueArray2[EDITORFORMAT].ulPropTag = PR_MSG_EDITOR_FORMAT;
    				if (cstrBodyHTML.IsEmpty()) {
    					lpPropValueArray2[EDITORFORMAT].Value.l = EDITOR_FORMAT_PLAINTEXT;
    				} else {
    					lpPropValueArray2[EDITORFORMAT].Value.l = EDITOR_FORMAT_RTF;
    				}
    				//lpPropValueArray2[MSG_DEL].ulPropTag = PR_DELETE_AFTER_SUBMIT;
    				//lpPropValueArray2[MSG_DEL].Value.b = FALSE;
    				lpPropValueArray2[MSG_MOVE].ulPropTag = PR_SENTMAIL_ENTRYID;
    				lpPropValueArray2[MSG_MOVE].Value.bin.cb = pPropValId->Value.bin.cb;
    				lpPropValueArray2[MSG_MOVE].Value.bin.lpb = pPropValId->Value.bin.lpb;
    				lpPropValueArray2[SENDER_NAME].ulPropTag = PR_SENDER_NAME;
    				lpPropValueArray2[SENDER_NAME].Value.lpszW = _T("Test@test.com");
    				_DbgLog0(_T("CAOMMapi::SendMail AddRecipients"));
    				AddRecipients(pNewMessage, pSendData);
    				for (size_t index=0; index<vctAttachmentFiles.size(); index++) {
    					CMapiAttachmentInfo l_AttachmentInfo;
    					l_AttachmentInfo.m_cstrFileName=vctAttachmentFiles[index];
    					l_vctAttachmentInfo.push_back(l_AttachmentInfo);
    				}
    				AddAttachments(pNewMessage, l_vctAttachmentInfo);
    				if (SUCCEEDED(hr = pNewMessage->SetProps(MSG_PROPS,lpPropValueArray2,NULL))) {
    					SetBody(pNewMessage, cstrBody, cstrBodyHTML);
    					if (SUCCEEDED(hr = pNewMessage->SubmitMessage(FORCE_SUBMIT))) {
    						retVal=true;
    					} else {
    						LPTSTR lpBuffer;
    						CString cstrError;
    						cstrError.Format(_T("CAOMMapi::SendMail error Submit Message 0x%x"), hr);
    						_DbgLog0(cstrError);
    						if(!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    								NULL,  hr,
    								MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
    								(LPTSTR) &lpBuffer, 0, NULL)) {
    							cstrError.Format(_T("Err=0x%x (Windows Fehlertext ist nicht vorhanden.)"), hr);
    						} else {
    							cstrError.Format(_T("%s"), lpBuffer);
    							LocalFree(lpBuffer);
    						}
    						_DbgLog0(cstrError);
    					}
    				}
    				if (pNewMessage!=NULL) {
    					pNewMessage->Release();
    					pNewMessage=NULL;
    				}
    				if (bOutlookForceSend) {
    					_DbgLog0(_T("CAOMMapi::SendMail OutlookForceSend"));
    					OutlookForceSend();
    				}
    			}
    		}
    	}
    	CloseOutbox();
    	return retVal;
    }
    Sorry my dumb question, what's OOM?

    Thursday, September 10, 2015 2:56 PM
  • OOM = Outlook Object Model. Why are you setting the PR_SENDER_NAME property?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, September 10, 2015 3:01 PM
  • Hello,

    thanks for both fast answers.

    I have 3 accounts open in Outlook 2 on the same Exchange Server, one in a remote Company. I use my private and the second "local" Exchange account to send the mails

    when I use the second account i see in Outlook-Outbox that the mail is created there, and send a few seconds later. But in the send mail the from address is my personal mail address.

    With mfcmapi I have the same behaviour, and may I ask where I can get OutlookSpy?

    regards

    WOlfgang

    Thursday, September 10, 2015 3:02 PM
  • OutlookSpy is at http://www.dimastr.com/outspy/home.htm

    Try to comment out the code that sets the sender name and call SaveChanges instead of Submit.
    Are any sender properties present?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, September 10, 2015 3:15 PM
  • Ah Forgot to remove the PR_SENDER_NAME, it was just a test, as you surely assumed, I call a SaveChange and post the results in a second (or minite ;) )
    Friday, September 11, 2015 6:11 AM
  • Ok the Minute took longer (with the help of  some interrruptions)

    I implemented following code:

    					if (SUCCEEDED(hr = pNewMessage->SaveChanges(KEEP_OPEN_READWRITE))) {
    						SizedSPropTagArray(3,msgProps) = {3, PR_SENDER_ADDRTYPE, PR_SENDER_EMAIL_ADDRESS, PR_SENDER_NAME};
    						ULONG l_lRowCount=0, l_lRowIndex=0;
    						LPSPropValue	lpPropArray=NULL;
    						hr = pNewMessage->GetProps((LPSPropTagArray)&msgProps, MAPI_UNICODE, &l_lRowCount, &lpPropArray);
    						if (SUCCEEDED(hr) && lpPropArray!=NULL) {
    							for (l_lRowIndex=0; l_lRowIndex<l_lRowCount; l_lRowIndex++) {
    								switch (lpPropArray[l_lRowIndex].ulPropTag) {
    								case PR_SENDER_ADDRTYPE:
    									_DbgLog0(_T("PR_SENDER_ADDRTYPE"));
    									break;
    								case PR_SENDER_EMAIL_ADDRESS:
    									_DbgLog0(_T("PR_SENDER_EMAIL_ADDRESS"));
    									break;
    								case PR_SENDER_NAME:
    									_DbgLog0(_T("PR_SENDER_NAME"));
    									break;
    								}
    								_DbgLog0(CString(lpPropArray[l_lRowIndex].Value.lpszW));
    							}
    						}
    						retVal=true;
    					} else {
    						LPTSTR lpBuffer;
    						CString cstrError;
    						cstrError.Format(_T("CAOMMapi::SendMail error SaveChanges 0x%x"), hr);
    						_DbgLog0(cstrError);
    						if(!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    								NULL,  hr,
    								MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
    								(LPTSTR) &lpBuffer, 0, NULL)) {
    							cstrError.Format(_T("Err=0x%x (Windows Fehlertext ist nicht vorhanden.)"), hr);
    						} else {
    							cstrError.Format(_T("%s"), lpBuffer);
    							LocalFree(lpBuffer);
    						}
    						_DbgLog0(cstrError);
    					}
    


    interesstingly SaveChanges executed ok, but i got no Properties-Strings for the given parameters, I also tried

    #define PR_SENDER_SMTP_ADDRESS			PROP_TAG( PT_TSTRING,	0x5D01)
    #define PR_SENDER_SMTP_ADDRESS_W		PROP_TAG( PT_UNICODE,	0x5D01)
    #define PR_SENDER_SMTP_ADDRESS_A		PROP_TAG( PT_STRING8,	0x5D01)
    #define PR_SENDING_SMTP_ADDRESS			PROP_TAG( PT_TSTRING,	0x5D09)
    #define PR_SENDING_SMTP_ADDRESS_W		PROP_TAG( PT_UNICODE,	0x5D09)
    #define PR_SENDING_SMTP_ADDRESS_A		PROP_TAG( PT_STRING8,	0x5D09)
    

    I tried to read this values from the OutlookSpy, which looks really great! THanks for the tip

    Nevertheless it seems I am missing something... Maybe you have an Idea?

    thanks
    Wolfgang

    Friday, September 11, 2015 9:02 AM
  • Greetings,

    after some days working on other Problems, the From-address Problem has shifted somehow,

    the user will have a lot of messageboxes allowed and connected. I fetch the mails from one Mailbox, but must Forward/reply them from "another" address. This new From-Address ist noch currently an opened Mailbox in Outlook.

    Is there a way to do this with MAPI and Outlook?

    Regards

    Wolfgang

    Tuesday, September 15, 2015 8:25 AM