From 9cb3392ce4617acb9e611937e425cb88539a2b62 Mon Sep 17 00:00:00 2001
From: Yuhang Zhao <2546789017@qq.com>
Date: Sat, 14 Nov 2020 20:42:16 +0800
Subject: [PATCH] Fix system metric is double scaled
Fixes: #36
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
---
examples/QMainWindow/TitleBar.ui | 18 ++++++-------
winnativeeventfilter.cpp | 43 ++++++++++++++++----------------
2 files changed, 30 insertions(+), 31 deletions(-)
diff --git a/examples/QMainWindow/TitleBar.ui b/examples/QMainWindow/TitleBar.ui
index 109bf3e..8183547 100644
--- a/examples/QMainWindow/TitleBar.ui
+++ b/examples/QMainWindow/TitleBar.ui
@@ -144,13 +144,13 @@
- 45
+ 46
31
- 45
+ 46
31
@@ -169,7 +169,7 @@
- 45
+ 46
31
@@ -185,13 +185,13 @@
- 45
+ 46
31
- 45
+ 46
31
@@ -211,7 +211,7 @@
- 45
+ 46
31
@@ -230,13 +230,13 @@
- 45
+ 46
31
- 45
+ 46
31
@@ -255,7 +255,7 @@
- 45
+ 46
31
diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp
index db42df4..7ec4252 100644
--- a/winnativeeventfilter.cpp
+++ b/winnativeeventfilter.cpp
@@ -1046,20 +1046,23 @@ void UpdateFrameMarginsForWindow(const HWND handle, const bool resetToDefault =
}
}
-int GetSystemMetricsForWindow(const HWND handle, const int index)
+int GetSystemMetricsForWindow(const HWND handle, const int index, const bool dpiAware = false)
{
Q_ASSERT(handle);
if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, handle)) {
if (coreData()->m_lpGetSystemMetricsForDpi) {
- return coreData()->m_lpGetSystemMetricsForDpi(index,
- static_cast(qRound(GetPreferedNumber(
- GetDotsPerInchForWindow(handle)))));
+ const UINT dpi = dpiAware ? qRound(GetPreferedNumber(GetDotsPerInchForWindow(handle)))
+ : m_defaultDotsPerInch;
+ return coreData()->m_lpGetSystemMetricsForDpi(index, dpi);
} else {
- return qRound(WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, index)
- * GetDevicePixelRatioForWindow(handle));
+ // Although Microsoft claims that GetSystemMetrics() is not DPI
+ // aware, it still returns a scaled value on Win7, Win8.1 and
+ // Win10.
+ const qreal dpr = dpiAware ? 1.0 : GetDevicePixelRatioForWindow(handle);
+ return qRound(WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, index) / dpr);
}
}
- return -1;
+ return 0;
}
void createUserData(const HWND handle, const WinNativeEventFilter::WINDOWDATA *data = nullptr)
@@ -1202,7 +1205,7 @@ void install()
// The standard values of border width, border height and title bar height
// when DPI is 96.
-const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 30;
+const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBarHeight = 31;
// The thickness of an auto-hide taskbar in pixels.
const int kAutoHideTaskbarThicknessPx = 2;
@@ -2192,11 +2195,10 @@ int WinNativeEventFilter::getSystemMetric(void *handle,
if (bw > 0) {
ret = qRound(bw * dpr);
} else {
- const int result_nondpi
- = WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CXSIZEFRAME)
- + WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CXPADDEDBORDER);
- const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CXSIZEFRAME)
- + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER);
+ const int result_nondpi = GetSystemMetricsForWindow(hwnd, SM_CXSIZEFRAME)
+ + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER);
+ const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CXSIZEFRAME, true)
+ + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER, true);
const int result = dpiAware ? result_dpi : result_nondpi;
ret = result > 0 ? result : qRound(m_defaultBorderWidth * dpr);
}
@@ -2206,11 +2208,10 @@ int WinNativeEventFilter::getSystemMetric(void *handle,
if (bh > 0) {
ret = qRound(bh * dpr);
} else {
- const int result_nondpi
- = WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CYSIZEFRAME)
- + WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics, 0, SM_CXPADDEDBORDER);
- const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CYSIZEFRAME)
- + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER);
+ const int result_nondpi = GetSystemMetricsForWindow(hwnd, SM_CYSIZEFRAME)
+ + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER);
+ const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CYSIZEFRAME, true)
+ + GetSystemMetricsForWindow(hwnd, SM_CXPADDEDBORDER, true);
const int result = dpiAware ? result_dpi : result_nondpi;
ret = result > 0 ? result : qRound(m_defaultBorderHeight * dpr);
}
@@ -2220,10 +2221,8 @@ int WinNativeEventFilter::getSystemMetric(void *handle,
if (tbh > 0) {
ret = qRound(tbh * dpr);
} else {
- const int result_nondpi = WNEF_EXECUTE_WINAPI_RETURN(GetSystemMetrics,
- 0,
- SM_CYCAPTION);
- const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CYCAPTION);
+ const int result_nondpi = GetSystemMetricsForWindow(hwnd, SM_CYCAPTION);
+ const int result_dpi = GetSystemMetricsForWindow(hwnd, SM_CYCAPTION, true);
const int result = dpiAware ? result_dpi : result_nondpi;
ret = result > 0 ? result : qRound(m_defaultTitleBarHeight * dpr);
}