@@ -319,6 +319,8 @@ PyImaging_DisplayModeWin32(PyObject* self, PyObject* args)
319319/* -------------------------------------------------------------------- */
320320/* Windows screen grabber */
321321
322+ typedef HANDLE (__stdcall* Func_SetThreadDpiAwarenessContext )(HANDLE );
323+
322324PyObject *
323325PyImaging_GrabScreenWin32 (PyObject * self , PyObject * args )
324326{
@@ -329,6 +331,9 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
329331 HDC screen , screen_copy ;
330332 DWORD rop ;
331333 PyObject * buffer ;
334+ HANDLE dpiAwareness ;
335+ HMODULE user32 ;
336+ Func_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContext_function ;
332337
333338 if (!PyArg_ParseTuple (args , "|ii" , & includeLayeredWindows , & all_screens ))
334339 return NULL ;
@@ -339,6 +344,17 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
339344 screen = CreateDC ("DISPLAY" , NULL , NULL , NULL );
340345 screen_copy = CreateCompatibleDC (screen );
341346
347+ // added in Windows 10 (1607)
348+ // loaded dynamically to avoid link errors
349+ user32 = LoadLibraryA ("User32.dll" );
350+ SetThreadDpiAwarenessContext_function =
351+ (Func_SetThreadDpiAwarenessContext )
352+ GetProcAddress (user32 , "SetThreadDpiAwarenessContext" );
353+ if (SetThreadDpiAwarenessContext_function != NULL ) {
354+ // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = ((DPI_CONTEXT_HANDLE)-3)
355+ dpiAwareness = SetThreadDpiAwarenessContext_function ((HANDLE ) - 3 );
356+ }
357+
342358 if (all_screens ) {
343359 x = GetSystemMetrics (SM_XVIRTUALSCREEN );
344360 y = GetSystemMetrics (SM_YVIRTUALSCREEN );
@@ -349,6 +365,12 @@ PyImaging_GrabScreenWin32(PyObject* self, PyObject* args)
349365 height = GetDeviceCaps (screen , VERTRES );
350366 }
351367
368+ if (SetThreadDpiAwarenessContext_function != NULL ) {
369+ SetThreadDpiAwarenessContext_function (dpiAwareness );
370+ }
371+
372+ FreeLibrary (user32 );
373+
352374 bitmap = CreateCompatibleBitmap (screen , width , height );
353375 if (!bitmap )
354376 goto error ;
0 commit comments