简体   繁体   English

Outlook 互操作添加正文

[英]Outlook Interop add body text

Updated to try and make the question more readable, following comments below更新以尝试使问题更具可读性,遵循以下评论

Scenario: user clicks reply in outlook 365 this opens a mailItem within the main window of outlook.场景:用户在 Outlook 365 中单击回复,这将在 Outlook 主窗口中打开一个 mailItem。 we are attempting to add text to the body of this mailItem.我们正在尝试将文本添加到此 mailItem 的正文中。

Currently my method can add text to the to and cc field of the imbedded mailItem but not the body.目前,我的方法可以将文本添加到嵌入 mailItem 的 to 和 cc 字段,但不能添加正文。 It will add text to the body, To, Cc, and Subject of a modal mailItem, with this modal open it will even add text to the mailItem's body that it would not work with previously.它将向模式 mailItem 的正文、收件人、抄送和主题添加文本,在此模式打开的情况下,它甚至会向 mailItem 的正文添加以前无法使用的文本。

When only the main window is open, the focusedClass is not present, so it hits the SendMessage method.当只打开主窗口时,focusedClass 不存在,因此它会触发 SendMessage 方法。

Question: How do you add text to the body of this mailItem?问题:如何将文本添加到此 mailItem 的正文中? When only the main Outlook window is open and the MailItem is imbedded in the main window.只有 Outlook 主窗口打开并且 MailItem 嵌入在主窗口中时。

So far I have looked at Spy++ and the Z order always changes so I cannot find a logical way to get a child window to work with, plus the structure for the mailItem is different while in the main window and modal.到目前为止,我已经查看了 Spy++,并且 Z 顺序总是在变化,所以我找不到让子窗口可以使用的合乎逻辑的方法,而且 mailItem 的结构在主窗口和模式中是不同的。

My current solution uses GetWindowThreadProcessId and GetCurrentThreadId to get the focused window, then the GetFocusClass to find the class, with this class obtained we finally call the below to insert the text:我目前的解决方案是使用GetWindowThreadProcessId和GetCurrentThreadId获取焦点窗口,然后GetFocusClass找到类,有了这个类我们最后调用下面的方法插入文本:

 if (focusedClass.ToLower() == "_wwg")
                InsertTextToEmailBody(text);
            else
                SendMessage(focused, EM_REPLACESEL, 0, newText);
private void InsertTextToEmailBody(string text)
        {
            var outlookApplication = GetOulookApplication();
            var activityInspector = outlookApplication.ActiveInspector();
            var currentItem = activityInspector?.CurrentItem;

            if (currentItem == null)
            {
                _log.Error("InsertTextToEmailBody could not find CurrentItem and cannot inject into email body");
                return;
            }

            var myInspector = ((MailItem) currentItem).GetInspector;
            var wdDoc = (Document) myInspector.WordEditor;
            var currentSelection = wdDoc.Application.Selection;

            if (currentSelection.Range?.Text?.Length > 0)
            {
                //The user has a selected range of text, replace that with transcription
                currentSelection.Range.Text = text;
                return;
            }

            // Store the user's current Overtype selection
            var userOvertype = wdDoc.Application.Options.Overtype;

            // Make sure Overtype is turned off.
            if (wdDoc.Application.Options.Overtype) wdDoc.Application.Options.Overtype = false;

            // Test to see if selection is an insertion point.
            if (currentSelection.Type == WdSelectionType.wdSelectionIP)
                currentSelection.TypeText(text);
            else if (currentSelection.Type == WdSelectionType.wdSelectionNormal)
            {
                // Move to start of selection.
                if (wdDoc.Application.Options.ReplaceSelection)
                {
                    object direction = WdCollapseDirection.wdCollapseStart;
                    currentSelection.Collapse(ref direction);
                }

                currentSelection.TypeText(text);
            }

            // Restore the user's Overtype selection
            wdDoc.Application.Options.Overtype = userOvertype;
        }

Not sure why you'd want to use GetFocus() etc. to find the HWND of the Word editor - the focus can be anywhere in the Inspector (eg Subject or To edit box), plus clicking on the ribbon can take the focus away from the Word editor even if it was there to begin with.不知道为什么要使用GetFocus()等来查找 Word 编辑器的HWND - 焦点可以在检查器中的任何位置(例如主题或编辑框),加上单击功能区可以将焦点移开来自 Word 编辑器,即使它一开始就在那里。

What works for me is the following:对我有用的是以下内容:

  1. QI/cast your Inspector object (eg retrieved from from Application.ActiveInspector ) to IOleWindow . QI/cast 您的Inspector对象(例如从Application.ActiveInspector检索)到IOleWindow Call IOleWindows.GetWindow() to get the top level HWND of the inspector.调用IOleWindows.GetWindow()以获取检查器的顶级HWND
  2. Call EnumChildWindows with a callback that calls GetClassName and compares it with "_WwG" .使用调用GetClassName并将其与"_WwG"进行比较的回调调用EnumChildWindows Note that in Office 12 and older the class name is "_WwF" .请注意,在 Office 12 及更早版本中,类名称为"_WwF"

I also not sure what is wrong with your code that uses Word Object Model to insert text.我也不确定您使用 Word 对象模型插入文本的代码有什么问题。 It looks perfectly fine to me (without actually debugging it), and it would be the preferable solution since it would work out-of-proc since SendMessage(EM_REPLACESEL) requires that both the caller and the target window are in the same process (since it takes a pointer to a text buffer).它对我来说看起来非常好(没有实际调试它),这将是更好的解决方案,因为它可以在进程外工作,因为SendMessage(EM_REPLACESEL)要求调用者和目标窗口都在同一个进程中(因为它需要一个指向文本缓冲区的指针)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM