Windows: fixed wrong layout in maximized frame after changing screen scale factor (issue #904)

Windows binaries built and signed locally in clean workspace
This commit is contained in:
Karl Tauber
2024-11-17 19:41:54 +01:00
parent ee9e238592
commit c37712b0f0
10 changed files with 173 additions and 2 deletions

View File

@@ -309,6 +309,8 @@ public class FlatWindowsNativeWindowBorder
WM_ENTERSIZEMOVE = 0x0231,
WM_EXITSIZEMOVE = 0x0232,
WM_DPICHANGED = 0x02E0,
WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320;
// WM_SIZE wParam
@@ -501,6 +503,22 @@ public class FlatWindowsNativeWindowBorder
isMoving = true;
break;
case WM_DPICHANGED:
LRESULT lResult = User32Ex.INSTANCE.CallWindowProc( defaultWndProc, hwnd, uMsg, wParam, lParam );
// if window is maximized and DPI/scaling changed, then Windows
// does not send a subsequent WM_SIZE message and Java window bounds,
// which depend on scale factor, are not updated
boolean isMaximized = User32Ex.INSTANCE.IsZoomed( hwnd );
if( isMaximized ) {
MyRECT r = new MyRECT( new Pointer( lParam.longValue() ) );
int width = r.right - r.left;
int height = r.bottom - r.top;
User32Ex.INSTANCE.CallWindowProc( defaultWndProc, hwnd, WM_SIZE, new WPARAM( SIZE_MAXIMIZED ), MAKELPARAM( width, height ) );
}
return lResult;
case WM_ERASEBKGND:
// do not erase background while the user is moving the window,
// otherwise there may be rendering artifacts on HiDPI screens with Java 9+
@@ -818,6 +836,13 @@ public class FlatWindowsNativeWindowBorder
return (low & 0xffff) | ((high & 0xffff) << 16);
}
/**
* Same implementation as MAKELPARAM(l, h) macro in winuser.h.
*/
private LPARAM MAKELPARAM( int low, int high ) {
return new LPARAM( MAKELONG( low, high ) );
}
/**
* Same implementation as RGB(r,g,b) macro in wingdi.h.
*/
@@ -937,6 +962,23 @@ public class FlatWindowsNativeWindowBorder
}
}
//---- class MyRECT -------------------------------------------------------
@FieldOrder( { "left", "top", "right", "bottom" } )
public static class MyRECT
extends Structure
{
public int left;
public int top;
public int right;
public int bottom;
public MyRECT( Pointer pointer ) {
super( pointer );
read();
}
}
//---- class MENUITEMINFO -------------------------------------------------
@FieldOrder( { "cbSize", "fMask", "fType", "fState", "wID", "hSubMenu",