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 <oliver.wolff@qt.io>
This commit is contained in:
Friedemann Kleint 2018-10-16 13:19:24 +02:00
parent 17fc079acd
commit 0aa27af801
3 changed files with 55 additions and 3 deletions

View File

@ -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<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());

View File

@ -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;

View File

@ -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);