从阅读窗格中获取点击的超链接

Get clicked hyperlink from reading pane

我有一个 Outlook VSTO 加载项,它向超链接上下文菜单添加了一个按钮(使用 idMso="ContextMenuReadOnlyMailHyperlink"),我想获得点击的超链接。

感谢 post how to add a new option to context menu of hyperlink in an email for Outlook 2010?,当邮件在新 window 中打开时,我设法获得了点击的超链接。 post 建议在阅读窗格中对邮件使用 ActiveInlineResponseWordEditor,但这对我不起作用,因为它总是 null

根据 post ,在此上下文中不能使用 ActiveInlineResponseWordEditor,而应使用 Explorer.Selection。我已尝试按照该方向进行操作,但没有获得点击的超链接。 Word.Selection 似乎指向邮件的开头而不是指向单击的超链接,因为它 returns 指向邮件的第一个字母。

如何从阅读窗格中获取点击的超链接?

// mail in new window
if (control.Context is Inspector inspector)
{
    Document document = inspector.WordEditor;
    if (document != null && document.Windows != null && document.Windows.Count > 0)
    {
        Microsoft.Office.Interop.Word.Selection word = document.Windows[1].Selection;
        if (word != null && word.Hyperlinks != null && word.Hyperlinks.Count > 0)
        {
            Hyperlink hyperlink = word.Hyperlinks[1];
            MessageBox.Show(hyperlink.Address); // output: the clicked hyperlink
        }
    }
}
// mail in reading pane
else if (control.Context is Explorer explorer)
{
    Microsoft.Office.Interop.Outlook.Selection selection = explorer.Selection;
    if (selection[1] is MailItem mailItem)
    {
        Inspector inspector = mailItem.GetInspector;
        Document document = inspector.WordEditor;
        if (document != null && document.Windows != null && document.Windows.Count > 0)
        {
            Microsoft.Office.Interop.Word.Selection word = document.Windows[1].Selection;
            if (word != null && word.Hyperlinks != null)
            {
                MessageBox.Show(word.Hyperlinks.Count.ToString()); // output: 0
                MessageBox.Show(word.Text); // output: the first letter of the mail
            }
        }
    }
}

您的算法必须是:

  1. 检查 Application.ActiveWindow 是否为 Inspector。如果是,请使用 Application.ActiveWindow.WordEditor
  2. 否则,将Application.ActiveWindow转换为Explorer
  3. 检查 Explorer.ActiveInlineResponseWordEditor 是否不为空。使用它。
  4. 否则,使用Explorer.PreviewPane.WordEditor

可以通过 Redemption's ReadingPane or Outlook 2016PreviewPane 获得点击的超链接。我选择了 PreviewPane,但请注意它仅适用于 Outlook 2016 或更新版本。

困难的部分是获得包含 PreviewPane 属性 的正确互操作引用。通常的做法是删除旧的程序集引用并在 COM 选项卡中添加对象库,但由于 GAC,这对我不起作用,我找不到成功绕过 GAC 的方法。我最终使用后期绑定来访问 属性.

在下面发布完整代码,希望它能帮助其他遇到同样问题的人,因为我在网上找到的所有其他答案都已过时或没有足够的信息来理解/复制它们。

public void GetSelected(Office.IRibbonControl control)
{
    Document document = null;
    // mail in new window
    if (control.Context is Inspector inspector)
    {
        document = inspector.WordEditor;
    }
    // mail in reading pane
    else if (control.Context is Explorer explorer)
    {
        try
        {
            // late binding for Explorer.PreviewPane.WordEditor
            Type eType = explorer.GetType();
            var pane = eType.InvokeMember(
                "PreviewPane",
                BindingFlags.GetProperty,
                null, explorer, new object[] { });
            Type pType = pane.GetType();
            document = pType.InvokeMember(
                "WordEditor",
                BindingFlags.GetProperty,
                null, pane, new object[] { }) as Document;
        }
        catch
        {
            MessageBox.Show("Require Outlook 2016 or newer");
            return;
        }
    }
    // get right clicked hyperlink from document
    if (document != null && document.Windows != null && document.Windows.Count > 0)
    {
        Microsoft.Office.Interop.Word.Selection selection = document.Windows[1].Selection;
        if (selection != null && selection.Hyperlinks != null && selection.Hyperlinks.Count > 0)
        {
            Hyperlink hyperlink = selection.Hyperlinks[1];
            // the right clicked hyperlink
            MessageBox.Show(hyperlink.Address);
        }
        else
        {
            MessageBox.Show("No selection or hyperlink");
        }
    } 
    else
    {
        MessageBox.Show("No document");
    }
}

仅供参考,我在 MSDN 上有 another post,其中有更多关于我尝试实现此解决方案的信息。