1

I am creating a C# VSTO add-in for Outlook 2010. I am attempting to generate a hyperlink at the insertion point of the active outgoing message that is being worked on (the hyperlink is inserted via a button on the message window ribbon). All other functions of the add-in (ribbon button, accessing the ActiveInspector().CurrentItem, etc.) work fine. I am working with this code:

object linktext = txtDisplayText.Text;
object result = "MY URL";
object missObj = Type.Missing;

Outlook.MailItem currentMessage = 
     Globals.ThisAddIn.Application.ActiveInspector().CurrentItem;
Word.Document doc = currentMessage.GetInspector.WordEditor;
object oRange = doc.Windows[1].Selection;
doc.Application.Selection.Hyperlinks.Add
    (oRange, ref result, ref missObj, ref missObj, ref linktext, ref missObj);

When I run this code I get the message "Command failed." I suspect I am missing something either in regards to how Outlook uses Microsoft Word's editor for Outlook messages or in the way I have specified the selection object in oRange. Any help is very much appreciated.

joeschwa
  • 3,083
  • 1
  • 21
  • 41

2 Answers2

2

This issue was indeed caused by the way the selection was defined for the Hyperlinks.Add command. Instead of an object type, the selection needed to be typed as a Microsoft Word Selection (due to the fact that Outlook uses Word as its editor):

Word.Selection objSel = doc.Windows[1].Selection;

So to insert a hyperlink at the insertion point of an Outlook message during composition, the code has using statements for both Word and Outlook:

using Outlook = Microsoft.Office.Interop.Outlook;
using Word = Microsoft.Office.Interop.Word;

And then this code:

object linktext = txtDisplayText.Text;
object result = "MY URL";
object missObj = Type.Missing;

Outlook.MailItem currentMessage = 
     Globals.ThisAddIn.Application.ActiveInspector().CurrentItem;
Word.Document doc = currentMessage.GetInspector.WordEditor;
Word.Selection objSel = doc.Windows[1].Selection;
doc.Hyperlinks.Add
     (objSel.Range, ref result, ref missObj, ref missObj, ref linktext, ref missObj);

Two other adjustments are worth noting. Because a Word.Selection type was used for the anchor of the hyperlink, the Hyperlinks.Add command needed to be changed from doc.Application.Selection.Hyperlinks.Add to doc.Hyperlinks.Add. And because Outlook uses Microsoft's Word editor, the anchor for doc.Hyperlinks.Add used a range: objSel.Range.

joeschwa
  • 3,083
  • 1
  • 21
  • 41
  • Hey joe, thank you for posting your answer. It helped me a lot actually. But one minor thing. If you were to add a new line to the hyperlink, how would you do it? I am calling your code in a loop to add multiple hyperlinks but adding System.Environment.NewLine to my linktext results in a wired icon showing on the new line before my next link. Much appreciated! – pixel Aug 16 '16 at 19:46
  • 1
    @dbnex14 I think you want to add the new line to the range object that contains the link. Try `objSel.Range.Text = @"\r\n";` Here's additional info: [How to Programmatically Insert Text into Word Documents](https://msdn.microsoft.com/en-us/library/6b9478cs.aspx) – joeschwa Aug 17 '16 at 02:41
  • Thanks but that is just adding string "\r\n". I also tried setting just to "\n" or objSel.Range.Text = System.Environment.NewLine but that wouldn't add new line either. Much appreciated Joe! – pixel Aug 17 '16 at 16:48
  • 1
    @dbnex14 Am I misunderstanding? Don't you want to output a hyperlink followed by a newline followed by another link, etc? I see you've posted this question here: [Outlook VSTO - Add new line to WordEditor Document Hyperlink](http://stackoverflow.com/questions/38983496/outlook-vsto-add-new-line-to-wordeditor-document-hyperlink). If I have time I'll play with the code this evening and continue this conversation where you posted this question (linked above). – joeschwa Aug 17 '16 at 21:59
  • You are correct, that is exactly what I want but doing objSel.Range.Text=@"\r\n" as you suggested just inserts "\r\n" string without new line. If I have 10 links, I want them to show in 10 lines one under the other. As you can see in my post you refered to above, I use System.Environment.NewLine concatenated to the link. That works but shows the wired character at the beginning of each line. I am referencing Microsoft.Interop 14 (which is I believe Office 2010) library in my project. – pixel Aug 17 '16 at 22:05
  • 1
    @dbnex14 I posted my answer where your SO question appears. Apologies for typing `@"\r\n"` in my comment above. Was a typo and should not have the "@" symbol (which makes the backslash a literal string character instead of starting the escape sequence). In any case, ignore the comment completely as I now understand what's going on and have detailed what I believe to be the correct answer with your SO question. Cheers. – joeschwa Aug 18 '16 at 05:56
  • I'll take a look but I do remember trying several things including just "\n". I'll take a look at your answer and let you know. Much appreciated Joe! – pixel Aug 18 '16 at 15:26
0

Use the HTMLBody property of the MailItem class for modifying the message body (inserting a hyperlink) in the ItemSend event handler instead. You need to find the place where to paste a hyperlink <a href=.../>, modify the HTML well formed string and assign it back.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Eugene, the `ItemSend` event handler intercepts the message after the user sends it. I am using a custom ribbon button that I placed in the message ribbon for the user to insert the hyperlink and then continue working on the message. The `HTMLBody` property replaces the entire Outlook message, but I wish to insert text at the message text's insertion point (where one would see text appear when typing). I currently believe that I need to alter the range in some way to stop the `Hyperlinks.Add` from failing. – joeschwa Aug 07 '15 at 12:36
  • You need to insert a hyperlink in the existing HTML markup and then set it back. The `HTMLBody` property doesn't replace the entire Outlook message. What code did you try? – Eugene Astafiev Aug 07 '15 at 16:08
  • Eugene, `HTMLBody` wasn't the answer. See my code above. Thanks. – joeschwa Aug 07 '15 at 17:15
  • `HTMLBody` is an alternative way for getting the job done. – Eugene Astafiev Aug 07 '15 at 17:29
  • Eugene, if you'd like to post your code for making `HTMLBody` work with adding a hyperlink at the insertion point in an outgoing Outlook message (and returning the insertion point to the user's previous editable point after the hyperlink is created) I think myself and others would benefit from it. – joeschwa Aug 07 '15 at 17:37
  • @EugeneAstafiev Yes, using HTMLBody works but it is an alternative. In some cases, we might not want to use HTMLBody but WordEditor. – pixel Aug 16 '16 at 19:47