From 955961cf9b3027119a4242d09f3877446d39ffec Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Sat, 24 Oct 2020 23:45:23 +0800 Subject: [PATCH] Minor tweaks. Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- examples/Quick/qml.qrc | 3 +- .../Quick/qml/{main.qml => main_unix.qml} | 3 +- examples/Quick/qml/main_windows.qml | 121 ++++++++++++++++++ examples/Win32Demo/widget.cpp | 107 +--------------- examples/Win32Demo/widget.h | 7 - framelessquickhelper.cpp | 57 ++++++++- framelessquickhelper.h | 29 +++++ winnativeeventfilter.cpp | 118 ++++++++++++++++- winnativeeventfilter.h | 21 +++ 9 files changed, 349 insertions(+), 117 deletions(-) rename examples/Quick/qml/{main.qml => main_unix.qml} (97%) create mode 100644 examples/Quick/qml/main_windows.qml diff --git a/examples/Quick/qml.qrc b/examples/Quick/qml.qrc index d379b89..0c4d57a 100644 --- a/examples/Quick/qml.qrc +++ b/examples/Quick/qml.qrc @@ -1,6 +1,7 @@ - qml/main.qml + qml/main_windows.qml + qml/main_unix.qml qml/MinimizeButton.qml qml/MaximizeButton.qml qml/CloseButton.qml diff --git a/examples/Quick/qml/main.qml b/examples/Quick/qml/main_unix.qml similarity index 97% rename from examples/Quick/qml/main.qml rename to examples/Quick/qml/main_unix.qml index 9d13ffa..6296354 100644 --- a/examples/Quick/qml/main.qml +++ b/examples/Quick/qml/main_unix.qml @@ -50,9 +50,8 @@ Window { Text { id: titleBarText text: window.title - font.family: "Noto Sans CJK SC" font.pointSize: 13 - color: "black" + color: window.active ? "black" : "gray" anchors.left: parent.left anchors.leftMargin: 15 anchors.verticalCenter: parent.verticalCenter diff --git a/examples/Quick/qml/main_windows.qml b/examples/Quick/qml/main_windows.qml new file mode 100644 index 0000000..3091662 --- /dev/null +++ b/examples/Quick/qml/main_windows.qml @@ -0,0 +1,121 @@ +/* + * MIT License + * + * Copyright (C) 2020 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import QtQuick 2.15 +import QtQuick.Window 2.15 +import wangwenx190.Utils 1.0 + +Window { + id: window + visible: true + width: 800 + height: 600 + title: qsTr("Hello, World!") + + FramelessHelper { + id: framelessHelper + } + + Rectangle { + id: titleBar + height: framelessHelper.titleBarHeight + color: (window.active && framelessHelper.colorizationEnabled) ? framelessHelper.colorizationColor : "white" + anchors { + top: parent.top + left: parent.left + right: parent.right + } + + Text { + id: titleBarText + text: window.title + font.pointSize: 13 + color: window.active ? (framelessHelper.colorizationEnabled ? "white" : "black") : "gray" + anchors.left: parent.left + anchors.leftMargin: 15 + anchors.verticalCenter: parent.verticalCenter + } + + Row { + anchors.top: parent.top + anchors.right: parent.right + + MinimizeButton { + id: minimizeButton + onClicked: window.showMinimized() + Component.onCompleted: framelessHelper.addIgnoreObject( + minimizeButton) + } + + MaximizeButton { + id: maximizeButton + maximized: window.visibility === Window.Maximized + onClicked: { + if (maximized) { + window.showNormal() + } else { + window.showMaximized() + } + } + Component.onCompleted: framelessHelper.addIgnoreObject( + maximizeButton) + } + + CloseButton { + id: closeButton + onClicked: window.close() + Component.onCompleted: framelessHelper.addIgnoreObject( + closeButton) + } + } + } + + Rectangle { + id: content + color: "#f0f0f0" + anchors { + top: titleBar.bottom + bottom: parent.bottom + left: parent.left + right: parent.right + } + } + + Rectangle { + id: topFrame + visible: framelessHelper.canHaveWindowFrame && (window.visibility === Window.Windowed) + color: window.active ? (framelessHelper.colorizationEnabled ? framelessHelper.colorizationColor : "#707070") : "#aaaaaa" + anchors { + top: parent.top + left: parent.left + right: parent.right + } + height: 1 + } + + Component.onCompleted: { + framelessHelper.setWindowFrameVisible(framelessHelper.canHaveWindowFrame) + framelessHelper.removeWindowFrame(true) + } +} diff --git a/examples/Win32Demo/widget.cpp b/examples/Win32Demo/widget.cpp index 47ab7d8..d29ea7a 100644 --- a/examples/Win32Demo/widget.cpp +++ b/examples/Win32Demo/widget.cpp @@ -24,7 +24,6 @@ #include "widget.h" #include "../../winnativeeventfilter.h" -#include #include #include #include @@ -34,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -54,12 +52,7 @@ namespace { -enum : WORD { DwmwaUseImmersiveDarkMode = 20, DwmwaUseImmersiveDarkModeBefore20h1 = 19 }; - const Widget::Win10Version g_vAcrylicEffectVersion = Widget::Win10Version::Win10_1803; -const Widget::Win10Version g_vLightThemeVersion = Widget::Win10Version::Win10_1809; -const Widget::Win10Version g_vDarkThemeVersion = g_vLightThemeVersion; // check -const Widget::Win10Version g_vDarkFrameVersion = g_vDarkThemeVersion; // check const QColor g_cDefaultActiveBorderColor = {"#707070"}; const QColor g_cDefaultInactiveBorderColor = {"#aaaaaa"}; @@ -70,10 +63,6 @@ const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME"; const char g_sForceUseAcrylicEffect[] = "WNEF_FORCE_ACRYLIC_ON_WIN10"; const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME"; -const QLatin1String g_sDwmRegistryKey(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)"); -const QLatin1String g_sPersonalizeRegistryKey( - R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"); - const QLatin1String g_sSystemButtonsStyleSheet(R"( #iconButton, #minimizeButton, #maximizeButton, #closeButton { background-color: transparent; @@ -296,17 +285,18 @@ bool Widget::shouldDrawBorder(const bool ignoreWindowState) const bool Widget::shouldDrawThemedBorder(const bool ignoreWindowState) const { - return (shouldDrawBorder(ignoreWindowState) && colorizationColorEnabled()); + return (shouldDrawBorder(ignoreWindowState) && WinNativeEventFilter::colorizationEnabled()); } bool Widget::shouldDrawThemedTitleBar() const { - return m_bIsWin10OrGreater && colorizationColorEnabled(); + return m_bIsWin10OrGreater && WinNativeEventFilter::colorizationEnabled(); } QColor Widget::activeBorderColor() { - return colorizationColorEnabled() ? g_cColorizationColor : g_cDefaultActiveBorderColor; + return WinNativeEventFilter::colorizationEnabled() ? g_cColorizationColor + : g_cDefaultActiveBorderColor; } QColor Widget::inactiveBorderColor() @@ -330,91 +320,6 @@ bool Widget::isWin10OrGreater(const Win10Version subVer) static_cast(subVer)))); } -QColor Widget::colorizationColor() -{ -#if 0 - DWORD color = 0; - BOOL opaqueBlend = FALSE; - return SUCCEEDED(DwmGetColorizationColor(&color, &opaqueBlend)) ? QColor::fromRgba(color) - : Qt::white; -#else - bool ok = false; - const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat); - const quint64 color = registry.value(QLatin1String("ColorizationColor"), 0).toULongLong(&ok); - return ok ? QColor::fromRgba(color) : Qt::white; -#endif -} - -bool Widget::colorizationColorEnabled() -{ - if (!isWin10OrGreater()) { - return false; - } - bool ok = false; - const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat); - const bool colorPrevalence = registry.value(QLatin1String("ColorPrevalence"), 0).toULongLong(&ok) - != 0; - return (ok && colorPrevalence); -} - -bool Widget::lightThemeEnabled() -{ - if (!isWin10OrGreater(g_vLightThemeVersion)) { - return false; - } - bool ok = false; - const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat); - const bool appsUseLightTheme - = registry.value(QLatin1String("AppsUseLightTheme"), 0).toULongLong(&ok) != 0; - return (ok && appsUseLightTheme); -} - -bool Widget::darkThemeEnabled() -{ - if (!isWin10OrGreater(g_vDarkThemeVersion)) { - return false; - } - return !lightThemeEnabled(); -} - -bool Widget::highContrastModeEnabled() -{ - HIGHCONTRASTW hc; - SecureZeroMemory(&hc, sizeof(hc)); - hc.cbSize = sizeof(hc); - return SystemParametersInfoW(SPI_GETHIGHCONTRAST, 0, &hc, 0) ? (hc.dwFlags & HCF_HIGHCONTRASTON) - : false; -} - -bool Widget::darkFrameEnabled(void *handle) -{ - Q_ASSERT(handle); - if (!isWin10OrGreater(g_vDarkFrameVersion)) { - return false; - } - const auto hwnd = reinterpret_cast(handle); - BOOL result = FALSE; - const bool ok - = SUCCEEDED(DwmGetWindowAttribute(hwnd, DwmwaUseImmersiveDarkMode, &result, sizeof(result))) - || SUCCEEDED(DwmGetWindowAttribute(hwnd, - DwmwaUseImmersiveDarkModeBefore20h1, - &result, - sizeof(result))); - return (ok && result); -} - -bool Widget::transparencyEffectEnabled() -{ - if (!isWin10OrGreater()) { - return false; - } - bool ok = false; - const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat); - const bool enableTransparency - = registry.value(QLatin1String("EnableTransparency"), 0).toULongLong(&ok) != 0; - return (ok && enableTransparency); -} - void *Widget::rawHandle() const { return reinterpret_cast(winId()); @@ -650,7 +555,7 @@ void Widget::setupConnections() } WinNativeEventFilter::setBlurEffectEnabled(rawHandle(), enable, color); updateWindow(); - if (useAcrylicEffect && enable && transparencyEffectEnabled()) { + if (useAcrylicEffect && enable && WinNativeEventFilter::transparencyEffectEnabled()) { QMessageBox::warning(this, tr("BUG Warning!"), tr("You have enabled the transparency effect in the personalize " @@ -697,7 +602,7 @@ void Widget::initializeVariables() m_bIsWin10OrGreater = isWin10OrGreater(); if (m_bIsWin10OrGreater) { m_bCanAcrylicBeEnabled = isWin10OrGreater(g_vAcrylicEffectVersion); - g_cColorizationColor = colorizationColor(); + g_cColorizationColor = WinNativeEventFilter::colorizationColor(); } } diff --git a/examples/Win32Demo/widget.h b/examples/Win32Demo/widget.h index 5558b2d..b7c1bca 100644 --- a/examples/Win32Demo/widget.h +++ b/examples/Win32Demo/widget.h @@ -80,13 +80,6 @@ public: QColor borderColor() const; static bool isWin10OrGreater(const Win10Version subVer = Win10Version::Windows10); - static QColor colorizationColor(); - static bool colorizationColorEnabled(); - static bool lightThemeEnabled(); - static bool darkThemeEnabled(); - static bool highContrastModeEnabled(); - static bool darkFrameEnabled(void *handle); - static bool transparencyEffectEnabled(); public Q_SLOTS: void retranslateUi(); diff --git a/framelessquickhelper.cpp b/framelessquickhelper.cpp index 160dc23..4891661 100644 --- a/framelessquickhelper.cpp +++ b/framelessquickhelper.cpp @@ -26,8 +26,26 @@ #include "framelesswindowsmanager.h" #include +#ifdef Q_OS_WINDOWS +#include "winnativeeventfilter.h" +#include +#endif -FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent) {} +#ifdef Q_OS_WINDOWS +namespace { + +const char g_sPreserveWindowFrame[] = "WNEF_FORCE_PRESERVE_WINDOW_FRAME"; +const char g_sDontExtendFrame[] = "WNEF_DO_NOT_EXTEND_FRAME"; + +} // namespace +#endif + +FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent) : QQuickItem(parent) +{ +#ifdef Q_OS_WINDOWS + startTimer(500); +#endif +} int FramelessQuickHelper::borderWidth() const { @@ -84,6 +102,23 @@ void FramelessQuickHelper::setTitleBarEnabled(const bool val) Q_EMIT titleBarEnabledChanged(val); } +#ifdef Q_OS_WINDOWS +bool FramelessQuickHelper::canHaveWindowFrame() const +{ + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10; +} + +bool FramelessQuickHelper::colorizationEnabled() const +{ + return WinNativeEventFilter::colorizationEnabled(); +} + +QColor FramelessQuickHelper::colorizationColor() const +{ + return WinNativeEventFilter::colorizationColor(); +} +#endif + QSize FramelessQuickHelper::minimumSize() const { return FramelessWindowsManager::getMinimumSize(window()); @@ -152,3 +187,23 @@ void FramelessQuickHelper::addDraggableObject(QQuickItem *val) Q_ASSERT(val); FramelessWindowsManager::addDraggableObject(window(), val); } + +#ifdef Q_OS_WINDOWS +void FramelessQuickHelper::timerEvent(QTimerEvent *event) +{ + QQuickItem::timerEvent(event); + Q_EMIT colorizationEnabledChanged(colorizationEnabled()); + Q_EMIT colorizationColorChanged(colorizationColor()); +} + +void FramelessQuickHelper::setWindowFrameVisible(const bool value) +{ + if (value) { + qputenv(g_sPreserveWindowFrame, "1"); + qputenv(g_sDontExtendFrame, "1"); + } else { + qunsetenv(g_sPreserveWindowFrame); + qunsetenv(g_sDontExtendFrame); + } +} +#endif diff --git a/framelessquickhelper.h b/framelessquickhelper.h index ff8cc37..823df39 100644 --- a/framelessquickhelper.h +++ b/framelessquickhelper.h @@ -27,6 +27,11 @@ #include "framelesshelper_global.h" #include +#if (defined(Q_OS_WIN) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)) \ + && !defined(Q_OS_WINDOWS) +#define Q_OS_WINDOWS +#endif + #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0)) #define Q_DISABLE_MOVE(Class) \ Class(Class &&) = delete; \ @@ -53,6 +58,11 @@ class FRAMELESSHELPER_EXPORT FramelessQuickHelper : public QQuickItem Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize NOTIFY maximumSizeChanged) Q_PROPERTY(bool titleBarEnabled READ titleBarEnabled WRITE setTitleBarEnabled NOTIFY titleBarEnabledChanged) +#ifdef Q_OS_WINDOWS + Q_PROPERTY(bool canHaveWindowFrame READ canHaveWindowFrame CONSTANT) + Q_PROPERTY(bool colorizationEnabled READ colorizationEnabled NOTIFY colorizationEnabledChanged) + Q_PROPERTY(QColor colorizationColor READ colorizationColor NOTIFY colorizationColorChanged) +#endif public: explicit FramelessQuickHelper(QQuickItem *parent = nullptr); @@ -79,6 +89,12 @@ public: bool titleBarEnabled() const; void setTitleBarEnabled(const bool val); +#ifdef Q_OS_WINDOWS + bool canHaveWindowFrame() const; + bool colorizationEnabled() const; + QColor colorizationColor() const; +#endif + public Q_SLOTS: void removeWindowFrame(const bool center = false); @@ -94,6 +110,15 @@ public Q_SLOTS: void addIgnoreObject(QQuickItem *val); void addDraggableObject(QQuickItem *val); +#ifdef Q_OS_WINDOWS + void setWindowFrameVisible(const bool value = true); +#endif + +#ifdef Q_OS_WINDOWS +protected: + void timerEvent(QTimerEvent *event) override; +#endif + Q_SIGNALS: void borderWidthChanged(int); void borderHeightChanged(int); @@ -102,4 +127,8 @@ Q_SIGNALS: void minimumSizeChanged(const QSize &); void maximumSizeChanged(const QSize &); void titleBarEnabledChanged(bool); +#ifdef Q_OS_WINDOWS + void colorizationEnabledChanged(bool); + void colorizationColorChanged(const QColor &); +#endif }; diff --git a/winnativeeventfilter.cpp b/winnativeeventfilter.cpp index 341a2f4..c5f8929 100644 --- a/winnativeeventfilter.cpp +++ b/winnativeeventfilter.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -154,6 +155,8 @@ Q_DECLARE_METATYPE(QMargins) namespace { +enum : WORD { DwmwaUseImmersiveDarkMode = 20, DwmwaUseImmersiveDarkModeBefore20h1 = 19 }; + using WINDOWCOMPOSITIONATTRIB = enum _WINDOWCOMPOSITIONATTRIB { WCA_ACCENT_POLICY = 19 }; using WINDOWCOMPOSITIONATTRIBDATA = struct _WINDOWCOMPOSITIONATTRIBDATA @@ -198,6 +201,15 @@ bool isWin8Point1OrGreater() #endif } +bool isWin10OrGreater() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10; +#else + return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10; +#endif +} + bool isWin10OrGreater(const int ver) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) @@ -487,6 +499,7 @@ using WNEF_CORE_DATA = struct _WNEF_CORE_DATA WNEF_GENERATE_WINAPI(TrackPopupMenu, BOOL, HMENU, UINT, int, int, int, HWND, CONST RECT *) WNEF_GENERATE_WINAPI(PostMessageW, BOOL, HWND, UINT, WPARAM, LPARAM) WNEF_GENERATE_WINAPI(GetMessagePos, DWORD) + WNEF_GENERATE_WINAPI(SystemParametersInfoW, BOOL, UINT, UINT, PVOID, UINT) #endif // WNEF_LINK_SYSLIB @@ -566,6 +579,7 @@ using WNEF_CORE_DATA = struct _WNEF_CORE_DATA } resolved = true; // Available since Windows 2000. + WNEF_RESOLVE_WINAPI(User32, SystemParametersInfoW) WNEF_RESOLVE_WINAPI(User32, GetMessagePos) WNEF_RESOLVE_WINAPI(User32, GetSystemMenu) WNEF_RESOLVE_WINAPI(User32, SetMenuItemInfoW) @@ -685,11 +699,7 @@ bool shouldHaveWindowFrame() if (should) { // If you preserve the window frame on Win7~8.1, // the window will have a terrible appearance. -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10; -#else - return QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10; -#endif + return isWin10OrGreater(); } } return false; @@ -1208,6 +1218,10 @@ const int m_defaultBorderWidth = 8, m_defaultBorderHeight = 8, m_defaultTitleBar const int kAutoHideTaskbarThicknessPx = 2; const int kAutoHideTaskbarThicknessPy = kAutoHideTaskbarThicknessPx; +const QLatin1String g_sDwmRegistryKey(R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)"); +const QLatin1String g_sPersonalizeRegistryKey( + R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"); + } // namespace WinNativeEventFilter::WinNativeEventFilter() @@ -2489,3 +2503,97 @@ void WinNativeEventFilter::setWindowResizable(void *handle, const bool resizable updateWindow(hwnd, true, false); } } + +bool WinNativeEventFilter::colorizationEnabled() +{ + if (!isWin10OrGreater()) { + return false; + } + bool ok = false; + const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat); + const bool colorPrevalence = registry.value(QLatin1String("ColorPrevalence"), 0).toULongLong(&ok) + != 0; + return (ok && colorPrevalence); +} + +QColor WinNativeEventFilter::colorizationColor() +{ + /* + DWORD color = 0; + BOOL opaqueBlend = FALSE; + return SUCCEEDED(DwmGetColorizationColor(&color, &opaqueBlend)) ? QColor::fromRgba(color) + : Qt::white; + */ + bool ok = false; + const QSettings registry(g_sDwmRegistryKey, QSettings::NativeFormat); + const quint64 color = registry.value(QLatin1String("ColorizationColor"), 0).toULongLong(&ok); + return ok ? QColor::fromRgba(color) : Qt::white; +} + +bool WinNativeEventFilter::lightThemeEnabled() +{ + if (!isWin10OrGreater(17763)) { + return false; + } + bool ok = false; + const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat); + const bool appsUseLightTheme + = registry.value(QLatin1String("AppsUseLightTheme"), 0).toULongLong(&ok) != 0; + return (ok && appsUseLightTheme); +} + +bool WinNativeEventFilter::darkThemeEnabled() +{ + if (!isWin10OrGreater(17763)) { + return false; + } + return !lightThemeEnabled(); +} + +bool WinNativeEventFilter::highContrastModeEnabled() +{ + HIGHCONTRASTW hc; + SecureZeroMemory(&hc, sizeof(hc)); + hc.cbSize = sizeof(hc); + return WNEF_EXECUTE_WINAPI_RETURN(SystemParametersInfoW, FALSE, SPI_GETHIGHCONTRAST, 0, &hc, 0) + ? (hc.dwFlags & HCF_HIGHCONTRASTON) + : false; +} + +bool WinNativeEventFilter::darkFrameEnabled(void *handle) +{ + Q_ASSERT(handle); + if (!isWin10OrGreater(17763)) { + return false; + } + const auto hwnd = reinterpret_cast(handle); + if (WNEF_EXECUTE_WINAPI_RETURN(IsWindow, FALSE, hwnd)) { + BOOL result = FALSE; + const bool ok = SUCCEEDED(WNEF_EXECUTE_WINAPI_RETURN(DwmGetWindowAttribute, + E_FAIL, + hwnd, + DwmwaUseImmersiveDarkMode, + &result, + sizeof(result))) + || SUCCEEDED(WNEF_EXECUTE_WINAPI_RETURN(DwmGetWindowAttribute, + E_FAIL, + hwnd, + DwmwaUseImmersiveDarkModeBefore20h1, + &result, + sizeof(result))); + return (ok && result); + } + return false; +} + +bool WinNativeEventFilter::transparencyEffectEnabled() +{ + if (!isWin10OrGreater()) { + return false; + } + bool ok = false; + const QSettings registry(g_sPersonalizeRegistryKey, QSettings::NativeFormat); + const bool enableTransparency + = registry.value(QLatin1String("EnableTransparency"), 0).toULongLong(&ok) != 0; + return (ok && enableTransparency); +} diff --git a/winnativeeventfilter.h b/winnativeeventfilter.h index 7ed0792..80d0f2c 100644 --- a/winnativeeventfilter.h +++ b/winnativeeventfilter.h @@ -153,6 +153,27 @@ public: // window can only be moved and minimized, it can't be resized and maximized. static void setWindowResizable(void *handle /* HWND */, const bool resizable = true); + // Query whether colorization is enabled or not. + static bool colorizationEnabled(); + + // Acquire the theme/colorization color set by the user. + static QColor colorizationColor(); + + // Query whether the user is using the light theme or not. + static bool lightThemeEnabled(); + + // Query whether the user is using the dark theme or not. + static bool darkThemeEnabled(); + + // Query whether the high contrast mode is enabled or not. + static bool highContrastModeEnabled(); + + // Query whether the given window is using dark frame or not. + static bool darkFrameEnabled(void *handle /* HWND */); + + // Query whether the transparency effect is enabled or not. + static bool transparencyEffectEnabled(); + /////////////////////////////////////////////// /// CORE FUNCTION - THE SOUL OF THIS CODE ///////////////////////////////////////////////