From 835e769f97eda4ff3ecc16ddca6d36c5496dc50d Mon Sep 17 00:00:00 2001 From: Zhao Yuhang <2546789017@qq.com> Date: ćšć, 06 3æ 2025 18:32:04 +0800 Subject: [PATCH] fix build with old win-sdk --- src/core/shared/qwkwindowsextra_p.h | 107 ++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h index f7be35e..3bd086e 100644 --- a/src/core/shared/qwkwindowsextra_p.h +++ b/src/core/shared/qwkwindowsextra_p.h @@ -14,18 +14,51 @@ // version without notice, or may even be removed. // -#include <shellscalingapi.h> -#include <dwmapi.h> -#include <timeapi.h> - #include <QWKCore/qwindowkit_windows.h> -#include <QtCore/private/qsystemlibrary_p.h> +#include <QtCore/QtMath> #include <QtGui/QGuiApplication> #include <QtGui/QStyleHints> #include <QtGui/QPalette> +#include <QtCore/private/qsystemlibrary_p.h> + // Don't include this header in any header files. + +typedef struct _MARGINS +{ + int cxLeftWidth; + int cxRightWidth; + int cyTopHeight; + int cyBottomHeight; +} MARGINS, *PMARGINS; + +typedef enum MONITOR_DPI_TYPE { + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI +} MONITOR_DPI_TYPE; + +typedef struct _DWM_BLURBEHIND +{ + DWORD dwFlags; + BOOL fEnable; + HRGN hRgnBlur; + BOOL fTransitionOnMaximized; +} DWM_BLURBEHIND, *PDWM_BLURBEHIND; + +extern "C" { + UINT WINAPI GetDpiForWindow(HWND); + int WINAPI GetSystemMetricsForDpi(int, UINT); + HRESULT WINAPI GetDpiForMonitor(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *); + HRESULT WINAPI DwmFlush(); + HRESULT WINAPI DwmIsCompositionEnabled(BOOL*); + HRESULT WINAPI DwmGetWindowAttribute(HWND, DWORD, PVOID, DWORD); + HRESULT WINAPI DwmSetWindowAttribute(HWND, DWORD, LPCVOID, DWORD); + HRESULT WINAPI DwmExtendFrameIntoClientArea(HWND, const MARGINS*); + HRESULT WINAPI DwmEnableBlurBehindWindow(HWND, const DWM_BLURBEHIND*); +} // extern "C" namespace QWK { @@ -158,7 +191,7 @@ namespace { struct DynamicApis { - static const DynamicApis &instance() { + static inline const DynamicApis &instance() { static const DynamicApis inst; return inst; } @@ -167,7 +200,6 @@ DYNAMIC_API_DECLARE(DwmFlush); DYNAMIC_API_DECLARE(DwmIsCompositionEnabled); - DYNAMIC_API_DECLARE(DwmGetCompositionTimingInfo); DYNAMIC_API_DECLARE(DwmGetWindowAttribute); DYNAMIC_API_DECLARE(DwmSetWindowAttribute); DYNAMIC_API_DECLARE(DwmExtendFrameIntoClientArea); @@ -176,9 +208,6 @@ DYNAMIC_API_DECLARE(GetSystemMetricsForDpi); DYNAMIC_API_DECLARE(AdjustWindowRectExForDpi); DYNAMIC_API_DECLARE(GetDpiForMonitor); - DYNAMIC_API_DECLARE(timeGetDevCaps); - DYNAMIC_API_DECLARE(timeBeginPeriod); - DYNAMIC_API_DECLARE(timeEndPeriod); #undef DYNAMIC_API_DECLARE @@ -190,7 +219,7 @@ SetPreferredAppModePtr pSetPreferredAppMode = nullptr; private: - DynamicApis() { + inline DynamicApis() { #define DYNAMIC_API_RESOLVE(DLL, NAME) \ p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME)) @@ -206,16 +235,10 @@ QSystemLibrary dwmapi(QStringLiteral("dwmapi")); DYNAMIC_API_RESOLVE(dwmapi, DwmFlush); DYNAMIC_API_RESOLVE(dwmapi, DwmIsCompositionEnabled); - DYNAMIC_API_RESOLVE(dwmapi, DwmGetCompositionTimingInfo); DYNAMIC_API_RESOLVE(dwmapi, DwmGetWindowAttribute); DYNAMIC_API_RESOLVE(dwmapi, DwmSetWindowAttribute); DYNAMIC_API_RESOLVE(dwmapi, DwmExtendFrameIntoClientArea); DYNAMIC_API_RESOLVE(dwmapi, DwmEnableBlurBehindWindow); - - QSystemLibrary winmm(QStringLiteral("winmm")); - DYNAMIC_API_RESOLVE(winmm, timeGetDevCaps); - DYNAMIC_API_RESOLVE(winmm, timeBeginPeriod); - DYNAMIC_API_RESOLVE(winmm, timeEndPeriod); #undef DYNAMIC_API_RESOLVE @@ -232,7 +255,7 @@ #undef UNDOC_API_RESOLVE } - ~DynamicApis() = default; + inline ~DynamicApis() = default; Q_DISABLE_COPY(DynamicApis) }; @@ -345,8 +368,11 @@ if (!registry.isValid()) { return false; } - auto value = registry.value<DWORD>(L"ColorPrevalence"); - return value.value_or(false); + auto value = registry.dwordValue(L"ColorPrevalence"); + if (!value.second) { + return false; + } + return value.first; } inline bool isHighContrastModeEnabled() { @@ -368,8 +394,11 @@ if (!registry.isValid()) { return false; } - auto value = registry.value<DWORD>(L"AppsUseLightTheme"); - return value.value_or(false); + auto value = registry.dwordValue(L"AppsUseLightTheme"); + if (!value.second) { + return false; + } + return !value.first; #endif } @@ -379,8 +408,10 @@ } BOOL enabled = FALSE; const DynamicApis &apis = DynamicApis::instance(); - const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; - return SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, attr, &enabled, sizeof(enabled))) && enabled; + const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE + : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; + return SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, attr, &enabled, sizeof(enabled))) && + enabled; } inline QColor getAccentColor() { @@ -391,13 +422,13 @@ if (!registry.isValid()) { return {}; } - auto value = registry.value<DWORD>(L"AccentColor"); - if (!value) { + auto value = registry.dwordValue(L"AccentColor"); + if (!value.second) { return {}; } // The retrieved value is in the #AABBGGRR format, we need to // convert it to the #AARRGGBB format which Qt expects. - QColor color = QColor::fromRgba(*value); + QColor color = QColor::fromRgba(value.first); if (!color.isValid()) { return {}; } @@ -407,7 +438,7 @@ inline quint32 getDpiForWindow(HWND hwnd) { const DynamicApis &apis = DynamicApis::instance(); - if (apis.pGetDpiForWindow) { // Win10 + if (apis.pGetDpiForWindow) { // Win10 return apis.pGetDpiForWindow(hwnd); } else if (apis.pGetDpiForMonitor) { // Win8.1 HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); @@ -429,7 +460,14 @@ if (apis.pGetSystemMetricsForDpi) { return apis.pGetSystemMetricsForDpi(index, dpi); } - return ::GetSystemMetrics(index); + const int result = ::GetSystemMetrics(index); + // GetSystemMetrics() always give you scaled value. + if (dpi != USER_DEFAULT_SCREEN_DPI) { + return result; + } + const qreal dpr = qreal(dpi) / qreal(USER_DEFAULT_SCREEN_DPI); + // ### Not sure how Windows itself rounds non-integer value. + return qFloor(qreal(result) / dpr); } inline quint32 getWindowFrameBorderThickness(HWND hwnd) { @@ -442,19 +480,28 @@ } } if (isWin10OrGreater()) { - return static_cast<quint32>(qreal(1) * qreal(getDpiForWindow(hwnd)) / qreal(USER_DEFAULT_SCREEN_DPI)); + const quint32 dpi = getDpiForWindow(hwnd); + // When DPI is 96, it should be 1px. + return getSystemMetricsForDpi(SM_CXBORDER, dpi); } + // There's no such thing (a visible frame border line) before Win10. return 0; } inline quint32 getResizeBorderThickness(HWND hwnd) { const quint32 dpi = getDpiForWindow(hwnd); + // When DPI is 96, SM_CXSIZEFRAME is 4px, SM_CXPADDEDBORDER is also 4px, + // so the result should be 8px. This result won't be affected by OS version, + // it's 8px in Win7, and so in Win11. return getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); } inline quint32 getTitleBarHeight(HWND hwnd) { const quint32 dpi = getDpiForWindow(hwnd); + // When DPI is 96, SM_CYCAPTION is 23px, so the result should be 31px. + // However, according to latest MS design manual, the title bar height + // should be 32px, maybe there's some rounding issue. return getSystemMetricsForDpi(SM_CYCAPTION, dpi) + getSystemMetricsForDpi(SM_CYSIZEFRAME, dpi) + getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); -- Gitblit v1.9.1