UIAutomation方法ElementFromPoint()从Windows 10上的记事本中检索不正确的元素

时间:2018-05-29 18:52:38

标签: c# winforms windows-10 notepad dpi-aware

我们正在开发C#Windows窗体应用程序并使用UI自动化来记录用户活动。我们的应用程序将其DPI感知声明为Per-monitor,因此系统不会因协调虚拟化而对其产生影响。

在Windows 10上,我们在执行屏幕缩放后遇到记事本的问题,在调用传递了正确物理坐标的UIA方法ElementFromPoint()时返回了错误的元素< / strong>即可。此外,CurrentBoundingRectangle()调用返回的BoundingRectangle坐标也不正确:除以当前屏幕比例值,即1.5%表示150%。

之前是否有人遇到此问题,您是如何解决的?

背景

并非所有记事本窗口的UI元素都会受到影响:仅限系统按钮和主菜单项。其他元素,如主文本区域,滚动条,窗口标题,对话框按钮,子菜单项,都可以正确处理。

考虑以下测试代码:

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上,此代码为“File”主菜单项返回一个不正确的元素和BoundingRectangle:

  

MouseDown收到:X = 735 Y = 391

     

UIA元素:名称=应用

     

Rect = [left = 475 top = 249 right = 822 bot = 268]

系统按钮只是不正确的BoundingRectangle:

  

MouseDown收到:X = 701 Y = 282

     

UIA元素:名称=系统

     

Rect = [left = 453 top = 183 right = 475 bot = 205]

为其他UI控件更正元素和BoundingRectangle(即文件 - &gt;保存子菜单项):

  

收到MouseDown:X = 1386 Y = 666

     

UIA元素:名称=保存

     

Rect = [left = 1320 top = 652 right = 1452 bot = 691]

这些结果不能在旧版本的Notepad上重现,它声明自己可以识别System-DPI。

例如,在Windows 7上,始终更正元素并检索边界值。

此外,我在Win 10上测试了其他应用程序,这些应用程序实现了每监视器DPI感知模式:Acrobat Reader DC,Edge,Skype,Slack,Explorer。这些应用程序的主菜单也可以正确处理:检索正确的元素和边界值。

因此,Windows 10记事本的每监视器模式实现可能存在问题。

1 个答案:

答案 0 :(得分:0)

经过大量测试,我发现原因是在“ Prefer 32-bit”标志中:当为可执行项目启用它时,从记事本中检索了不正确的UIA元素和边界矩形。

启用“首选32位”:

(请注意菜单元素边界框位置enter image description here和单击点enter image description here

enter image description here

“首选32位”已禁用:

enter image description here