From 6eb2efea00eb07ce3a6b089b984885ce4a08c9ca Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周五, 29 12月 2023 20:55:09 +0800
Subject: [PATCH] Add WinRegKey support

---
 examples/shared/widgetframe/windowbar_p.h |    2 
 src/quick/quickwindowagent.h              |    2 
 src/core/shared/qwkwindowsextra_p.h       |   24 ++++----
 src/core/qwindowkit_windows.h             |   34 +++++++++++
 src/core/qwindowkit_windows.cpp           |   61 ++++++++++++++++++++
 src/widgets/widgetwindowagent.h           |    2 
 src/core/windowagentbase_p.h              |    2 
 7 files changed, 111 insertions(+), 16 deletions(-)

diff --git a/examples/shared/widgetframe/windowbar_p.h b/examples/shared/widgetframe/windowbar_p.h
index 5f0f4cf..3d52f1a 100644
--- a/examples/shared/widgetframe/windowbar_p.h
+++ b/examples/shared/widgetframe/windowbar_p.h
@@ -45,7 +45,7 @@
         }
 
     private:
-        Q_DISABLE_COPY_MOVE(WindowBarPrivate)
+        Q_DISABLE_COPY(WindowBarPrivate)
     };
 
 }
diff --git a/src/core/qwindowkit_windows.cpp b/src/core/qwindowkit_windows.cpp
index 8292de5..b28e4e0 100644
--- a/src/core/qwindowkit_windows.cpp
+++ b/src/core/qwindowkit_windows.cpp
@@ -22,4 +22,65 @@
 
     }
 
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
+    WindowsRegistryKey::WindowsRegistryKey(HKEY parentHandle, QStringView subKey,
+                                           REGSAM permissions, REGSAM access) {
+        if (::RegOpenKeyExW(parentHandle, reinterpret_cast<const wchar_t *>(subKey.utf16()), 0,
+                            permissions | access, &m_key) != ERROR_SUCCESS) {
+            m_key = nullptr;
+        }
+    }
+
+    WindowsRegistryKey::~WindowsRegistryKey() {
+        close();
+    }
+
+    void WindowsRegistryKey::close() {
+        if (isValid()) {
+            ::RegCloseKey(m_key);
+            m_key = nullptr;
+        }
+    }
+
+    QString WindowsRegistryKey::stringValue(QStringView subKey) const {
+        QString result;
+        if (!isValid())
+            return result;
+        DWORD type;
+        DWORD size;
+        auto subKeyC = reinterpret_cast<const wchar_t *>(subKey.utf16());
+        if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, nullptr, &size) != ERROR_SUCCESS ||
+            (type != REG_SZ && type != REG_EXPAND_SZ) || size <= 2) {
+            return result;
+        }
+        // Reserve more for rare cases where trailing '\0' are missing in registry.
+        // Rely on 0-termination since strings of size 256 padded with 0 have been
+        // observed (QTBUG-84455).
+        size += 2;
+        QVarLengthArray<unsigned char> buffer(static_cast<int>(size));
+        std::fill(buffer.data(), buffer.data() + size, 0u);
+        if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, buffer.data(), &size) ==
+            ERROR_SUCCESS)
+            result = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(buffer.constData()));
+        return result;
+    }
+
+    QPair<DWORD, bool> WindowsRegistryKey::dwordValue(QStringView subKey) const {
+        if (!isValid())
+            return qMakePair(0, false);
+        DWORD type;
+        auto subKeyC = reinterpret_cast<const wchar_t *>(subKey.utf16());
+        if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, nullptr, nullptr) != ERROR_SUCCESS ||
+            type != REG_DWORD) {
+            return qMakePair(0, false);
+        }
+        DWORD value = 0;
+        DWORD size = sizeof(value);
+        const bool ok =
+            ::RegQueryValueExW(m_key, subKeyC, nullptr, nullptr,
+                               reinterpret_cast<unsigned char *>(&value), &size) == ERROR_SUCCESS;
+        return qMakePair(value, ok);
+    }
+#endif
+
 }
\ No newline at end of file
diff --git a/src/core/qwindowkit_windows.h b/src/core/qwindowkit_windows.h
index 2e0c2dd..c84f50d 100644
--- a/src/core/qwindowkit_windows.h
+++ b/src/core/qwindowkit_windows.h
@@ -4,6 +4,10 @@
 #include <QtCore/qt_windows.h>
 #include <QtCore/qglobal.h>
 
+#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+#  include <QtCore/private/qwinregistry_p.h>
+#endif
+
 #include <QWKCore/qwkglobal.h>
 
 #ifndef GET_X_LPARAM
@@ -106,6 +110,36 @@
     }
 
     //
+    // Registry Helpers
+    //
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
+    class QWK_CORE_EXPORT WindowsRegistryKey {
+    public:
+        WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions = KEY_READ,
+                           REGSAM access = 0);
+
+        ~WindowsRegistryKey();
+
+        inline bool isValid() const;
+
+        void close();
+        QString stringValue(QStringView subKey) const;
+        QPair<DWORD, bool> dwordValue(QStringView subKey) const;
+
+    private:
+        HKEY m_key;
+
+        Q_DISABLE_COPY(WindowsRegistryKey)
+    };
+
+    inline bool WindowsRegistryKey::isValid() const {
+        return m_key != nullptr;
+    }
+#else
+    using WindowsRegistryKey = QWinRegistryKey;
+#endif
+
+    //
     // Version Helpers
     //
 
diff --git a/src/core/shared/qwkwindowsextra_p.h b/src/core/shared/qwkwindowsextra_p.h
index 29f69d0..20d3127 100644
--- a/src/core/shared/qwkwindowsextra_p.h
+++ b/src/core/shared/qwkwindowsextra_p.h
@@ -15,9 +15,7 @@
 #include <timeapi.h>
 
 #include <QWKCore/qwindowkit_windows.h>
-
 #include <QtCore/private/qsystemlibrary_p.h>
-#include <QtCore/private/qwinregistry_p.h>
 
 #include <QtGui/QGuiApplication>
 #include <QtGui/QStyleHints>
@@ -132,12 +130,14 @@
     };
     using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
 
-    enum PREFERRED_APP_MODE
-    {
-        PAM_DEFAULT = 0, // Default behavior on systems before Win10 1809. It indicates the application doesn't support dark mode at all.
-        PAM_AUTO = 1,    // Available since Win10 1809, let system decide whether to enable dark mode or not.
-        PAM_DARK = 2,    // Available since Win10 1903, force dark mode regardless of the system theme.
-        PAM_LIGHT = 3,   // Available since Win10 1903, force light mode regardless of the system theme.
+    enum PREFERRED_APP_MODE {
+        PAM_DEFAULT = 0, // Default behavior on systems before Win10 1809. It indicates the
+                         // application doesn't support dark mode at all.
+        PAM_AUTO =
+            1, // Available since Win10 1809, let system decide whether to enable dark mode or not.
+        PAM_DARK = 2, // Available since Win10 1903, force dark mode regardless of the system theme.
+        PAM_LIGHT =
+            3, // Available since Win10 1903, force light mode regardless of the system theme.
         PAM_MAX = 4
     };
 
@@ -230,7 +230,7 @@
 
             ~DynamicApis() = default;
 
-            Q_DISABLE_COPY_MOVE(DynamicApis)
+            Q_DISABLE_COPY(DynamicApis)
         };
 
     }
@@ -337,7 +337,7 @@
     }
 
     static inline bool isWindowFrameBorderColorized() {
-        QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
+        WindowsRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
         if (!registry.isValid()) {
             return false;
         }
@@ -359,7 +359,7 @@
 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
         return QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark;
 #else
-        QWinRegistryKey registry(
+        WindowsRegistryKey registry(
             HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)");
         if (!registry.isValid()) {
             return false;
@@ -390,7 +390,7 @@
 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
         return QGuiApplication::palette().color(QPalette::Accent);
 #else
-        QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
+        WindowsRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
         if (!registry.isValid()) {
             return {};
         }
diff --git a/src/core/windowagentbase_p.h b/src/core/windowagentbase_p.h
index cbf2655..3c978b3 100644
--- a/src/core/windowagentbase_p.h
+++ b/src/core/windowagentbase_p.h
@@ -37,7 +37,7 @@
         static WindowContextFactoryMethod windowContextFactoryMethod;
 
     private:
-        Q_DISABLE_COPY_MOVE(WindowAgentBasePrivate)
+        Q_DISABLE_COPY(WindowAgentBasePrivate)
     };
 
 }
diff --git a/src/quick/quickwindowagent.h b/src/quick/quickwindowagent.h
index 2fd7b3e..daab5c5 100644
--- a/src/quick/quickwindowagent.h
+++ b/src/quick/quickwindowagent.h
@@ -31,7 +31,7 @@
         Q_INVOKABLE void setHitTestVisible(const QQuickItem *item, bool visible = true);
 
 #ifdef Q_OS_MAC
-        // The system button area APIs are experimental, may be changed in the future.
+        // The system button area APIs are experimental, very likely to change in the future.
         Q_INVOKABLE QQuickItem *systemButtonArea() const;
         Q_INVOKABLE void setSystemButtonArea(QQuickItem *item);
 
diff --git a/src/widgets/widgetwindowagent.h b/src/widgets/widgetwindowagent.h
index d159448..e1642ba 100644
--- a/src/widgets/widgetwindowagent.h
+++ b/src/widgets/widgetwindowagent.h
@@ -27,7 +27,7 @@
         void setSystemButton(SystemButton button, QWidget *w);
 
 #ifdef Q_OS_MAC
-        // The system button area APIs are experimental, may be changed in the future.
+        // The system button area APIs are experimental, very likely to change in the future.
         QWidget *systemButtonArea() const;
         void setSystemButtonArea(QWidget *widget);
 

--
Gitblit v1.9.1