R
Raiv
I am trying to replace content of e-mail attachment handling
Outlook::ApplicationEvents::OnNewMailEx event.
And I have a trouble: mail is sending without replacement of item, new item
is simply added as another attachment. the most confusing thing that "sent
items" folder of the outlook shows correct mail item, but it comes with two
attachments to mail receiver.
Maybe the trouble is in the outlook threads? May the mail be sent before
replacement save is complete? is there any walkaround to wait for full mail
saving before it sent?
static bool SetBinaryByTag_MAPI(IDispatch *object, ULONG tag,
const void *data, int size)
{
bool ret = false;
LOG_ENTER_PTR(object);
IUnknown *iunkObject = ObtainMAPIOBJECT(object);
if (iunkObject)
{
CComQIPtr<IMAPIProp, &IID_IMAPIProp> mapiObject(iunkObject);
ret = SetBinaryByKnownObjectAndTag(mapiObject, tag, data, size);
iunkObject->Release();
}
LOG_RETURN_INT(ret);
return ret;
}
bool MAPIPropWrapper::SetPropertyByTag(IDispatch *object,
ULONG tag, const void *data, int size,
bool useMAPI)
{
bool ret = false;
LOG_ENTER("object = %p, useMAPI = %d, isMAPIInit = %d", object, useMAPI,
m_isMAPIInit);
if (!useMAPI)
{
ret = SetBinaryByTag_PA(object, tag, data, size);
}
else
{
if (m_isMAPIInit)
{
ret = SetBinaryByTag_MAPI(object, tag, data, size);
}
}
LOG_RETURN_INT(ret);
return ret;
}
bool MAPIPropWrapper::SaveChanges(IDispatch *object, bool useMAPI, ULONG
flags)
{
bool ret = false;
LOG_ENTER("object = %p, useMAPI = %d, isMAPIInit = %d, flags = 0x%08X",
object, useMAPI, m_isMAPIInit, flags);
if (!useMAPI)
{
/* PropertyAccessor automatically save changes after property changed. */
ret = true;
}
else
{
if (m_isMAPIInit)
{
IUnknown *iunkObject = ObtainMAPIOBJECT(object);
if (iunkObject)
{
CComQIPtr<IMAPIProp, &IID_IMAPIProp> mapiObject(iunkObject);
if (!mapiObject)
{
LOG_ERROR("Obtain invalid MAPI object %p!", iunkObject);
}
else
{
HRESULT hr = mapiObject->SaveChanges(flags);
if (FAILED(hr))
{
LOG_ERROR_HRESULT("mapiObject->SaveChanges()", hr);
}
else
{
ret = true;
}
}
iunkObject->Release();
}
}
}
LOG_RETURN_INT(ret);
return ret;
}
bool MAPIWrapper::ReplaceAttachmentData(IDispatch *mail, int num,
void *data, int dataSize)
{
bool ret = true;
CComPtr<Outlook::Attachments> attachments;
CComQIPtr<Outlook::_MailItem> mailItem(mail);
if (!mailItem)
{
ret = false;
}
else
{
HRESULT hr = mailItem->get_Attachments(&attachments);
if (FAILED(hr))
{
ret = false;
}
else
{
CComPtr<Outlook::Attachment> attachment;
hr = attachments->Item(CComVariant(num), &attachment);
if (FAILED(hr))
{
ret = false;
}
else
{
bool localUseMAPI = true;
ret = SetPropertyByTag(attachment, PR_ATTACH_DATA_BIN,
data, dataSize, localUseMAPI);
if (ret)
{
CComVariant v(true);
ret = SetPropertyByTag(attachment, PR_ATTACHMENT_HIDDEN, v,
localUseMAPI);
}
if (ret)
{
ret = SaveChanges(attachment, localUseMAPI, FORCE_SAVE);
}
}
}
}
return ret;
}
class variables:
CComPtr<IDispatch> m_mail;
int attachmentNum;
void* binaryData;
int dataSize;
Event handler:
{
...
bool ret= ReplaceAttachmentData(m_mail, attachmentNum,
binaryData, dataSize)
....
// another modifications
....
if(ret)
{
ret = MAPIWrapper::SaveMail(m_mail);
}
return ret;
}
I use MSVC2005sp1 + Outlook2007 12.0.4518.1014
Outlook::ApplicationEvents::OnNewMailEx event.
And I have a trouble: mail is sending without replacement of item, new item
is simply added as another attachment. the most confusing thing that "sent
items" folder of the outlook shows correct mail item, but it comes with two
attachments to mail receiver.
Maybe the trouble is in the outlook threads? May the mail be sent before
replacement save is complete? is there any walkaround to wait for full mail
saving before it sent?
static bool SetBinaryByTag_MAPI(IDispatch *object, ULONG tag,
const void *data, int size)
{
bool ret = false;
LOG_ENTER_PTR(object);
IUnknown *iunkObject = ObtainMAPIOBJECT(object);
if (iunkObject)
{
CComQIPtr<IMAPIProp, &IID_IMAPIProp> mapiObject(iunkObject);
ret = SetBinaryByKnownObjectAndTag(mapiObject, tag, data, size);
iunkObject->Release();
}
LOG_RETURN_INT(ret);
return ret;
}
bool MAPIPropWrapper::SetPropertyByTag(IDispatch *object,
ULONG tag, const void *data, int size,
bool useMAPI)
{
bool ret = false;
LOG_ENTER("object = %p, useMAPI = %d, isMAPIInit = %d", object, useMAPI,
m_isMAPIInit);
if (!useMAPI)
{
ret = SetBinaryByTag_PA(object, tag, data, size);
}
else
{
if (m_isMAPIInit)
{
ret = SetBinaryByTag_MAPI(object, tag, data, size);
}
}
LOG_RETURN_INT(ret);
return ret;
}
bool MAPIPropWrapper::SaveChanges(IDispatch *object, bool useMAPI, ULONG
flags)
{
bool ret = false;
LOG_ENTER("object = %p, useMAPI = %d, isMAPIInit = %d, flags = 0x%08X",
object, useMAPI, m_isMAPIInit, flags);
if (!useMAPI)
{
/* PropertyAccessor automatically save changes after property changed. */
ret = true;
}
else
{
if (m_isMAPIInit)
{
IUnknown *iunkObject = ObtainMAPIOBJECT(object);
if (iunkObject)
{
CComQIPtr<IMAPIProp, &IID_IMAPIProp> mapiObject(iunkObject);
if (!mapiObject)
{
LOG_ERROR("Obtain invalid MAPI object %p!", iunkObject);
}
else
{
HRESULT hr = mapiObject->SaveChanges(flags);
if (FAILED(hr))
{
LOG_ERROR_HRESULT("mapiObject->SaveChanges()", hr);
}
else
{
ret = true;
}
}
iunkObject->Release();
}
}
}
LOG_RETURN_INT(ret);
return ret;
}
bool MAPIWrapper::ReplaceAttachmentData(IDispatch *mail, int num,
void *data, int dataSize)
{
bool ret = true;
CComPtr<Outlook::Attachments> attachments;
CComQIPtr<Outlook::_MailItem> mailItem(mail);
if (!mailItem)
{
ret = false;
}
else
{
HRESULT hr = mailItem->get_Attachments(&attachments);
if (FAILED(hr))
{
ret = false;
}
else
{
CComPtr<Outlook::Attachment> attachment;
hr = attachments->Item(CComVariant(num), &attachment);
if (FAILED(hr))
{
ret = false;
}
else
{
bool localUseMAPI = true;
ret = SetPropertyByTag(attachment, PR_ATTACH_DATA_BIN,
data, dataSize, localUseMAPI);
if (ret)
{
CComVariant v(true);
ret = SetPropertyByTag(attachment, PR_ATTACHMENT_HIDDEN, v,
localUseMAPI);
}
if (ret)
{
ret = SaveChanges(attachment, localUseMAPI, FORCE_SAVE);
}
}
}
}
return ret;
}
class variables:
CComPtr<IDispatch> m_mail;
int attachmentNum;
void* binaryData;
int dataSize;
Event handler:
{
...
bool ret= ReplaceAttachmentData(m_mail, attachmentNum,
binaryData, dataSize)
....
// another modifications
....
if(ret)
{
ret = MAPIWrapper::SaveMail(m_mail);
}
return ret;
}
I use MSVC2005sp1 + Outlook2007 12.0.4518.1014