diff options
Diffstat (limited to 'src/gui/platform/windows')
-rw-r--r-- | src/gui/platform/windows/qwindowsguieventdispatcher.cpp | 50 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsguieventdispatcher_p.h | 40 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsmime_p.h | 85 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsmimeconverter.cpp | 170 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsmimeconverter.h | 43 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsnativeinterface.cpp | 79 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsthemecache.cpp | 79 | ||||
-rw-r--r-- | src/gui/platform/windows/qwindowsthemecache_p.h | 35 |
8 files changed, 366 insertions, 215 deletions
diff --git a/src/gui/platform/windows/qwindowsguieventdispatcher.cpp b/src/gui/platform/windows/qwindowsguieventdispatcher.cpp index 999e119681..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" @@ -209,6 +173,12 @@ messageDebugEntries[] = { {WM_POINTERROUTEDAWAY, "WM_POINTERROUTEDAWAY", true}, {WM_POINTERROUTEDRELEASED, "WM_POINTERROUTEDRELEASED", true}, #endif // WM_POINTERROUTEDTO +#ifdef WM_GETDPISCALEDSIZE + {WM_GETDPISCALEDSIZE, "WM_GETDPISCALEDSIZE", true}, +#endif +#ifdef WM_DPICHANGED + {WM_DPICHANGED, "WM_DPICHANGED", true}, +#endif }; static inline const MessageDebugEntry *messageDebugEntry(UINT msg) @@ -227,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 cacfceeb7c..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 @@ -53,12 +17,14 @@ using namespace QNativeInterface::Private; /*! \class QNativeInterface::QWGLContext + \inheaderfile QOpenGLContext \since 6.0 \brief Native interface to a WGL context on Windows. Accessed through QOpenGLContext::nativeInterface(). \inmodule QtGui + \inheaderfile QOpenGLContext \ingroup native-interfaces \ingroup native-interfaces-qopenglcontext */ @@ -94,7 +60,7 @@ using namespace QNativeInterface::Private; \note This function requires that the QGuiApplication instance is already created. */ -QT_DEFINE_NATIVE_INTERFACE(QWGLContext, QOpenGLContext); +QT_DEFINE_NATIVE_INTERFACE(QWGLContext); QT_DEFINE_PRIVATE_NATIVE_INTERFACE(QWindowsGLIntegration); HMODULE QNativeInterface::QWGLContext::openGLModuleHandle() @@ -123,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(). @@ -200,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() */ /*! @@ -242,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 |