From 0aa27af8014f5344d604b3f4eaa5f0a2fb2b44e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 16 Oct 2018 13:19:24 +0200 Subject: [PATCH] Windows QPA: Add helper function to obtain DPI-dependent metrics on Windows 10 Use newly introduced SystemParametersInfoForDpi() API with some convenience overloads. Task-number: QTBUG-4362 Change-Id: I4c41c700007bf7cc4fd5868356e3145c136704c0 Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowscontext.cpp | 40 +++++++++++++++++++ .../platforms/windows/qwindowscontext.h | 14 +++++++ .../platforms/windows/qwindowstheme.cpp | 4 +- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4959ed952d..1f80ac5872 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -213,6 +213,7 @@ void QWindowsUser32DLL::init() enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling"); getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); + systemParametersInfoForDpi = (SystemParametersInfoForDpi)library.resolve("SystemParametersInfoForDpi"); } } @@ -916,6 +917,45 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) return result; } +bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out, + unsigned dpi) +{ + const BOOL result = QWindowsContext::user32dll.systemParametersInfoForDpi != nullptr && dpi != 0 + ? QWindowsContext::user32dll.systemParametersInfoForDpi(action, param, out, 0, dpi) + : SystemParametersInfo(action, param, out, 0); + return result == TRUE; +} + +bool QWindowsContext::systemParametersInfoForScreen(unsigned action, unsigned param, void *out, + const QPlatformScreen *screen) +{ + return systemParametersInfo(action, param, out, screen ? screen->logicalDpi().first : 0); +} + +bool QWindowsContext::systemParametersInfoForWindow(unsigned action, unsigned param, void *out, + const QPlatformWindow *win) +{ + return systemParametersInfoForScreen(action, param, out, win ? win->screen() : nullptr); +} + +bool QWindowsContext::nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi) +{ + memset(ncm, 0, sizeof(NONCLIENTMETRICS)); + ncm->cbSize = sizeof(NONCLIENTMETRICS); + return systemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm->cbSize, ncm, dpi); +} + +bool QWindowsContext::nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, + const QPlatformScreen *screen) +{ + return nonClientMetrics(ncm, screen ? screen->logicalDpi().first : 0); +} + +bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, const QPlatformWindow *win) +{ + return nonClientMetricsForScreen(ncm, win ? win->screen() : nullptr); +} + static inline QWindowsInputContext *windowsInputContext() { return qobject_cast(QWindowsIntegration::instance()->inputContext()); diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 19e9c26130..fd6c72668c 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -70,6 +70,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaTrayIcon) class QWindow; class QPlatformScreen; +class QPlatformWindow; class QWindowsMenuBar; class QWindowsScreenManager; class QWindowsTabletSupport; @@ -104,6 +105,7 @@ struct QWindowsUser32DLL typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND); typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); + typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT); // Windows pointer functions (Windows 8 or later). EnableMouseInPointer enableMouseInPointer = nullptr; @@ -132,6 +134,7 @@ struct QWindowsUser32DLL EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr; GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr; GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr; + SystemParametersInfoForDpi systemParametersInfoForDpi = nullptr; }; // Shell scaling library (Windows 8.1 onwards) @@ -237,6 +240,17 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + static bool systemParametersInfo(unsigned action, unsigned param, void *out, unsigned dpi = 0); + static bool systemParametersInfoForScreen(unsigned action, unsigned param, void *out, + const QPlatformScreen *screen = nullptr); + static bool systemParametersInfoForWindow(unsigned action, unsigned param, void *out, + const QPlatformWindow *win = nullptr); + static bool nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi = 0); + static bool nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, + const QPlatformScreen *screen = nullptr); + static bool nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, + const QPlatformWindow *win = nullptr); + static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue); QTouchDevice *touchDevice() const; diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index d01a7b0a8a..4b70e915a8 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -507,9 +507,7 @@ void QWindowsTheme::refreshFonts() if (!QGuiApplication::desktopSettingsAware()) return; NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); - + QWindowsContext::nonClientMetrics(&ncm); const QFont menuFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMenuFont); const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont); const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont);