diff options
| author | Pavel Dubsky <[email protected]> | 2025-11-09 20:22:58 +0100 |
|---|---|---|
| committer | Pavel Dubsky <[email protected]> | 2025-11-25 17:23:51 +0100 |
| commit | a5218f692c135ae88b5ae691d38e727b7c6eb9f6 (patch) | |
| tree | e2e9f5c65b38b28f9522c7cf7a6b5048d9a0e05d | |
| parent | 3f570a7b92a1be18585bb9ca45e6fda7e75f3cdc (diff) | |
Add QWindowsWindowClassDescription class
Replace loose parameter set with a small value type to clarify call
sites and allow future extension (cursor/menu/extra bytes) without API
churn.
Change-Id: I84303ab62f22778338a5950557117db7cc2edb77
Reviewed-by: Volker Hilsheimer <[email protected]>
7 files changed, 152 insertions, 80 deletions
diff --git a/src/plugins/platforms/direct2d/CMakeLists.txt b/src/plugins/platforms/direct2d/CMakeLists.txt index 0b3ecf33967..38d7e4160a5 100644 --- a/src/plugins/platforms/direct2d/CMakeLists.txt +++ b/src/plugins/platforms/direct2d/CMakeLists.txt @@ -33,6 +33,7 @@ qt_internal_add_plugin(QWindowsDirect2DIntegrationPlugin ../windows/qwindowstheme.cpp ../windows/qwindowstheme.h ../windows/qwindowsthreadpoolrunner.h ../windows/qwindowswindow.cpp ../windows/qwindowswindow.h + ../windows/qwindowswindowclassdescription.cpp ../windows/qwindowswindowclassdescription.h ../windows/qwindowswindowclassregistry.cpp ../windows/qwindowswindowclassregistry.h qwindowsdirect2dbackingstore.cpp qwindowsdirect2dbackingstore.h qwindowsdirect2dbitmap.cpp qwindowsdirect2dbitmap.h diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt index c7563c72979..40f173c8c82 100644 --- a/src/plugins/platforms/windows/CMakeLists.txt +++ b/src/plugins/platforms/windows/CMakeLists.txt @@ -38,6 +38,7 @@ qt_internal_add_plugin(QWindowsIntegrationPlugin qwindowstheme.cpp qwindowstheme.h qwindowsthreadpoolrunner.h qwindowswindow.cpp qwindowswindow.h + qwindowswindowclassdescription.cpp qwindowswindowclassdescription.h qwindowswindowclassregistry.cpp qwindowswindowclassregistry.h NO_UNITY_BUILD_SOURCES qwindowspointerhandler.cpp diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index c49ddbb3247..26d0f907b92 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -23,6 +23,7 @@ #ifdef QT_NO_CURSOR # include "qwindowscursor.h" #endif +#include "qwindowswindowclassdescription.h" #include "qwindowswindowclassregistry.h" #include <QtGui/qguiapplication.h> @@ -886,7 +887,9 @@ QWindowsWindowData const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr)); const QString windowClassName = QWindowsWindowClassRegistry::instance()->registerWindowClass(w); - const QString windowTitlebarName = QWindowsWindowClassRegistry::instance()->registerWindowClass(QStringLiteral("_q_titlebar"), DefWindowProc, CS_VREDRAW|CS_HREDRAW, nullptr, false); + const QString windowTitlebarName = QWindowsWindowClassRegistry::instance()->registerWindowClass({ + QStringLiteral("_q_titlebar"), DefWindowProc, CS_VREDRAW | CS_HREDRAW + }); const QScreen *screen{}; const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, diff --git a/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp b/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp new file mode 100644 index 00000000000..cb862bba47c --- /dev/null +++ b/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qwindowswindowclassdescription.h" + +#include <QtGui/qwindow.h> + +#include "qwindowswindowclassregistry.h" + +QT_BEGIN_NAMESPACE + +using namespace Qt::StringLiterals; + +QWindowsWindowClassDescription QWindowsWindowClassDescription::fromName(QString name, WNDPROC procedure) +{ + return { std::move(name), procedure }; +} + +QWindowsWindowClassDescription QWindowsWindowClassDescription::fromWindow(const QWindow *window, WNDPROC procedure) +{ + Q_ASSERT(window); + + QWindowsWindowClassDescription description; + description.procedure = procedure; + + const Qt::WindowFlags flags = window->flags(); + const Qt::WindowFlags type = flags & Qt::WindowType_Mask; + // Determine style and icon. + description.style = CS_DBLCLKS; + description.hasIcon = true; + // The following will not set CS_OWNDC for any widget window, even if it contains a + // QOpenGLWidget or QQuickWidget later on. That cannot be detected at this stage. + if (window->surfaceType() == QSurface::OpenGLSurface || (flags & Qt::MSWindowsOwnDC)) + description.style |= CS_OWNDC; + if (!(flags & Qt::NoDropShadowWindowHint) + && (type == Qt::Popup || window->property("_q_windowsDropShadow").toBool())) { + description.style |= CS_DROPSHADOW; + } + switch (type) { + case Qt::Tool: + case Qt::ToolTip: + case Qt::Popup: + description.style |= CS_SAVEBITS; // Save/restore background + description.hasIcon = false; + break; + case Qt::Dialog: + if (!(flags & Qt::WindowSystemMenuHint)) + description.hasIcon = false; // QTBUG-2027, dialogs without system menu. + break; + } + // Create a unique name for the flag combination + description.name = QWindowsWindowClassRegistry::classNamePrefix(); + description.name += "QWindow"_L1; + switch (type) { + case Qt::Tool: + description.name += "Tool"_L1; + break; + case Qt::ToolTip: + description.name += "ToolTip"_L1; + break; + case Qt::Popup: + description.name += "Popup"_L1; + break; + default: + break; + } + if (description.style & CS_DROPSHADOW) + description.name += "DropShadow"_L1; + if (description.style & CS_SAVEBITS) + description.name += "SaveBits"_L1; + if (description.style & CS_OWNDC) + description.name += "OwnDC"_L1; + if (description.hasIcon) + description.name += "Icon"_L1; + + return description; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindowclassdescription.h b/src/plugins/platforms/windows/qwindowswindowclassdescription.h new file mode 100644 index 00000000000..ece48e4343c --- /dev/null +++ b/src/plugins/platforms/windows/qwindowswindowclassdescription.h @@ -0,0 +1,29 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QWINDOWSWINDOWCLASSDESCRIPTION_H +#define QWINDOWSWINDOWCLASSDESCRIPTION_H + +#include "qtwindowsglobal.h" + +#include <QtCore/qstring.h> + +QT_BEGIN_NAMESPACE + +class QWindow; + +struct QWindowsWindowClassDescription +{ + static QWindowsWindowClassDescription fromName(QString name, WNDPROC procedure); + static QWindowsWindowClassDescription fromWindow(const QWindow *window, WNDPROC procedure); + + QString name; + WNDPROC procedure{ DefWindowProc }; + unsigned int style{ 0 }; + HBRUSH brush{ nullptr }; + bool hasIcon{ false }; +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSWINDOWCLASSDESCRIPTION_H diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp index 0d405dc419a..e367350d55e 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp @@ -6,9 +6,9 @@ #include <QtCore/qlibraryinfo.h> #include <QtCore/quuid.h> -#include <QtGui/qwindow.h> #include "qwindowscontext.h" +#include "qwindowswindowclassdescription.h" QT_BEGIN_NAMESPACE @@ -55,64 +55,10 @@ QString QWindowsWindowClassRegistry::classNamePrefix() return result; } -QString QWindowsWindowClassRegistry::registerWindowClass(const QWindow *w) +QString QWindowsWindowClassRegistry::registerWindowClass(const QWindowsWindowClassDescription &description) { - Q_ASSERT(w); - const Qt::WindowFlags flags = w->flags(); - const Qt::WindowFlags type = flags & Qt::WindowType_Mask; - // Determine style and icon. - uint style = CS_DBLCLKS; - bool icon = true; - // The following will not set CS_OWNDC for any widget window, even if it contains a - // QOpenGLWidget or QQuickWidget later on. That cannot be detected at this stage. - if (w->surfaceType() == QSurface::OpenGLSurface || (flags & Qt::MSWindowsOwnDC)) - style |= CS_OWNDC; - if (!(flags & Qt::NoDropShadowWindowHint) - && (type == Qt::Popup || w->property("_q_windowsDropShadow").toBool())) { - style |= CS_DROPSHADOW; - } - switch (type) { - case Qt::Tool: - case Qt::ToolTip: - case Qt::Popup: - style |= CS_SAVEBITS; // Save/restore background - icon = false; - break; - case Qt::Dialog: - if (!(flags & Qt::WindowSystemMenuHint)) - icon = false; // QTBUG-2027, dialogs without system menu. - break; - } - // Create a unique name for the flag combination - QString cname = classNamePrefix(); - cname += "QWindow"_L1; - switch (type) { - case Qt::Tool: - cname += "Tool"_L1; - break; - case Qt::ToolTip: - cname += "ToolTip"_L1; - break; - case Qt::Popup: - cname += "Popup"_L1; - break; - default: - break; - } - if (style & CS_DROPSHADOW) - cname += "DropShadow"_L1; - if (style & CS_SAVEBITS) - cname += "SaveBits"_L1; - if (style & CS_OWNDC) - cname += "OwnDC"_L1; - if (icon) - cname += "Icon"_L1; - - return registerWindowClass(cname, m_proc, style, nullptr, icon); -} + QString className = description.name; -QString QWindowsWindowClassRegistry::registerWindowClass(QString cname, WNDPROC proc, unsigned style, HBRUSH brush, bool icon) -{ // since multiple Qt versions can be used in one process // each one has to have window class names with a unique name // The first instance gets the unmodified name; if the class @@ -122,52 +68,63 @@ QString QWindowsWindowClassRegistry::registerWindowClass(QString cname, WNDPROC // Note: GetClassInfo() returns != 0 when a class exists. const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); WNDCLASS wcinfo; - const bool classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo) != FALSE - && wcinfo.lpfnWndProc != proc; + const bool classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(className.utf16()), &wcinfo) != FALSE + && wcinfo.lpfnWndProc != description.procedure; if (classExists) - cname += QUuid::createUuid().toString(); + className += QUuid::createUuid().toString(); - if (m_registeredWindowClassNames.contains(cname)) // already registered in our list - return cname; + if (m_registeredWindowClassNames.contains(className)) // already registered in our list + return className; WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); - wc.style = style; - wc.lpfnWndProc = proc; + wc.style = description.style; + wc.lpfnWndProc = description.procedure; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = appInstance; wc.hCursor = nullptr; - wc.hbrBackground = brush; - if (icon) { + wc.hbrBackground = description.brush; + if (description.hasIcon) { wc.hIcon = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE)); if (wc.hIcon) { int sw = GetSystemMetrics(SM_CXSMICON); int sh = GetSystemMetrics(SM_CYSMICON); wc.hIconSm = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0)); - } else { + } + else { wc.hIcon = static_cast<HICON>(LoadImage(nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED)); wc.hIconSm = nullptr; } - } else { + } + else { wc.hIcon = nullptr; wc.hIconSm = nullptr; } wc.lpszMenuName = nullptr; - wc.lpszClassName = reinterpret_cast<LPCWSTR>(cname.utf16()); + wc.lpszClassName = reinterpret_cast<LPCWSTR>(className.utf16()); ATOM atom = RegisterClassEx(&wc); - if (!atom) { + if (!atom) qErrnoWarning("QApplication::regClass: Registering window class '%s' failed.", - qPrintable(cname)); - } + qPrintable(className)); + + m_registeredWindowClassNames.insert(className); + qCDebug(lcQpaWindowClass).nospace() << __FUNCTION__ << ' ' << className + << " style=0x" << Qt::hex << description.style << Qt::dec + << " brush=" << description.brush << " icon=" << description.hasIcon << " atom=" << atom; + return className; +} - m_registeredWindowClassNames.insert(cname); - qCDebug(lcQpaWindowClass).nospace() << __FUNCTION__ << ' ' << cname - << " style=0x" << Qt::hex << style << Qt::dec - << " brush=" << brush << " icon=" << icon << " atom=" << atom; - return cname; +QString QWindowsWindowClassRegistry::registerWindowClass(const QWindow *window) +{ + return registerWindowClass(QWindowsWindowClassDescription::fromWindow(window, m_proc)); +} + +QString QWindowsWindowClassRegistry::registerWindowClass(QString name, WNDPROC procedure) +{ + return registerWindowClass(QWindowsWindowClassDescription::fromName(name, procedure)); } void QWindowsWindowClassRegistry::unregisterWindowClasses() diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.h b/src/plugins/platforms/windows/qwindowswindowclassregistry.h index d599497abd0..d1f10310dc8 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.h +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.h @@ -16,6 +16,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQpaWindowClass) class QWindow; +struct QWindowsWindowClassDescription; class QWindowsWindowClassRegistry { @@ -28,8 +29,9 @@ public: static QString classNamePrefix(); - QString registerWindowClass(const QWindow *w); - QString registerWindowClass(QString cname, WNDPROC proc, unsigned style = 0, HBRUSH brush = nullptr, bool icon = false); + QString registerWindowClass(const QWindowsWindowClassDescription &description); + QString registerWindowClass(const QWindow *window); + QString registerWindowClass(QString name, WNDPROC procedure); private: void unregisterWindowClasses(); |
