如何使用 Microsoft UI Automation 从 Point 获取文本值?
How to get the text value from Point using Microsoft UI Automation?
我正在寻找提高在聚焦 AutomationElement(点)上查找文本的性能的方法。
我已经有这样的代码了。它使用 UIAComWrapper 并且非常慢。
public static string GetValueFromNativeElementFromPoint(Point p)
{
var element = UIAComWrapper::System.Windows.Automation.AutomationElement.FromPoint(p);
var pattern =
((UIAComWrapper::System.Windows.Automation.LegacyIAccessiblePattern)
element.GetCurrentPattern(UIAComWrapper::System.Windows.Automation.LegacyIAccessiblePattern.Pattern));
return pattern.Current.Value;
}
找到解决方案。 2 秒对 7 秒 使用 UIAComWrapper。
public static string GetValueFromNativeElementFromPoint2(Point p)
{
var element = AutomationElement.FromPoint(p);
object patternObj;
if (element.TryGetCurrentPattern(ValuePattern.Pattern, out patternObj))
{
var valuePattern = (ValuePattern) patternObj;
return valuePattern.Current.Value;
}
return null;
}
另一种选择是通过 tlbimp 工具生成的托管包装器尝试使用本机 Windows UIA API。作为测试,我只是按以下方式生成了包装器...
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\x64\tlbimp.exe" c:\windows\system32\uiautomationcore.dll /out:Interop.UIAutomationCore.dll
然后我编写了下面的代码并在 C# 项目中引用了包装器。
代码在感兴趣的点获取 UIA 元素,并请求在我们获取元素时缓存说明该元素是否支持值模式的信息。这意味着一旦我们拥有该元素,我们就可以了解它是否支持值模式,而无需进行另一个跨进程调用。
相对于托管 .NET UIA API 和 UIAComWrapper 的使用,比较这段代码在您感兴趣的元素上的性能会很有趣。
IUIAutomation uiAutomation = new CUIAutomation8();
int patternIdValue = 10002; // UIA_ValuePatternId
IUIAutomationCacheRequest cacheRequestValuePattern = uiAutomation.CreateCacheRequest();
cacheRequestValuePattern.AddPattern(patternIdValue);
IUIAutomationElement element = uiAutomation.ElementFromPointBuildCache(pt, cacheRequestValuePattern);
IUIAutomationValuePattern valuePattern = element.GetCachedPattern(patternIdValue);
if (valuePattern != null)
{
// Element supports the Value pattern...
}
我正在寻找提高在聚焦 AutomationElement(点)上查找文本的性能的方法。 我已经有这样的代码了。它使用 UIAComWrapper 并且非常慢。
public static string GetValueFromNativeElementFromPoint(Point p)
{
var element = UIAComWrapper::System.Windows.Automation.AutomationElement.FromPoint(p);
var pattern =
((UIAComWrapper::System.Windows.Automation.LegacyIAccessiblePattern)
element.GetCurrentPattern(UIAComWrapper::System.Windows.Automation.LegacyIAccessiblePattern.Pattern));
return pattern.Current.Value;
}
找到解决方案。 2 秒对 7 秒 使用 UIAComWrapper。
public static string GetValueFromNativeElementFromPoint2(Point p)
{
var element = AutomationElement.FromPoint(p);
object patternObj;
if (element.TryGetCurrentPattern(ValuePattern.Pattern, out patternObj))
{
var valuePattern = (ValuePattern) patternObj;
return valuePattern.Current.Value;
}
return null;
}
另一种选择是通过 tlbimp 工具生成的托管包装器尝试使用本机 Windows UIA API。作为测试,我只是按以下方式生成了包装器...
"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\x64\tlbimp.exe" c:\windows\system32\uiautomationcore.dll /out:Interop.UIAutomationCore.dll
然后我编写了下面的代码并在 C# 项目中引用了包装器。
代码在感兴趣的点获取 UIA 元素,并请求在我们获取元素时缓存说明该元素是否支持值模式的信息。这意味着一旦我们拥有该元素,我们就可以了解它是否支持值模式,而无需进行另一个跨进程调用。
相对于托管 .NET UIA API 和 UIAComWrapper 的使用,比较这段代码在您感兴趣的元素上的性能会很有趣。
IUIAutomation uiAutomation = new CUIAutomation8();
int patternIdValue = 10002; // UIA_ValuePatternId
IUIAutomationCacheRequest cacheRequestValuePattern = uiAutomation.CreateCacheRequest();
cacheRequestValuePattern.AddPattern(patternIdValue);
IUIAutomationElement element = uiAutomation.ElementFromPointBuildCache(pt, cacheRequestValuePattern);
IUIAutomationValuePattern valuePattern = element.GetCachedPattern(patternIdValue);
if (valuePattern != null)
{
// Element supports the Value pattern...
}