From eb1c6f4a62e903305f81da8acacdb3fb3b62a603 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Fri, 1 Apr 2022 20:06:48 +0800 Subject: [PATCH] win32: minor improvements 1. Fix build on 32bit platforms: the "Ptr" suffixed APIs not available on 32bit platforms 2. Reduce the confusion caused by the original "UseStandardWindowLayout" option 3. Minor tweaks of the quick implementation Signed-off-by: Yuhang Zhao <2546789017@qq.com> --- examples/widget/widget.cpp | 2 +- .../Core/framelesshelper_windows.h | 40 +++++++++++++++++++ .../Core/framelesshelpercore_global.h | 4 +- src/quick/framelesshelper_quick.cpp | 34 +++++++++++----- src/widgets/framelesswidgetshelper.cpp | 28 ++++++------- 5 files changed, 81 insertions(+), 27 deletions(-) diff --git a/examples/widget/widget.cpp b/examples/widget/widget.cpp index 0380229..b641fcf 100644 --- a/examples/widget/widget.cpp +++ b/examples/widget/widget.cpp @@ -37,7 +37,7 @@ static const UserSettings settings = /* startupPosition */ QPoint(), /* startupSize */ QSize(), /* startupState */ Qt::WindowNoState, - /* options */ { Option::UseStandardWindowLayout }, + /* options */ { Option::CreateStandardWindowLayout }, // Only needed by this demo application, you most probably don't need this option. /* systemMenuOffset */ QPoint(), /* minimizeButton */ nullptr, /* maximizeButton */ nullptr, diff --git a/include/FramelessHelper/Core/framelesshelper_windows.h b/include/FramelessHelper/Core/framelesshelper_windows.h index b114f71..9068c5e 100644 --- a/include/FramelessHelper/Core/framelesshelper_windows.h +++ b/include/FramelessHelper/Core/framelesshelper_windows.h @@ -157,6 +157,46 @@ using MONITOR_DPI_TYPE = enum MONITOR_DPI_TYPE MDT_DEFAULT = MDT_EFFECTIVE_DPI }; +#if !(defined(WIN64) || defined(_WIN64)) +EXTERN_C inline LONG_PTR WINAPI +GetWindowLongPtrA( + _In_ HWND hWnd, + _In_ int nIndex +) +{ + return GetWindowLongA(hWnd, nIndex); +} + +EXTERN_C inline LONG_PTR WINAPI +GetWindowLongPtrW( + _In_ HWND hWnd, + _In_ int nIndex +) +{ + return GetWindowLongW(hWnd, nIndex); +} + +EXTERN_C inline LONG_PTR WINAPI +SetWindowLongPtrA( + _In_ HWND hWnd, + _In_ int nIndex, + _In_ LONG_PTR dwNewLong +) +{ + return SetWindowLongA(hWnd, nIndex, dwNewLong); +} + +EXTERN_C inline LONG_PTR WINAPI +SetWindowLongPtrW( + _In_ HWND hWnd, + _In_ int nIndex, + _In_ LONG_PTR dwNewLong +) +{ + return SetWindowLongW(hWnd, nIndex, dwNewLong); +} +#endif // !(defined(WIN64) || defined(_WIN64)) + EXTERN_C MMRESULT WINAPI timeGetDevCaps( _Out_writes_bytes_(cbtc) LPTIMECAPS ptc, diff --git a/include/FramelessHelper/Core/framelesshelpercore_global.h b/include/FramelessHelper/Core/framelesshelpercore_global.h index 0d4b9b7..bb328a3 100644 --- a/include/FramelessHelper/Core/framelesshelpercore_global.h +++ b/include/FramelessHelper/Core/framelesshelpercore_global.h @@ -125,7 +125,7 @@ using NATIVE_EVENT_RESULT_TYPE = long; #endif #ifndef FRAMELESSHELPER_NAMESPACE -# define FRAMELESSHELPER_NAMESPACE __wwx190_flh_ns +# define FRAMELESSHELPER_NAMESPACE wangwenx190::FramelessHelper #endif #ifndef FRAMELESSHELPER_BEGIN_NAMESPACE @@ -193,7 +193,7 @@ enum class Option : int EnableRoundedWindowCorners = 0x00000008, // Not implemented yet. TransparentWindowBackground = 0x00000010, // Not implemented yet. MaximizeButtonDocking = 0x00000020, // Windows only, enable the window docking feature introduced in Windows 11. - UseStandardWindowLayout = 0x00000040, // The standard window layout is a titlebar always on top and fill the window width. + CreateStandardWindowLayout = 0x00000040, // Using this option will cause FramelessHelper create a homemade titlebar and a window layout to contain it. If your window has a layout already, the newly created layout will mess up your own layout. BeCompatibleWithQtFramelessWindowHint = 0x00000080, // Windows only, make the code compatible with Qt::FramelessWindowHint. Don't use this option unless you really need that flag. DontTouchQtInternals = 0x00000100, // Windows only, don't modify Qt's internal data. DontTouchWindowFrameBorderColor = 0x00000200, // Windows only, don't change the window frame border color. diff --git a/src/quick/framelesshelper_quick.cpp b/src/quick/framelesshelper_quick.cpp index b0a4158..492d262 100644 --- a/src/quick/framelesshelper_quick.cpp +++ b/src/quick/framelesshelper_quick.cpp @@ -38,8 +38,24 @@ # define QUICK_URI_SHORT FRAMELESSHELPER_QUICK_URI, 1 #endif +#ifndef QUICK_URI_FULL +# define QUICK_URI_FULL QUICK_URI_SHORT, 0 +#endif + #ifndef QUICK_URI_EXPAND -# define QUICK_URI_EXPAND(name) QUICK_URI_SHORT, 0, name +# define QUICK_URI_EXPAND(name) QUICK_URI_FULL, name +#endif + +#ifndef qmlRegisterAnonymousType2 +# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# define qmlRegisterAnonymousType2(Class, ...) qmlRegisterAnonymousType(__VA_ARGS__) +# else +# define qmlRegisterAnonymousType2(Class, ...) qmlRegisterAnonymousType(__VA_ARGS__) +# endif +#endif + +#ifndef qmlRegisgerFile +# define qmlRegisterFile(Name) qmlRegisterType(QML_URL_EXPAND(Name), QUICK_URI_EXPAND(Name)) #endif // The "Q_INIT_RESOURCE()" macro can't be used inside a namespace, @@ -64,6 +80,7 @@ void FramelessHelper::Quick::registerTypes(QQmlEngine *engine) } inited = true; engine->addImageProvider(FRAMELESSHELPER_STRING_LITERAL("framelesshelper"), new FramelessHelperImageProvider); + qmlRegisterModule(QUICK_URI_FULL); qmlRegisterUncreatableMetaObject(Global::staticMetaObject, QUICK_URI_EXPAND("FramelessHelper"), FRAMELESSHELPER_STRING_LITERAL("The FramelessHelper namespace is not creatable, you can only use it to access its enums.")); qmlRegisterSingletonType(QUICK_URI_EXPAND("FramelessUtils"), @@ -72,17 +89,14 @@ void FramelessHelper::Quick::registerTypes(QQmlEngine *engine) Q_UNUSED(scriptEngine); return new FramelessQuickUtils; }); -#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) - qmlRegisterAnonymousType(QUICK_URI_SHORT); -#else - qmlRegisterAnonymousType(QUICK_URI_SHORT); -#endif + qmlRegisterAnonymousType2(QWindow, QUICK_URI_SHORT); + qmlRegisterAnonymousType2(QQuickWindow, QUICK_URI_SHORT); qmlRegisterType(QUICK_URI_EXPAND("FramelessWindow")); initResource(); - qmlRegisterType(QML_URL_EXPAND("MinimizeButton"), QUICK_URI_EXPAND("MinimizeButton")); - qmlRegisterType(QML_URL_EXPAND("MaximizeButton"), QUICK_URI_EXPAND("MaximizeButton")); - qmlRegisterType(QML_URL_EXPAND("CloseButton"), QUICK_URI_EXPAND("CloseButton")); - qmlRegisterType(QML_URL_EXPAND("StandardTitleBar"), QUICK_URI_EXPAND("StandardTitleBar")); + qmlRegisterFile("MinimizeButton"); + qmlRegisterFile("MaximizeButton"); + qmlRegisterFile("CloseButton"); + qmlRegisterFile("StandardTitleBar"); } FRAMELESSHELPER_END_NAMESPACE diff --git a/src/widgets/framelesswidgetshelper.cpp b/src/widgets/framelesswidgetshelper.cpp index 73588e4..c343151 100644 --- a/src/widgets/framelesswidgetshelper.cpp +++ b/src/widgets/framelesswidgetshelper.cpp @@ -127,7 +127,7 @@ void FramelessWidgetsHelper::setTitleBarWidget(QWidget *widget) if (m_userTitleBarWidget == widget) { return; } - if (m_settings.options & Option::UseStandardWindowLayout) { + if (m_settings.options & Option::CreateStandardWindowLayout) { if (m_systemTitleBarWidget && m_systemTitleBarWidget->isVisible()) { m_mainLayout->removeWidget(m_systemTitleBarWidget); m_systemTitleBarWidget->hide(); @@ -155,7 +155,7 @@ void FramelessWidgetsHelper::setContentWidget(QWidget *widget) if (!widget) { return; } - if (!(m_settings.options & Option::UseStandardWindowLayout)) { + if (!(m_settings.options & Option::CreateStandardWindowLayout)) { return; } if (m_userContentWidget == widget) { @@ -226,7 +226,7 @@ void FramelessWidgetsHelper::changeEventHandler(QEvent *event) if ((type != QEvent::WindowStateChange) && (type != QEvent::ActivationChange)) { return; } - const bool standardLayout = (m_settings.options & Option::UseStandardWindowLayout); + const bool standardLayout = (m_settings.options & Option::CreateStandardWindowLayout); if (type == QEvent::WindowStateChange) { if (standardLayout) { if (isZoomed()) { @@ -386,10 +386,10 @@ void FramelessWidgetsHelper::initialize() m_params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool { return isInSystemButtons(pos, button); }; m_params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); }; m_params.getWindowDevicePixelRatio = [this]() -> qreal { return q->devicePixelRatioF(); }; - if (m_settings.options & Option::UseStandardWindowLayout) { + if (m_settings.options & Option::CreateStandardWindowLayout) { if (q->inherits(QT_MAINWINDOW_CLASS_NAME)) { - m_settings.options &= ~Options(Option::UseStandardWindowLayout); - qWarning() << "\"Option::UseStandardWindowLayout\" is not compatible with QMainWindow and it's subclasses." + m_settings.options &= ~Options(Option::CreateStandardWindowLayout); + qWarning() << "\"Option::CreateStandardWindowLayout\" is not compatible with QMainWindow and it's subclasses." " Enabling this option will mess up with your main window's layout."; } } @@ -404,7 +404,7 @@ void FramelessWidgetsHelper::initialize() manager->addWindow(m_settings, m_params); q->installEventFilter(this); connect(manager, &FramelessWindowsManager::systemThemeChanged, this, [this](){ - if (m_settings.options & Option::UseStandardWindowLayout) { + if (m_settings.options & Option::CreateStandardWindowLayout) { updateSystemTitleBarStyleSheet(); updateSystemButtonsIcon(); q->update(); @@ -417,7 +417,7 @@ void FramelessWidgetsHelper::initialize() QMetaObject::invokeMethod(q, "zoomedChanged"); }); setupInitialUi(); - if (m_settings.options & Option::UseStandardWindowLayout) { + if (m_settings.options & Option::CreateStandardWindowLayout) { m_settings.minimizeButton = m_systemMinimizeButton; m_settings.maximizeButton = m_systemMaximizeButton; m_settings.closeButton = m_systemCloseButton; @@ -426,7 +426,7 @@ void FramelessWidgetsHelper::initialize() void FramelessWidgetsHelper::createSystemTitleBar() { - if (!(m_settings.options & Option::UseStandardWindowLayout)) { + if (!(m_settings.options & Option::CreateStandardWindowLayout)) { return; } m_systemTitleBarWidget = new QWidget(q); @@ -469,7 +469,7 @@ void FramelessWidgetsHelper::createSystemTitleBar() void FramelessWidgetsHelper::createUserContentContainer() { - if (!(m_settings.options & Option::UseStandardWindowLayout)) { + if (!(m_settings.options & Option::CreateStandardWindowLayout)) { return; } m_userContentContainerWidget = new QWidget(q); @@ -482,7 +482,7 @@ void FramelessWidgetsHelper::createUserContentContainer() void FramelessWidgetsHelper::setupInitialUi() { - if (m_settings.options & Option::UseStandardWindowLayout) { + if (m_settings.options & Option::CreateStandardWindowLayout) { createSystemTitleBar(); createUserContentContainer(); m_mainLayout = new QVBoxLayout(q); @@ -555,7 +555,7 @@ bool FramelessWidgetsHelper::isInTitleBarDraggableArea(const QPoint &pos) const } return region; } - if (m_settings.options & Option::UseStandardWindowLayout) { + if (m_settings.options & Option::CreateStandardWindowLayout) { QRegion region = mapWidgetGeometryToScene(m_systemTitleBarWidget); region -= mapWidgetGeometryToScene(m_systemMinimizeButton); region -= mapWidgetGeometryToScene(m_systemMaximizeButton); @@ -595,7 +595,7 @@ void FramelessWidgetsHelper::updateContentsMargins() void FramelessWidgetsHelper::updateSystemTitleBarStyleSheet() { - if (!(m_settings.options & Option::UseStandardWindowLayout)) { + if (!(m_settings.options & Option::CreateStandardWindowLayout)) { return; } const bool active = q->isActiveWindow(); @@ -630,7 +630,7 @@ void FramelessWidgetsHelper::updateSystemTitleBarStyleSheet() void FramelessWidgetsHelper::updateSystemButtonsIcon() { - if (!(m_settings.options & Option::UseStandardWindowLayout)) { + if (!(m_settings.options & Option::CreateStandardWindowLayout)) { return; } const SystemTheme theme = ((Utils::shouldAppsUseDarkMode() || Utils::isTitleBarColorized()) ? SystemTheme::Dark : SystemTheme::Light);