summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Dubsky <[email protected]>2025-11-09 20:22:58 +0100
committerPavel Dubsky <[email protected]>2025-11-25 17:23:51 +0100
commita5218f692c135ae88b5ae691d38e727b7c6eb9f6 (patch)
treee2e9f5c65b38b28f9522c7cf7a6b5048d9a0e05d
parent3f570a7b92a1be18585bb9ca45e6fda7e75f3cdc (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]>
-rw-r--r--src/plugins/platforms/direct2d/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/windows/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowswindowclassdescription.cpp79
-rw-r--r--src/plugins/platforms/windows/qwindowswindowclassdescription.h29
-rw-r--r--src/plugins/platforms/windows/qwindowswindowclassregistry.cpp111
-rw-r--r--src/plugins/platforms/windows/qwindowswindowclassregistry.h6
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();