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