Win32api is not giving the correct coordinates with GetCursorPos() in python
Asked Answered
M

2

2

When using the win32api from pywin, I am getting incorrect values for the cursor position. My screen's resolution is 1920x1080, but when I use GetCursorPos() I have (0,0) in the top left and (1535,863) in the bottom right. The code I am using is as follows:

import win32api

def getCursor():
    print win32api.GetCursorPos()

I am trying this using python 2.7 on windows 10, but I was also getting this error in python 2.6 on windows 8. Is there any solution or workaround to this problem?

Mussel answered 12/9, 2015 at 17:5 Comment(1)
I get the correct positions. (0, 0) top left and (1919, 1199) bottom right. Windows 10, Python 2.7Blame
I
9

You are subject to DPI virtualization. Your application has not declared itself aware of high DPI and you have a font scaling of 125%.

If you want to avoid DPI virtualization either add the high DPI aware option to the application manifest or call either SetProcessDPIAware or SetProcessDPIAwareness.

Ieper answered 12/9, 2015 at 17:25 Comment(4)
import ctypes user32 = ctypes.windll.user32 user32.SetProcessDPIAware() Is that what you mean?Blame
Note that SetProcessDPIAware is deprecated.Vanpelt
@Mussel It's what you use on Vista or 7, or 8 IIRC. SetProcessDPIAwareness is new in 8.1 I think.Ieper
@Blame I added the code that you mentioned and I am now getting the correct cursor coordinates. I tried using SetProcessDPIAwareness but it gave me an attribute error saying that the function was not found. Thank you!Mussel
L
2

You can set the awareness level like this:

import ctypes
awareness = ctypes.c_int()
ctypes.windll.shcore.SetProcessDpiAwareness(2)

The awareness levels are defined as follows:

typedef enum _PROCESS_DPI_AWARENESS { 
    PROCESS_DPI_UNAWARE = 0,
    /*  DPI unaware. This app does not scale for DPI changes and is
        always assumed to have a scale factor of 100% (96 DPI). It
        will be automatically scaled by the system on any other DPI
        setting. */

    PROCESS_SYSTEM_DPI_AWARE = 1,
    /*  System DPI aware. This app does not scale for DPI changes.
        It will query for the DPI once and use that value for the
        lifetime of the app. If the DPI changes, the app will not
        adjust to the new DPI value. It will be automatically scaled
        up or down by the system when the DPI changes from the system
        value. */

    PROCESS_PER_MONITOR_DPI_AWARE = 2
    /*  Per monitor DPI aware. This app checks for the DPI when it is
        created and adjusts the scale factor whenever the DPI changes.
        These applications are not automatically scaled by the system. */
} PROCESS_DPI_AWARENESS;

Check this answer: https://mcmap.net/q/130842/-can-dpi-scaling-be-enabled-disabled-programmatically-on-a-per-session-basis

Lakitalaks answered 13/7, 2018 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.