diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java index 444bbb54250..9e3d32df788 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java @@ -39,6 +39,7 @@ public class OS extends C { /** * Values taken from https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions */ + public static final int WIN32_BUILD_WIN8_1 = 9600; // "Windows 8.1" public static final int WIN32_BUILD_WIN10_1607 = 14393; // "Windows 10 August 2016 Update" public static final int WIN32_BUILD_WIN10_1809 = 17763; // "Windows 10 October 2018 Update" public static final int WIN32_BUILD_WIN10_2004 = 19041; // "Windows 10 May 2020 Update" @@ -1069,6 +1070,7 @@ public class OS extends C { public static final int PLANES = 0xe; public static final int PM_NOREMOVE = 0x0; public static final int PM_NOYIELD = 0x2; + public static final int PW_RENDERFULLCONTENT = 0x2; // undocumented ( >= Windows 8.1) public static final int QS_HOTKEY = 0x0080; public static final int QS_KEY = 0x0001; public static final int QS_MOUSEMOVE = 0x0002; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java index 66cc5ee1e24..e60309bde07 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java @@ -2219,7 +2219,15 @@ public boolean print (GC gc) { } int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; OS.RedrawWindow (topHandle, null, 0, flags); - printWidget (topHandle, hdc, gc); + int printWindowFlags = 0; + if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN8_1) { + /* + * Undocumented flag in windows, which also allows the capturing + * of GPU-drawn areas, e.g. an embedded Edge WebView2. + */ + printWindowFlags |= OS.PW_RENDERFULLCONTENT; + } + printWidget (topHandle, hdc, gc, printWindowFlags); if (gdipGraphics != 0) { OS.RestoreDC(hdc, state); Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc); @@ -2227,7 +2235,7 @@ public boolean print (GC gc) { return true; } -void printWidget (long hwnd, long hdc, GC gc) { +void printWidget (long hwnd, long hdc, GC gc, int printWindowFlags) { /* * Bug in Windows. For some reason, PrintWindow() * returns success but does nothing when it is called @@ -2311,7 +2319,7 @@ void printWidget (long hwnd, long hdc, GC gc) { if ((bits1 & OS.WS_VISIBLE) == 0) { OS.ShowWindow (hwnd, OS.SW_SHOW); } - success = OS.PrintWindow (hwnd, hdc, 0); + success = OS.PrintWindow (hwnd, hdc, printWindowFlags); if ((bits1 & OS.WS_VISIBLE) == 0) { OS.ShowWindow (hwnd, OS.SW_HIDE); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java index 0277d353dec..357fa87b9cc 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Group.java @@ -294,7 +294,7 @@ boolean mnemonicMatch (char key) { } @Override -void printWidget (long hwnd, long hdc, GC gc) { +void printWidget (long hwnd, long hdc, GC gc, int printWindowFlags) { /* * Bug in Windows. For some reason, PrintWindow() * returns success but does nothing when it is called @@ -307,7 +307,7 @@ void printWidget (long hwnd, long hdc, GC gc) { if ((bits & OS.WS_VISIBLE) == 0) { OS.ShowWindow (hwnd, OS.SW_SHOW); } - success = OS.PrintWindow (hwnd, hdc, 0); + success = OS.PrintWindow (hwnd, hdc, printWindowFlags); if ((bits & OS.WS_VISIBLE) == 0) { OS.ShowWindow (hwnd, OS.SW_HIDE); } @@ -334,6 +334,14 @@ void printWidget (long hwnd, long hdc, GC gc) { Control [] children = _getChildren (); Rectangle rect = getBoundsInPixels (); OS.IntersectClipRect (hdc, 0, 0, rect.width, rect.height); + // When looping over child windows and printWindowFlags has + // PW_RENDERFULLCONTENT set, then the printed content is always + // rendered at the top-left of the passed hdc. + // clear that flag + // This should be not an issue, since with PW_RENDERFULLCONTENT set + // the problem above (push button) does not appear to occurr. + // To be on the safe side, clear the flag when dealing with children + printWindowFlags &= ~OS.PW_RENDERFULLCONTENT; for (int i=children.length - 1; i>=0; --i) { Point location = children [i].getLocationInPixels (); int graphicsMode = OS.GetGraphicsMode(hdc); @@ -346,7 +354,7 @@ void printWidget (long hwnd, long hdc, GC gc) { long topHandle = children [i].topHandle(); int bits = OS.GetWindowLong (topHandle, OS.GWL_STYLE); if ((bits & OS.WS_VISIBLE) != 0) { - children [i].printWidget (topHandle, hdc, gc); + children [i].printWidget (topHandle, hdc, gc, printWindowFlags); } if (graphicsMode == OS.GM_ADVANCED) { float [] lpXform = {1, 0, 0, 1, -location.x, -location.y};