Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SetProcessDpiAwareness Failed to fit High DPI in windows if once called #184

Open
narumi147 opened this issue Sep 16, 2020 · 0 comments
Open

Comments

@narumi147
Copy link
Contributor

General information:

  • OS name: Windows
  • OS version: Windows 10 version 2004
  • OS architecture: 64 bits
  • Resolutions:
    • Monitor 1: 1920x1080, scale 1.25 (Laptop)
    • Monitor 2: 1920x1080, scale 1.00 (External, Main)
  • Python version: 3.7.5
  • MSS version: 6.0.0

Description of the warning/error

Once first time setting DPI awareness is not PROCESS_PER_MONITOR_DPI_AWARE=2, mss will not fit DPI scaling for all monitors.

Details

According to Microsoft Docs SetProcessDpiAwareness:

Once API awareness is set for an app, any future calls to this API will fail.

This function will return S_OK=0 only if first time to set DPI awareness, otherwise return E_ACCESSDENIED=0x80070005=-2147024891. We can print the return value to check it.

Available DPI awareness setting functions including:

  • SetProcessDpiAwareness
  • SetProcessDpiAware should equals to SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE=1)
  • SetProcessDpiAwarenessContext not tested
  • SetThreadDpiAwarenessContext not tested

In this mss package, we use SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE=2) inside __init__. However some other python packages will just call SetProcessDpiAware() during import process, like mouseinfo / pyautogui / pyscreeze. It means that only monitor which startup program has the correct DPI awareness(PROCESS_SYSTEM_DPI_AWARE) while mostly we need PROCESS_PER_MONITOR_DPI_AWARE.

Then mss uses user32.EnumDisplayMonitors to get monitor RECT and this function is affected by DPI awareness setting.

Solution

Currently I have no idea about how to avoid E_ACCESSDENIED error, one possible way is to get the real resolution of monitors regardless of DPI awareness.

According to Microsoft Docs of functions with prefix EnumDisplaySettings, e.g. EnumDisplaySettingsA, EnumDisplaySettingsExA, EnumDisplaySettingsExW, EnumDisplaySettingsW :

This API does not participate in DPI virtualization. The output given is always in terms of physical pixels, and is not related to the calling context.

I think it may be a prefer way to obtain monitor information. But I never learned Windows programming, hope anyone else can help on this problem.

@BoboTiG BoboTiG added the Windows label Apr 8, 2023
@BoboTiG BoboTiG added the bug label Apr 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants