BoboTiG / python-mss

An ultra fast cross-platform multiple screenshots module in pure Python using ctypes.
https://pypi.org/project/mss/
MIT License
1.01k stars 93 forks source link

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

Open narumi147 opened 4 years ago

narumi147 commented 4 years ago

General information:

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:

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.

Upvote & Fund

Fund with Polar