From 9286c8b9c23a613f96636b8e2d1391d89cedd199 Mon Sep 17 00:00:00 2001 From: Zhao Yuhang <2546789017@qq.com> Date: 周六, 07 12月 2024 21:11:05 +0800 Subject: [PATCH] Win32 code cleanup & improve --- src/core/shared/qwkwindowsextra_p.h | 95 ++++++++++++----------- src/core/qwindowkit_windows.h | 84 +++++++++++++++----- src/core/qwindowkit_windows.cpp | 2 src/core/contexts/win32windowcontext.cpp | 10 - 4 files changed, 116 insertions(+), 75 deletions(-) diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp index 6d54ad6..3c7ba80 100644 --- a/src/core/contexts/win32windowcontext.cpp +++ b/src/core/contexts/win32windowcontext.cpp @@ -948,7 +948,7 @@ if (key == QStringLiteral("extra-margins")) { auto margins = qmargins2margins(attribute.value<QMargins>()); - return apis.pDwmExtendFrameIntoClientArea(hwnd, &margins) == S_OK; + return SUCCEEDED(apis.pDwmExtendFrameIntoClientArea(hwnd, &margins)); } if (key == QStringLiteral("dark-mode")) { @@ -962,12 +962,8 @@ } else { apis.pAllowDarkModeForApp(enable); } - for (const auto attr : { - _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, - _DWMWA_USE_IMMERSIVE_DARK_MODE, - }) { - apis.pDwmSetWindowAttribute(hwnd, attr, &enable, sizeof(enable)); - } + const auto attr = isWin1020H1OrGreater() ? _DWMWA_USE_IMMERSIVE_DARK_MODE : _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1; + apis.pDwmSetWindowAttribute(hwnd, attr, &enable, sizeof(enable)); apis.pFlushMenuThemes(); return true; diff --git a/src/core/qwindowkit_windows.cpp b/src/core/qwindowkit_windows.cpp index a9cc371..c022e26 100644 --- a/src/core/qwindowkit_windows.cpp +++ b/src/core/qwindowkit_windows.cpp @@ -8,9 +8,11 @@ static RTL_OSVERSIONINFOW GetRealOSVersionImpl() { HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); + Q_ASSERT(hMod); using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW); auto pRtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(::GetProcAddress(hMod, "RtlGetVersion")); + Q_ASSERT(pRtlGetVersion); RTL_OSVERSIONINFOW rovi{}; rovi.dwOSVersionInfoSize = sizeof(rovi); pRtlGetVersion(&rovi); diff --git a/src/core/qwindowkit_windows.h b/src/core/qwindowkit_windows.h index 20f24ef..8c5c7c0 100644 --- a/src/core/qwindowkit_windows.h +++ b/src/core/qwindowkit_windows.h @@ -30,6 +30,10 @@ # define RECT_HEIGHT(rect) ((rect).bottom - (rect).top) #endif +#ifndef USER_DEFAULT_SCREEN_DPI +# define USER_DEFAULT_SCREEN_DPI (96) +#endif + // Maybe undocumented Windows messages // https://github.com/tinysec/public/blob/master/win32k/MessageTable.md // https://ulib.sourceforge.io/doxy/a00239.html @@ -58,35 +62,53 @@ inline bool IsWindows1122H2OrGreater_Real() { RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); return (rovi.dwMajorVersion > 10) || - (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && - rovi.dwBuildNumber >= 22621); + (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 || + rovi.dwBuildNumber >= 22621)); } inline bool IsWindows11OrGreater_Real() { RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); return (rovi.dwMajorVersion > 10) || - (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && - rovi.dwBuildNumber >= 22000); + (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 || + rovi.dwBuildNumber >= 22000)); + } + + inline bool IsWindows1020H1OrGreater_Real() { + RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); + return (rovi.dwMajorVersion > 10) || + (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 || + rovi.dwBuildNumber >= 19041)); + } + + inline bool IsWindows102004OrGreater_Real() { + return IsWindows1020H1OrGreater_Real(); } inline bool IsWindows101903OrGreater_Real() { RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); return (rovi.dwMajorVersion > 10) || - (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && - rovi.dwBuildNumber >= 18362); + (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 || + rovi.dwBuildNumber >= 18362)); + } + + inline bool IsWindows1019H1OrGreater_Real() { + return IsWindows101903OrGreater_Real(); } inline bool IsWindows101809OrGreater_Real() { RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); return (rovi.dwMajorVersion > 10) || - (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && - rovi.dwBuildNumber >= 17763); + (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 || + rovi.dwBuildNumber >= 17763)); + } + + inline bool IsWindows10RS5OrGreater_Real() { + return IsWindows101809OrGreater_Real(); } inline bool IsWindows10OrGreater_Real() { RTL_OSVERSIONINFOW rovi = GetRealOSVersion(); - return (rovi.dwMajorVersion > 10) || - (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0); + return rovi.dwMajorVersion >= 10; } inline bool IsWindows8Point1OrGreater_Real() { @@ -110,7 +132,7 @@ // // Registry Helpers // - + #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) class QWK_CORE_EXPORT WindowsRegistryKey { public: @@ -119,7 +141,7 @@ ~WindowsRegistryKey(); - inline bool isValid() const; + bool isValid() const; void close(); QString stringValue(QStringView subKey) const; @@ -149,11 +171,10 @@ #elif QT_VERSION < QT_VERSION_CHECK(6, 8, 1) class WindowsRegistryKey : public QWinRegistryKey { public: - - explicit WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions = KEY_READ, REGSAM access = 0); + WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions = KEY_READ, REGSAM access = 0); template<typename T> - inline std::optional<T> value(QStringView subKey) const; + std::optional<T> value(QStringView subKey) const; }; template<> @@ -172,42 +193,59 @@ // Version Helpers // - static inline bool isWin8OrGreater() { + inline bool isWin8OrGreater() { static const bool result = Private::IsWindows8OrGreater_Real(); return result; } - static inline bool isWin8Point1OrGreater() { + inline bool isWin8Point1OrGreater() { static const bool result = Private::IsWindows8Point1OrGreater_Real(); return result; } - static inline bool isWin10OrGreater() { + inline bool isWin10OrGreater() { static const bool result = Private::IsWindows10OrGreater_Real(); return result; } - static inline bool isWin101809OrGreater() { + inline bool isWin101809OrGreater() { static const bool result = Private::IsWindows101809OrGreater_Real(); return result; } - static inline bool isWin101903OrGreater() { + inline bool isWin10RS5OrGreater() { + return isWin101809OrGreater(); + } + + inline bool isWin101903OrGreater() { static const bool result = Private::IsWindows101903OrGreater_Real(); return result; } - static inline bool isWin11OrGreater() { + inline bool isWin1019H1OrGreater() { + return isWin101903OrGreater(); + } + + inline bool isWin1020H1OrGreater() { + static const bool result = Private::IsWindows1020H1OrGreater_Real(); + return result; + } + + inline bool isWin102004OrGreater() { + return isWin1020H1OrGreater(); + } + + inline bool isWin11OrGreater() { static const bool result = Private::IsWindows11OrGreater_Real(); return result; } - static inline bool isWin1122H2OrGreater() { + inline bool isWin1122H2OrGreater() { static const bool result = Private::IsWindows1122H2OrGreater_Real(); return result; } - static inline bool isWin10Only() { + inline bool isWin10Only() { static const bool result = Private::IsWindows10Only_Real(); return result; }; diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h index 52d8943..f7be35e 100644 --- a/src/core/shared/qwkwindowsextra_p.h +++ b/src/core/shared/qwkwindowsextra_p.h @@ -239,96 +239,96 @@ } - static inline constexpr bool operator==(const POINT &lhs, const POINT &rhs) noexcept { + inline constexpr bool operator==(const POINT &lhs, const POINT &rhs) noexcept { return ((lhs.x == rhs.x) && (lhs.y == rhs.y)); } - static inline constexpr bool operator!=(const POINT &lhs, const POINT &rhs) noexcept { + inline constexpr bool operator!=(const POINT &lhs, const POINT &rhs) noexcept { return !operator==(lhs, rhs); } - static inline constexpr bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept { + inline constexpr bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept { return ((lhs.cx == rhs.cx) && (lhs.cy == rhs.cy)); } - static inline constexpr bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept { + inline constexpr bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept { return !operator==(lhs, rhs); } - static inline constexpr bool operator>(const SIZE &lhs, const SIZE &rhs) noexcept { + inline constexpr bool operator>(const SIZE &lhs, const SIZE &rhs) noexcept { return ((lhs.cx * lhs.cy) > (rhs.cx * rhs.cy)); } - static inline constexpr bool operator>=(const SIZE &lhs, const SIZE &rhs) noexcept { + inline constexpr bool operator>=(const SIZE &lhs, const SIZE &rhs) noexcept { return (operator>(lhs, rhs) || operator==(lhs, rhs)); } - static inline constexpr bool operator<(const SIZE &lhs, const SIZE &rhs) noexcept { + inline constexpr bool operator<(const SIZE &lhs, const SIZE &rhs) noexcept { return (operator!=(lhs, rhs) && !operator>(lhs, rhs)); } - static inline constexpr bool operator<=(const SIZE &lhs, const SIZE &rhs) noexcept { + inline constexpr bool operator<=(const SIZE &lhs, const SIZE &rhs) noexcept { return (operator<(lhs, rhs) || operator==(lhs, rhs)); } - static inline constexpr bool operator==(const RECT &lhs, const RECT &rhs) noexcept { + inline constexpr bool operator==(const RECT &lhs, const RECT &rhs) noexcept { return ((lhs.left == rhs.left) && (lhs.top == rhs.top) && (lhs.right == rhs.right) && (lhs.bottom == rhs.bottom)); } - static inline constexpr bool operator!=(const RECT &lhs, const RECT &rhs) noexcept { + inline constexpr bool operator!=(const RECT &lhs, const RECT &rhs) noexcept { return !operator==(lhs, rhs); } - static inline constexpr QPoint point2qpoint(const POINT &point) { + inline constexpr QPoint point2qpoint(const POINT &point) { return QPoint{int(point.x), int(point.y)}; } - static inline constexpr POINT qpoint2point(const QPoint &point) { + inline constexpr POINT qpoint2point(const QPoint &point) { return POINT{LONG(point.x()), LONG(point.y())}; } - static inline constexpr QSize size2qsize(const SIZE &size) { + inline constexpr QSize size2qsize(const SIZE &size) { return QSize{int(size.cx), int(size.cy)}; } - static inline constexpr SIZE qsize2size(const QSize &size) { + inline constexpr SIZE qsize2size(const QSize &size) { return SIZE{LONG(size.width()), LONG(size.height())}; } - static inline constexpr QRect rect2qrect(const RECT &rect) { + inline constexpr QRect rect2qrect(const RECT &rect) { return QRect{ QPoint{int(rect.left), int(rect.top) }, QSize{int(RECT_WIDTH(rect)), int(RECT_HEIGHT(rect))} }; } - static inline constexpr RECT qrect2rect(const QRect &qrect) { + inline constexpr RECT qrect2rect(const QRect &qrect) { return RECT{LONG(qrect.left()), LONG(qrect.top()), LONG(qrect.right()), LONG(qrect.bottom())}; } - static inline constexpr QMargins margins2qmargins(const MARGINS &margins) { + inline constexpr QMargins margins2qmargins(const MARGINS &margins) { return {margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight}; } - static inline constexpr MARGINS qmargins2margins(const QMargins &qmargins) { + inline constexpr MARGINS qmargins2margins(const QMargins &qmargins) { return {qmargins.left(), qmargins.right(), qmargins.top(), qmargins.bottom()}; } - static inline /*constexpr*/ QString hwnd2str(const WId windowId) { + inline /*constexpr*/ QString hwnd2str(const WId windowId) { // NULL handle is allowed here. return QLatin1String("0x") + QString::number(windowId, 16).toUpper().rightJustified(8, u'0'); } - static inline /*constexpr*/ QString hwnd2str(HWND hwnd) { + inline /*constexpr*/ QString hwnd2str(HWND hwnd) { // NULL handle is allowed here. return hwnd2str(reinterpret_cast<WId>(hwnd)); } - static inline bool isDwmCompositionEnabled() { + inline bool isDwmCompositionEnabled() { if (isWin8OrGreater()) { return true; } @@ -340,7 +340,7 @@ return SUCCEEDED(apis.pDwmIsCompositionEnabled(&enabled)) && enabled; } - static inline bool isWindowFrameBorderColorized() { + inline bool isWindowFrameBorderColorized() { WindowsRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)"); if (!registry.isValid()) { return false; @@ -349,14 +349,17 @@ return value.value_or(false); } - static inline bool isHighContrastModeEnabled() { + inline bool isHighContrastModeEnabled() { HIGHCONTRASTW hc{}; hc.cbSize = sizeof(hc); ::SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, FALSE); return (hc.dwFlags & HCF_HIGHCONTRASTON); } - static inline bool isDarkThemeActive() { + inline bool isDarkThemeActive() { + if (!isWin101809OrGreater()) { + return false; + } #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) return QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark; #else @@ -370,21 +373,17 @@ #endif } - static inline bool isDarkWindowFrameEnabled(HWND hwnd) { + inline bool isDarkWindowFrameEnabled(HWND hwnd) { + if (!isWin101809OrGreater()) { + return false; + } BOOL enabled = FALSE; const DynamicApis &apis = DynamicApis::instance(); - if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE, &enabled, - sizeof(enabled)))) { - return enabled; - } else if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, - _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, - &enabled, sizeof(enabled)))) { - return enabled; - } - return false; + 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; } - static inline QColor getAccentColor() { + inline QColor getAccentColor() { #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) return QGuiApplication::palette().color(QPalette::Accent); #else @@ -406,7 +405,7 @@ #endif } - static inline quint32 getDpiForWindow(HWND hwnd) { + inline quint32 getDpiForWindow(HWND hwnd) { const DynamicApis &apis = DynamicApis::instance(); if (apis.pGetDpiForWindow) { // Win10 return apis.pGetDpiForWindow(hwnd); @@ -425,7 +424,7 @@ } } - static inline quint32 getSystemMetricsForDpi(int index, quint32 dpi) { + inline quint32 getSystemMetricsForDpi(int index, quint32 dpi) { const DynamicApis &apis = DynamicApis::instance(); if (apis.pGetSystemMetricsForDpi) { return apis.pGetSystemMetricsForDpi(index, dpi); @@ -433,25 +432,31 @@ return ::GetSystemMetrics(index); } - static inline quint32 getWindowFrameBorderThickness(HWND hwnd) { + inline quint32 getWindowFrameBorderThickness(HWND hwnd) { const DynamicApis &apis = DynamicApis::instance(); - if (UINT result = 0; SUCCEEDED(apis.pDwmGetWindowAttribute( - hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &result, sizeof(result)))) { - return result; + if (isWin11OrGreater()) { + UINT result = 0; + if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, + &result, sizeof(result)))) { + return result; + } } - return getSystemMetricsForDpi(SM_CXBORDER, getDpiForWindow(hwnd)); + if (isWin10OrGreater()) { + return static_cast<quint32>(qreal(1) * qreal(getDpiForWindow(hwnd)) / qreal(USER_DEFAULT_SCREEN_DPI)); + } + return 0; } - static inline quint32 getResizeBorderThickness(HWND hwnd) { + inline quint32 getResizeBorderThickness(HWND hwnd) { const quint32 dpi = getDpiForWindow(hwnd); return getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); } - static inline quint32 getTitleBarHeight(HWND hwnd) { + inline quint32 getTitleBarHeight(HWND hwnd) { const quint32 dpi = getDpiForWindow(hwnd); return getSystemMetricsForDpi(SM_CYCAPTION, dpi) + - getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + + getSystemMetricsForDpi(SM_CYSIZEFRAME, dpi) + getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); } -- Gitblit v1.9.1