pywinauto: target position is wrong for _perform_click in some cases

Expected Behavior

pywinauto.controls.hwndwrapper._perform_click should simulate the click behavior correctly.

Actual Behavior

when the “Dispaly -> Scale and layout -> Change the size of text, apps and other items” setting for windows 10 OS is NOT 100%, the target position of pywinauto.controls.hwndwrapper._perform_click may need to be adjusted according to the scale ratio.

Steps to Reproduce the Problem

  1. set “dispaly -> scale and layout -> change the size of text, apps and other items” to be 200%

  2. use pywinauto with win32 backend to get an item from a SysTreeView32 control in an app ,and then call the click() method for this item

Short Example of Code to Demonstrate the Problem

            tree_view = app.top_window().child_window(
                control_id=129, class_name="SysTreeView32"
            )
            target_item = tree_view.wrapper_object().get_item(['query','target'])
            target_item.click()

A raw method to solve this problem

  1. add import win32print into hwndwrapper.py

  2. insert the following code into pywinauto.controls.hwndwrapper._perform_click near line 1663 in hwndwrapper.py

    scale_ratio = win32print.GetDeviceCaps(win32gui.GetDC(ctrl.handle), win32con.LOGPIXELSX) / 96
    if scale_ratio != 1.0:
        coords = [int(item*scale_ratio) for item in coords]

after

    if absolute:
        coords = ctrl.client_to_screen(coords)

Relevent Problem

pywinauto.mouse._perform_click_input may also need to be adjusted.

Specifications

  • Pywinauto version: 0.6.8
  • Python version and bitness: 3.7
  • Platform and OS: windows 10

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Comments: 15 (5 by maintainers)

Commits related to this issue

Most upvoted comments

@airelil I’ve found addtional docs relevent to this issue:

  1. DWM scaling
  2. High DPI Settings in Windows

This issue may be caused by a setting in which the coordinates got from the API and the coordinates displayed do not match(differ by the scale ratio). To figure out the exact way to get the right coordinates in different situations is cumbersome, a simple way to handle this issue is to add extra parameters to let the user to decide whether to make an adjustment and the scale ratio to adjust the coordinates。 Finally, people who use pywinauto include me should thank you contributors of this project. 😃

okay… it cost me one day to figure out why _listview_item.click() chooses wrong item… 😦

I also spent a little time to find the real cause,so I opened this issue to remind other users。