Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwindowstheme.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/qt_windows.h>
5
6#include "qwindowstheme.h"
7#include "qwindowsmenu.h"
9#include "qwindowscontext.h"
10#include "qwindowsiconengine.h"
11#include "qwindowsintegration.h"
12#if QT_CONFIG(systemtrayicon)
14#endif
15#include "qwindowsscreen.h"
16#include "qwindowswindow.h"
17#include <commctrl.h>
18#include <objbase.h>
19#include <commoncontrols.h>
20#include <shellapi.h>
21
22#include <QtCore/qapplicationstatic.h>
23#include <QtCore/qvariant.h>
24#include <QtCore/qcoreapplication.h>
25#include <QtCore/qdebug.h>
26#include <QtCore/qsysinfo.h>
27#include <QtCore/qcache.h>
28#include <QtCore/qthread.h>
29#include <QtCore/qqueue.h>
30#include <QtCore/qmutex.h>
31#include <QtCore/qwaitcondition.h>
32#include <QtCore/qoperatingsystemversion.h>
33#include <QtGui/qcolor.h>
34#include <QtGui/qpalette.h>
35#include <QtGui/qguiapplication.h>
36#include <QtGui/qpainter.h>
37#include <QtGui/qpixmapcache.h>
38#include <qpa/qwindowsysteminterface.h>
39#include <QtGui/private/qabstractfileiconengine_p.h>
40#include <QtGui/private/qwindowsfontdatabase_p.h>
41#include <private/qhighdpiscaling_p.h>
42#include <private/qsystemlibrary_p.h>
43#include <private/qwinregistry_p.h>
44#include <QtCore/private/qfunctions_win_p.h>
45
46#include <algorithm>
47
48#if QT_CONFIG(cpp_winrt)
49# include <QtCore/private/qt_winrtbase_p.h>
50
51# include <winrt/Windows.UI.ViewManagement.h>
52#endif // QT_CONFIG(cpp_winrt)
53
55
56using namespace Qt::StringLiterals;
57
58static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue)
59{
60 BOOL result;
61 if (SystemParametersInfo(what, 0, &result, 0))
62 return result != FALSE;
63 return defaultValue;
64}
65
66static inline DWORD dWordSystemParametersInfo(UINT what, DWORD defaultValue)
67{
68 DWORD result;
69 if (SystemParametersInfo(what, 0, &result, 0))
70 return result;
71 return defaultValue;
72}
73
74static inline QColor mixColors(const QColor &c1, const QColor &c2)
75{
76 return {(c1.red() + c2.red()) / 2,
77 (c1.green() + c2.green()) / 2,
78 (c1.blue() + c2.blue()) / 2};
79}
80
86
87#if QT_CONFIG(cpp_winrt)
88static constexpr QColor getSysColor(winrt::Windows::UI::Color &&color)
89{
90 return QColor(color.R, color.G, color.B, color.A);
91}
92#endif
93
94[[maybe_unused]] [[nodiscard]] static inline QColor qt_accentColor(AccentColorLevel level)
95{
96#if QT_CONFIG(cpp_winrt)
97 using namespace winrt::Windows::UI::ViewManagement;
98 const auto settings = UISettings();
99 const QColor accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
100 const QColor accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
101 const QColor accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
102#else
103 const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
104 if (!registry.isValid())
105 return {};
106 const QVariant value = registry.value(L"AccentColor");
107 if (!value.isValid())
108 return {};
109 // The retrieved value is in the #AABBGGRR format, we need to
110 // convert it to the #AARRGGBB format which Qt expects.
111 const QColor abgr = QColor::fromRgba(qvariant_cast<DWORD>(value));
112 if (!abgr.isValid())
113 return {};
114 const QColor accent = QColor::fromRgb(abgr.blue(), abgr.green(), abgr.red(), abgr.alpha());
115 const QColor accentLight = accent.lighter(120);
116 const QColor accentDarkest = accent.darker(120 * 120 * 120);
117#endif
119 return accentDarkest;
120 else if (level == AccentColorLightest)
121 return accentLight;
122 return accent;
123}
124
125static inline QColor getSysColor(int index)
126{
127 COLORREF cr = GetSysColor(index);
128 return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr));
129}
130
131// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system
132// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the
133// behavior by running it in a thread.
135{
136public:
137 struct Task
138 {
139 Task(const QString &fn, DWORD a, UINT f)
140 : fileName(fn), attributes(a), flags(f)
141 {}
143 ~Task()
144 {
145 DestroyIcon(hIcon);
146 hIcon = 0;
147 }
148 // Request
150 const DWORD attributes;
151 const UINT flags;
152 // Result
153 HICON hIcon = 0;
154 int iIcon = -1;
155 bool finished = false;
156 bool resultValid() const { return hIcon != 0 && iIcon >= 0 && finished; }
157 };
158
160 : QThread()
161 {
162 start();
163 }
164
166 {
167 cancel();
168 wait();
169 }
170
171 QSharedPointer<Task> getNextTask()
172 {
173 QMutexLocker l(&m_waitForTaskMutex);
174 while (!isInterruptionRequested()) {
175 if (!m_taskQueue.isEmpty())
176 return m_taskQueue.dequeue();
177 m_waitForTaskCondition.wait(&m_waitForTaskMutex);
178 }
179 return nullptr;
180 }
181
182 void run() override
183 {
184 QComHelper comHelper(COINIT_MULTITHREADED);
185
186 while (!isInterruptionRequested()) {
187 auto task = getNextTask();
188 if (task) {
189 SHFILEINFO info;
190 const bool result = SHGetFileInfo(reinterpret_cast<const wchar_t *>(task->fileName.utf16()),
191 task->attributes, &info, sizeof(SHFILEINFO),
192 task->flags);
193 if (result) {
194 task->hIcon = info.hIcon;
195 task->iIcon = info.iIcon;
196 }
197 task->finished = true;
198 m_doneCondition.wakeAll();
199 }
200 }
201 }
202
203 void runWithParams(const QSharedPointer<Task> &task,
204 std::chrono::milliseconds timeout = std::chrono::milliseconds(5000))
205 {
206 {
207 QMutexLocker l(&m_waitForTaskMutex);
208 m_taskQueue.enqueue(task);
209 m_waitForTaskCondition.wakeAll();
210 }
211
212 QMutexLocker doneLocker(&m_doneMutex);
213 while (!task->finished && !isInterruptionRequested()) {
214 if (!m_doneCondition.wait(&m_doneMutex, QDeadlineTimer(timeout)))
215 return;
216 }
217 }
218
219 void cancel()
220 {
222 m_doneCondition.wakeAll();
223 m_waitForTaskCondition.wakeAll();
224 }
225
226private:
227 QQueue<QSharedPointer<Task>> m_taskQueue;
228 QWaitCondition m_doneCondition;
229 QWaitCondition m_waitForTaskCondition;
230 QMutex m_doneMutex;
231 QMutex m_waitForTaskMutex;
232};
234
235// from QStyle::standardPalette
236static inline QPalette standardPalette()
237{
238 QColor backgroundColor(0xd4, 0xd0, 0xc8); // win 2000 grey
239 QColor lightColor(backgroundColor.lighter());
240 QColor darkColor(backgroundColor.darker());
241 const QBrush darkBrush(darkColor);
242 QColor midColor(Qt::gray);
243 QPalette palette(Qt::black, backgroundColor, lightColor, darkColor,
244 midColor, Qt::black, Qt::white);
245 palette.setBrush(QPalette::Disabled, QPalette::WindowText, darkBrush);
246 palette.setBrush(QPalette::Disabled, QPalette::Text, darkBrush);
247 palette.setBrush(QPalette::Disabled, QPalette::ButtonText, darkBrush);
248 palette.setBrush(QPalette::Disabled, QPalette::Base, QBrush(backgroundColor));
249 return palette;
250}
251
253{
254 textColor.setAlpha(128);
255 return textColor;
256}
257
258/*
259 This is used when the theme is light mode, and when the theme is dark but the
260 application doesn't support dark mode. In the latter case, we need to check.
261*/
262void QWindowsTheme::populateLightSystemBasePalette(QPalette &result)
263{
264 const QColor background = getSysColor(COLOR_BTNFACE);
265 const QColor textColor = getSysColor(COLOR_WINDOWTEXT);
266
268 const QColor accentDarkest = qt_accentColor(AccentColorDarkest);
269
270 const QColor linkColor = accent;
271 const QColor btnFace = background;
272 const QColor btnHighlight = getSysColor(COLOR_BTNHIGHLIGHT);
273
274 result.setColor(QPalette::Highlight, getSysColor(COLOR_HIGHLIGHT));
275 result.setColor(QPalette::WindowText, getSysColor(COLOR_WINDOWTEXT));
276 result.setColor(QPalette::Button, btnFace);
277 result.setColor(QPalette::Light, btnHighlight);
278 result.setColor(QPalette::Dark, getSysColor(COLOR_BTNSHADOW));
279 result.setColor(QPalette::Mid, result.button().color().darker(150));
280 result.setColor(QPalette::Text, textColor);
282 result.setColor(QPalette::BrightText, btnHighlight);
283 result.setColor(QPalette::Base, getSysColor(COLOR_WINDOW));
284 result.setColor(QPalette::Window, btnFace);
285 result.setColor(QPalette::ButtonText, getSysColor(COLOR_BTNTEXT));
286 result.setColor(QPalette::Midlight, getSysColor(COLOR_3DLIGHT));
287 result.setColor(QPalette::Shadow, getSysColor(COLOR_3DDKSHADOW));
288 result.setColor(QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT));
289 result.setColor(QPalette::Accent, accent);
290
291 result.setColor(QPalette::Link, linkColor);
292 result.setColor(QPalette::LinkVisited, accentDarkest);
293 result.setColor(QPalette::Inactive, QPalette::Button, result.button().color());
294 result.setColor(QPalette::Inactive, QPalette::Window, result.window().color());
295 result.setColor(QPalette::Inactive, QPalette::Light, result.light().color());
296 result.setColor(QPalette::Inactive, QPalette::Dark, result.dark().color());
297
298 if (result.midlight() == result.button())
299 result.setColor(QPalette::Midlight, result.button().color().lighter(110));
300}
301
302void QWindowsTheme::populateDarkSystemBasePalette(QPalette &result)
303{
304 QColor foreground, background,
305 accent, accentDark, accentDarker, accentDarkest,
306 accentLight, accentLighter, accentLightest;
307#if QT_CONFIG(cpp_winrt)
308 using namespace winrt::Windows::UI::ViewManagement;
309 const auto settings = UISettings();
310
311 // We have to craft a palette from these colors. The settings.UIElementColor(UIElementType) API
312 // returns the old system colors, not the dark mode colors. If the background is black (which it
313 // usually), then override it with a dark gray instead so that we can go up and down the lightness.
314 if (QWindowsTheme::queryColorScheme() == Qt::ColorScheme::Dark) {
315 // the system is actually running in dark mode, so UISettings will give us dark colors
316 foreground = getSysColor(settings.GetColorValue(UIColorType::Foreground));
317 background = [&settings]() -> QColor {
318 auto systemBackground = getSysColor(settings.GetColorValue(UIColorType::Background));
319 if (systemBackground == Qt::black)
320 systemBackground = QColor(0x1E, 0x1E, 0x1E);
321 return systemBackground;
322 }();
323
324 accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
325 accentDark = getSysColor(settings.GetColorValue(UIColorType::AccentDark1));
326 accentDarker = getSysColor(settings.GetColorValue(UIColorType::AccentDark2));
327 accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
328 accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
329 accentLighter = getSysColor(settings.GetColorValue(UIColorType::AccentLight2));
330 accentLightest = getSysColor(settings.GetColorValue(UIColorType::AccentLight3));
331 } else
332#endif
333 {
334 // If the system is running in light mode, then we need to make up our own dark palette
335 foreground = Qt::white;
336 background = QColor(0x1E, 0x1E, 0x1E);
338 accentDark = accent.darker(120);
339 accentDarker = accentDark.darker(120);
340 accentDarkest = accentDarker.darker(120);
341 accentLight = accent.lighter(120);
342 accentLighter = accentLight.lighter(120);
343 accentLightest = accentLighter.lighter(120);
344 }
345 const QColor linkColor = accent;
346 const QColor buttonColor = background.lighter(200);
347
348 result.setColor(QPalette::All, QPalette::WindowText, foreground);
349 result.setColor(QPalette::All, QPalette::Text, foreground);
350 result.setColor(QPalette::All, QPalette::BrightText, accentLightest);
351
352 result.setColor(QPalette::All, QPalette::Button, buttonColor);
353 result.setColor(QPalette::All, QPalette::ButtonText, foreground);
354 result.setColor(QPalette::All, QPalette::Light, buttonColor.lighter(200));
355 result.setColor(QPalette::All, QPalette::Midlight, buttonColor.lighter(150));
356 result.setColor(QPalette::All, QPalette::Dark, buttonColor.darker(200));
357 result.setColor(QPalette::All, QPalette::Mid, buttonColor.darker(150));
359
360 result.setColor(QPalette::All, QPalette::Base, background.lighter(150));
361 result.setColor(QPalette::All, QPalette::Window, background);
362
363 result.setColor(QPalette::All, QPalette::Highlight, accent);
365 result.setColor(QPalette::All, QPalette::Link, linkColor);
366 result.setColor(QPalette::All, QPalette::LinkVisited, accentDarkest);
367 result.setColor(QPalette::All, QPalette::AlternateBase, accentDarkest);
368 result.setColor(QPalette::All, QPalette::ToolTipBase, buttonColor);
369 result.setColor(QPalette::All, QPalette::ToolTipText, foreground.darker(120));
371 result.setColor(QPalette::All, QPalette::Accent, accent);
372}
373
374static inline QPalette toolTipPalette(const QPalette &systemPalette, bool light)
375{
376 QPalette result(systemPalette);
377 const QColor tipBgColor = light ? getSysColor(COLOR_INFOBK)
378 : systemPalette.button().color();
379 const QColor tipTextColor = light ? getSysColor(COLOR_INFOTEXT)
380 : systemPalette.buttonText().color().darker(120);
381
382 result.setColor(QPalette::All, QPalette::Button, tipBgColor);
383 result.setColor(QPalette::All, QPalette::Window, tipBgColor);
384 result.setColor(QPalette::All, QPalette::Text, tipTextColor);
385 result.setColor(QPalette::All, QPalette::WindowText, tipTextColor);
386 result.setColor(QPalette::All, QPalette::ButtonText, tipTextColor);
387 result.setColor(QPalette::All, QPalette::Button, tipBgColor);
388 result.setColor(QPalette::All, QPalette::Window, tipBgColor);
389 result.setColor(QPalette::All, QPalette::Text, tipTextColor);
390 result.setColor(QPalette::All, QPalette::WindowText, tipTextColor);
391 result.setColor(QPalette::All, QPalette::ButtonText, tipTextColor);
392 result.setColor(QPalette::All, QPalette::ToolTipBase, tipBgColor);
393 result.setColor(QPalette::All, QPalette::ToolTipText, tipTextColor);
394 const QColor disabled = mixColors(result.windowText().color(), result.button().color());
401 return result;
402}
403
404static inline QPalette menuPalette(const QPalette &systemPalette, bool light)
405{
406 if (!light)
407 return systemPalette;
408
409 QPalette result(systemPalette);
410 const QColor menuColor = getSysColor(COLOR_MENU);
411 const QColor menuTextColor = getSysColor(COLOR_MENUTEXT);
412 const QColor disabled = getSysColor(COLOR_GRAYTEXT);
413 // we might need a special color group for the result.
414 result.setColor(QPalette::Active, QPalette::Button, menuColor);
415 result.setColor(QPalette::Active, QPalette::Text, menuTextColor);
416 result.setColor(QPalette::Active, QPalette::WindowText, menuTextColor);
417 result.setColor(QPalette::Active, QPalette::ButtonText, menuTextColor);
420 const bool isFlat = booleanSystemParametersInfo(SPI_GETFLATMENU, false);
421 const QColor highlightColor = getSysColor(isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT);
422 result.setColor(QPalette::Disabled, QPalette::Highlight, highlightColor);
439 systemPalette.color(QPalette::Inactive, QPalette::Dark));
440 return result;
441}
442
443static inline QPalette *menuBarPalette(const QPalette &menuPalette, bool light)
444{
445 QPalette *result = nullptr;
446 if (!light || !booleanSystemParametersInfo(SPI_GETFLATMENU, false))
447 return result;
448
450 const QColor menubar(getSysColor(COLOR_MENUBAR));
451 result->setColor(QPalette::Active, QPalette::Button, menubar);
452 result->setColor(QPalette::Disabled, QPalette::Button, menubar);
453 result->setColor(QPalette::Inactive, QPalette::Button, menubar);
454 return result;
455}
456
457const char *QWindowsTheme::name = "windows";
458QWindowsTheme *QWindowsTheme::m_instance = nullptr;
459
461{
462 m_instance = this;
463 s_colorScheme = QWindowsTheme::queryColorScheme();
464 std::fill(m_fonts, m_fonts + NFonts, nullptr);
465 std::fill(m_palettes, m_palettes + NPalettes, nullptr);
466 refresh();
467 refreshIconPixmapSizes();
468}
469
471{
472 clearPalettes();
473 clearFonts();
474 m_instance = nullptr;
475}
476
478{
479 const QFileInfo appDir(QCoreApplication::applicationDirPath() + "/icons"_L1);
480 return appDir.isDir() ? QStringList(appDir.absoluteFilePath()) : QStringList();
481}
482
483static inline QStringList styleNames()
484{
485 QStringList styles = { QStringLiteral("WindowsVista"), QStringLiteral("Windows") };
487 styles.prepend(QStringLiteral("Windows11"));
488 return styles;
489}
490
506
508{
509 switch (hint) {
511 return QVariant(true);
516 case StyleNames:
517 return QVariant(styleNames());
518 case TextCursorWidth:
519 return QVariant(int(dWordSystemParametersInfo(SPI_GETCARETWIDTH, 1u)));
520 case DropShadow:
521 return QVariant(booleanSystemParametersInfo(SPI_GETDROPSHADOW, false));
523 return QVariant(qRound(qreal(QWindowsContext::instance()->defaultDPI()) * 1.375));
524 case KeyboardScheme:
525 return QVariant(int(WindowsKeyboardScheme));
526 case UiEffects:
527 return QVariant(uiEffects());
528 case IconPixmapSizes:
529 return QVariant::fromValue(m_fileIconSizes);
531 return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
533 return QVariant(true);
534 case WheelScrollLines: {
535 int result = 3;
536 const DWORD scrollLines = dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, DWORD(result));
537 if (scrollLines != DWORD(-1)) // Special value meaning "scroll one screen", unimplemented in Qt.
538 result = int(scrollLines);
539 return QVariant(result);
540 }
542 return GetSystemMetrics(SM_CXDOUBLECLK);
544 return true;
545 default:
546 break;
547 }
549}
550
552{
553 return QWindowsTheme::effectiveColorScheme();
554}
555
556Qt::ColorScheme QWindowsTheme::effectiveColorScheme()
557{
558 if (queryHighContrast())
560 if (s_colorSchemeOverride != Qt::ColorScheme::Unknown)
561 return s_colorSchemeOverride;
562 if (s_colorScheme != Qt::ColorScheme::Unknown)
563 return s_colorScheme;
564 return queryColorScheme();
565}
566
568{
569 s_colorSchemeOverride = scheme;
571}
572
574{
575 const auto oldColorScheme = s_colorScheme;
576 s_colorScheme = Qt::ColorScheme::Unknown; // make effectiveColorScheme() query registry
577 const auto newColorScheme = effectiveColorScheme();
578 const bool colorSchemeChanged = newColorScheme != oldColorScheme;
579 s_colorScheme = newColorScheme;
580 auto integration = QWindowsIntegration::instance();
581 integration->updateApplicationBadge();
582 if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) {
583 QWindowsTheme::instance()->refresh();
584 QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
585 }
586 if (colorSchemeChanged) {
587 for (QWindowsWindow *w : std::as_const(QWindowsContext::instance()->windows()))
588 w->setDarkBorder(s_colorScheme == Qt::ColorScheme::Dark);
589 }
590}
591
592void QWindowsTheme::clearPalettes()
593{
594 qDeleteAll(m_palettes, m_palettes + NPalettes);
595 std::fill(m_palettes, m_palettes + NPalettes, nullptr);
596}
597
598void QWindowsTheme::refreshPalettes()
599{
601 return;
602 const bool light =
603 effectiveColorScheme() != Qt::ColorScheme::Dark
604 || !QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle);
605 clearPalettes();
606 m_palettes[SystemPalette] = new QPalette(QWindowsTheme::systemPalette(s_colorScheme));
607 m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette], light));
608 m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette], light));
609 m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette], light);
610 if (!light) {
611 m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]);
615 m_palettes[RadioButtonPalette] = new QPalette(*m_palettes[CheckBoxPalette]);
616 }
617}
618
620{
621 QPalette result = standardPalette();
622
623 switch (colorScheme) {
625 // when a high-contrast theme is active or when we fail to read, assume light
628 populateLightSystemBasePalette(result);
629 break;
631 populateDarkSystemBasePalette(result);
632 break;
633 }
634
635 if (result.window() != result.base()) {
642 }
643
644 const QColor disabled = mixColors(result.windowText().color(), result.button().color());
645
646 result.setColorGroup(QPalette::Disabled, result.windowText(), result.button(),
647 result.light(), result.dark(), result.mid(),
648 result.text(), result.brightText(), result.base(),
649 result.window());
656 result.setColor(QPalette::Disabled, QPalette::Base, result.window().color());
657 return result;
658}
659
660void QWindowsTheme::clearFonts()
661{
662 qDeleteAll(m_fonts, m_fonts + NFonts);
663 std::fill(m_fonts, m_fonts + NFonts, nullptr);
664}
665
667{
668 refreshPalettes();
669 refreshFonts();
670}
671
672#ifndef QT_NO_DEBUG_STREAM
673QDebug operator<<(QDebug d, const NONCLIENTMETRICS &m)
674{
675 QDebugStateSaver saver(d);
676 d.nospace();
677 d.noquote();
678 d << "NONCLIENTMETRICS(iMenu=" << m.iMenuWidth << 'x' << m.iMenuHeight
679 << ", lfCaptionFont=";
680 QWindowsFontDatabase::debugFormat(d, m.lfCaptionFont);
681 d << ", lfSmCaptionFont=";
682 QWindowsFontDatabase::debugFormat(d, m.lfSmCaptionFont);
683 d << ", lfMenuFont=";
685 d << ", lfMessageFont=";
686 QWindowsFontDatabase::debugFormat(d, m.lfMessageFont);
687 d <<", lfStatusFont=";
689 d << ')';
690 return d;
691}
692#endif // QT_NO_DEBUG_STREAM
693
695{
696 clearFonts();
698 return;
699
700 const int dpi = 96;
701 NONCLIENTMETRICS ncm;
703 qCDebug(lcQpaWindow) << __FUNCTION__ << ncm;
704
705 const QFont menuFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMenuFont, dpi);
706 const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont, dpi);
707 const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont, dpi);
708 const QFont titleFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfCaptionFont, dpi);
709 QFont fixedFont(QStringLiteral("Courier New"), messageBoxFont.pointSize());
711
712 LOGFONT lfIconTitleFont;
713 SystemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
714 const QFont iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont, dpi);
715
717 m_fonts[MenuFont] = new QFont(menuFont);
718 m_fonts[MenuBarFont] = new QFont(menuFont);
719 m_fonts[MessageBoxFont] = new QFont(messageBoxFont);
720 m_fonts[TipLabelFont] = new QFont(statusFont);
721 m_fonts[StatusBarFont] = new QFont(statusFont);
722 m_fonts[MdiSubWindowTitleFont] = new QFont(titleFont);
723 m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
724 m_fonts[ItemViewFont] = new QFont(iconTitleFont);
725 m_fonts[FixedFont] = new QFont(fixedFont);
726}
727
729 // Standard icons obtainable via shGetFileInfo(), SHGFI_SMALLICON, SHGFI_LARGEICON
731 // Larger icons obtainable via SHGetImageList()
733 JumboFileIcon, // Vista onwards
736
741
746
747#if QT_CONFIG(systemtrayicon)
749{
750 return new QWindowsSystemTrayIcon;
751}
752#endif
753
759
761
762void QWindowsTheme::refreshIconPixmapSizes()
763{
764 // Standard sizes: 16, 32, 48, 256
765 fileIconSizes[SmallFileIcon] = GetSystemMetrics(SM_CXSMICON); // corresponds to SHGFI_SMALLICON);
766 fileIconSizes[LargeFileIcon] = GetSystemMetrics(SM_CXICON); // corresponds to SHGFI_LARGEICON
769 fileIconSizes[JumboFileIcon] = 8 * fileIconSizes[LargeFileIcon]; // empirical, has not been observed to work
770
771 int *availEnd = fileIconSizes + JumboFileIcon + 1;
772 m_fileIconSizes = QAbstractFileIconEngine::toSizeList(fileIconSizes, availEnd);
773 qCDebug(lcQpaWindow) << __FUNCTION__ << m_fileIconSizes;
774}
775
776// Defined in qpixmap_win.cpp
777Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon);
778
779static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
780{
781 if (const HMODULE hmod = QSystemLibrary::load(L"shell32")) {
782 auto iconHandle =
783 static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId),
784 IMAGE_ICON, int(size.width()), int(size.height()), 0));
785 if (iconHandle) {
786 QPixmap iconpixmap = qt_pixmapFromWinHICON(iconHandle);
787 DestroyIcon(iconHandle);
788 return iconpixmap;
789 }
790 }
791 return QPixmap();
792}
793
795{
796 int resourceId = -1;
797 SHSTOCKICONID stockId = SIID_INVALID;
798 UINT stockFlags = 0;
799 LPCTSTR iconName = nullptr;
800 switch (sp) {
801 case DriveCDIcon:
802 stockId = SIID_DRIVECD;
803 resourceId = 12;
804 break;
805 case DriveDVDIcon:
806 stockId = SIID_DRIVEDVD;
807 resourceId = 12;
808 break;
809 case DriveNetIcon:
810 stockId = SIID_DRIVENET;
811 resourceId = 10;
812 break;
813 case DriveHDIcon:
814 stockId = SIID_DRIVEFIXED;
815 resourceId = 9;
816 break;
817 case DriveFDIcon:
818 stockId = SIID_DRIVE35;
819 resourceId = 7;
820 break;
821 case FileLinkIcon:
822 stockFlags = SHGSI_LINKOVERLAY;
824 case FileIcon:
825 stockId = SIID_DOCNOASSOC;
826 resourceId = 1;
827 break;
828 case DirLinkIcon:
829 stockFlags = SHGSI_LINKOVERLAY;
831 case DirClosedIcon:
832 case DirIcon:
833 stockId = SIID_FOLDER;
834 resourceId = 4;
835 break;
836 case DesktopIcon:
837 resourceId = 35;
838 break;
839 case ComputerIcon:
840 resourceId = 16;
841 break;
842 case DirLinkOpenIcon:
843 stockFlags = SHGSI_LINKOVERLAY;
845 case DirOpenIcon:
846 stockId = SIID_FOLDEROPEN;
847 resourceId = 5;
848 break;
850 stockId = SIID_FOLDER;
851 resourceId = 319;
852 break;
853 case DirHomeIcon:
854 resourceId = 235;
855 break;
856 case TrashIcon:
857 stockId = SIID_RECYCLER;
858 resourceId = 191;
859 break;
861 stockId = SIID_INFO;
862 iconName = IDI_INFORMATION;
863 break;
865 stockId = SIID_WARNING;
866 iconName = IDI_WARNING;
867 break;
869 stockId = SIID_ERROR;
870 iconName = IDI_ERROR;
871 break;
873 stockId = SIID_HELP;
874 iconName = IDI_QUESTION;
875 break;
876 case VistaShield:
877 stockId = SIID_SHIELD;
878 break;
879 default:
880 break;
881 }
882
883 if (stockId != SIID_INVALID) {
884 SHSTOCKICONINFO iconInfo;
885 memset(&iconInfo, 0, sizeof(iconInfo));
886 iconInfo.cbSize = sizeof(iconInfo);
887 stockFlags |= SHGSI_ICONLOCATION;
888 if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
889 const auto iconSize = pixmapSize.width();
890 HICON icon;
891 if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
893 DestroyIcon(icon);
894 return pixmap;
895 }
896 }
897 }
898
899 if (resourceId != -1) {
900 QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
901 if (!pixmap.isNull()) {
902 if (sp == FileLinkIcon || sp == DirLinkIcon || sp == DirLinkOpenIcon) {
904 QPixmap link = loadIconFromShell32(30, pixmapSize);
905 painter.drawPixmap(0, 0, int(pixmapSize.width()), int(pixmapSize.height()), link);
906 }
907 return pixmap;
908 }
909 }
910
911 if (iconName) {
912 HICON iconHandle = LoadIcon(nullptr, iconName);
914 DestroyIcon(iconHandle);
915 if (!pixmap.isNull())
916 return pixmap;
917 }
918
919 return QPlatformTheme::standardPixmap(sp, pixmapSize);
920}
921
922enum { // Shell image list ids
923 sHIL_EXTRALARGE = 0x2, // 48x48 or user-defined
924 sHIL_JUMBO = 0x4 // 256x256 (Vista or later)
926
927static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize)
928{
929 QString key = "qt_dir_"_L1 + QString::number(iIcon);
930 if (iconSize == SHGFI_LARGEICON)
931 key += u'l';
932 switch (imageListSize) {
933 case sHIL_EXTRALARGE:
934 key += u'e';
935 break;
936 case sHIL_JUMBO:
937 key += u'j';
938 break;
939 }
940 return key;
941}
942
943template <typename T>
945{
946public:
947
948 static_assert(sizeof(T) <= sizeof(void *), "FakePointers can only go that far.");
949
950 static FakePointer *create(T thing)
951 {
952 return reinterpret_cast<FakePointer *>(qintptr(thing));
953 }
954
955 T operator * () const
956 {
957 return T(qintptr(this));
958 }
959
960 void operator delete (void *) {}
961};
962
963// Shell image list helper functions.
964
965static QPixmap pixmapFromShellImageList(int iImageList, int iIcon)
966{
968 // For MinGW:
969 static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
970
971 IImageList *imageList = nullptr;
972 HRESULT hr = SHGetImageList(iImageList, iID_IImageList, reinterpret_cast<void **>(&imageList));
973 if (hr != S_OK)
974 return result;
975 HICON hIcon;
976 hr = imageList->GetIcon(iIcon, ILD_TRANSPARENT, &hIcon);
977 if (hr == S_OK) {
979 DestroyIcon(hIcon);
980 }
981 imageList->Release();
982 return result;
983}
984
986{
987public:
988 explicit QWindowsFileIconEngine(const QFileInfo &info, QPlatformTheme::IconOptions opts) :
990
992 { return QWindowsTheme::instance()->availableFileIconSizes(); }
993
994protected:
995 QString cacheKey() const override;
997};
998
1000{
1001 // Cache directories unless custom or drives, which have custom icons depending on type
1002 if ((options() & QPlatformTheme::DontUseCustomDirectoryIcons) && fileInfo().isDir() && !fileInfo().isRoot())
1003 return QStringLiteral("qt_/directory/");
1004 if (!fileInfo().isFile())
1005 return QString();
1006 // Return "" for .exe, .lnk and .ico extensions.
1007 // It is faster to just look at the file extensions;
1008 // avoiding slow QFileInfo::isExecutable() (QTBUG-13182)
1009 QString suffix = fileInfo().suffix();
1010 if (!suffix.compare(u"exe", Qt::CaseInsensitive)
1011 || !suffix.compare(u"lnk", Qt::CaseInsensitive)
1012 || !suffix.compare(u"ico", Qt::CaseInsensitive)) {
1013 return QString();
1014 }
1015 return "qt_."_L1
1016 + (suffix.isEmpty() ? fileInfo().fileName() : std::move(suffix).toUpper()); // handle "Makefile" ;)
1017}
1018
1020{
1021 QComHelper comHelper;
1022
1023 static QCache<QString, FakePointer<int> > dirIconEntryCache(1000);
1024 Q_CONSTINIT static QMutex mx;
1025 static int defaultFolderIIcon = -1;
1026 const bool useDefaultFolderIcon = options() & QPlatformTheme::DontUseCustomDirectoryIcons;
1027
1029 const QString filePath = QDir::toNativeSeparators(fileInfo().filePath());
1030 const int width = int(size.width());
1031 const int iconSize = width > fileIconSizes[SmallFileIcon] ? SHGFI_LARGEICON : SHGFI_SMALLICON;
1032 const int requestedImageListSize =
1034 ? sHIL_JUMBO
1036 bool cacheableDirIcon = fileInfo().isDir() && !fileInfo().isRoot();
1037 if (cacheableDirIcon) {
1038 QMutexLocker locker(&mx);
1039 int iIcon = (useDefaultFolderIcon && defaultFolderIIcon >= 0) ? defaultFolderIIcon
1040 : **dirIconEntryCache.object(filePath);
1041 if (iIcon) {
1042 QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize),
1043 &pixmap);
1044 if (pixmap.isNull()) // Let's keep both caches in sync
1045 dirIconEntryCache.remove(filePath);
1046 else
1047 return pixmap;
1048 }
1049 }
1050
1051 unsigned int flags = SHGFI_ICON | iconSize | SHGFI_SYSICONINDEX | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX;
1052 DWORD attributes = 0;
1053 QString path = filePath;
1054 if (cacheableDirIcon && useDefaultFolderIcon) {
1055 flags |= SHGFI_USEFILEATTRIBUTES;
1056 attributes |= FILE_ATTRIBUTE_DIRECTORY;
1057 path = QStringLiteral("dummy");
1058 } else if (!fileInfo().exists()) {
1059 flags |= SHGFI_USEFILEATTRIBUTES;
1060 attributes |= FILE_ATTRIBUTE_NORMAL;
1061 }
1062 auto task = QSharedPointer<QShGetFileInfoThread::Task>(
1063 new QShGetFileInfoThread::Task(path, attributes, flags));
1064 s_shGetFileInfoThread()->runWithParams(task);
1065 // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
1066 if (task->resultValid()) {
1067 QString key;
1068 if (cacheableDirIcon) {
1069 if (useDefaultFolderIcon && defaultFolderIIcon < 0)
1070 defaultFolderIIcon = task->iIcon;
1071
1072 //using the unique icon index provided by windows save us from duplicate keys
1073 key = dirIconPixmapCacheKey(task->iIcon, iconSize, requestedImageListSize);
1075 if (!pixmap.isNull()) {
1076 QMutexLocker locker(&mx);
1077 dirIconEntryCache.insert(filePath, FakePointer<int>::create(task->iIcon));
1078 }
1079 }
1080
1081 if (pixmap.isNull()) {
1082 if (requestedImageListSize) {
1083 pixmap = pixmapFromShellImageList(requestedImageListSize, task->iIcon);
1084 if (pixmap.isNull() && requestedImageListSize == sHIL_JUMBO)
1086 }
1087 if (pixmap.isNull())
1089 if (!pixmap.isNull()) {
1090 if (cacheableDirIcon) {
1091 QMutexLocker locker(&mx);
1093 dirIconEntryCache.insert(filePath, FakePointer<int>::create(task->iIcon));
1094 }
1095 } else {
1096 qWarning("QWindowsTheme::fileIconPixmap() no icon found");
1097 }
1098 }
1099 }
1100
1101 return pixmap;
1102}
1103
1104QIcon QWindowsTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const
1105{
1106 return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions));
1107}
1108
1110{
1111 return new QWindowsIconEngine(iconName);
1112}
1113
1114static inline bool doUseNativeMenus()
1115{
1116 const unsigned options = QWindowsIntegration::instance()->options();
1117 if ((options & QWindowsIntegration::NoNativeMenus) != 0)
1118 return false;
1119 if ((options & QWindowsIntegration::AlwaysUseNativeMenus) != 0)
1120 return true;
1121 // "Auto" mode: For non-widget or Quick Controls 2 applications
1122 if (!QCoreApplication::instance()->inherits("QApplication"))
1123 return true;
1124 const QWindowList &topLevels = QGuiApplication::topLevelWindows();
1125 for (const QWindow *t : topLevels) {
1126 if (t->inherits("QQuickApplicationWindow"))
1127 return true;
1128 }
1129 return false;
1130}
1131
1133{
1134 static const bool result = doUseNativeMenus();
1135 return result;
1136}
1137
1138Qt::ColorScheme QWindowsTheme::queryColorScheme()
1139{
1140 if (queryHighContrast())
1142
1143 const auto setting = QWinRegistryKey(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)")
1144 .dwordValue(L"AppsUseLightTheme");
1145 return setting.second && setting.first == 0 ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
1146}
1147
1148bool QWindowsTheme::queryHighContrast()
1149{
1150 HIGHCONTRAST hcf = {};
1151 hcf.cbSize = static_cast<UINT>(sizeof(HIGHCONTRAST));
1152 if (SystemParametersInfo(SPI_GETHIGHCONTRAST, hcf.cbSize, &hcf, FALSE))
1153 return hcf.dwFlags & HCF_HIGHCONTRASTON;
1154 return false;
1155}
1156
1158{
1159 qCDebug(lcQpaMenus) << __FUNCTION__;
1160 return QWindowsTheme::useNativeMenus() ? new QWindowsMenuItem : nullptr;
1161}
1162
1164{
1165 qCDebug(lcQpaMenus) << __FUNCTION__;
1166 // We create a popup menu here, since it will likely be used as context
1167 // menu. Submenus should be created the factory functions of
1168 // QPlatformMenu/Bar. Note though that Quick Controls 1 will use this
1169 // function for submenus as well, but this has been found to work.
1170 return QWindowsTheme::useNativeMenus() ? new QWindowsPopupMenu : nullptr;
1171}
1172
1174{
1175 qCDebug(lcQpaMenus) << __FUNCTION__;
1176 return QWindowsTheme::useNativeMenus() ? new QWindowsMenuBar : nullptr;
1177}
1178
1180{
1181 qCDebug(lcQpaMenus) << __FUNCTION__;
1182}
1183
T operator*() const
static FakePointer * create(T thing)
Helper base class for retrieving icons for files for usage by QFileIconProvider and related.
QPlatformTheme::IconOptions options() const
static QList< QSize > toSizeList(It i1, It i2)
\inmodule QtGui
Definition qbrush.h:30
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
QColor darker(int f=200) const noexcept
Definition qcolor.cpp:2857
static QColor fromRgb(QRgb rgb) noexcept
Static convenience function that returns a QColor constructed from the given QRgb value rgb.
Definition qcolor.cpp:2369
int lightness() const noexcept
Definition qcolor.cpp:1860
static QColor fromRgba(QRgb rgba) noexcept
Static convenience function that returns a QColor constructed from the given QRgb value rgba.
Definition qcolor.cpp:2385
int red() const noexcept
Returns the red color component of this color.
Definition qcolor.cpp:1528
int blue() const noexcept
Returns the blue color component of this color.
Definition qcolor.cpp:1583
int green() const noexcept
Returns the green color component of this color.
Definition qcolor.cpp:1555
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
Definition qcolor.cpp:1481
QColor lighter(int f=150) const noexcept
Definition qcolor.cpp:2812
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static QString applicationDirPath()
Returns the directory that contains the application executable.
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
static QString toNativeSeparators(const QString &pathName)
Definition qdir.cpp:929
QString suffix() const
Returns the suffix (extension) of the file.
bool isRoot() const
Returns true if the object points to a directory or to a symbolic link to a directory,...
QString fileName() const
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
\reentrant
Definition qfont.h:22
@ TypeWriter
Definition qfont.h:28
void setStyleHint(StyleHint, StyleStrategy=PreferDefault)
Sets the style hint and strategy to hint and strategy, respectively.
Definition qfont.cpp:1505
static QWindowList topLevelWindows()
Returns a list of the top-level windows in the application.
static bool desktopSettingsAware()
Returns true if Qt is set to use the system's standard colors, fonts, etc.; otherwise returns false.
The QIconEngine class provides an abstract base class for QIcon renderers.
Definition qiconengine.h:15
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
Mode
This enum type describes the mode for which a pixmap is intended to be used.
Definition qicon.h:22
@ Normal
Definition qicon.h:22
State
This enum describes the state for which a pixmap is intended to be used.
Definition qicon.h:23
@ Off
Definition qicon.h:23
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:281
Native interface to QPlatformWindow. \inmodule QtGui.
static Q_CORE_EXPORT QOperatingSystemVersionBase current()
static constexpr QOperatingSystemVersionBase Windows11
\variable QOperatingSystemVersion::Windows11
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
const QBrush & button() const
Returns the button brush of the current color group.
Definition qpalette.h:84
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition qpalette.h:67
@ Inactive
Definition qpalette.h:49
@ Disabled
Definition qpalette.h:49
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition qpalette.h:146
@ HighlightedText
Definition qpalette.h:53
@ ToolTipBase
Definition qpalette.h:57
@ BrightText
Definition qpalette.h:52
@ AlternateBase
Definition qpalette.h:55
@ ButtonText
Definition qpalette.h:52
@ WindowText
Definition qpalette.h:51
@ Highlight
Definition qpalette.h:53
@ ToolTipText
Definition qpalette.h:57
@ PlaceholderText
Definition qpalette.h:58
@ Midlight
Definition qpalette.h:51
@ LinkVisited
Definition qpalette.h:54
const QBrush & buttonText() const
Returns the button text foreground brush of the current color group.
Definition qpalette.h:96
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
QString key() const override
\variable QIconEngine::ScaledPixmapArgument::size
Definition qicon.cpp:477
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
The QPlatformDialogHelper class allows for platform-specific customization of dialogs.
virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const
virtual QVariant themeHint(ThemeHint hint) const
virtual QPlatformSystemTrayIcon * createPlatformSystemTrayIcon() const
Factory function for QSystemTrayIcon.
ThemeHint
This enum describes the available theme hints.
void runWithParams(const QSharedPointer< Task > &task, std::chrono::milliseconds timeout=std::chrono::milliseconds(5000))
QSharedPointer< Task > getNextTask()
\inmodule QtCore
Definition qsize.h:208
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6664
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
QString toUpper() const &
Definition qstring.h:439
bool isInterruptionRequested() const
Definition qthread.cpp:1075
bool wait(QDeadlineTimer deadline=QDeadlineTimer(QDeadlineTimer::Forever))
Definition qthread.cpp:1023
void requestInterruption()
Definition qthread.cpp:1070
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
bool wait(QMutex *, QDeadlineTimer=QDeadlineTimer(QDeadlineTimer::Forever))
std::pair< DWORD, bool > dwordValue(QStringView subKey) const
bool isValid() const
QVariant value(QStringView subKey) const
static void handleThemeChange(QWindow *window=nullptr)
\inmodule QtGui
Definition qwindow.h:63
static bool nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi=0)
static QWindowsContext * instance()
QList< QSize > availableSizes(QIcon::Mode=QIcon::Normal, QIcon::State=QIcon::Off) override
QPixmap filePixmap(const QSize &size, QIcon::Mode mode, QIcon::State) override
QWindowsFileIconEngine(const QFileInfo &info, QPlatformTheme::IconOptions opts)
QString cacheKey() const override
static QFont LOGFONT_to_QFont(const LOGFONT &lf, int verticalDPI=0)
static void debugFormat(QDebug &d, const LOGFONT &lf)
static QWindowsIntegration * instance()
Windows native menu bar.
Windows native system tray icon.
static bool useNativeMenus()
static void handleSettingsChanged()
void requestColorScheme(Qt::ColorScheme scheme) override
void windowsThemeChanged(QWindow *window)
void showPlatformMenuBar() override
QIconEngine * createIconEngine(const QString &iconName) const override
Factory function for the QIconEngine used by QIcon::fromTheme().
QPlatformMenuBar * createPlatformMenuBar() const override
bool usePlatformNativeDialog(DialogType type) const override
static const char * name
QPlatformMenuItem * createPlatformMenuItem() const override
Qt::ColorScheme colorScheme() const override
static QPalette systemPalette(Qt::ColorScheme)
QVariant themeHint(ThemeHint) const override
~QWindowsTheme() override
QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions={}) const override
Return an icon for fileInfo, observing iconOptions.
QPlatformDialogHelper * createPlatformDialogHelper(DialogType type) const override
static QWindowsTheme * instance()
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override
QPlatformMenu * createPlatformMenu() const override
qDeleteAll(list.begin(), list.end())
opt iconSize
Combined button and popup list for selecting options.
bool useHelper(QPlatformTheme::DialogType type)
QPlatformDialogHelper * createHelper(QPlatformTheme::DialogType type)
Definition qcompare.h:63
ColorScheme
Definition qnamespace.h:50
@ gray
Definition qnamespace.h:33
@ white
Definition qnamespace.h:31
@ black
Definition qnamespace.h:30
@ CaseInsensitive
#define Q_APPLICATION_STATIC(TYPE, NAME,...)
#define Q_FALLTHROUGH()
QList< QString > QStringList
Constructs a string list that contains the given string, str.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
#define qWarning
Definition qlogging.h:166
#define qCDebug(category,...)
GLenum mode
const GLfloat * m
GLenum GLuint GLint level
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLbitfield GLuint64 timeout
[4]
GLfloat GLfloat f
GLint GLsizei width
GLuint color
[2]
GLenum type
GLbitfield flags
GLuint start
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
QPixmap qt_pixmapFromWinHICON(HICON icon)
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define sp
#define SPI_GETMENUANIMATION
Definition qt_windows.h:50
#define SPI_GETFLATMENU
Definition qt_windows.h:94
#define SPI_GETTOOLTIPANIMATION
Definition qt_windows.h:59
#define SPI_GETCOMBOBOXANIMATION
Definition qt_windows.h:56
#define SPI_GETUIEFFECTS
Definition qt_windows.h:65
#define SPI_GETMENUFADE
Definition qt_windows.h:53
double qreal
Definition qtypes.h:187
ptrdiff_t qintptr
Definition qtypes.h:166
long HRESULT
HINSTANCE HMODULE
#define disabled
QDebug operator<<(QDebug d, const NONCLIENTMETRICS &m)
static QPixmap pixmapFromShellImageList(int iImageList, int iIcon)
static QStringList styleNames()
static bool doUseNativeMenus()
static QPalette toolTipPalette(const QPalette &systemPalette, bool light)
AccentColorLevel
@ AccentColorNormal
@ AccentColorDarkest
@ AccentColorLightest
static QStringList iconThemeSearchPaths()
static QColor qt_accentColor(AccentColorLevel level)
static QColor getSysColor(int index)
static int fileIconSizes[FileIconSizeCount]
static QString dirIconPixmapCacheKey(int iIcon, int iconSize, int imageListSize)
static int uiEffects()
static QColor mixColors(const QColor &c1, const QColor &c2)
FileIconSize
@ JumboFileIcon
@ ExtraLargeFileIcon
@ SmallFileIcon
@ LargeFileIcon
@ FileIconSizeCount
static QColor placeHolderColor(QColor textColor)
static DWORD dWordSystemParametersInfo(UINT what, DWORD defaultValue)
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
static QPalette menuPalette(const QPalette &systemPalette, bool light)
@ sHIL_EXTRALARGE
@ sHIL_JUMBO
static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
static QPalette * menuBarPalette(const QPalette &menuPalette, bool light)
static bool booleanSystemParametersInfo(UINT what, bool defaultValue)
QSettings settings("MySoft", "Star Runner")
[0]
timer inherits("QTimer")
MyCustomStruct c2
widget render & pixmap
QPainter painter(this)
[7]
aWidget window() -> setWindowTitle("New Window Title")
[2]
QHostInfo info
[0]
Task(const QString &fn, DWORD a, UINT f)