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