I wrote an addin a while back for Outlook that adds/removes an optional tagline below the signature in an outlook message. This add-in works with no issues.
I'm writing a second add-in that needs to potentially add information below that (whether or not the optional signature is there) and am again referencing the _MailAutoSig bookmark from the Word editor. The issue I'm running into is that this bookmark no longer seems to appear, nor does the bookmark from my other add-in.
One difference in the two pieces of code below is that the first one has the MailItem being converted from an object passed by ItemSend, whereas the second is processed BEFORE the ItemSend event.
Here is the code from what I am currently writing:
Word.Document toMsg = msg.GetInspector.WordEditor as Word.Document;
foreach (Word.Bookmark b in toMsg.Bookmarks)
Debug.Print(b.ToString());
Word.Range r_toMsg;
try
{
string oBookmark = "_MailAutoSig"; // Outlook internal bookmark for location of the e-mail signature`
object oBookmarkObj = oBookmark;
if (toMsg.Bookmarks.Exists(oBookmark) == true)
Debug.Print("sigbookmark");
r_toMsg = toMsg.Bookmarks.get_Item(ref oBookmarkObj).Range;
}
catch
{
string oOffsiteBookmark = "OffsiteBookmark";
object oOffsiteBookmarkObj = oOffsiteBookmark;
if (toMsg.Bookmarks.Exists(oOffsiteBookmark) == true) // if the custom bookmark exists, remove it
Debug.Print("offsite bookmark");
}
finally
{
r_toMsg = toMsg.Range(missing,missing);
}
and here is code from my working add-in:
void InsertOffsiteSig(Outlook.MailItem oMsg)
{
object oBookmarkName = "_MailAutoSig"; // Outlook internal bookmark for location of the e-mail signature
string oOffsiteBookmark = "OffsiteBookmark"; // bookmark to be created in Outlook for the Offsite tagline
object oOffsiteBookmarkObj = oOffsiteBookmark;
Word.Document SigDoc = oMsg.GetInspector.WordEditor as Word.Document; // edit the message using Word
string bf = oMsg.BodyFormat.ToString(); // determine the message body format (text, html, rtf)
// Go to the e-mail signature bookmark, then set the cursor to the very end of the range.
// This is where we will insert/remove our tagline, and the start of the new range of text
Word.Range r = SigDoc.Bookmarks.get_Item(ref oBookmarkName).Range;
object collapseEnd = Word.WdCollapseDirection.wdCollapseEnd;
r.Collapse(ref collapseEnd);
string[] taglines = GetRssItem(); // Get tagline information from the RSS XML file and place into an array
// Loop through the array and insert each line of text separated by a newline
foreach (string taglineText in taglines)
r.InsertAfter(taglineText + "\n");
r.InsertAfter("\n");
// Add formatting to HTML/RTF messages
if (bf != "olFormatPlain" && bf != "olFormatUnspecified")
{
SigDoc.Hyperlinks.Add(r, taglines[2]); // turn the link text into a hyperlink
r.Font.Underline = 0; // remove the hyperlink underline
r.Font.Color = Word.WdColor.wdColorGray45; // change all text to Gray45
r.Font.Size = 8; // Change the font size to 8 point
r.Font.Name = "Arial"; // Change the font to Arial
}
r.NoProofing = -1; // turn off spelling/grammar check for this range of text
object range1 = r;
SigDoc.Bookmarks.Add(oOffsiteBookmark, ref range1); // define this range as our custom bookmark
if (bf != "olFormatPlain" && bf != "olFormatUnspecified")
{
// Make the first line BOLD only for HTML/RTF messages
Word.Find f = r.Find;
f.Text = taglines[0];
f.MatchWholeWord = true;
f.Execute();
while (f.Found)
{
r.Font.Bold = -1;
f.Execute();
}
}
else
{
// otherwise turn the plain text hyperlink into an active hyperlink
// this is done here instead of above due to the extra formatting needed for HTML/RTF text
Word.Find f = r.Find;
f.Text = taglines[2];
f.MatchWholeWord = true;
f.Execute();
SigDoc.Hyperlinks.Add(r, taglines[2]);
}
r.NoProofing = -1; // disable spelling/grammar checking on the updated range
r.Collapse(collapseEnd);
}
The problem is that Microsoft converts the "Office HTML" (I'm not sure the proper term) to normal HTML before it fires the ItemSend() event, which causes the _MailAutoSig bookmark to disappear.
The only way to get the _MailAutoSig bookmark back is to first CANCEL the ItemSend() event, then fire off a timer to run a function which will in turn access the email object and manipulate it how you want, add a user property to mark the email has been processed, and then send the email again.
For example:
Dim modItem As Object 'need to hold the item somewhere so the timer can access it Sub object_ItemSend(ByVal Item As Object, Cancel As Boolean) If Item.UserProperties.Item("isModded") Is Nothing Then 'User has composed a mail and hit "Send", we need to make our modifications to the signature though modItem = item Cancel = True 'cancel the Send so we can make the modifications mytimer.Enabled = True 'fire off a timer to make the modifications Exit Sub Else Item.UserProperties.Item("isModded").Delete 'this flag will keep the email from ping-ponging between ItemSend and the timer End If End Sub '10 millisecond timer? I think the cancel is almost instant, but experiment Sub mytimer_Timer() mytimer.Enabled = False If Not modItem Is Nothing Then modItem.HtmlBody = ...... the signature bookmark will be intact again, so make your modifications ...... modItem.UserProperties.Add("isModded", olText) 'no ping-pong modItem.Send 'send it again modItem = Nothing End If End Sub
I had to do something similar for a project where some Outlook fields were not set until I was in the ItemSend() event, so I was forcing the email to send, get my information, then cancel the send. It worked great.
Now, this was written off the top of my head, so I'm sure the code above will not be perfect, but it should give you the idea of what needs to be done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With