UIAutomation 方法 ElementFromPoint() 在 Windows 10 从记事本中检索了不正确的元素
UIAutomation method ElementFromPoint() retrieves an incorrect element from Notepad on Windows 10
我们正在开发 C# Windows 表单应用程序并使用 UI 自动化来记录用户 activity。我们的应用程序将其 DPI-awareness 声明为 Per-monitor,因此系统不会对其进行坐标虚拟化。
在 Windows 10,我们 运行 遇到了 Notepad 的问题:执行屏幕缩放后,返回了不正确的元素当调用 UI方法 ElementFromPoint()
时传递了正确的物理坐标 。此外,CurrentBoundingRectangle()
调用返回的 BoundingRectangle 坐标也不正确:除以当前屏幕比例值,即 1.5 表示 150%。
有没有人遇到过这个问题,你是怎么解决的?
背景
并非记事本 window 的所有 UI 元素都受到影响:只有系统按钮和主菜单项。其他元素,如主文本区域、滚动条、window 标题、对话框按钮、子菜单项,都得到了正确处理。
考虑以下测试代码:
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 上,此代码 returns“文件”主菜单项的元素和 BoundingRectangle 不正确:
MouseDown received: X=735 Y=391
UIA element: Name=Application
Rect=[left=475 top=249 right=822 bot=268]
系统按钮的 BoundingRectangle 不正确:
MouseDown received: X=701 Y=282
UIA element: Name=System
Rect=[left=453 top=183 right=475 bot=205]
并为其他 UI 控件(即文件 -> 保存子菜单项)更正元素和 BoundingRectangle:
MouseDown received: X=1386 Y=666
UIA element: Name=Save
Rect=[left=1320 top=652 right=1452 bot=691]
这些结果不会在声明为 System-DPI-aware.
的旧版记事本上重现
例如,在 Windows 上检索到 7 个总是正确的元素和边界矩形。
此外,我已经在 Win 10 上测试了实现 Per-monitor DPI-awareness 模式的其他应用程序:Acrobat Reader DC、Edge、Skype、Slack、Explorer。这些应用程序的主菜单也得到了正确处理:检索了正确的元素和边界矩形。
因此 Windows 10 的记事本 Per-monitor 模式实现可能存在问题。
经过大量测试,我发现原因出在“首选 32 位”标志中:当为可执行项目启用它时,从记事本中检索到不正确的 UIA 元素和边界矩形。
启用“首选 32 位”:
(注意菜单元素边框位置 and the clicked point )
禁用“首选 32 位”:
我们正在开发 C# Windows 表单应用程序并使用 UI 自动化来记录用户 activity。我们的应用程序将其 DPI-awareness 声明为 Per-monitor,因此系统不会对其进行坐标虚拟化。
在 Windows 10,我们 运行 遇到了 Notepad 的问题:执行屏幕缩放后,返回了不正确的元素当调用 UI方法 ElementFromPoint()
时传递了正确的物理坐标 。此外,CurrentBoundingRectangle()
调用返回的 BoundingRectangle 坐标也不正确:除以当前屏幕比例值,即 1.5 表示 150%。
有没有人遇到过这个问题,你是怎么解决的?
背景
并非记事本 window 的所有 UI 元素都受到影响:只有系统按钮和主菜单项。其他元素,如主文本区域、滚动条、window 标题、对话框按钮、子菜单项,都得到了正确处理。
考虑以下测试代码:
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 上,此代码 returns“文件”主菜单项的元素和 BoundingRectangle 不正确:
MouseDown received: X=735 Y=391
UIA element: Name=Application
Rect=[left=475 top=249 right=822 bot=268]
系统按钮的 BoundingRectangle 不正确:
MouseDown received: X=701 Y=282
UIA element: Name=System
Rect=[left=453 top=183 right=475 bot=205]
并为其他 UI 控件(即文件 -> 保存子菜单项)更正元素和 BoundingRectangle:
MouseDown received: X=1386 Y=666
UIA element: Name=Save
Rect=[left=1320 top=652 right=1452 bot=691]
这些结果不会在声明为 System-DPI-aware.
的旧版记事本上重现例如,在 Windows 上检索到 7 个总是正确的元素和边界矩形。
此外,我已经在 Win 10 上测试了实现 Per-monitor DPI-awareness 模式的其他应用程序:Acrobat Reader DC、Edge、Skype、Slack、Explorer。这些应用程序的主菜单也得到了正确处理:检索了正确的元素和边界矩形。
因此 Windows 10 的记事本 Per-monitor 模式实现可能存在问题。
经过大量测试,我发现原因出在“首选 32 位”标志中:当为可执行项目启用它时,从记事本中检索到不正确的 UIA 元素和边界矩形。
启用“首选 32 位”:
(注意菜单元素边框位置
禁用“首选 32 位”: