Search code examples
c#winformswindows-10notepaddpi-aware

UIAutomation method ElementFromPoint() retrieves an incorrect element from Notepad on Windows 10


We are developing a C# Windows Forms App and use UI Automation to record user activity. Our app declares its DPI-awareness as Per-monitor, so the system doesn't lie to it with coordinate virtualization.

On Windows 10 we ran into an issue with Notepad: after a screen scaling performed, an incorrect element is returned when calling UIA method ElementFromPoint() with correct physical coordinates passed. Also, coordinates of its BoundingRectangle returned by a CurrentBoundingRectangle() call are also incorrect: divided by the current screen scale value, i.e. 1.5 for 150%.

Has anyone encountered this problem before and how did you solve it?

Background

Not all UI elements of the Notepad window are affected: only System button and Main menu items. Other elements, like main text area, scroller, window title, dialog buttons, submenu items, are handled properly.

Consider the following test code:

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);
    }
}

On Win 10 this code returns an incorrect element and BoundingRectangle for the "File" main menu item:

MouseDown received: X=735 Y=391

UIA element: Name=Application

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

Just incorrect BoundingRectangle for the System button:

MouseDown received: X=701 Y=282

UIA element: Name=System

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

And correct element and BoundingRectangle for other UI controls (i.e. File -> Save submenu item):

MouseDown received: X=1386 Y=666

UIA element: Name=Save

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

These results are not reproducing on older versions of Notepad that declares itself as System-DPI-aware.

For instance, on Windows 7 always correct elements and bounding rects are retrieved.

Also, I've tested other apps on Win 10 that implement Per-monitor DPI-awareness mode: Acrobat Reader DC, Edge, Skype, Slack, Explorer. Main menus of these apps are handled properly too: correct elements and bounding rects are retrieved.

So possibly there is a problem in a Per-monitor mode implementation of Notepad for Windows 10.


Solution

  • After tons of testing I've found out that the cause was in the "Prefer 32-bit" flag: when it's enabled for the executable project, incorrect UIA elements and bounding rectangles were retrieved from Notepad.

    "Prefer 32-bit" enabled:

    (pay attention to the menu element bounding box location enter image description here and the clicked point enter image description here)

    enter image description here

    "Prefer 32-bit" disabled:

    enter image description here