Метод 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-битный" отключен: