Метод UIAutomation ElementFromPoint() извлекает неверный элемент из Блокнота в Windows 10

Мы разрабатываем приложение Windows Forms на C# и используем автоматизацию пользовательского интерфейса для регистрации активности пользователей. Наше приложение объявляет о поддержке DPI как Per-monitor, поэтому система не обманывает его виртуализацией координат.

В Windows 10 возникла проблема с Блокнотом: после масштабирования экрана при вызове метода UI A возвращается неверный элемент ElementFromPoint() с правильными физическими координатами. Кроме того, координаты его BoundingRectangle возвращаются CurrentBoundingRectangle() вызов также неверен: делится на текущее значение масштаба экрана, то есть 1,5 на 150%.

Кто-нибудь сталкивался с этой проблемой раньше и как вы ее решили?

Фон

Это касается не всех элементов пользовательского интерфейса окна "Блокнот": только кнопка "Система" и пункты главного меню. Другие элементы, такие как основная текстовая область, скроллер, заголовок окна, кнопки диалога, элементы подменю, обрабатываются правильно.

Рассмотрим следующий тестовый код:

private CUIAutomation automation = new CUIAutomation();
public async Task GetElement(int x, int y)
{
    try
    {
        Debug.WriteLine($"MouseDown received: X={x} Y={y}");
        await Task.Run(() =>
        {
            // Retrieving an UIA element lying on physical coordinates
            tagPOINT point = new tagPOINT { x = x, y = y };
            IUIAutomationElement clickedElement = automation.ElementFromPoint(point);
            var elementName = clickedElement.GetCurrentPropertyValue(30005);
            var elementRect = clickedElement.CurrentBoundingRectangle;

            // Actually retrieved UIA element
            Debug.WriteLine($"UIA element: Name={elementName} " +
                $"Rect=[left={elementRect.left} top={elementRect.top} right={elementRect.right} bot={elementRect.bottom}]");
        });
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
    }
}

На Win 10 этот код возвращает неверный элемент и BoundingRectangle для пункта главного меню "Файл":

MouseDown получил: X=735 Y=391

Элемент МСА: Имя = Приложение

Rect=[слева =475 сверху =249 справа =822 бота =268]

Просто неверный прямоугольник BoundingRectangle для кнопки System:

MouseDown получен: X=701 Y=282

Элемент МСА: Имя = Система

Rect=[слева =453 сверху =183 справа =475 бот =205]

И исправьте элемент и BoundingRectangle для других элементов управления пользовательского интерфейса (например, Файл -> Сохранить элемент подменю):

MouseDown получил: X=1386 Y=666

Элемент МСА: Имя = Сохранить

Rect=[слева =1320 сверху =652 справа =1452 бота =691]

Эти результаты не воспроизводятся в более старых версиях Блокнота, который объявляет себя системно-DPI-совместимым.

Например, в Windows 7 всегда правильные элементы и ограничивающие точки извлекаются.

Кроме того, я протестировал другие приложения на Win 10, которые реализуют режим поддержки DPI для каждого монитора: Acrobat Reader DC, Edge, Skype, Slack, Explorer. Основные меню этих приложений также обрабатываются правильно: извлекаются правильные элементы и ограничивающие рамки.

Так что, возможно, проблема в реализации режима "Блок-монитор" в Notepad для Windows 10.

0 ответов

После множества тестов я обнаружил, что причина кроется в флаге "Предпочитать 32-битный": когда он включен для исполняемого проекта, некорректные элементы UIA и ограничивающие прямоугольники извлекались из Блокнота.

"Предпочитать 32-битный" включен:

(обратите внимание на расположение ограничительной рамки элемента меню и точку щелчка )

"Предпочитать 32-битный" отключен:

Другие вопросы по тегам