Win32: Add some useful functions back

1. Also rename some leftovers to more appropriate names
2. Be more verbose to help debugging

TODO: improve widget example, make use of the these functions

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2021-09-05 09:20:19 +08:00
parent bc8a70dbb2
commit a5a5942d80
6 changed files with 349 additions and 53 deletions

View File

@ -25,6 +25,7 @@
#pragma once
#include <QtCore/qglobal.h>
#include <QtCore/qobject.h>
#ifndef FRAMELESSHELPER_API
#ifdef FRAMELESSHELPER_STATIC
@ -85,6 +86,8 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_NAMESPACE_EXPORT(FRAMELESSHELPER_API)
namespace Constants
{
@ -100,4 +103,21 @@ namespace Constants
}
enum class SystemMetric : int
{
ResizeBorderThickness = 0,
CaptionHeight,
TitleBarHeight
};
Q_ENUM_NS(SystemMetric)
enum class ColorizationArea : int
{
None = 0,
StartMenu_TaskBar_ActionCenter,
TitleBar_WindowBorder,
All
};
Q_ENUM_NS(ColorizationArea)
FRAMELESSHELPER_END_NAMESPACE

View File

@ -320,12 +320,12 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// then the window is clipped to the monitor so that the resize handle
// do not appear because you don't need them (because you can't resize
// a window when it's maximized unless you restore it).
const int rbt = Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true);
clientRect->top += rbt;
const int resizeBorderThickness = Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true);
clientRect->top += resizeBorderThickness;
if (!shouldHaveWindowFrame()) {
clientRect->bottom -= rbt;
clientRect->left += rbt;
clientRect->right -= rbt;
clientRect->bottom -= resizeBorderThickness;
clientRect->left += resizeBorderThickness;
clientRect->right -= resizeBorderThickness;
}
nonClientAreaExists = true;
}
@ -352,11 +352,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
monitorInfo.cbSize = sizeof(monitorInfo);
const HMONITOR monitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST);
if (!monitor) {
qWarning() << "Failed to retrieve the screen that contains the current window.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr);
break;
}
if (GetMonitorInfoW(monitor, &monitorInfo) == FALSE) {
qWarning() << "Failed to retrieve the screen information.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetMonitorInfoW"), hr);
break;
}
// This helper can be used to determine if there's a
@ -386,12 +388,14 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
if (_abd.hWnd) {
const HMONITOR windowMonitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST);
if (!windowMonitor) {
qWarning() << "Failed to retrieve the screen that contains the current window.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr);
break;
}
const HMONITOR taskbarMonitor = MonitorFromWindow(_abd.hWnd, MONITOR_DEFAULTTOPRIMARY);
if (!taskbarMonitor) {
qWarning() << "Failed to retrieve the screen that contains the task bar.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr);
break;
}
if (taskbarMonitor == windowMonitor) {
@ -580,13 +584,15 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
POINT winLocalMouse = {GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam)};
if (ScreenToClient(msg->hwnd, &winLocalMouse) == FALSE) {
qWarning() << "Failed to translate global screen coordinate to local window coordinate.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("ScreenToClient"), hr);
break;
}
const QPointF localMouse = {static_cast<qreal>(winLocalMouse.x), static_cast<qreal>(winLocalMouse.y)};
RECT clientRect = {0, 0, 0, 0};
if (GetClientRect(msg->hwnd, &clientRect) == FALSE) {
qWarning() << "Failed to retrieve the client rect of the current window.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetClientRect"), hr);
break;
}
const LONG windowWidth = clientRect.right;
@ -690,14 +696,16 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// Prevent Windows from drawing the default title bar by temporarily
// toggling the WS_VISIBLE style.
if (SetWindowLongPtrW(msg->hwnd, GWL_STYLE, oldStyle & ~WS_VISIBLE) == 0) {
qWarning() << "SetWindowLongPtrW() failed.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"), hr);
break;
}
const auto winId = reinterpret_cast<WId>(msg->hwnd);
Utilities::triggerFrameChange(winId);
const LRESULT ret = DefWindowProcW(msg->hwnd, msg->message, msg->wParam, msg->lParam);
if (SetWindowLongPtrW(msg->hwnd, GWL_STYLE, oldStyle) == 0) {
qWarning() << "SetWindowLongPtrW() failed.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"), hr);
break;
}
Utilities::triggerFrameChange(winId);

View File

@ -122,11 +122,11 @@ int FramelessWindowsManager::getTitleBarHeight(const QWindow *window)
{
Q_ASSERT(window);
if (!window) {
return 23;
return 31;
}
#ifdef FRAMELESSHELPER_USE_UNIX_VERSION
const int value = window->property(Constants::kTitleBarHeightFlag).toInt();
return value <= 0 ? 23 : value;
return value <= 0 ? 31 : value;
#else
return Utilities::getSystemMetric(window, SystemMetric::TitleBarHeight, false);
#endif

View File

@ -29,13 +29,6 @@
FRAMELESSHELPER_BEGIN_NAMESPACE
enum class SystemMetric : int
{
ResizeBorderThickness = 0,
CaptionHeight,
TitleBarHeight
};
namespace Utilities
{
@ -54,6 +47,13 @@ namespace Utilities
FRAMELESSHELPER_API void triggerFrameChange(const WId winId);
FRAMELESSHELPER_API void updateFrameMargins(const WId winId, const bool reset);
FRAMELESSHELPER_API void updateQtFrameMargins(QWindow *window, const bool enable);
[[nodiscard]] FRAMELESSHELPER_API QString getSystemErrorMessage(const QString &function, const HRESULT hr);
[[nodiscard]] FRAMELESSHELPER_API QColor getColorizationColor();
[[nodiscard]] FRAMELESSHELPER_API int getWindowVisibleFrameBorderThickness(const QWindow *window);
[[nodiscard]] FRAMELESSHELPER_API bool shouldAppsUseDarkMode();
[[nodiscard]] FRAMELESSHELPER_API bool isHighContrastModeEnabled();
[[nodiscard]] FRAMELESSHELPER_API ColorizationArea getColorizationArea();
[[nodiscard]] FRAMELESSHELPER_API bool isWindowDarkFrameBorderEnabled(const WId winId);
#endif
}

View File

@ -23,3 +23,59 @@
*/
#include "utilities.h"
static constexpr int kDefaultResizeBorderThickness = 8;
static constexpr int kDefaultCaptionHeight = 23;
int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, const bool dpiScale, const bool forceSystemValue)
{
Q_ASSERT(window);
if (!window) {
return 0;
}
const qreal devicePixelRatio = window->devicePixelRatio();
const qreal scaleFactor = (dpiScale ? devicePixelRatio : 1.0);
switch (metric) {
case SystemMetric::ResizeBorderThickness: {
const int resizeBorderThickness = window->property(Constants::kResizeBorderThicknessFlag).toInt();
if ((resizeBorderThickness > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(resizeBorderThickness) * scaleFactor);
} else {
// ### TODO: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultResizeBorderThickness) * devicePixelRatio);
} else {
return kDefaultResizeBorderThickness;
}
}
}
case SystemMetric::CaptionHeight: {
const int captionHeight = window->property(Constants::kCaptionHeightFlag).toInt();
if ((captionHeight > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(captionHeight) * scaleFactor);
} else {
// ### TODO: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
return kDefaultCaptionHeight;
}
}
}
case SystemMetric::TitleBarHeight: {
const int titleBarHeight = window->property(Constants::kTitleBarHeightFlag).toInt();
if ((titleBarHeight > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(titleBarHeight) * scaleFactor);
} else {
const int captionHeight = getSystemMetric(window,SystemMetric::CaptionHeight,
dpiScale, forceSystemValue);
const int resizeBorderThickness = getSystemMetric(window, SystemMetric::ResizeBorderThickness,
dpiScale, forceSystemValue);
return (((window->windowState() == Qt::WindowMaximized)
|| (window->windowState() == Qt::WindowFullScreen))
? captionHeight : (captionHeight + resizeBorderThickness));
}
}
}
return 0;
}

View File

@ -49,26 +49,87 @@ Q_DECLARE_METATYPE(QMargins)
FRAMELESSHELPER_BEGIN_NAMESPACE
static constexpr char kDwmRegistryKey[] = R"(Software\Microsoft\Windows\DWM)";
static constexpr char kDwmRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)";
static constexpr char kPersonalizeRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)";
static constexpr int kDefaultResizeBorderThicknessClassic = 4;
static constexpr int kDefaultResizeBorderThicknessAero = 8;
static constexpr int kDefaultCaptionHeight = 23;
enum : WORD
{
_DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
_DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
_DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37
};
[[nodiscard]] static inline bool isWin10RS1OrGreater()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14393));
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10);
#endif
return result;
}
[[nodiscard]] static inline bool isWin1019H1OrGreater()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 18362));
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10);
#endif
return result;
}
bool Utilities::isWin8OrGreater()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8);
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8);
#endif
return result;
}
bool Utilities::isWin8Point1OrGreater()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1);
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8_1);
#endif
return result;
}
bool Utilities::isWin10OrGreater()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10);
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10);
#endif
return result;
}
bool Utilities::isDwmCompositionAvailable()
{
// DWM Composition is always enabled and can't be disabled since Windows 8.
// DWM composition is always enabled and can't be disabled since Windows 8.
if (isWin8OrGreater()) {
return true;
}
BOOL enabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled))) {
const HRESULT hr = DwmIsCompositionEnabled(&enabled);
if (SUCCEEDED(hr)) {
return (enabled != FALSE);
} else {
qWarning() << getSystemErrorMessage(QStringLiteral("DwmIsCompositionEnabled"), hr);
const QSettings registry(QString::fromUtf8(kDwmRegistryKey), QSettings::NativeFormat);
bool ok = false;
const DWORD value = registry.value(QStringLiteral("Composition"), 0).toUInt(&ok);
return (ok && (value != 0));
}
const QSettings registry(QString::fromUtf8(kDwmRegistryKey), QSettings::NativeFormat);
bool ok = false;
const int value = registry.value(QStringLiteral("Composition"), 0).toInt(&ok);
return (ok && (value != 0));
}
int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric, const bool dpiScale, const bool forceSystemValue)
@ -93,6 +154,8 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
return qRound(static_cast<qreal>(result) / devicePixelRatio);
}
} else {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"), hr);
// The padded border will disappear if DWM composition is disabled.
const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic);
if (dpiScale) {
@ -116,6 +179,8 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
return qRound(static_cast<qreal>(result) / devicePixelRatio);
}
} else {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"), hr);
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
@ -151,7 +216,8 @@ void Utilities::triggerFrameChange(const WId winId)
const auto hwnd = reinterpret_cast<HWND>(winId);
constexpr UINT flags = (SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
if (SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, flags) == FALSE) {
qWarning() << "SetWindowPos() failed.";
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowPos"), hr);
}
}
@ -168,8 +234,9 @@ void Utilities::updateFrameMargins(const WId winId, const bool reset)
}
const auto hwnd = reinterpret_cast<HWND>(winId);
const MARGINS margins = reset ? MARGINS{0, 0, 0, 0} : MARGINS{1, 1, 1, 1};
if (FAILED(DwmExtendFrameIntoClientArea(hwnd, &margins))) {
qWarning() << "DwmExtendFrameIntoClientArea() failed.";
const HRESULT hr = DwmExtendFrameIntoClientArea(hwnd, &margins);
if (FAILED(hr)) {
qWarning() << getSystemErrorMessage(QStringLiteral("DwmExtendFrameIntoClientArea"), hr);
}
}
@ -191,44 +258,189 @@ void Utilities::updateQtFrameMargins(QWindow *window, const bool enable)
QPlatformWindow *platformWindow = window->handle();
if (platformWindow) {
QGuiApplication::platformNativeInterface()->setWindowProperty(platformWindow, QStringLiteral("WindowsCustomMargins"), marginsVar);
} else {
qWarning() << "Failed to retrieve the platform window.";
}
#else
auto *platformWindow = dynamic_cast<QNativeInterface::Private::QWindowsWindow *>(
window->handle());
if (platformWindow) {
platformWindow->setCustomMargins(margins);
} else {
qWarning() << "Failed to retrieve the platform window.";
}
#endif
}
bool Utilities::isWin8OrGreater()
QString Utilities::getSystemErrorMessage(const QString &function, const HRESULT hr)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8);
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8);
#endif
return result;
Q_ASSERT(!function.isEmpty());
if (function.isEmpty()) {
return {};
}
if (SUCCEEDED(hr)) {
return QStringLiteral("Operation succeeded.");
}
const DWORD dwError = HRESULT_CODE(hr);
LPWSTR buf = nullptr;
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, nullptr) == 0) {
return QStringLiteral("Failed to retrieve the error message from system.");
}
const QString message = QStringLiteral("%1 failed with error %2: %3.")
.arg(function, QString::number(dwError), QString::fromWCharArray(buf));
LocalFree(buf);
return message;
}
bool Utilities::isWin8Point1OrGreater()
QColor Utilities::getColorizationColor()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1);
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8_1);
#endif
return result;
COLORREF color = RGB(0, 0, 0);
BOOL opaque = FALSE;
const HRESULT hr = DwmGetColorizationColor(&color, &opaque);
if (FAILED(hr)) {
qWarning() << getSystemErrorMessage(QStringLiteral("DwmGetColorizationColor"), hr);
const QSettings registry(QString::fromUtf8(kDwmRegistryKey), QSettings::NativeFormat);
bool ok = false;
color = registry.value(QStringLiteral("ColorizationColor"), 0).toUInt(&ok);
if (!ok || (color == 0)) {
color = RGB(128, 128, 128); // Dark gray
}
}
return QColor::fromRgba(color);
}
bool Utilities::isWin10OrGreater()
int Utilities::getWindowVisibleFrameBorderThickness(const QWindow *window)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
static const bool result = (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10);
#else
static const bool result = (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS10);
#endif
return result;
Q_ASSERT(window);
if (!window) {
return 0;
}
if (!isWin10OrGreater()) {
return 0;
}
const auto hWnd = reinterpret_cast<HWND>(window->winId());
UINT value = 0;
const HRESULT hr = DwmGetWindowAttribute(hWnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &value, sizeof(value));
if (SUCCEEDED(hr)) {
return value;
} else {
// We just eat this error because this enum value was introduced in a very
// late Windows 10 version, so querying it's value will always result in
// a "parameter error" (code: 87) on systems before that value was introduced.
}
const bool max = (window->windowState() == Qt::WindowMaximized);
const bool full = (window->windowState() == Qt::WindowFullScreen);
return ((max || full) ? 0 : qRound(1.0 * window->devicePixelRatio()));
}
bool Utilities::shouldAppsUseDarkMode()
{
if (!isWin10RS1OrGreater()) {
return false;
}
const auto resultFromRegistry = []() -> bool {
const QSettings registry(QString::fromUtf8(kPersonalizeRegistryKey), QSettings::NativeFormat);
bool ok = false;
const DWORD value = registry.value(QStringLiteral("AppsUseLightTheme"), 0).toUInt(&ok);
return (ok && (value == 0));
};
// Starting from Windows 10 19H1, ShouldAppsUseDarkMode() always return "TRUE"
// (actually, a random non-zero number at runtime), so we can't use it due to
// this unreliability. In this case, we just simply read the user's setting from
// the registry instead, it's not elegant but at least it works well.
if (isWin1019H1OrGreater()) {
return resultFromRegistry();
} else {
static bool tried = false;
using sig = BOOL(WINAPI *)();
static sig func = nullptr;
if (!func) {
if (tried) {
return resultFromRegistry();
} else {
tried = true;
const HMODULE dll = LoadLibraryExW(L"UxTheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!dll) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("LoadLibraryExW"), hr);
return resultFromRegistry();
}
func = reinterpret_cast<sig>(GetProcAddress(dll, MAKEINTRESOURCEA(132)));
if (!func) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("GetProcAddress"), hr);
return resultFromRegistry();
}
}
}
return (func() != FALSE);
}
}
bool Utilities::isHighContrastModeEnabled()
{
HIGHCONTRASTW hc;
SecureZeroMemory(&hc, sizeof(hc));
hc.cbSize = sizeof(hc);
if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, 0) == FALSE) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SystemParametersInfoW"), hr);
return false;
}
return (hc.dwFlags & HCF_HIGHCONTRASTON);
}
ColorizationArea Utilities::getColorizationArea()
{
if (!isWin10OrGreater()) {
return ColorizationArea::None;
}
const QString keyName = QStringLiteral("ColorPrevalence");
const QSettings themeRegistry(QString::fromUtf8(kPersonalizeRegistryKey), QSettings::NativeFormat);
const DWORD themeValue = themeRegistry.value(keyName, 0).toUInt();
const QSettings dwmRegistry(QString::fromUtf8(kDwmRegistryKey), QSettings::NativeFormat);
const DWORD dwmValue = dwmRegistry.value(keyName, 0).toUInt();
const bool theme = (themeValue != 0);
const bool dwm = (dwmValue != 0);
if (theme && dwm) {
return ColorizationArea::All;
} else if (theme) {
return ColorizationArea::StartMenu_TaskBar_ActionCenter;
} else if (dwm) {
return ColorizationArea::TitleBar_WindowBorder;
}
return ColorizationArea::None;
}
bool Utilities::isWindowDarkFrameBorderEnabled(const WId winId)
{
Q_ASSERT(winId);
if (!winId) {
return false;
}
if (!isWin10RS1OrGreater()) {
return false;
}
const auto hWnd = reinterpret_cast<HWND>(winId);
BOOL enabled = FALSE;
HRESULT hr = DwmGetWindowAttribute(hWnd, _DWMWA_USE_IMMERSIVE_DARK_MODE, &enabled, sizeof(enabled));
if (SUCCEEDED(hr)) {
return (enabled != FALSE);
} else {
// We just eat this error because this enum value was introduced in a very
// late Windows 10 version, so querying it's value will always result in
// a "parameter error" (code: 87) on systems before that value was introduced.
}
hr = DwmGetWindowAttribute(hWnd, _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, &enabled, sizeof(enabled));
if (SUCCEEDED(hr)) {
return (enabled != FALSE);
} else {
// We just eat this error because this enum value was introduced in a very
// late Windows 10 version, so querying it's value will always result in
// a "parameter error" (code: 87) on systems before that value was introduced.
}
return false;
}
FRAMELESSHELPER_END_NAMESPACE