Minor refactor

1. Remove compiler specific flags
2. Build shared library by default
3. Remove unused functions
4. Minor tweaks of some internal logic, the final behavior is not affected

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2021-09-06 14:24:43 +08:00
parent 8367331278
commit 138a2b90cb
11 changed files with 130 additions and 204 deletions

View File

@ -5,6 +5,8 @@ project(FramelessHelper LANGUAGES CXX)
option(BUILD_EXAMPLES "Build examples." ON)
option(TEST_UNIX "Test UNIX version (from Win32)." OFF)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
@ -15,34 +17,6 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
if(WIN32)
set(CMAKE_DEBUG_POSTFIX d)
else()
set(CMAKE_DEBUG_POSTFIX _debug)
endif()
endif()
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug") AND BUILD_SHARED_LIBS)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
endif()
if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Quick)
@ -94,16 +68,6 @@ if(NOT BUILD_SHARED_LIBS)
)
endif()
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /utf-8 /permissive-)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(${PROJECT_NAME} PRIVATE /JMC)
else()
target_compile_options(${PROJECT_NAME} PRIVATE /guard:cf)
target_link_options(${PROJECT_NAME} PRIVATE /GUARD:CF)
endif()
endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE
QT_NO_CAST_FROM_ASCII
QT_NO_CAST_TO_ASCII

View File

@ -36,16 +36,6 @@ target_compile_definitions(MainWindow PRIVATE
QT_DISABLE_DEPRECATED_BEFORE=0x060100
)
if(MSVC)
target_compile_options(MainWindow PRIVATE /utf-8 /permissive-)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(MainWindow PRIVATE /JMC)
else()
target_compile_options(MainWindow PRIVATE /guard:cf)
target_link_options(MainWindow PRIVATE /GUARD:CF)
endif()
endif()
if(WIN32)
target_link_libraries(MainWindow PRIVATE dwmapi)
endif()

View File

@ -34,16 +34,6 @@ target_compile_definitions(Quick PRIVATE
QT_DISABLE_DEPRECATED_BEFORE=0x060100
)
if(MSVC)
target_compile_options(Quick PRIVATE /utf-8 /permissive-)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(Quick PRIVATE /JMC)
else()
target_compile_options(Quick PRIVATE /guard:cf)
target_link_options(Quick PRIVATE /GUARD:CF)
endif()
endif()
if(WIN32)
target_link_libraries(Quick PRIVATE dwmapi)
endif()

View File

@ -34,16 +34,6 @@ target_compile_definitions(Widget PRIVATE
QT_DISABLE_DEPRECATED_BEFORE=0x060100
)
if(MSVC)
target_compile_options(Widget PRIVATE /utf-8 /permissive-)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(Widget PRIVATE /JMC)
else()
target_compile_options(Widget PRIVATE /guard:cf)
target_link_options(Widget PRIVATE /GUARD:CF)
endif()
endif()
if(WIN32)
target_link_libraries(Widget PRIVATE dwmapi)
endif()

View File

@ -23,11 +23,12 @@
*/
#include "widget.h"
#include <QtCore/qdebug.h>
#include <QtCore/qdatetime.h>
#include <QtGui/qpainter.h>
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qlabel.h>
#include <QtCore/qdatetime.h>
#include <QtWidgets/qpushbutton.h>
#include <QtGui/qpainter.h>
#include "../../utilities.h"
#include "../../framelesswindowsmanager.h"
@ -315,10 +316,13 @@ bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *resul
if (Utilities::isThemeChanged(message)) {
updateStyleSheet();
updateSystemButtonIcons();
return true;
}
QPointF pos = {};
if (Utilities::isSystemMenuRequested(message, &pos)) {
if (!Utilities::showSystemMenu(winId(), pos)) {
if (Utilities::showSystemMenu(winId(), pos)) {
return true;
} else {
qWarning() << "Failed to display the system menu.";
}
}

View File

@ -313,13 +313,11 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
monitorInfo.cbSize = sizeof(monitorInfo);
const HMONITOR monitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST);
if (!monitor) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"));
break;
}
if (GetMonitorInfoW(monitor, &monitorInfo) == FALSE) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetMonitorInfoW"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetMonitorInfoW"));
break;
}
// This helper can be used to determine if there's a
@ -349,14 +347,12 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
if (_abd.hWnd) {
const HMONITOR windowMonitor = MonitorFromWindow(msg->hwnd, MONITOR_DEFAULTTONEAREST);
if (!windowMonitor) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"));
break;
}
const HMONITOR taskbarMonitor = MonitorFromWindow(_abd.hWnd, MONITOR_DEFAULTTOPRIMARY);
if (!taskbarMonitor) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("MonitorFromWindow"));
break;
}
if (taskbarMonitor == windowMonitor) {
@ -545,15 +541,13 @@ 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) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("ScreenToClient"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("ScreenToClient"));
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) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetClientRect"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("GetClientRect"));
break;
}
const LONG windowWidth = clientRect.right;
@ -653,27 +647,24 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// Disable painting while these messages are handled to prevent them
// from drawing a window caption over the client area.
const auto oldStyle = GetWindowLongPtrW(msg->hwnd, GWL_STYLE);
const LONG_PTR oldStyle = GetWindowLongPtrW(msg->hwnd, GWL_STYLE);
// 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) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"), hr);
if (SetWindowLongPtrW(msg->hwnd, GWL_STYLE, static_cast<LONG_PTR>(oldStyle & ~WS_VISIBLE)) == 0) {
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
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) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"), hr);
qWarning() << Utilities::getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
break;
}
Utilities::triggerFrameChange(winId);
*result = ret;
return true;
}
#if 0
case WM_SIZE: {
const bool normal = (msg->wParam == SIZE_RESTORED);
const bool max = (msg->wParam == SIZE_MAXIMIZED);
@ -683,7 +674,6 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
Utilities::updateQtFrameMargins(const_cast<QWindow *>(window), true);
}
} break;
#endif
default:
break;
}

View File

@ -105,18 +105,13 @@
#define IsMaximized(window) (IsZoomed(window) != FALSE)
#endif
constexpr int kAutoHideTaskbarThickness = 2; // The thickness of an auto-hide taskbar in pixels
[[maybe_unused]] constexpr int kAutoHideTaskbarThickness = 2; // The thickness of an auto-hide taskbar in pixels
constexpr char kDwmRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)";
constexpr char kPersonalizeRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)";
[[maybe_unused]] constexpr char kDwmRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM)";
[[maybe_unused]] constexpr char kPersonalizeRegistryKey[] = R"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)";
constexpr int kDefaultResizeBorderThicknessClassic = 4;
constexpr int kDefaultResizeBorderThicknessAero = 8;
constexpr int kDefaultCaptionHeight = 23;
[[maybe_unused]] constexpr int kDefaultResizeBorderThicknessClassic = 4;
[[maybe_unused]] constexpr int kDefaultResizeBorderThicknessAero = 8;
[[maybe_unused]] 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
};
[[maybe_unused]] constexpr WORD _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37;

View File

@ -54,15 +54,6 @@ void FramelessWindowsManager::addWindow(QWindow *window)
framelessHelperUnix()->removeWindowFrame(window);
#else
FramelessHelperWin::addFramelessWindow(window);
QObject::connect(window, &QWindow::windowStateChanged, [window](Qt::WindowState state){
const bool normal = (state == Qt::WindowNoState);
const bool max = (state == Qt::WindowMaximized);
const bool full = (state == Qt::WindowFullScreen);
if (normal || max || full) {
Utilities::updateFrameMargins(window->winId(), (max || full));
Utilities::updateQtFrameMargins(window, true);
}
});
// Work-around a Win32 multi-monitor bug.
QObject::connect(window, &QWindow::screenChanged, [window](QScreen *screen){
Q_UNUSED(screen);

View File

@ -41,9 +41,7 @@ namespace Utilities
[[nodiscard]] FRAMELESSHELPER_API QColor getColorizationColor();
[[nodiscard]] FRAMELESSHELPER_API int getWindowVisibleFrameBorderThickness(const WId winId);
[[nodiscard]] FRAMELESSHELPER_API bool shouldAppsUseDarkMode();
[[nodiscard]] FRAMELESSHELPER_API bool isHighContrastModeEnabled();
[[nodiscard]] FRAMELESSHELPER_API ColorizationArea getColorizationArea();
[[nodiscard]] FRAMELESSHELPER_API bool isWindowDarkFrameBorderEnabled(const WId winId);
[[nodiscard]] FRAMELESSHELPER_API bool isThemeChanged(const void *data);
[[nodiscard]] FRAMELESSHELPER_API bool isSystemMenuRequested(const void *data, QPointF *pos);
[[nodiscard]] FRAMELESSHELPER_API bool showSystemMenu(const WId winId, const QPointF &pos);
@ -57,6 +55,7 @@ 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 QString getSystemErrorMessage(const QString &function);
#endif
}

View File

@ -41,7 +41,7 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
if ((resizeBorderThickness > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(resizeBorderThickness) * scaleFactor);
} else {
// ### TODO: Retrieve system value through official API
// ### TO BE IMPLEMENTED: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultResizeBorderThickness) * devicePixelRatio);
} else {
@ -54,7 +54,7 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
if ((captionHeight > 0) && !forceSystemValue) {
return qRound(static_cast<qreal>(captionHeight) * scaleFactor);
} else {
// ### TODO: Retrieve system value through official API
// ### TO BE IMPLEMENTED: Retrieve system value through official API
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
@ -79,3 +79,51 @@ int Utilities::getSystemMetric(const QWindow *window, const SystemMetric metric,
}
return 0;
}
QColor Utilities::getColorizationColor()
{
// ### TO BE IMPLEMENTED
return Qt::darkGray;
}
int Utilities::getWindowVisibleFrameBorderThickness(const WId winId)
{
// ### TO BE IMPLEMENTED
Q_UNUSED(winId);
return 1;
}
bool Utilities::shouldAppsUseDarkMode()
{
// ### TO BE IMPLEMENTED
return false;
}
ColorizationArea Utilities::getColorizationArea()
{
// ### TO BE IMPLEMENTED
return ColorizationArea::None;
}
bool Utilities::isThemeChanged(const void *data)
{
// ### TO BE IMPLEMENTED
Q_UNUSED(data);
return false;
}
bool Utilities::isSystemMenuRequested(const void *data, QPointF *pos)
{
// ### TO BE IMPLEMENTED
Q_UNUSED(data);
Q_UNUSED(pos);
return false;
}
bool Utilities::showSystemMenu(const WId winId, const QPointF &pos)
{
// ### TO BE IMPLEMENTED
Q_UNUSED(winId);
Q_UNUSED(pos);
return false;
}

View File

@ -43,6 +43,12 @@ Q_DECLARE_METATYPE(QMargins)
FRAMELESSHELPER_BEGIN_NAMESPACE
[[nodiscard]] static inline QPointF extractMousePositionFromLParam(const LPARAM lParam)
{
const POINT nativePos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
return QPointF(static_cast<qreal>(nativePos.x), static_cast<qreal>(nativePos.y));
}
[[nodiscard]] static inline bool isWin10RS1OrGreater()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
@ -134,8 +140,7 @@ 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);
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"));
// The padded border will disappear if DWM composition is disabled.
const int defaultResizeBorderThickness = (isDwmCompositionAvailable() ? kDefaultResizeBorderThicknessAero : kDefaultResizeBorderThicknessClassic);
if (dpiScale) {
@ -159,8 +164,7 @@ 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);
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMetrics"));
if (dpiScale) {
return qRound(static_cast<qreal>(kDefaultCaptionHeight) * devicePixelRatio);
} else {
@ -196,8 +200,7 @@ 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) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowPos"), hr);
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowPos"));
}
}
@ -226,11 +229,11 @@ void Utilities::updateQtFrameMargins(QWindow *window, const bool enable)
if (!window) {
return;
}
const bool shouldApplyCustomFrameMargins = (enable
&& (window->windowState() != Qt::WindowMaximized)
&& (window->windowState() != Qt::WindowFullScreen));
const int resizeBorderThickness = shouldApplyCustomFrameMargins ? Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true, true) : 0;
const int titleBarHeight = shouldApplyCustomFrameMargins ? Utilities::getSystemMetric(window, SystemMetric::TitleBarHeight, true, true) : 0;
const bool useCustomFrameMargin = (enable && (window->windowState() != Qt::WindowMaximized)
&& (window->windowState() != Qt::WindowFullScreen));
const int resizeBorderThickness = useCustomFrameMargin ?
Utilities::getSystemMetric(window, SystemMetric::ResizeBorderThickness, true, true) : 0;
const int titleBarHeight = enable ? Utilities::getSystemMetric(window, SystemMetric::TitleBarHeight, true, true) : 0;
const QMargins margins = {-resizeBorderThickness, -titleBarHeight, -resizeBorderThickness, -resizeBorderThickness}; // left, top, right, bottom
const QVariant marginsVar = QVariant::fromValue(margins);
window->setProperty("_q_windowsCustomMargins", marginsVar);
@ -273,6 +276,19 @@ QString Utilities::getSystemErrorMessage(const QString &function, const HRESULT
return message;
}
QString Utilities::getSystemErrorMessage(const QString &function)
{
Q_ASSERT(!function.isEmpty());
if (function.isEmpty()) {
return {};
}
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hr)) {
return QStringLiteral("Operation succeeded.");
}
return getSystemErrorMessage(function, hr);
}
QColor Utilities::getColorizationColor()
{
COLORREF color = RGB(0, 0, 0);
@ -340,14 +356,12 @@ bool Utilities::shouldAppsUseDarkMode()
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);
qWarning() << getSystemErrorMessage(QStringLiteral("LoadLibraryExW"));
return resultFromRegistry();
}
func = reinterpret_cast<sig>(GetProcAddress(dll, MAKEINTRESOURCEA(132)));
if (!func) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("GetProcAddress"), hr);
qWarning() << getSystemErrorMessage(QStringLiteral("GetProcAddress"));
return resultFromRegistry();
}
}
@ -356,19 +370,6 @@ bool Utilities::shouldAppsUseDarkMode()
}
}
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()) {
@ -391,36 +392,6 @@ ColorizationArea Utilities::getColorizationArea()
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;
}
bool Utilities::isThemeChanged(const void *data)
{
Q_ASSERT(data);
@ -446,17 +417,26 @@ bool Utilities::isSystemMenuRequested(const void *data, QPointF *pos)
if (!data) {
return false;
}
bool result = false;
const auto msg = static_cast<const MSG *>(data);
if (msg->message == WM_NCRBUTTONUP) {
if (msg->wParam == HTCAPTION) {
if (pos) {
const POINT nativePos = {GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam)};
*pos = QPointF(static_cast<qreal>(nativePos.x), static_cast<qreal>(nativePos.y));
}
return true;
result = true;
}
} else if (msg->message == WM_SYSCOMMAND) {
const WPARAM filteredWParam = (msg->wParam & 0xFFF0);
if ((filteredWParam == SC_KEYMENU) && (msg->lParam == VK_SPACE)) {
result = true;
}
} else if (msg->message == WM_CONTEXTMENU) {
//
}
if (result) {
if (pos) {
*pos = extractMousePositionFromLParam(msg->lParam);
}
}
return false;
return result;
}
bool Utilities::showSystemMenu(const WId winId, const QPointF &pos)
@ -468,8 +448,7 @@ bool Utilities::showSystemMenu(const WId winId, const QPointF &pos)
const auto hWnd = reinterpret_cast<HWND>(winId);
const HMENU menu = GetSystemMenu(hWnd, FALSE);
if (!menu) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMenu"), hr);
qWarning() << getSystemErrorMessage(QStringLiteral("GetSystemMenu"));
return false;
}
// Update the options based on window state.
@ -480,54 +459,40 @@ bool Utilities::showSystemMenu(const WId winId, const QPointF &pos)
mii.fType = MFT_STRING;
const auto setState = [&mii, menu](const UINT item, const bool enabled) -> bool {
mii.fState = (enabled ? MF_ENABLED : MF_DISABLED);
return (SetMenuItemInfoW(menu, item, FALSE, &mii) != FALSE);
if (SetMenuItemInfoW(menu, item, FALSE, &mii) == FALSE) {
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"));
return false;
}
return true;
};
const bool max = IsMaximized(hWnd);
if (!setState(SC_RESTORE, max)) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr);
return false;
}
if (!setState(SC_MOVE, !max)) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr);
return false;
}
if (!setState(SC_SIZE, !max)) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr);
return false;
}
if (!setState(SC_MINIMIZE, true)) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr);
return false;
}
if (!setState(SC_MAXIMIZE, !max)) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr);
return false;
}
if (!setState(SC_CLOSE, true)) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuItemInfoW"), hr);
return false;
}
if (SetMenuDefaultItem(menu, UINT_MAX, FALSE) == FALSE) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuDefaultItem"), hr);
qWarning() << getSystemErrorMessage(QStringLiteral("SetMenuDefaultItem"));
return false;
}
const QPoint roundedPos = pos.toPoint();
UINT flags = TPM_RETURNCMD;
if (QGuiApplication::isRightToLeft()) {
flags |= TPM_LAYOUTRTL;
}
const auto ret = TrackPopupMenu(menu, flags, roundedPos.x(), roundedPos.y(), 0, hWnd, nullptr);
const auto ret = TrackPopupMenu(menu, TPM_RETURNCMD, roundedPos.x(), roundedPos.y(), 0, hWnd, nullptr);
if (ret != 0) {
if (PostMessageW(hWnd, WM_SYSCOMMAND, ret, 0) == FALSE) {
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
qWarning() << getSystemErrorMessage(QStringLiteral("PostMessageW"), hr);
qWarning() << getSystemErrorMessage(QStringLiteral("PostMessageW"));
return false;
}
}