当我尝试使用UI Automation的UI自动化时,我只能在使用RangeFromPoint时获得第一个字符/单词

该代码适用于Word和Outlook但由于PowerPoint失败,因为只有文本框的第一个字符或第一个字被选中。 这是一个错误吗? 有没有解决方法? 在PowerPoint 2013中的简单PowerPoint幻灯片上试试这个。

private static async Task getText(double x, double y) { string result = null; try { var location = new System.Windows.Point(x, y); AutomationElement element = AutomationElement.FromPoint(location); object patternObj; if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj)) { var textPattern = (TextPattern)patternObj; var range = textPattern.RangeFromPoint(location); range.ExpandToEnclosingUnit(TextUnit.Word); range.Select(); var text = range.GetText(-1).TrimEnd('\r'); return text.Trim(); } else { return "no text found"; } } catch (Exception ex) { return ex.Message; } } 

您无法从屏幕截图中看到它,但鼠标处于“先”而不是“卡住”,但无论鼠标放在何处,它总是卡住。 也许这已在PowerPoint 2016中修复?

在此处输入图像描述

当我查看范围的边界框时,它始终是整个元素,而不是选定的单词。 这可能是RangeToPoint无法正常工作的问题的一部分。

原帖在MSDN上发布但没有回复……

更新。 如果我使用

 text = printRange(range, text); while (range.Move(TextUnit.Word, 1) > 0) { text += Environment.NewLine; text = printRange(range, text); } 

我明白了

在此处输入图像描述

此行为可能是由于PowerPoint 2013中的限制,我希望您无法使用UIA解决此问题。 当您调用RangeFromPoint()时,UIA提供程序命中鼠标(即实现IUIAutomationTextPattern :: RangeFromPoint()的那个)意味着返回鼠标光标所在的退化(即空)范围。 然后UIA客户端可以扩展返回的范围以获取周围的字符,单词,行或段落。

但是,正如您所指出的,PowerPoint 2013并没有这样做。 我刚刚编写了下面的测试代码,(使用tlbimp.exe生成的本机Windows UIA API的托管包装器),发现PowerPoint显然返回了光标下方整个文本框的TextRange。 当我运行代码时,我发现我确实在WordPad,Word 2013和PowerPoint OnLine中获得了光标下的预期字,但没有获得PowerPoint 2013.当我运行Inspect SDK的Text Explorer工具时,我得到了相同的结果工具。 下图显示了文本资源管理器报告,当鼠标hover在其中一个单词上时,从PowerPoint 2013返回的文本是文本框中的整个文本。

(我应该补充说下面的测试代码完全可以工作,我认为当前的显示缩放设置需要达到100%。我没有添加代码来解释其他一些活动的扩展。)

我不知道这是否已在PowerPoint 2016中修复,我将尝试调查并告知您。

谢谢,

家伙

在此处输入图像描述

 private void buttonGetTheText_Click(object sender, EventArgs e) { labelText.Text = "No text found."; IUIAutomation uiAutomation = new CUIAutomation8(); Point ptCursor = Cursor.Position; tagPOINT pt; pt.x = ptCursor.X; pt.y = ptCursor.Y; // Cache the Text pattern that's available through the element beneath // the mouse cursor, (if the Text pattern's supported by the element,) in // order to avoid another cross-process call to get the pattern later. int patternIdText = 10014; // UIA_TextPatternId IUIAutomationCacheRequest cacheRequestTextPattern = uiAutomation.CreateCacheRequest(); cacheRequestTextPattern.AddPattern(patternIdText); // Now get the element beneath the mouse. IUIAutomationElement element = uiAutomation.ElementFromPointBuildCache(pt, cacheRequestTextPattern); // Does the element support the Text pattern? IUIAutomationTextPattern textPattern = element.GetCachedPattern(patternIdText); if (textPattern != null) { // Now get the degenerative TextRange where the mouse is. IUIAutomationTextRange range = textPattern.RangeFromPoint(pt); if (range != null) { // Expand the range to include the word surrounding // the point where the mouse is. range.ExpandToEnclosingUnit(TextUnit.TextUnit_Word); // Show the word in the test app. labelText.Text = "Text is: \"" + range.GetText(256) + "\""; } } } 

我只能建议Python代码获取幻灯片的标题文本(例如)。 对不起,我没时间在C#上重写它。 您可以使用PowerPoint.Application COM对象和Power Point自动化的MSDN示例 。

 from __future__ import print_function import win32com.client as com pp = com.Dispatch('PowerPoint.Application') print(pp.Presentations[0].Slides[8].Shapes[0].TextFrame.TextRange.Text)