背景信息
我正在研究Windows语音转文本应用程序。
识别语音后,应将文本插入当前具有键盘焦点的文本框(Think Word / Firefox /其他应用程序)。 要插入文本,我目前正在使用InputSimulatorPlus。
插入文本时,重要的一点是将可识别的文本设置为适合周围文本的格式,例如:
依此类推
问题
要能够设置文本格式,我需要 文本 和 插入符位置 。
目前,我一直在将UI Automation和NuGet Package与Text Pattern一起使用。 这对于所有支持“文本模式”的文本框都适用,但是许多程序不支持“文本模式”。
策略问题:我应该使用UI Automation之外的其他方法吗?
我注意到我要支持的许多应用程序不支持文本模式,但是支持值模式或旧式IAccessible模式(Microsoft Active Accessibility)。
我一直在研究使用Value Pattern并可以获取文本框的文本,但不是插入符号的位置。
using System.Windows.Automation;
using System.Windows.Automation.Text;
...
AutomationElement automationElement = AutomationElement.FocusedElement;
var elements = automationElement.FindAll(TreeScope.Element,
new AndCondition(
new PropertyCondition(AutomationElement.HasKeyboardFocusProperty, true),
new PropertyCondition(AutomationElement.IsValuePatternAvailableProperty, true)));
foreach (AutomationElement element in elements)
{
if (element.GetCurrentPattern(ValuePattern.Pattern) is ValuePattern valuePattern)
{
var text = valuePattern.Current.Value;
var caret = ? //How to get caret position?
Console.WriteLine($"Caret: {caret}, Text: {text}");
return (text,caret);
}
}
我也一直在研究使用Legacy IAccessible Pattern并可以获取文本框的文本,但不是插入符号的位置。
using System.Windows.Automation;
using System.Windows.Automation.Text;
...
AutomationElement automationElement = AutomationElement.FocusedElement;
var elements = automationElement.FindAll(TreeScope.Element,
new AndCondition(
new PropertyCondition(AutomationElement.HasKeyboardFocusProperty, true),
new PropertyCondition(AutomationElement.IsLegacyIAccessiblePatternAvailableProperty, true)));
foreach (AutomationElement element in elements)
{
if (element.GetCurrentPattern(LegacyIAccessiblePattern.Pattern) is LegacyIAccessiblePattern legazyAccessiblePattern)
{
var text = legazyAccessiblePattern.Current.Value;
var caret = ? //How to get caret position?
Console.WriteLine($"Caret: {caret}, Text: {text}");
return (text,caret);
}
}
主要问题:如何使用UI自动化获取给定文本框的插入符位置?
P.S。我知道这永远不会对所有应用程序都有效,但是如果它可以对大多数普通应用程序都适用,那就太好了。
答案 0 :(得分:1)
您不需要ValuePattern,而需要IUIAutomationTextPattern2
,它支持GetCaretRange。
如果您需要退回MSAA,这会很麻烦(而且您根本无法获得插入符号周围的文字)。 MSAA只是没有UIAutomation具有的文本支持。如果您真的不能使用UIAutomation,那么您唯一的实际选择是使用Text Services Framework,该文档记录不充分,因此没有得到广泛实施。如果您需要文本服务框架,则可能要看看my blog,它已经有一段时间没有更新了。
对于MSAA插入符号,请先调用GetGUIThreadInfo
。返回有关hwndCaret
的数据,hwndFocus
是当前包含插入符号的窗口。 (或者,如果hwndCaret
为NULL,则可以尝试使用IAccessible *pAccCaret = NULL;
VARIANT varCaret;
varCaret.vt = VT_I4;
varCaret.lVal = CHILDID_SELF;
if (SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_CARET, IID_IAccessible, (void **)&pAccCaret)))
{
hr = pAccCaret->accLocation( &rcCaret.left, &rcCaret.top, &rcCaret.right, &rcCaret.bottom, varCaret);
pAccCaret->Release();
}
。)使用这些窗口之一,您可以执行以下操作:
// route.js
actions: {
reloadModel() {
this.store.peekAll('my-model').forEach((r) => {
this.store.unloadRecord(r);
})
this.refresh(); // to force a fresh load of data from API
}
}