@@ -320,25 +320,36 @@ typedef HANDLE(__stdcall *Func_SetThreadDpiAwarenessContext)(HANDLE);
320320
321321PyObject *
322322PyImaging_GrabScreenWin32 (PyObject * self , PyObject * args ) {
323- int x = 0 , y = 0 , width , height ;
324- int includeLayeredWindows = 0 , all_screens = 0 ;
323+ int x = 0 , y = 0 , width = -1 , height ;
324+ int includeLayeredWindows = 0 , screens = 0 ;
325325 HBITMAP bitmap ;
326326 BITMAPCOREHEADER core ;
327327 HDC screen , screen_copy ;
328+ HWND wnd ;
328329 DWORD rop ;
329330 PyObject * buffer ;
330331 HANDLE dpiAwareness ;
331332 HMODULE user32 ;
332333 Func_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContext_function ;
333334
334- if (!PyArg_ParseTuple (args , "|ii" , & includeLayeredWindows , & all_screens )) {
335+ if (!PyArg_ParseTuple (
336+ args , "|ii" F_HANDLE , & includeLayeredWindows , & screens , & wnd
337+ )) {
335338 return NULL ;
336339 }
337340
338341 /* step 1: create a memory DC large enough to hold the
339342 entire screen */
340343
341- screen = CreateDC ("DISPLAY" , NULL , NULL , NULL );
344+ if (screens == -1 ) {
345+ screen = GetDC (wnd );
346+ if (screen == NULL ) {
347+ PyErr_SetString (PyExc_OSError , "unable to get device context for handle" );
348+ return NULL ;
349+ }
350+ } else {
351+ screen = CreateDC ("DISPLAY" , NULL , NULL , NULL );
352+ }
342353 screen_copy = CreateCompatibleDC (screen );
343354
344355 // added in Windows 10 (1607)
@@ -351,11 +362,17 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) {
351362 dpiAwareness = SetThreadDpiAwarenessContext_function ((HANDLE )- 3 );
352363 }
353364
354- if (all_screens ) {
365+ if (screens == 1 ) {
355366 x = GetSystemMetrics (SM_XVIRTUALSCREEN );
356367 y = GetSystemMetrics (SM_YVIRTUALSCREEN );
357368 width = GetSystemMetrics (SM_CXVIRTUALSCREEN );
358369 height = GetSystemMetrics (SM_CYVIRTUALSCREEN );
370+ } else if (screens == -1 ) {
371+ RECT rect ;
372+ if (GetClientRect (wnd , & rect )) {
373+ width = rect .right ;
374+ height = rect .bottom ;
375+ }
359376 } else {
360377 width = GetDeviceCaps (screen , HORZRES );
361378 height = GetDeviceCaps (screen , VERTRES );
@@ -367,6 +384,10 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) {
367384
368385 FreeLibrary (user32 );
369386
387+ if (width == -1 ) {
388+ goto error ;
389+ }
390+
370391 bitmap = CreateCompatibleBitmap (screen , width , height );
371392 if (!bitmap ) {
372393 goto error ;
@@ -412,15 +433,23 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) {
412433
413434 DeleteObject (bitmap );
414435 DeleteDC (screen_copy );
415- DeleteDC (screen );
436+ if (screens == -1 ) {
437+ ReleaseDC (wnd , screen );
438+ } else {
439+ DeleteDC (screen );
440+ }
416441
417442 return Py_BuildValue ("(ii)(ii)N" , x , y , width , height , buffer );
418443
419444error :
420445 PyErr_SetString (PyExc_OSError , "screen grab failed" );
421446
422447 DeleteDC (screen_copy );
423- DeleteDC (screen );
448+ if (screens == -1 ) {
449+ ReleaseDC (wnd , screen );
450+ } else {
451+ DeleteDC (screen );
452+ }
424453
425454 return NULL ;
426455}
0 commit comments