Embed Graphic in existing MailItem using Outlook Redemption?

K

Kristy

Hi

I am using Windows XP and writing a com add-in for Outlook 2000 and
XP, I am also using Outlook Redemption.

I am having a few problems embedding a graphic, the code works
perfectly when I create a new item, but I need to attach the graphic
and then embed it into an existing item. I am getting no error
messages but the new files are not getting attached and therefore
cannot be embedded.

The code looks something like this...

Set MailItem = objNamespace.GetItemFromID(EID)
Set sItem = CreateObject("FSRedemption.FSMailItem")
sItem.item = MailItem

'Hide paperclip
PT_BOOLEAN = 11
PR_HIDE_ATTACH = sItem.GetIDsFromNames("{00062008-0000-0000-C000-000000000046}",
&H8514) Or PT_BOOLEAN
sItem.Fields(PR_HIDE_ATTACH) = True

'NO ERROR MESSAGES AND IT APPEARS TO BE THERE BUT THE FILE IS NOT
BEING ATTACHED

Set attach = sItem.Attachments.Add "C:\Temp.jpg"

'content type
attach.Fields(&H370E001E) = "image/jpeg"
'Attachment cid
attach.Fields(&H3712001E) = "Graphic1"

sItem.Save
EID2 = sItem.EntryID

Set MailItem = Nothing
Set sItem = Nothing
Set attach = Nothing

Set sItem = golApp.Session.GetItemFromID(EID2)

sItem.HTMLBody = "<IMG align=baseline border=0 hspace=0
src=cid:"Graphic1">"

sItem.Display

I just can't seem to get the files to attach to the existing MailItem,
they just simply aren't there and therfore I get a box with a red
cross instead of my graphic.

When the item is newly created ('Set MailItem =
golApp.CreateItem(olMailItem)', instead of 'Set MailItem =
objNamespace.GetItemFromID(EID)') it works so what is the difference
between using a newly created Item and an existing Item when attaching
files in this way? I have tried moving things around, displaying the
Item first, and using separate subs but to no avail, I hope that
someone can spot the error that I am missing!

Thank you

Kristy
 
D

Dmitry Streblechenko

That happens because Outlook does not see the attachment you added using
Redemption. Try to dereference both OOM and Redemption objects, reopen the
message using Namespace.GetItemFromID(), then call MailItem.Display.
Or add the attachment using OOM (adding is not blocked), save the message
(so that Redemption can see teh change), then access the newly added
attachment using Redemption to set the &H3712001E property.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
K

Kristy

Thanks Dmitry

I have tried a combination of what you suggested and have managed to
get the attachment onto the email with my existing email still intact,
however I still cannot seem to embed the graphic. I think the problem
occurs when I try to access the newly added attachment using
Redemption and set the &H3712001E property. The code below is the
only combination that I tried that would actually add the attachment.
After the attachment is added I then try to access the attachment by
setting "attach" property. (The email potentially already has
attachments so a counter is necessary to make sure I embed the correct
file).

All objects relating to existing email have been deferenced prior to
this is a separate sub...

Set golApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If golApp Is Nothing Then
Err.Clear
'create it
Set golApp = CreateObject("Outlook.Application")
End If

Set objNamespace = golApp.GetNamespace("MAPI")
objNamespace.Logon "", "", False, False

Set MailItem = objNamespace.GetItemFromID(EID)

'check to see any attachments on existing email
intNumberOfAttachments = MailItem.Attachments.Count
intLHAttachNumber = intNumberOfAttachments + 1

With MailItem
.Attachments.Add ("C:\Test.jpg")
End With

MailItem.Save
Set sItem = CreateObject("FSRedemption.FSMailItem")
sItem.item = MailItem

'Name for cid:
strGraphic = "MyGraphic" & intLHAttachNumber

'tell Outlook to hide the paperclip icon
PT_BOOLEAN = 11
PR_HIDE_ATTACH = sItem.GetIDsFromNames("{00062008-0000-0000-C000-000000000046}",
&H8514) Or PT_BOOLEAN
sItem.Fields(PR_HIDE_ATTACH) = True

'get attachment
Set attach = sItem.Attachments(intLHAttachNumber)
'content type
attach.Fields(&H370E001E) = "image/jpeg"
'Attachment cid
attach.Fields(&H3712001E) = strGraphic
sItem.Save
EID2 = sItem.EntryID

'de-reference the old item
Set MailItem = Nothing
Set sItem = Nothing
Set attach = Nothing

Set sItem = golApp.Session.GetItemFromID(EID2)

sItem.HTMLBody = "<IMG align=baseline border=0 hspace=0 src=cid:" &
strGraphic & ">"
sItem.Display

Set sItem = Nothing
Set MailItem = Nothing
objNamespace.Logoff
Set objNamespace = Nothing
Set golApp = Nothing

End Sub

Thanks for all your help so far, any further suggestions would be
greatly appreciated, I am so close to finishing this... but still so
far away!

Cheers

Kristy
 
D

Dmitry Streblechenko

Redemption (or Extended MAPI for that matter) will not see the newly added
attachment unless the message is saved. After the line
..Attachments.Add ("C:\Test.jpg")
add
..Save

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
K

Kristy

In addition to my other follow-up post...

Using the code that I posted there, I can get the attachment to show
on the email but still get the box and cross instead of the object
being embedded as I mentioned. It isn't setting the attachment that
fails as I thought though, it still has something to do with
deferencing all the objects to get them out of memory. I feel sure
that I am setting them all to nothing but it is obviously not working
because if I:

a) send the email, or
b) close it, save it, open another (unrelated item) and then open my
item from drafts, or
c) save the item to drafts, close Outlook, come back in and open it...

the graphic will show as being embedded every time?

No matter what I try I just can't get it to display correctly the
first time I open it, can you see where the problem might be, am I
doing things in the wrong order?
 
D

Dmitry Streblechenko

One piece was missing: before calling sItem.Save, you need to convince
Outlook that something has changed, otherwise Save won't do anything:

MailItem.Subject = MailItem.Subject
sItem.Save

Below is what I used to test the code in OutlookSpy: click Script Editor on
the OutlookSpy toolbar, paste the code, click Run. The code grabs the first
item from the Drafts folder.



Set objNamespace = Application.GetNamespace("MAPI")
objNamespace.Logon "", "", False, False

'get the first item from the Drafts folder
Set MailItem = objNamespace.GetDefaultFolder(16).Items(1)

'check to see any attachments on existing email
intNumberOfAttachments = MailItem.Attachments.Count
intLHAttachNumber = intNumberOfAttachments + 1

With MailItem
.Attachments.Add ("C:\Test.jpg")
End With

MailItem.Save
Set sItem = CreateObject("Redemption.SafeMailItem")
sItem.item = MailItem

'Name for cid:
strGraphic = "MyGraphic" & intLHAttachNumber

'tell Outlook to hide the paperclip icon
PT_BOOLEAN = 11
PR_HIDE_ATTACH =
sItem.GetIDsFromNames("{00062008-0000-0000-C000-000000000046}", _
&H8514) Or PT_BOOLEAN
sItem.Fields(PR_HIDE_ATTACH) = True

'get attachment
Set attach = sItem.Attachments(intLHAttachNumber)
'content type
attach.Fields(&H370E001E) = "image/jpeg"
'Attachment cid
attach.Fields(&H3712001E) = strGraphic
MailItem.Subject = MailItem.Subject
sItem.Save
EID2 = sItem.EntryID

'de-reference the old item
Set MailItem = Nothing
Set sItem = Nothing
Set attach = Nothing

Set sItem = Application.Session.GetItemFromID(EID2)

sItem.HTMLBody = "<IMG align=baseline border=0 hspace=0 src=cid:" & _
strGraphic & ">"
sItem.Display

Set sItem = Nothing
Set MailItem = Nothing
objNamespace.Logoff
Set objNamespace = Nothing
Set golApp = Nothing



Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
K

Kristy

Hi again, I really do appreciate your help, I am going crazy because I
just don't understand what the problem is and I have noone to ask but
the group - thank goodness for this group!

I have tried the .save and it's still not working, for some reason it
is not being released from memory and isn't updating properly when I
first display it. (I sent another reply to this post outlining the
problem but I don't think it arrived, anyway sorry if I am repeating
myself...) If I send the Item to myself I can see the embedded object
when I receive it, but initially when I view it (before send) it is
just a box and cross (very off putting for the composer!).

Saving the item and reopening doesn't work either, it has to be either
sent or outlook closed completely and then reopened and my item
displayed or another item opened and closed and then my item opened
for it to be displayed properly(weird! confusing!).

Do you know why this is happening? I know that I should be able to
work it out for myself but I just can't. When I use the same code but
for Item.Reply/ReplyAll or Forward it is all OK, if I create a new
item it is also fine, but getting Item from id.... I have explicity
dereferenced everything that I can see, is my order of events way out
or something... I have tried so many options and I am going getting
nowhere?

Cheers

Agony Aunt!
 
D

Dmitry Streblechenko

The problem might be implicit variables that VB creates. E.g. when you have
a line of code like
MailItem.Attachments.Add ("C:\Test.jpg")
VB creates an implicit variable to hold MailItem.Attachments, then calls
Attachments.Add. Since Attachments has never been dimmed, you cannot set it
to Nothing. A workaround is to wrap the code manipulating the attachments in
a separate sub, when it exists, all implicit and explicit variables will be
dereferenced automatically (unless you are using .Net).

Call DoTheAttachmentsThing(Item)
Item.Save
entryid = Item.EntryID
set Item = Nothing
set Item = Namespace.GetItemFromID(entryid)
Item.Display

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
K

Kristy

Hi Dmitry

I realise that this is getting very long and tedious, if you can be
bothered then below is my latest attempt to get this to work (and
still it doesn't)... It is a combination of everything that you have
suggested to try to ensure that all implicit variables are released
from memory, all items are saved, all explicitly referenced variables
are de-referenced etc, and still I get a box and cross until I either
send the item, close outlook and come back in or open another item and
then reopen my item.

If I use the same code but instead of getting the saved item using ...

Set MailItem = objNamespace.GetDefaultFolder(16).Items(1)

I get an existing item and use...

Set oReply = objItem.Reply

everything works fine.

I just can't see what the difference could be with regards releasing
all variables in these 2 scenarios... and I guess that's why I can't
get it to work, can you think of anything else that I can try? Do you
think that I'll ever be able to get this to work or is it something
that is out of my control?

Thanks so much for your time so far, I think I'll just go to the
garden and eat worms (that seems to make more sense than this!).

Kristy


Sub CreateNewMail()

Call CreateItem

'Now need to get saved Item
' create new Outlook MailItem
Set golApp = GetObject(, "Outlook.Application")
On Error GoTo 0 'close your error trap
If golApp Is Nothing Then
Err.Clear
'Try and create it
Set golApp = CreateObject("Outlook.Application")
End If

Set objNamespace = golApp.GetNamespace("MAPI")
objNamespace.Logon "", "", False, False 'Added for Redemption

Set MailItem = objNamespace.GetDefaultFolder(16).Items(1)

Set sItem = CreateObject("FSRedemption.FSMailItem")
sItem.item = MailItem

strGraphic = "MyGraphic" & intLHAttachNumber

'tell Outlook to hide the paperclip icon
PT_BOOLEAN = 11
PR_HIDE_ATTACH = sItem.GetIDsFromNames("{00062008-0000-0000-C000-000000000046}",
&H8514) Or PT_BOOLEAN
sItem.Fields(PR_HIDE_ATTACH) = True
'add attachment

Set attach = sItem.Attachments(intLHAttachNumber)

'content type
attach.Fields(&H370E001E) = "image/jpeg"
'Attachment cid
attach.Fields(&H3712001E) = strGraphic
sItem.Subject = sItem.Subject
sItem.Save
EID = sItem.EntryID



'de-reference the old item
Set attach = Nothing
Set sItem = Nothing
Set MailItem = Nothing
objNamespace.Logoff
Set objNamespace = Nothing
Set golApp = Nothing

Set golApp = GetObject(, "Outlook.Application")
On Error GoTo 0 'close your error trap
If golApp Is Nothing Then
Err.Clear
'Try and create it
Set golApp = CreateObject("Outlook.Application")
End If
Set objNamespace = golApp.GetNamespace("MAPI")
objNamespace.Logon "", "", False, False 'Added for Redemption


Set sItem = objNamespace.GetItemFromID(EID)

sItem.HTMLBody = "<IMG align=baseline border=0 hspace=0 src=cid:" &
strGraphic & ">" & "<body bgcolor=#FFFFFF>" _
& "<HTML><HEAD><TITLE>Test</TITLE>" & "</HEAD><BODY></B>" &
sItem.HTMLBody & "</BODY></HTML>"

sItem.Display

' clean up sItem

Set sItem = Nothing
objNamespace.Logoff
Set objNamespace = Nothing
Set golApp = Nothing
Finish:
End Sub


Sub CreateItem()

Set golApp = GetObject(, "Outlook.Application")

On Error GoTo 0 'close your error trap
If golApp Is Nothing Then
Err.Clear
'Try and create it
Set golApp = CreateObject("Outlook.Application")
End If

Set objSigMail = golApp.CreateItem(olMailItem)

'check to see any attachments(embedded objects) already
intNumberOfAttachments = objSigMail.Attachments.Count
intLHAttachNumber = intNumberOfAttachments + 1

'then add the graphic to be embedded
Call AddAttachments ("C:\Test.jpg")

objSigMail.Save
EID = objSigMail.EntryID
objSigMail.Close olDiscard


Set objSigMail = Nothing
Set golApp = Nothing

End Sub

Public Sub AddAttachments(ByVal strAttachments As String)

With objSigMail
.Attachments.Add strAttachments
.Subject = objSigMail.Subject
.Save
End With

End Sub
 
D

Dmitry Streblechenko

Hmmm... Hard to say without seeing the Outlook soure code - who knows how it
caches and releases its objects.
What is your latest code? I'll try to reproduce the problem in my
environment.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top