5#ifndef WINDOWKIT_WIN_P_H
6#define WINDOWKIT_WIN_P_H
18#if defined(Q_CC_MINGW) && (QT_VERSION >= QT_VERSION_CHECK(6, 5, 3))
19#define Q_CC_MINGW_SUPPORT_DPI_API
22#include <QtCore/private/qsystemlibrary_p.h>
23#include <QtGui/QGuiApplication>
24#include <QtGui/QPalette>
25#include <QtGui/QStyleHints>
29#if defined(Q_CC_MSVC) || defined(Q_CC_MINGW_SUPPORT_DPI_API)
30#include <shellscalingapi.h>
38enum _DWMWINDOWATTRIBUTE {
40 _DWMWA_USE_HOSTBACKDROPBRUSH = 17,
44 _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,
48 _DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
51 _DWMWA_WINDOW_CORNER_PREFERENCE = 33,
54 _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37,
58 _DWMWA_SYSTEMBACKDROP_TYPE = 38,
62 _DWMWA_MICA_EFFECT = 1029
66enum _DWM_SYSTEMBACKDROP_TYPE {
72 _DWMSBT_TRANSIENTWINDOW,
78enum WINDOWCOMPOSITIONATTRIB {
80 WCA_NCRENDERING_ENABLED = 1,
81 WCA_NCRENDERING_POLICY = 2,
82 WCA_TRANSITIONS_FORCEDISABLED = 3,
83 WCA_ALLOW_NCPAINT = 4,
84 WCA_CAPTION_BUTTON_BOUNDS = 5,
85 WCA_NONCLIENT_RTL_LAYOUT = 6,
86 WCA_FORCE_ICONIC_REPRESENTATION = 7,
87 WCA_EXTENDED_FRAME_BOUNDS = 8,
88 WCA_HAS_ICONIC_BITMAP = 9,
89 WCA_THEME_ATTRIBUTES = 10,
90 WCA_NCRENDERING_EXILED = 11,
91 WCA_NCADORNMENTINFO = 12,
92 WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
93 WCA_VIDEO_OVERLAY_ACTIVE = 14,
94 WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
95 WCA_DISALLOW_PEEK = 16,
98 WCA_ACCENT_POLICY = 19,
99 WCA_FREEZE_REPRESENTATION = 20,
100 WCA_EVER_UNCLOAKED = 21,
101 WCA_VISUAL_OWNER = 22,
102 WCA_HOLOGRAPHIC = 23,
103 WCA_EXCLUDED_FROM_DDA = 24,
104 WCA_PASSIVEUPDATEMODE = 25,
105 WCA_USEDARKMODECOLORS = 26,
106 WCA_CORNER_STYLE = 27,
108 WCA_DISABLE_MOVESIZE_FEEDBACK = 29,
114 ACCENT_ENABLE_GRADIENT = 1,
115 ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
116 ACCENT_ENABLE_BLURBEHIND = 3,
117 ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
118 ACCENT_ENABLE_HOST_BACKDROP = 5,
119 ACCENT_INVALID_STATE = 6
124 ACCENT_ENABLE_ACRYLIC = 1,
125 ACCENT_ENABLE_ACRYLIC_WITH_LUMINOSITY = 482
128struct ACCENT_POLICY {
131 DWORD dwGradientColor;
134using PACCENT_POLICY = ACCENT_POLICY *;
136struct WINDOWCOMPOSITIONATTRIBDATA {
137 WINDOWCOMPOSITIONATTRIB Attrib;
141using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
143enum PREFERRED_APP_MODE {
152using SetWindowCompositionAttributePtr = BOOL(WINAPI *)(HWND, PWINDOWCOMPOSITIONATTRIBDATA);
155using RefreshImmersiveColorPolicyStatePtr = VOID(WINAPI *)(VOID);
156using AllowDarkModeForWindowPtr = BOOL(WINAPI *)(HWND, BOOL);
157using AllowDarkModeForAppPtr = BOOL(WINAPI *)(BOOL);
158using FlushMenuThemesPtr = VOID(WINAPI *)(VOID);
160using SetPreferredAppModePtr = PREFERRED_APP_MODE(WINAPI *)(PREFERRED_APP_MODE);
166 static const DynamicApis &instance()
168 static const DynamicApis inst{};
172#define DYNAMIC_API_DECLARE(NAME) decltype(&::NAME) p##NAME = nullptr
181#if defined(Q_CC_MSVC) || defined(Q_CC_MINGW_SUPPORT_DPI_API)
191#undef DYNAMIC_API_DECLARE
193 SetWindowCompositionAttributePtr pSetWindowCompositionAttribute =
nullptr;
194 RefreshImmersiveColorPolicyStatePtr pRefreshImmersiveColorPolicyState =
nullptr;
195 AllowDarkModeForWindowPtr pAllowDarkModeForWindow =
nullptr;
196 AllowDarkModeForAppPtr pAllowDarkModeForApp =
nullptr;
197 FlushMenuThemesPtr pFlushMenuThemes =
nullptr;
198 SetPreferredAppModePtr pSetPreferredAppMode =
nullptr;
202#define DYNAMIC_API_RESOLVE(DLL, NAME) p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(#NAME))
204 QSystemLibrary user32(QStringLiteral(
"user32"));
205#if defined(Q_CC_MSVC) || defined(Q_CC_MINGW_SUPPORT_DPI_API)
212#if defined(Q_CC_MSVC) || defined(Q_CC_MINGW_SUPPORT_DPI_API)
213 QSystemLibrary shcore(QStringLiteral(
"shcore"));
217 QSystemLibrary dwmapi(QStringLiteral(
"dwmapi"));
226 QSystemLibrary winmm(QStringLiteral(
"winmm"));
231#undef DYNAMIC_API_RESOLVE
233#define UNDOC_API_RESOLVE(DLL, NAME, ORDINAL) \
234 p##NAME = reinterpret_cast<decltype(p##NAME)>(DLL.resolve(MAKEINTRESOURCEA(ORDINAL)))
236 QSystemLibrary uxtheme(QStringLiteral(
"uxtheme"));
243#undef UNDOC_API_RESOLVE
246 ~DynamicApis() =
default;
248 Q_DISABLE_COPY(DynamicApis)
253static inline constexpr bool operator==(
const POINT &lhs,
const POINT &rhs)
noexcept
255 return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
258static inline constexpr bool operator!=(
const POINT &lhs,
const POINT &rhs)
noexcept
260 return !operator==(lhs, rhs);
263static inline constexpr bool operator==(
const SIZE &lhs,
const SIZE &rhs)
noexcept
265 return ((lhs.cx == rhs.cx) && (lhs.cy == rhs.cy));
268static inline constexpr bool operator!=(
const SIZE &lhs,
const SIZE &rhs)
noexcept
270 return !operator==(lhs, rhs);
273static inline constexpr bool operator>(
const SIZE &lhs,
const SIZE &rhs)
noexcept
275 return ((lhs.cx * lhs.cy) > (rhs.cx * rhs.cy));
278static inline constexpr bool operator>=(
const SIZE &lhs,
const SIZE &rhs)
noexcept
280 return (
operator>(lhs, rhs) ||
operator==(lhs, rhs));
283static inline constexpr bool operator<(
const SIZE &lhs,
const SIZE &rhs)
noexcept
285 return (
operator!=(lhs, rhs) && !
operator>(lhs, rhs));
288static inline constexpr bool operator<=(
const SIZE &lhs,
const SIZE &rhs)
noexcept
290 return (
operator<(lhs, rhs) ||
operator==(lhs, rhs));
293static inline constexpr bool operator==(
const RECT &lhs,
const RECT &rhs)
noexcept
295 return ((lhs.left == rhs.left) && (lhs.top == rhs.top) && (lhs.right == rhs.right) && (lhs.bottom == rhs.bottom));
298static inline constexpr bool operator!=(
const RECT &lhs,
const RECT &rhs)
noexcept
300 return !operator==(lhs, rhs);
303static inline constexpr QPoint point2qpoint(
const POINT &point)
305 return QPoint{int(point.x), int(point.y)};
308static inline constexpr POINT qpoint2point(
const QPoint &point)
310 return POINT{LONG(point.x()), LONG(point.y())};
313static inline constexpr QSize size2qsize(
const SIZE &size)
315 return QSize{int(size.cx), int(size.cy)};
318static inline constexpr SIZE qsize2size(
const QSize &size)
320 return SIZE{LONG(size.width()), LONG(size.height())};
323static inline constexpr QRect rect2qrect(
const RECT &rect)
325 return QRect{QPoint{int(rect.left), int(rect.top)}, QSize{int(
RECT_WIDTH(rect)), int(
RECT_HEIGHT(rect))}};
328static inline constexpr RECT qrect2rect(
const QRect &qrect)
330 return RECT{LONG(qrect.left()), LONG(qrect.top()), LONG(qrect.right()), LONG(qrect.bottom())};
333static inline constexpr QMargins margins2qmargins(
const MARGINS &margins)
335 return {margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight};
338static inline constexpr MARGINS qmargins2margins(
const QMargins &qmargins)
340 return {qmargins.left(), qmargins.right(), qmargins.top(), qmargins.bottom()};
343static inline QString hwnd2str(
const WId windowId)
346 return QLatin1String(
"0x") + QString::number(windowId, 16).toUpper().rightJustified(8, u
'0');
349static inline QString hwnd2str(HWND hwnd)
352 return hwnd2str(
reinterpret_cast<WId
>(hwnd));
355static inline bool isDwmCompositionEnabled()
357 if (isWin8OrGreater()) {
360 const DynamicApis &apis = DynamicApis::instance();
361 if (!apis.pDwmIsCompositionEnabled) {
365 return SUCCEEDED(apis.pDwmIsCompositionEnabled(&
enabled)) &&
enabled;
368static inline bool isWindowFrameBorderColorized()
371 if (!registry.isValid()) {
374 QString value = registry.stringValue(L
"ColorPrevalence");
381static inline bool isHighContrastModeEnabled()
384 hc.cbSize =
sizeof(hc);
385 ::SystemParametersInfoW(SPI_GETHIGHCONTRAST,
sizeof(hc), &hc, FALSE);
386 return (hc.dwFlags & HCF_HIGHCONTRASTON);
389static inline bool isDarkThemeActive()
391#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
392 return QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark;
394 WindowsRegistryKey registry(HKEY_CURRENT_USER, LR
"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)");
395 if (!registry.isValid()) {
398 auto value = registry.dwordValue(L
"AppsUseLightTheme");
406static inline bool isDarkWindowFrameEnabled(HWND hwnd)
409 const DynamicApis &apis = DynamicApis::instance();
410 if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE, &
enabled,
sizeof(
enabled)))) {
412 }
else if (SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, &
enabled,
419static inline QColor getAccentColor()
421#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
422 return QGuiApplication::palette().color(QPalette::Accent);
425 if (!registry.isValid()) {
428 auto value = registry.dwordValue(L
"AccentColor");
434 QColor color = QColor::fromRgba(value.first);
435 if (!color.isValid()) {
438 return QColor::fromRgb(color.blue(), color.green(), color.red(), color.alpha());
442static inline quint32 getDpiForWindow(HWND hwnd)
444#if defined(Q_CC_MSVC) || defined(Q_CC_MINGW_SUPPORT_DPI_API)
445 const DynamicApis &apis = DynamicApis::instance();
446 if (apis.pGetDpiForWindow) {
447 return apis.pGetDpiForWindow(hwnd);
448 }
else if (apis.pGetDpiForMonitor) {
449 HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
452 apis.pGetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
459 HDC hdc = ::GetDC(
nullptr);
460 const int dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX);
462 ::ReleaseDC(
nullptr, hdc);
463 return quint32(dpiX);
467static inline quint32 getSystemMetricsForDpi(
int index, quint32 dpi)
469#if defined(Q_CC_MSVC) || defined(Q_CC_MINGW_SUPPORT_DPI_API)
470 const DynamicApis &apis = DynamicApis::instance();
471 if (apis.pGetSystemMetricsForDpi) {
472 return ::GetSystemMetricsForDpi(index, dpi);
477 return ::GetSystemMetrics(index);
480static inline quint32 getWindowFrameBorderThickness(HWND hwnd)
482 const DynamicApis &apis = DynamicApis::instance();
484 SUCCEEDED(apis.pDwmGetWindowAttribute(hwnd, _DWMWA_VISIBLE_FRAME_BORDER_THICKNESS, &result,
sizeof(result)))) {
487 return getSystemMetricsForDpi(SM_CXBORDER, getDpiForWindow(hwnd));
490static inline quint32 getResizeBorderThickness(HWND hwnd)
492 const quint32 dpi = getDpiForWindow(hwnd);
493 return getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + getSystemMetricsForDpi(
SM_CXPADDEDBORDER, dpi);
496static inline quint32 getTitleBarHeight(HWND hwnd)
498 const quint32 dpi = getDpiForWindow(hwnd);
499 return getSystemMetricsForDpi(SM_CYCAPTION, dpi) + getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) +
QWinRegistryKey WindowsRegistryKey
#define QX_WINDOW_END_NAMESPACE
#define QX_WINDOW_BEGIN_NAMESPACE
#define SM_CXPADDEDBORDER
#define RECT_HEIGHT(rect)
#define UNDOC_API_RESOLVE(DLL, NAME, ORDINAL)
#define DYNAMIC_API_RESOLVE(DLL, NAME)
#define DYNAMIC_API_DECLARE(NAME)