mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
562 lines
16 KiB
C++
562 lines
16 KiB
C++
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// File: MAPIMessage.cpp
|
|
// Description: MAPI Message class wrapper
|
|
//
|
|
// Copyright (C) 2005-2011, Noel Dillabough
|
|
//
|
|
// This source code is free to use and modify provided this notice remains intact and that any enhancements
|
|
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
|
|
//
|
|
// Usage: see the CodeProject article at http://www.codeproject.com/internet/CMapiEx.asp
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "MAPIExPCH.h"
|
|
#include "MAPIEx.h"
|
|
|
|
#include <IMessage.h>
|
|
|
|
const GUID CLSID_MailMessage={ 0x00020D0B, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
// CMAPIMessage
|
|
|
|
CMAPIMessage::CMAPIMessage()
|
|
{
|
|
m_pRecipients=NULL;
|
|
}
|
|
|
|
CMAPIMessage::~CMAPIMessage()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
BOOL CMAPIMessage::Open(CMAPIEx* pMAPI, SBinary entryID)
|
|
{
|
|
if(!CMAPIObject::Open(pMAPI,entryID)) return FALSE;
|
|
|
|
GetPropertyString(PR_SENDER_NAME, m_strSenderName);
|
|
FillSenderEmail();
|
|
GetPropertyString(PR_SUBJECT, m_strSubject);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CMAPIMessage::Close()
|
|
{
|
|
RELEASE(m_pRecipients);
|
|
CMAPIObject::Close();
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetHeader(CString& strHeader)
|
|
{
|
|
return GetPropertyString(PR_TRANSPORT_MESSAGE_HEADERS, strHeader);
|
|
}
|
|
|
|
void CMAPIMessage::FillSenderEmail()
|
|
{
|
|
CString strAddrType;
|
|
GetPropertyString(PR_SENDER_ADDRTYPE, strAddrType);
|
|
GetPropertyString(PR_SENDER_EMAIL_ADDRESS, m_strSenderEmail);
|
|
|
|
// for Microsoft Exchange server internal mails we want to try to resolve the SMTP email address
|
|
if(strAddrType==_T("EX"))
|
|
{
|
|
LPSPropValue pProp;
|
|
if(GetProperty(PR_SENDER_ENTRYID, pProp)==S_OK)
|
|
{
|
|
if(m_pMAPI) m_pMAPI->GetExEmail(pProp->Value.bin, m_strSenderEmail);
|
|
MAPIFreeBuffer(pProp);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetReceivedTime(SYSTEMTIME& tmReceived)
|
|
{
|
|
LPSPropValue pProp;
|
|
if(GetProperty(PR_MESSAGE_DELIVERY_TIME, pProp)==S_OK)
|
|
{
|
|
FILETIME tmLocal;
|
|
FileTimeToLocalFileTime(&pProp->Value.ft, &tmLocal);
|
|
FileTimeToSystemTime(&tmLocal, &tmReceived);
|
|
MAPIFreeBuffer(pProp);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetReceivedTime(CString& strReceivedTime, LPCTSTR szFormat)
|
|
{
|
|
SYSTEMTIME tm;
|
|
if(GetReceivedTime(tm))
|
|
{
|
|
TCHAR szTime[256];
|
|
if(!szFormat) szFormat=_T("MM/dd/yyyy hh:mm:ss tt");
|
|
GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &tm, szFormat, szTime, 256);
|
|
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &tm, szTime, szTime, 256);
|
|
strReceivedTime=szTime;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetSubmitTime(SYSTEMTIME& tmSubmit)
|
|
{
|
|
LPSPropValue pProp;
|
|
if(GetProperty(PR_CLIENT_SUBMIT_TIME, pProp)==S_OK)
|
|
{
|
|
FILETIME tmLocal;
|
|
FileTimeToLocalFileTime(&pProp->Value.ft, &tmLocal);
|
|
FileTimeToSystemTime(&tmLocal, &tmSubmit);
|
|
MAPIFreeBuffer(pProp);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetSubmitTime(CString& strSubmitTime, LPCTSTR szFormat)
|
|
{
|
|
SYSTEMTIME tm;
|
|
if(GetSubmitTime(tm))
|
|
{
|
|
TCHAR szTime[256];
|
|
if(!szFormat) szFormat=_T("MM/dd/yyyy hh:mm:ss tt");
|
|
GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &tm, szFormat, szTime,256);
|
|
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &tm, szTime, szTime,256);
|
|
strSubmitTime=szTime;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetTo(CString& strTo)
|
|
{
|
|
return GetPropertyString(PR_DISPLAY_TO, strTo);
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetCC(CString& strCC)
|
|
{
|
|
return GetPropertyString(PR_DISPLAY_CC, strCC);
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetBCC(CString& strBCC)
|
|
{
|
|
return GetPropertyString(PR_DISPLAY_BCC, strBCC);
|
|
}
|
|
|
|
int CMAPIMessage::GetMessageStatus()
|
|
{
|
|
return GetPropertyValue(PR_MSG_STATUS, 0);
|
|
}
|
|
|
|
int CMAPIMessage::GetPriority()
|
|
{
|
|
return GetPropertyValue(PR_PRIORITY, PRIO_NONURGENT);
|
|
}
|
|
|
|
DWORD CMAPIMessage::GetSize()
|
|
{
|
|
return GetPropertyValue(PR_MESSAGE_SIZE, 0);
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetRecipients()
|
|
{
|
|
if(!Message()) return FALSE;
|
|
RELEASE(m_pRecipients);
|
|
|
|
if(Message()->GetRecipientTable(CMAPIEx::cm_nMAPICode, &m_pRecipients)!=S_OK) return FALSE;
|
|
|
|
const int nProperties=RECIPIENT_COLS;
|
|
SizedSPropTagArray(nProperties, Columns)={nProperties,{PR_RECIPIENT_TYPE, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_ADDRTYPE, PR_ENTRYID }};
|
|
return (m_pRecipients->SetColumns((LPSPropTagArray)&Columns, 0)==S_OK);
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetNextRecipient(CString& strName, CString& strEmail, int& nType)
|
|
{
|
|
if(!m_pRecipients) return FALSE;
|
|
|
|
LPSRowSet pRows=NULL;
|
|
BOOL bResult=FALSE;
|
|
if(m_pRecipients->QueryRows(1, 0, &pRows)==S_OK)
|
|
{
|
|
if(pRows->cRows)
|
|
{
|
|
nType=pRows->aRow[0].lpProps[PROP_RECIPIENT_TYPE].Value.ul;
|
|
strName=CMAPIEx::GetValidString(pRows->aRow[0].lpProps[PROP_RECIPIENT_NAME]);
|
|
|
|
// for Microsoft Exchange server internal mails we want to try to resolve the SMTP email address
|
|
CString strAddrType=CMAPIEx::GetValidString(pRows->aRow[0].lpProps[PROP_ADDR_TYPE]);
|
|
if(strAddrType==_T("EX"))
|
|
{
|
|
if(m_pMAPI) m_pMAPI->GetExEmail(pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin, strEmail);
|
|
}
|
|
else
|
|
{
|
|
strEmail=CMAPIEx::GetValidString(pRows->aRow[0].lpProps[PROP_RECIPIENT_EMAIL]);
|
|
}
|
|
bResult=TRUE;
|
|
}
|
|
FreeProws(pRows);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CMAPIMessage::GetReplyTo(CString& strEmail)
|
|
{
|
|
BOOL bResult=FALSE;
|
|
LPSPropValue prop;
|
|
if(GetProperty(PR_REPLY_RECIPIENT_ENTRIES, prop) == S_OK)
|
|
{
|
|
LPFLATENTRYLIST pReplyEntryList=(LPFLATENTRYLIST)prop->Value.bin.lpb;
|
|
if(pReplyEntryList->cEntries>0)
|
|
{
|
|
LPFLATENTRY pReplyEntry=(LPFLATENTRY)pReplyEntryList->abEntries;
|
|
|
|
SBinary entryID;
|
|
entryID.cb=pReplyEntry->cb;
|
|
entryID.lpb=pReplyEntry->abEntry;
|
|
bResult=m_pMAPI->GetExEmail(entryID, strEmail);
|
|
}
|
|
MAPIFreeBuffer(prop);
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
// nPriority defaults to IMPORTANCE_NORMAL, IMPORTANCE_HIGH or IMPORTANCE_LOW also valid
|
|
BOOL CMAPIMessage::Create(CMAPIEx* pMAPI, int nPriority, BOOL bSaveToSentFolder, CMAPIFolder* pFolder)
|
|
{
|
|
if(!pMAPI) return FALSE;
|
|
if(!pFolder) pFolder=pMAPI->GetFolder();
|
|
if(!pFolder) pFolder=pMAPI->OpenOutbox();
|
|
if(!CMAPIObject::Create(pMAPI, pFolder)) return FALSE;
|
|
|
|
SPropValue prop;
|
|
SetMessageFlags(MSGFLAG_UNSENT | MSGFLAG_FROMME);
|
|
|
|
LPSPropValue pProp=NULL;
|
|
ULONG cValues=0;
|
|
ULONG rgTags[]={ 1, PR_IPM_SENTMAIL_ENTRYID };
|
|
|
|
if(m_pMAPI->GetMessageStore()->GetProps((LPSPropTagArray) rgTags, CMAPIEx::cm_nMAPICode, &cValues, &pProp)==S_OK)
|
|
{
|
|
if(bSaveToSentFolder)
|
|
{
|
|
prop.ulPropTag=PR_SENTMAIL_ENTRYID;
|
|
prop.Value.bin=pProp[0].Value.bin;
|
|
}
|
|
else
|
|
{
|
|
prop.ulPropTag=PR_DELETE_AFTER_SUBMIT;
|
|
prop.Value.b=TRUE;
|
|
}
|
|
Message()->SetProps(1, &prop, NULL);
|
|
SetEntryID(&(pProp[0].Value.bin));
|
|
MAPIFreeBuffer(pProp);
|
|
}
|
|
|
|
if(nPriority!=IMPORTANCE_NORMAL)
|
|
{
|
|
prop.ulPropTag=PR_IMPORTANCE;
|
|
prop.Value.l=nPriority;
|
|
Message()->SetProps(1, &prop, NULL);
|
|
}
|
|
|
|
SetMessageClass(_T("IPM.Note"));
|
|
|
|
#ifdef _WIN32_WCE
|
|
prop.ulPropTag=PR_MSG_STATUS;
|
|
prop.Value.ul=MSGSTATUS_RECTYPE_SMTP;
|
|
Message()->SetProps(1, &prop, NULL);
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::IsUnread()
|
|
{
|
|
return (!(GetMessageFlags()&MSGFLAG_READ));
|
|
}
|
|
|
|
BOOL CMAPIMessage::MarkAsRead(BOOL bRead)
|
|
{
|
|
#ifdef _WIN32_WCE
|
|
int ulMessageFlags=GetMessageFlags();
|
|
if(bRead) ulMessageFlags|=MSGFLAG_READ;
|
|
else ulMessageFlags&=~MSGFLAG_READ;
|
|
return SetMessageFlags(ulMessageFlags);
|
|
#else
|
|
return (Message()->SetReadFlag(bRead ? MSGFLAG_READ : CLEAR_READ_FLAG)==S_OK);
|
|
#endif
|
|
}
|
|
|
|
BOOL CMAPIMessage::AddRecipients(LPADRLIST pAddressList)
|
|
{
|
|
HRESULT hr=E_INVALIDARG;
|
|
#ifdef _WIN32_WCE
|
|
hr=Message()->ModifyRecipients(MODRECIP_ADD, pAddressList);
|
|
#else
|
|
LPADRBOOK pAddressBook;
|
|
if(m_pMAPI->GetSession()->OpenAddressBook(0, NULL, AB_NO_DIALOG, &pAddressBook)!=S_OK) return FALSE;
|
|
|
|
if(pAddressBook->ResolveName(0, CMAPIEx::cm_nMAPICode, NULL, pAddressList)==S_OK) hr=Message()->ModifyRecipients(MODRECIP_ADD, pAddressList);
|
|
RELEASE(pAddressBook);
|
|
#endif
|
|
return (hr==S_OK);
|
|
}
|
|
|
|
// AddrType only needed by Windows CE, use SMTP, or SMS etc, default NULL will not set PR_ADDRTYPE
|
|
BOOL CMAPIMessage::AddRecipient(LPCTSTR szEmail, int nType, LPCTSTR szAddrType)
|
|
{
|
|
if(!Message() || !m_pMAPI) return FALSE;
|
|
|
|
int nBufSize=CbNewADRLIST(1);
|
|
LPADRLIST pAddressList=NULL;
|
|
MAPIAllocateBuffer(nBufSize, (LPVOID FAR*)&pAddressList);
|
|
memset(pAddressList, 0, nBufSize);
|
|
|
|
int nProperties=3;
|
|
if(szAddrType==NULL) nProperties--;
|
|
pAddressList->cEntries=1;
|
|
|
|
pAddressList->aEntries[0].ulReserved1=0;
|
|
pAddressList->aEntries[0].cValues=nProperties;
|
|
|
|
MAPIAllocateBuffer(sizeof(SPropValue)*nProperties, (LPVOID FAR*)&pAddressList->aEntries[0].rgPropVals);
|
|
memset(pAddressList->aEntries[0].rgPropVals, 0, sizeof(SPropValue)*nProperties);
|
|
|
|
pAddressList->aEntries[0].rgPropVals[0].ulPropTag=PR_RECIPIENT_TYPE;
|
|
pAddressList->aEntries[0].rgPropVals[0].Value.ul=nType;
|
|
|
|
#ifdef _WIN32_WCE
|
|
pAddressList->aEntries[0].rgPropVals[1].ulPropTag=PR_EMAIL_ADDRESS;
|
|
pAddressList->aEntries[0].rgPropVals[1].Value.LPSZ=(TCHAR*)szEmail;
|
|
#else
|
|
pAddressList->aEntries[0].rgPropVals[1].ulPropTag=PR_DISPLAY_NAME;
|
|
pAddressList->aEntries[0].rgPropVals[1].Value.LPSZ=(TCHAR*)szEmail;
|
|
#endif
|
|
|
|
if(szAddrType!=NULL)
|
|
{
|
|
pAddressList->aEntries[0].rgPropVals[2].ulPropTag=PR_ADDRTYPE;
|
|
pAddressList->aEntries[0].rgPropVals[2].Value.LPSZ=(TCHAR*)szAddrType;
|
|
}
|
|
|
|
BOOL bResult=AddRecipients(pAddressList);
|
|
CMAPIEx::ReleaseAddressList(pAddressList);
|
|
return bResult;
|
|
}
|
|
|
|
void CMAPIMessage::SetSubject(LPCTSTR szSubject)
|
|
{
|
|
m_strSubject=szSubject;
|
|
SetPropertyString(PR_SUBJECT, szSubject);
|
|
}
|
|
|
|
void CMAPIMessage::SetSender(LPCTSTR szSenderName, LPCTSTR szSenderEmail)
|
|
{
|
|
m_strSenderName=szSenderName;
|
|
m_strSenderEmail=szSenderEmail;
|
|
LPTSTR szAddrType=_T("SMTP");
|
|
if(m_strSenderName.GetLength() && m_strSenderEmail.GetLength())
|
|
{
|
|
SetPropertyString(PR_SENDER_NAME, szSenderName);
|
|
SetPropertyString(PR_SENDER_EMAIL_ADDRESS, szSenderEmail);
|
|
|
|
#ifndef _WIN32_WCE
|
|
LPADRBOOK pAddressBook;
|
|
if(m_pMAPI->GetSession()->OpenAddressBook(0, NULL, AB_NO_DIALOG, &pAddressBook)==S_OK)
|
|
{
|
|
SPropValue prop;
|
|
if(pAddressBook->CreateOneOff((LPTSTR)szSenderName, szAddrType, (LPTSTR)szSenderEmail, 0, &prop.Value.bin.cb, (LPENTRYID*)&prop.Value.bin.lpb)==S_OK)
|
|
{
|
|
prop.ulPropTag=PR_SENT_REPRESENTING_ENTRYID;
|
|
Message()->SetProps(1, &prop, NULL);
|
|
|
|
SetPropertyString(PR_SENT_REPRESENTING_NAME, szSenderName);
|
|
SetPropertyString(PR_SENT_REPRESENTING_EMAIL_ADDRESS, szSenderEmail);
|
|
SetPropertyString(PR_SENT_REPRESENTING_ADDRTYPE, szAddrType);
|
|
}
|
|
}
|
|
RELEASE(pAddressBook);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
BOOL CMAPIMessage::SetReceivedTime(SYSTEMTIME tmReceived, BOOL bLocalTime)
|
|
{
|
|
SPropValue prop;
|
|
prop.ulPropTag=PR_MESSAGE_DELIVERY_TIME;
|
|
#ifndef _WIN32_WCE
|
|
if(bLocalTime) TzSpecificLocalTimeToSystemTime(NULL, &tmReceived, &tmReceived);
|
|
#endif
|
|
SystemTimeToFileTime(&tmReceived, &prop.Value.ft);
|
|
return (Message() && Message()->SetProps(1, &prop, NULL)==S_OK);
|
|
}
|
|
|
|
BOOL CMAPIMessage::SetSubmitTime(SYSTEMTIME tmSubmit, BOOL bLocalTime)
|
|
{
|
|
SPropValue prop;
|
|
prop.ulPropTag=PR_CLIENT_SUBMIT_TIME;
|
|
#ifndef _WIN32_WCE
|
|
if(bLocalTime) TzSpecificLocalTimeToSystemTime(NULL, &tmSubmit, &tmSubmit);
|
|
#endif
|
|
SystemTimeToFileTime(&tmSubmit, &prop.Value.ft);
|
|
return (Message() && Message()->SetProps(1, &prop, NULL)==S_OK);
|
|
}
|
|
|
|
// request a Read Receipt sent to szReceiverEmail
|
|
BOOL CMAPIMessage::SetReadReceipt(BOOL bSet, LPCTSTR szReceiverEmail)
|
|
{
|
|
if(!Message()) return FALSE;
|
|
|
|
SPropValue prop;
|
|
prop.ulPropTag=PR_READ_RECEIPT_REQUESTED;
|
|
prop.Value.b=(unsigned short)bSet;
|
|
if(Message()->SetProps(1, &prop, NULL)!=S_OK) return FALSE;
|
|
|
|
if(bSet && szReceiverEmail && _tcslen(szReceiverEmail)>0) SetPropertyString(PR_READ_RECEIPT_REQUESTED, szReceiverEmail);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::SetDeliveryReceipt(BOOL bSet)
|
|
{
|
|
if(!Message()) return FALSE;
|
|
|
|
SPropValue prop;
|
|
prop.ulPropTag=PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED;
|
|
prop.Value.b=(unsigned short)bSet;
|
|
return (Message()->SetProps(1, &prop, NULL)!=S_OK);
|
|
}
|
|
|
|
// limited compare, compares entry IDs and subject to determine if two emails are equal
|
|
BOOL CMAPIMessage::operator==(CMAPIMessage& message)
|
|
{
|
|
if(!m_entryID.cb || !message.m_entryID.cb || m_entryID.cb!=message.m_entryID.cb) return FALSE;
|
|
if(memcmp(m_entryID.lpb,message.m_entryID.lpb, m_entryID.cb)) return FALSE;
|
|
return (!m_strSubject.Compare(message.m_strSubject));
|
|
}
|
|
|
|
// Novell GroupWise customization by jcadmin
|
|
#ifndef GROUPWISE
|
|
BOOL CMAPIMessage::MarkAsPrivate() { return FALSE; }
|
|
#else
|
|
#include GWMAPI.h
|
|
//(from Novell Developer Kit)
|
|
#define SEND_OPTIONS_MARK_PRIVATE 0x00080000L
|
|
|
|
void CMAPIMessage::MarkAsPrivate()
|
|
{
|
|
SPropValue prop;
|
|
prop.ulPropTag=PR_NGW_SEND_OPTIONS;
|
|
prop.Value.l=NGW_SEND_OPTIONS_MARK_PRIVATE;
|
|
return (Message()->SetProps(1, &prop, NULL)==S_OK);
|
|
}
|
|
#endif
|
|
|
|
// In WinCE, use MSGSTATUS_RECTYPE_SMS for an SMS, MSGSTATUS_RECTYPE_SMTP for an email
|
|
BOOL CMAPIMessage::SetMessageStatus(int nMessageStatus)
|
|
{
|
|
SPropValue prop;
|
|
prop.ulPropTag=PR_MSG_STATUS;
|
|
prop.Value.ul=nMessageStatus;
|
|
return (Message()->SetProps(1, &prop, NULL)==S_OK);
|
|
}
|
|
|
|
// Shows the default MAPI form for IMessage, returns FALSE on failure, IDOK on success or close existing messages
|
|
// and IDCANCEL on close new messages
|
|
int CMAPIMessage::ShowForm(CMAPIEx* pMAPI)
|
|
{
|
|
CMAPIFolder* pFolder=pMAPI->GetFolder();
|
|
IMAPISession* pSession=pMAPI->GetSession();
|
|
ULONG ulMessageToken;
|
|
|
|
if(pFolder && pSession && pSession->PrepareForm(NULL,Message(), &ulMessageToken)==S_OK)
|
|
{
|
|
ULONG ulMessageStatus=GetPropertyValue(PR_MSG_STATUS, 0);
|
|
ULONG ulMessageFlags=GetMessageFlags();
|
|
ULONG ulAccess=GetPropertyValue(PR_ACCESS, 0);
|
|
|
|
LPSPropValue pProp;
|
|
if(GetProperty(PR_MESSAGE_CLASS, pProp)==S_OK)
|
|
{
|
|
#ifdef UNICODE
|
|
char szMessageClass[256];
|
|
WideCharToMultiByte(CP_ACP, 0, pProp->Value.LPSZ,-1, szMessageClass,255, NULL, NULL);
|
|
#else
|
|
char* szMessageClass=pProp->Value.LPSZ;
|
|
#endif
|
|
HRESULT hr=pSession->ShowForm(NULL, pMAPI->GetMessageStore(), pFolder->Folder(), NULL,ulMessageToken, NULL, 0,ulMessageStatus,ulMessageFlags,ulAccess, szMessageClass);
|
|
MAPIFreeBuffer(pProp);
|
|
if(hr==S_OK) return IDOK;
|
|
if(hr==MAPI_E_USER_CANCEL) return IDCANCEL;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::Send()
|
|
{
|
|
if(Message() && Message()->SubmitMessage(0)==S_OK)
|
|
{
|
|
Close();
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMAPIMessage::SaveAsMsg(LPCTSTR szPath)
|
|
{
|
|
CString strPath=szPath;
|
|
if(strPath.GetLength()<4 || strPath.Right(4).CompareNoCase(".msg")) strPath+=".msg";
|
|
#ifdef _WIN32_WCE
|
|
return FALSE;
|
|
#else
|
|
LPSTORAGE pStorage;
|
|
DWORD dwFlags=STGM_READWRITE | STGM_TRANSACTED | STGM_CREATE;
|
|
#ifdef UNICODE
|
|
if(::StgCreateDocfile(strPath, dwFlags, 0, &pStorage) == S_OK)
|
|
#else
|
|
WCHAR wszPath[_MAX_PATH];
|
|
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strPath, -1, wszPath, _MAX_PATH);
|
|
if(StgCreateDocfile(wszPath, dwFlags, 0, &pStorage) == S_OK)
|
|
#endif
|
|
{
|
|
LPMSGSESS pMsgSession;
|
|
LPMALLOC pMalloc = MAPIGetDefaultMalloc();
|
|
if(OpenIMsgSession(pMalloc, 0, &pMsgSession) == S_OK)
|
|
{
|
|
LPMESSAGE pIMsg;
|
|
if(OpenIMsgOnIStg(pMsgSession, MAPIAllocateBuffer, MAPIAllocateMore, MAPIFreeBuffer, pMalloc, NULL, pStorage, NULL, 0, 0, &pIMsg) == S_OK)
|
|
{
|
|
// client must support CLSID_MailMessage as the compound document
|
|
if(WriteClassStg(pStorage, CLSID_MailMessage) == S_OK)
|
|
{
|
|
// exclude these properties from the copy operation to speed things up
|
|
SizedSPropTagArray ( 7, excludeTags );
|
|
excludeTags.cValues=7;
|
|
excludeTags.aulPropTag[0]=PR_ACCESS;
|
|
excludeTags.aulPropTag[1]=PR_BODY;
|
|
excludeTags.aulPropTag[2]=PR_RTF_SYNC_BODY_COUNT;
|
|
excludeTags.aulPropTag[3]=PR_RTF_SYNC_BODY_CRC;
|
|
excludeTags.aulPropTag[4]=PR_RTF_SYNC_BODY_TAG;
|
|
excludeTags.aulPropTag[5]=PR_RTF_SYNC_PREFIX_COUNT;
|
|
excludeTags.aulPropTag[6]=PR_RTF_SYNC_TRAILING_COUNT;
|
|
|
|
if(Message()->CopyTo(0, NULL, (LPSPropTagArray)&excludeTags, NULL, NULL, (LPIID)&IID_IMessage, pIMsg, 0, NULL ) == S_OK)
|
|
{
|
|
pIMsg->SaveChanges(KEEP_OPEN_READWRITE);
|
|
pStorage->Commit(STGC_DEFAULT);
|
|
}
|
|
}
|
|
RELEASE(pIMsg);
|
|
}
|
|
CloseIMsgSession(pMsgSession);
|
|
}
|
|
|
|
RELEASE(pStorage);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
#endif
|
|
}
|