unickq
unickq

Reputation: 3303

How to get the text value from Point using Microsoft UI Automation?

I'm looking for the ways to improve performance of finding text on focused AutomationElement (point). I already have code like this. It uses UIAComWrapper and pretty slow.

 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;
    }

Upvotes: 2

Views: 3333

Answers (2)

Guy Barker - Microsoft
Guy Barker - Microsoft

Reputation: 574

Another option would be to try using the native Windows UIA API through a managed wrapper generated by the tlbimp tool. As a test, I just generated the wrapper in the following way...

"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

I then wrote the code below and referenced the wrapper in the C# project.

The code gets the UIA element at the point of interest, and requests that information saying whether the element supports the Value pattern should be cached at the time we get the element. This means that once we have the element, we can learn whether it supports the Value pattern without having to make another cross-proc call.

It would be interesting to compare the performance of this code working at the element you're interested in, relative to the managed .NET UIA API and the use of the 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...
}

Upvotes: 3

unickq
unickq

Reputation: 3303

Found solution. 2 seconds vs 7 seconds using 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;
}

Upvotes: 2

Related Questions