summaryrefslogtreecommitdiffstats
path: root/src/gui/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/platform/windows')
-rw-r--r--src/gui/platform/windows/qwindowsguieventdispatcher.cpp44
-rw-r--r--src/gui/platform/windows/qwindowsguieventdispatcher_p.h40
-rw-r--r--src/gui/platform/windows/qwindowsmime_p.h85
-rw-r--r--src/gui/platform/windows/qwindowsmimeconverter.cpp170
-rw-r--r--src/gui/platform/windows/qwindowsmimeconverter.h43
-rw-r--r--src/gui/platform/windows/qwindowsnativeinterface.cpp76
-rw-r--r--src/gui/platform/windows/qwindowsthemecache.cpp79
-rw-r--r--src/gui/platform/windows/qwindowsthemecache_p.h35
8 files changed, 358 insertions, 214 deletions
diff --git a/src/gui/platform/windows/qwindowsguieventdispatcher.cpp b/src/gui/platform/windows/qwindowsguieventdispatcher.cpp
index 183ee20fa9..c2f0efe96e 100644
--- a/src/gui/platform/windows/qwindowsguieventdispatcher.cpp
+++ b/src/gui/platform/windows/qwindowsguieventdispatcher.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
+// Copyright (C) 2016 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 "qwindowsguieventdispatcher_p.h"
@@ -233,3 +197,5 @@ const char *QWindowsGuiEventDispatcher::windowsMessageName(UINT msg)
}
QT_END_NAMESPACE
+
+#include "moc_qwindowsguieventdispatcher_p.cpp"
diff --git a/src/gui/platform/windows/qwindowsguieventdispatcher_p.h b/src/gui/platform/windows/qwindowsguieventdispatcher_p.h
index 804c7e936d..7d326c0780 100644
--- a/src/gui/platform/windows/qwindowsguieventdispatcher_p.h
+++ b/src/gui/platform/windows/qwindowsguieventdispatcher_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 QWINDOWSGUIEVENTDISPATCHER_H
#define QWINDOWSGUIEVENTDISPATCHER_H
diff --git a/src/gui/platform/windows/qwindowsmime_p.h b/src/gui/platform/windows/qwindowsmime_p.h
deleted file mode 100644
index 71b1c8a87f..0000000000
--- a/src/gui/platform/windows/qwindowsmime_p.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSMIME_P_H
-#define QWINDOWSMIME_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qt_windows.h>
-#include <QtCore/qvariant.h>
-
-#include <QtGui/qtguiglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMimeData;
-
-namespace QNativeInterface::Private {
-
-class Q_GUI_EXPORT QWindowsMime
-{
-public:
- virtual ~QWindowsMime() = default;
-
- // for converting from Qt
- virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0;
- virtual bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const = 0;
- virtual QList<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const = 0;
-
- // for converting to Qt
- virtual bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const = 0;
- virtual QVariant convertToMime(const QString &mimeType, IDataObject *pDataObj, QMetaType preferredType) const = 0;
- virtual QString mimeForFormat(const FORMATETC &formatetc) const = 0;
-};
-
-} // QNativeInterface::Private
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSMIME_P_H
diff --git a/src/gui/platform/windows/qwindowsmimeconverter.cpp b/src/gui/platform/windows/qwindowsmimeconverter.cpp
new file mode 100644
index 0000000000..49d524cb99
--- /dev/null
+++ b/src/gui/platform/windows/qwindowsmimeconverter.cpp
@@ -0,0 +1,170 @@
+// Copyright (C) 2022 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 "qwindowsmimeconverter.h"
+
+#include <QtCore/qt_windows.h>
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsMimeConverter
+ \brief The QWindowsMimeConverter class maps open-standard MIME to Window Clipboard formats.
+ \inmodule QtGui
+
+ Qt's drag-and-drop and clipboard facilities use the MIME standard.
+ On X11, this maps trivially to the Xdnd protocol, but on Windows
+ although some applications use MIME types to describe clipboard
+ formats, others use arbitrary non-standardized naming conventions,
+ or unnamed built-in formats of Windows.
+
+ By instantiating subclasses of QWindowsMimeConverter that provide
+ conversions between Windows Clipboard and MIME formats, you can convert
+ proprietary clipboard formats to MIME formats.
+
+ Construct an instance of your converter implementation after instantiating
+ QGuiApplication:
+
+ \code
+ int main(int argc, char **argv)
+ {
+ QGuiApplication app(argc, argv);
+ JsonMimeConverter jsonConverter;
+ }
+ \endcode
+
+ Destroying the instance will unregister the converter and remove support
+ for the conversion. It is also valid to heap-allocate the converter
+ instance; Qt takes ownership and will delete the converter object during
+ QGuiApplication shut-down.
+
+ Qt has predefined support for the following Windows Clipboard formats:
+
+ \table
+ \header \li Windows Format \li Equivalent MIME type
+ \row \li \c CF_UNICODETEXT \li \c text/plain
+ \row \li \c CF_TEXT \li \c text/plain
+ \row \li \c CF_DIB \li \c{image/xyz}, where \c xyz is
+ a \l{QImageWriter::supportedImageFormats()}{Qt image format}
+ \row \li \c CF_HDROP \li \c text/uri-list
+ \row \li \c CF_INETURL \li \c text/uri-list
+ \row \li \c CF_HTML \li \c text/html
+ \endtable
+
+ An example use of this class would be to map the Windows Metafile
+ clipboard format (\c CF_METAFILEPICT) to and from the MIME type
+ \c{image/x-wmf}. This conversion might simply be adding or removing
+ a header, or even just passing on the data. See \l{Drag and Drop}
+ for more information on choosing and definition MIME types.
+
+ You can check if a MIME type is convertible using canConvertFromMime() and
+ can perform conversions with convertToMime() and convertFromMime().
+*/
+
+
+/*!
+ \fn bool QWindowsMimeConverter::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+
+ Returns \c true if the converter can convert from the \a mimeData to
+ the format specified in \a formatetc.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn bool QWindowsMimeConverter::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+
+ Returns \c true if the converter can convert to the \a mimeType from
+ the available formats in \a pDataObj.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QString QWindowsMimeConverter::mimeForFormat(const FORMATETC &formatetc) const
+
+ Returns the mime type that will be created form the format specified
+ in \a formatetc, or an empty string if this converter does not support
+ \a formatetc.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QList<FORMATETC> QWindowsMimeConverter::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+
+ Returns a QList of FORMATETC structures representing the different windows clipboard
+ formats that can be provided for the \a mimeType from the \a mimeData.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QVariant QWindowsMimeConverter::convertToMime(const QString &mimeType, IDataObject *pDataObj,
+ QMetaType preferredType) const
+
+ Returns a QVariant containing the converted data for \a mimeType from \a pDataObj.
+ If possible the QVariant should be of the \a preferredType to avoid needless conversions.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn bool QWindowsMimeConverter::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+
+ Convert the \a mimeData to the format specified in \a formatetc.
+ The converted data should then be placed in \a pmedium structure.
+
+ Return true if the conversion was successful.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ Constructs a QWindowsMimeConverter instance.
+
+ The instance is automatically registered, and will be called to convert data during
+ clipboard or drag'n'drop operations.
+
+ Call this constructor after QGuiApplication has been created.
+*/
+QWindowsMimeConverter::QWindowsMimeConverter()
+{
+ using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
+ auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
+ Q_ASSERT(nativeWindowsApp);
+ nativeWindowsApp->registerMime(this);
+}
+
+/*!
+ Constructs a QWindowsMimeConverter instance.
+
+ The instance is automatically unregistered.
+*/
+QWindowsMimeConverter::~QWindowsMimeConverter()
+{
+ using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
+ auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
+ Q_ASSERT(nativeWindowsApp);
+ nativeWindowsApp->unregisterMime(this);
+}
+
+/*!
+ Registers the MIME type \a mimeType, and returns an ID number
+ identifying the format on Windows.
+
+ A mime type \c {application/x-qt-windows-mime;value="WindowsType"} will be
+ registered as the clipboard format for \c WindowsType.
+*/
+int QWindowsMimeConverter::registerMimeType(const QString &mimeType)
+{
+ using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
+ auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration());
+ Q_ASSERT(nativeWindowsApp);
+ return nativeWindowsApp->registerMimeType(mimeType);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/platform/windows/qwindowsmimeconverter.h b/src/gui/platform/windows/qwindowsmimeconverter.h
new file mode 100644
index 0000000000..145355fe15
--- /dev/null
+++ b/src/gui/platform/windows/qwindowsmimeconverter.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2022 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 QWINDOWSMIMECONVERTER_P_H
+#define QWINDOWSMIMECONVERTER_P_H
+
+#include <QtGui/qtguiglobal.h>
+
+struct tagFORMATETC;
+using FORMATETC = tagFORMATETC;
+struct tagSTGMEDIUM;
+using STGMEDIUM = tagSTGMEDIUM;
+struct IDataObject;
+
+QT_BEGIN_NAMESPACE
+
+class QMetaType;
+class QMimeData;
+class QVariant;
+
+class Q_GUI_EXPORT QWindowsMimeConverter
+{
+ Q_DISABLE_COPY(QWindowsMimeConverter)
+public:
+ QWindowsMimeConverter();
+ virtual ~QWindowsMimeConverter();
+
+ static int registerMimeType(const QString &mimeType);
+
+ // for converting from Qt
+ virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0;
+ virtual bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const = 0;
+ virtual QList<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const = 0;
+
+ // for converting to Qt
+ virtual bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const = 0;
+ virtual QVariant convertToMime(const QString &mimeType, IDataObject *pDataObj, QMetaType preferredType) const = 0;
+ virtual QString mimeForFormat(const FORMATETC &formatetc) const = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSMIMECONVERTER_H
diff --git a/src/gui/platform/windows/qwindowsnativeinterface.cpp b/src/gui/platform/windows/qwindowsnativeinterface.cpp
index 4a7d0fd2c9..44f230e1d3 100644
--- a/src/gui/platform/windows/qwindowsnativeinterface.cpp
+++ b/src/gui/platform/windows/qwindowsnativeinterface.cpp
@@ -1,49 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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 <QtGui/qopenglcontext.h>
#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/private/qwindowsmime_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformwindow_p.h>
+#include <qpa/qplatformscreen_p.h>
QT_BEGIN_NAMESPACE
@@ -60,6 +24,7 @@ using namespace QNativeInterface::Private;
Accessed through QOpenGLContext::nativeInterface().
\inmodule QtGui
+ \inheaderfile QOpenGLContext
\ingroup native-interfaces
\ingroup native-interfaces-qopenglcontext
*/
@@ -124,6 +89,21 @@ QOpenGLContext *QNativeInterface::QWGLContext::fromNative(HGLRC context, HWND wi
QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QWindowsApplication);
/*!
+ \class QNativeInterface::QWindowsScreen
+ \since 6.7
+ \brief Native interface to a screen.
+
+ Accessed through QScreen::nativeInterface().
+ \inmodule QtGui
+ \ingroup native-interfaces
+ \ingroup native-interfaces-qscreen
+*/
+/*!
+ * \fn HWMONITOR QNativeInterface::QWindowsScreen::handle() const;
+ * \return The underlying HWMONITOR of the screen.
+ */
+QT_DEFINE_NATIVE_INTERFACE(QWindowsScreen);
+/*!
\enum QNativeInterface::Private::QWindowsApplication::TouchWindowTouchType
This enum represents the supported TouchWindow touch flags for registerTouchWindow().
@@ -201,15 +181,7 @@ QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QWindowsApplication);
\value DarkModeStyle The Windows Vista style will be turned off and
a simple dark style will be used.
- \sa isDarkMode(), setDarkModeHandling()
-*/
-
-/*!
- \fn bool QNativeInterface::Private::QWindowsApplication::isDarkMode() const = 0
- \internal
-
- Returns \c true if Windows 10 is configured to use dark mode for
- applications.
+ \sa setDarkModeHandling()
*/
/*!
@@ -243,21 +215,21 @@ QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QWindowsApplication);
*/
/*!
- \fn bool QNativeInterface::Private::QWindowsApplication::registerMime(QWindowsMime *mime)
+ \fn bool QNativeInterface::Private::QWindowsApplication::registerMime(QWindowsMimeConverter *mime)
\internal
Registers the converter \a mime to the system.
- \sa QNativeInterface::Private::QWindowsMime, unregisterMime()
+ \sa QWindowsMimeConverter, unregisterMime()
*/
/*!
- \fn void QNativeInterface::Private::QWindowsApplication::unregisterMime(QWindowsMime *mime)
+ \fn void QNativeInterface::Private::QWindowsApplication::unregisterMime(QWindowsMimeConverter *mime)
\internal
Unregisters the converter \a mime from the system.
- \sa QNativeInterface::Private::QWindowsMime, registerMime()
+ \sa QWindowsMimeConverter, registerMime()
*/
/*!
diff --git a/src/gui/platform/windows/qwindowsthemecache.cpp b/src/gui/platform/windows/qwindowsthemecache.cpp
new file mode 100644
index 0000000000..3bb92e67ca
--- /dev/null
+++ b/src/gui/platform/windows/qwindowsthemecache.cpp
@@ -0,0 +1,79 @@
+// Copyright (C) 2023 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 "qwindowsthemecache_p.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qhash.h>
+
+QT_BEGIN_NAMESPACE
+
+// Theme names matching the QWindowsVistaStylePrivate::Theme enumeration.
+constexpr const wchar_t *themeNames[] = {
+ L"BUTTON", L"COMBOBOX", L"EDIT", L"HEADER", L"LISTVIEW",
+ L"MENU", L"PROGRESS", L"REBAR", L"SCROLLBAR", L"SPIN",
+ L"TAB", L"TASKDIALOG", L"TOOLBAR", L"TOOLTIP", L"TRACKBAR",
+ L"WINDOW", L"STATUS", L"TREEVIEW"
+};
+
+typedef std::array<HTHEME, std::size(themeNames)> ThemeArray;
+typedef QHash<HWND, ThemeArray> ThemesCache;
+Q_GLOBAL_STATIC(ThemesCache, themesCache);
+
+QString QWindowsThemeCache::themeName(int theme)
+{
+ return theme >= 0 && theme < int(std::size(themeNames))
+ ? QString::fromWCharArray(themeNames[theme]) : QString();
+}
+
+HTHEME QWindowsThemeCache::createTheme(int theme, HWND hwnd)
+{
+ if (Q_UNLIKELY(theme < 0 || theme >= int(std::size(themeNames)) || !hwnd)) {
+ qWarning("Invalid parameters #%d, %p", theme, hwnd);
+ return nullptr;
+ }
+
+ // Get or create themes array for this window.
+ ThemesCache *cache = themesCache();
+ auto it = cache->find(hwnd);
+ if (it == cache->end())
+ it = cache->insert(hwnd, ThemeArray {});
+
+ // Get or create theme data
+ ThemeArray &themes = *it;
+ if (!themes[theme]) {
+ const wchar_t *name = themeNames[theme];
+ themes[theme] = OpenThemeData(hwnd, name);
+ if (Q_UNLIKELY(!themes[theme]))
+ qErrnoWarning("OpenThemeData() failed for theme %d (%s).",
+ theme, qPrintable(themeName(theme)));
+ }
+ return themes[theme];
+}
+
+static void clearThemes(ThemeArray &themes)
+{
+ for (auto &theme : themes) {
+ if (theme) {
+ CloseThemeData(theme);
+ theme = nullptr;
+ }
+ }
+}
+
+void QWindowsThemeCache::clearThemeCache(HWND hwnd)
+{
+ ThemesCache *cache = themesCache();
+ auto it = cache->find(hwnd);
+ if (it == cache->end())
+ return;
+ clearThemes(*it);
+}
+
+void QWindowsThemeCache::clearAllThemeCaches()
+{
+ ThemesCache *cache = themesCache();
+ for (auto &themeArray : *cache)
+ clearThemes(themeArray);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/platform/windows/qwindowsthemecache_p.h b/src/gui/platform/windows/qwindowsthemecache_p.h
new file mode 100644
index 0000000000..beb724dc5c
--- /dev/null
+++ b/src/gui/platform/windows/qwindowsthemecache_p.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 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 QWINDOWSTHEME_CACHE_P_H
+#define QWINDOWSTHEME_CACHE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/private/qtguiglobal_p.h"
+
+#include <QtCore/qt_windows.h>
+#include <uxtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QWindowsThemeCache
+{
+ Q_GUI_EXPORT QString themeName(int theme);
+ Q_GUI_EXPORT HTHEME createTheme(int theme, HWND hwnd);
+ Q_GUI_EXPORT void clearThemeCache(HWND hwnd);
+ Q_GUI_EXPORT void clearAllThemeCaches();
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSTHEME_CACHE_P_H