From cd6eb1a6e5f3ce4d551d9cb2167f66d654a1137b Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Wed, 1 Nov 2017 16:38:20 +0200 Subject: [PATCH] Win32: Improve window DPI change behavior When a window transitions between monitors with different scale/dpi settings: 1. It's automatically resized and repositioned by handling the WM_DPICHANGED event (Win8.1) 2. Its non-client area is automatically updated to match the new DPI (Win10) --- src/win32_init.c | 2 ++ src/win32_platform.h | 3 +++ src/win32_window.c | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/win32_init.c b/src/win32_init.c index ee7ccfdaa..737e113d9 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -98,6 +98,8 @@ static GLFWbool loadLibraries(void) _glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware) GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); + _glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling) + GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling"); _glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx) GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); diff --git a/src/win32_platform.h b/src/win32_platform.h index 1bfc638f4..5ac27efae 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -209,8 +209,10 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID* // user32.dll function pointer typedefs typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void); +typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND); typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); #define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_ +#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_ #define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_ // dwmapi.dll function pointer typedefs @@ -322,6 +324,7 @@ typedef struct _GLFWlibraryWin32 struct { HINSTANCE instance; PFN_SetProcessDPIAware SetProcessDPIAware_; + PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_; PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_; } user32; diff --git a/src/win32_window.c b/src/win32_window.c index 6d3e76cc3..06fbb5ed6 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -537,6 +537,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, break; } + + case WM_NCCREATE: + { + // Windows 10: enable automatic non-client area scaling + if (EnableNonClientDpiScaling) + { + EnableNonClientDpiScaling(hWnd); + } + break; + } } return DefWindowProcW(hWnd, uMsg, wParam, lParam); @@ -988,6 +998,19 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return 0; } + case WM_DPICHANGED: + { + // Resize and reposition the window to match the new DPI + RECT* const suggestedRect = (RECT*)lParam; + SetWindowPos(hWnd, NULL, + suggestedRect->left, + suggestedRect->top, + suggestedRect->right - suggestedRect->left, + suggestedRect->bottom - suggestedRect->top, + SWP_NOZORDER | SWP_NOACTIVATE); + return 0; + } + case WM_SETCURSOR: { if (LOWORD(lParam) == HTCLIENT)