Как получить идентификатор автоматизации окна элементов управления в стороннем приложении с помощью UIAutomation в определенных координатах экрана

Я использую UIAutomation и пытаюсь получить идентификатор окна любого элемента управления в сторонних приложениях. Я хочу знать, как узнать идентификатор элемента управления по определенной координате на экране.

Пример: у меня на рабочем столе запущены Калькулятор, Блокнот и Word. Все они работают и частично делят экран. Я хочу иметь возможность запускать свою программу, а затем щелкать в любом месте экрана и получать идентификатор окна основного элемента управления (если он есть под мышью).

Что мне нужно использовать для достижения этой функциональности. Я понимаю, что мне нужен какой-то хук для мыши, но реальная проблема заключается в том, как получить идентификатор окна (а не дескриптор окна) элемента управления на экране, где была нажата мышь.


person ResVic    schedule 20.03.2014    source источник


Ответы (2)


AutomationElement.FromPoint() вернет элемент автоматизации в заданной точке. Получив это, вы можете тривиально получить идентификатор автоматизации:

private string ElementFromCursor()
{
    // Convert mouse position from System.Drawing.Point to System.Windows.Point.
    System.Windows.Point point = new System.Windows.Point(Cursor.Position.X, Cursor.Position.Y);
    AutomationElement element = AutomationElement.FromPoint(point);
    string autoIdString;
    object autoIdNoDefault = element.GetCurrentPropertyValue(AutomationElement.AutomationIdProperty, true);
    if (autoIdNoDefault == AutomationElement.NotSupported)
    {
           // TODO Handle the case where you do not wish to proceed using the default value.
    }
    else
    {
        autoIdString = autoIdNoDefault as string;
    }
    return autoIdString;
}
person Eric Brown    schedule 20.03.2014

Если я правильно понимаю, чего вы пытаетесь достичь, это-> Щелкните в любой точке экрана, получите идентификатор окна базового элемента, если таковой имеется, из запущенных элементов:

Если это так, следующее должно помочь/подсказать идею (ПРИМЕЧАНИЕ. Это будет распространяться не только на позицию курсора, но и продолжит поиск по оси X на 100 пикселей с интервалом 10):

 /// <summary>
    /// Gets the automation identifier of underlying element.
    /// </summary>
    /// <returns></returns>
    public static string GetTheAutomationIDOfUnderlyingElement()
    {
        string requiredAutomationID = string.Empty;
        System.Drawing.Point currentLocation = Cursor.Position;//add you current location here
        AutomationElement aeOfRequiredPaneAtTop = GetElementFromPoint(currentLocation, 10, 100);
        if (aeOfRequiredPaneAtTop != null)
        {
            return aeOfRequiredPaneAtTop.Current.AutomationId;
        }
        return string.Empty;
    }
    /// <summary>
    /// Gets the element from point.
    /// </summary>
    /// <param name="startingPoint">The starting point.</param>
    /// <param name="interval">The interval.</param>
    /// <param name="maxLengthToTraverse">The maximum length to traverse.</param>
    /// <returns></returns>
    public static AutomationElement GetElementFromPoint(Point startingPoint, int interval, int maxLengthToTraverse)
    {
        AutomationElement requiredElement = null;
        for (Point p = startingPoint; ; )
        {
            requiredElement = AutomationElement.FromPoint(new System.Windows.Point(p.X, p.Y));
            Console.WriteLine(requiredElement.Current.Name);
            if (requiredElement.Current.ControlType.Equals(ControlType.Window))
            {
                return requiredElement;

            }
            if (p.X > (startingPoint.X + maxLengthToTraverse))
                break;
            p.X = p.X + interval;
        }
        return null;
    }
person Ronak Agrawal    schedule 18.11.2014