4#include <QtWidgets/private/qtwidgetsglobal_p.h>
6#if QT_CONFIG(style_windowsvista)
9#include <private/qapplication_p.h>
10#include <private/qwindowsfontdatabasebase_p.h>
11#include <qpa/qplatformwindow.h>
12#include <qpa/qplatformwindow_p.h>
16#include <QtCore/QOperatingSystemVersion>
17#include <QtCore/QVariant>
18#include <QtCore/QDebug>
19#include <QtGui/QMouseEvent>
20#include <QtGui/QWindow>
21#include <QtGui/private/qhighdpiscaling_p.h>
30#ifndef WM_DWMCOMPOSITIONCHANGED
31# define WM_DWMCOMPOSITIONCHANGED 0x031E
36qreal QVistaHelper::m_devicePixelRatio = 1.0;
47#if QT_CONFIG(shortcut)
52QSize QVistaBackButton::sizeHint()
const
78 const HANDLE theme = OpenThemeData(0, L
"Navigation");
81 const HDC hdc = QVistaHelper::backingStoreDC(parentWidget(), &origin);
85 const qreal dpr = devicePixelRatio();
90 clipRect.top = rDp.
top() + yoffsetDp;
91 clipRect.bottom = rDp.
bottom() + yoffsetDp;
92 clipRect.left = rDp.
left() + xoffsetDp;
93 clipRect.right = rDp.
right() + xoffsetDp;
95 int state = NAV_BB_NORMAL;
97 state = NAV_BB_DISABLED;
99 state = NAV_BB_PRESSED;
100 else if (underMouse())
103 DrawThemeBackground(theme, hdc,
104 layoutDirection() ==
Qt::LeftToRight ? NAV_BACKBUTTON : NAV_FORWARDBUTTON,
105 state, &clipRect, &clipRect);
112QVistaHelper::QVistaHelper(
QWizard *wizard)
120 backButton_ =
new QVistaBackButton(wizard);
126QVistaHelper::~QVistaHelper() =
default;
128void QVistaHelper::updateCustomMargins(
bool vistaMargins)
135 const QMargins customMarginsDp = vistaMargins
136 ?
QMargins(0, -titleBarSizeDp(), 0, 0)
140 window->setProperty(
"_q_windowsCustomMargins", customMarginsV);
143 platformWindow->setCustomMargins(customMarginsDp);
147void QVistaHelper::disconnectBackButton()
150 backButton_->disconnect(
SIGNAL(clicked()));
153QColor QVistaHelper::basicWindowFrameColor()
156 const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L
"WINDOW");
157 GetThemeColor(hTheme, WP_CAPTION, CS_ACTIVE,
159 BYTE
r = GetRValue(
rgb);
160 BYTE
g = GetGValue(
rgb);
161 BYTE
b = GetBValue(
rgb);
165bool QVistaHelper::setDWMTitleBar(TitleBarChangeType
type)
167 MARGINS mar = {0, 0, 0, 0};
168 if (
type == NormalTitleBar)
171 mar.cyTopHeight = (titleBarSize() + topOffset(wizard)) * QVistaHelper::m_devicePixelRatio;
172 if (
const HWND wizardHandle = wizardHWND()) {
173 if (SUCCEEDED(DwmExtendFrameIntoClientArea(wizardHandle, &mar)))
181static LOGFONT getCaptionLogFont(HANDLE hTheme)
183 LOGFONT
result = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } };
185 if (!hTheme || FAILED(GetThemeSysFont(hTheme, TMT_CAPTIONFONT, &
result))) {
186 NONCLIENTMETRICS ncm;
187 ncm.cbSize =
sizeof(NONCLIENTMETRICS);
188 SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS), &ncm,
false);
189 result = ncm.lfMessageFont;
196 const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L
"WINDOW");
200 const LOGFONT logFont = getCaptionLogFont(hTheme);
210 const HDC hdc = QVistaHelper::backingStoreDC(wizard, &origin);
214 titleBarSize() + topOffset(wizard)), hdc);
217 const int btnTop = backButton_->mapToParent(
QPoint()).y();
218 const int btnHeight = backButton_->size().height();
219 const int verticalCenter = (btnTop + btnHeight / 2) - 1;
227 const int glowOffset = glowSize(wizard);
228 int textHeight = brect.
height() + 2 * glowOffset;
229 int textWidth = brect.
width() + 2 * glowOffset;
232 ? titleOffset() - glowOffset
233 : wizard->
width() - titleOffset() - textWidth + glowOffset);
235 const QRect textRectangle(titleLeft, verticalCenter - textHeight / 2, textWidth, textHeight);
246 if (!windowIcon.
isNull()) {
247 const int size = QVistaHelper::iconSize(wizard);
250 : wizard->
width() - leftMargin(wizard) -
size);
252 const QPoint pos(origin.
x() + iconLeft, origin.
y() + verticalCenter -
size / 2);
253 const QPoint posDp =
pos * QVistaHelper::m_devicePixelRatio;
255 DrawIconEx(hdc, posDp.
x(), posDp.
y(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
260void QVistaHelper::setTitleBarIconAndCaptionVisible(
bool visible)
263 opt.dwFlags = WTNCA_NODRAWICON | WTNCA_NODRAWCAPTION;
267 opt.dwMask = WTNCA_NODRAWICON | WTNCA_NODRAWCAPTION;
268 if (
const HWND
handle = wizardHWND())
269 SetWindowThemeAttribute(
handle, WTA_NONCLIENT, &
opt,
sizeof(WTA_OPTIONS));
274 switch (msg->message) {
278 if (DwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult)) {
283 lResult = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
287 if (lResult == HTCLOSE || lResult == HTMAXBUTTON || lResult == HTMINBUTTON || lResult == HTHELP)
297 if (DwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult))
307void QVistaHelper::setMouseCursor(
QPoint pos)
310 if (rtTop.contains(
pos))
319 switch (
event->type()) {
339 if (
message->message == WM_NCPAINT)
349 int height = captionSize() + topOffset(wizard);
372 const int dy =
event->pos().
y() - pressedPos.y();
379 QPoint newPos =
event->pos() - pressedPos;
389 setMouseCursor(
event->pos());
403 if (rtTitle.contains(
event->pos())) {
404 change = movePosition;
405 }
else if (rtTop.contains(
event->pos()))
408 if (change != noChange) {
409 setMouseCursor(
event->pos());
411 pressedPos =
event->pos();
423 setMouseCursor(
event->pos());
431 return MAKELPARAM(point.x(), point.y());
443 msg.message = WM_NCHITTEST;
446 msg.hwnd = wizardHWND();
449 msg.message = WM_NCMOUSEMOVE;
457 msg.message = WM_NCHITTEST;
460 msg.hwnd = wizardHWND();
463 msg.message = WM_NCLBUTTONDOWN;
472 msg.message = WM_NCHITTEST;
475 msg.hwnd = wizardHWND();
478 msg.message = WM_NCLBUTTONUP;
498HWND QVistaHelper::wizardHWND()
const
506 return static_cast<HWND
>(vHwnd);
507 qWarning().nospace() <<
"Failed to obtain HWND for wizard.";
515 const QRect rectDp =
QRect(
rect.topLeft() * QVistaHelper::m_devicePixelRatio,
516 rect.size() * QVistaHelper::m_devicePixelRatio);
517 const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L
"WINDOW");
524 ZeroMemory(&dib,
sizeof(dib));
525 dcMem = CreateCompatibleDC(hdc);
527 dib.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
528 dib.bmiHeader.biWidth = rectDp.
width();
529 dib.bmiHeader.biHeight = -rectDp.
height();
530 dib.bmiHeader.biPlanes = 1;
531 dib.bmiHeader.biBitCount = 32;
532 dib.bmiHeader.biCompression = BI_RGB;
534 bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
537 const LOGFONT captionLogFont = getCaptionLogFont(hTheme);
538 const HFONT hCaptionFont = CreateFontIndirect(&captionLogFont);
539 auto hOldBmp =
reinterpret_cast<HBITMAP
>(SelectObject(dcMem, (HGDIOBJ) bmp));
540 auto hOldFont =
reinterpret_cast<HFONT
>(SelectObject(dcMem, (HGDIOBJ) hCaptionFont));
544 memset(&dto, 0,
sizeof(dto));
545 dto.dwSize =
sizeof(dto);
546 const UINT uFormat = DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_NOPREFIX;
547 RECT rctext ={0,0, rectDp.
width(), rectDp.
height()};
549 dto.dwFlags = DTT_COMPOSITED|DTT_GLOWSIZE;
550 dto.iGlowSize = glowSize(wizard);
552 DrawThemeTextEx(hTheme, dcMem, 0, 0,
reinterpret_cast<LPCWSTR
>(
text.
utf16()), -1, uFormat, &rctext, &dto );
553 BitBlt(hdc, rectDp.
left(), rectDp.
top(), rectDp.
width(), rectDp.
height(), dcMem, 0, 0, SRCCOPY);
554 SelectObject(dcMem, (HGDIOBJ) hOldBmp);
555 SelectObject(dcMem, (HGDIOBJ) hOldFont);
557 DeleteObject(hCaptionFont);
562void QVistaHelper::drawBlackRect(
const QRect &
rect, HDC hdc)
565 const QRect rectDp =
QRect(
rect.topLeft() * QVistaHelper::m_devicePixelRatio,
566 rect.size() * QVistaHelper::m_devicePixelRatio);
570 ZeroMemory(&dib,
sizeof(dib));
571 dcMem = CreateCompatibleDC(hdc);
573 dib.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
574 dib.bmiHeader.biWidth = rectDp.
width();
575 dib.bmiHeader.biHeight = -rectDp.
height();
576 dib.bmiHeader.biPlanes = 1;
577 dib.bmiHeader.biBitCount = 32;
578 dib.bmiHeader.biCompression = BI_RGB;
580 bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
581 auto hOldBmp =
reinterpret_cast<HBITMAP
>(SelectObject(dcMem, (HGDIOBJ) bmp));
583 BitBlt(hdc, rectDp.
left(), rectDp.
top(), rectDp.
width(), rectDp.
height(), dcMem, 0, 0, SRCCOPY);
584 SelectObject(dcMem, (HGDIOBJ) hOldBmp);
590int QVistaHelper::frameSizeDp()
592 return GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
595int QVistaHelper::captionSizeDp()
597 return GetSystemMetrics(SM_CYCAPTION);
600int QVistaHelper::titleOffset()
603 return leftMargin(wizard) + iconOffset;
619 return aeroOffset + titleBarSize();
IOBluetoothDevice * device
static QFont font()
Returns the default application font.
The QColor class provides colors based on RGB, HSV or CMYK values.
\reentrant \inmodule QtGui
static QPlatformNativeInterface * platformNativeInterface()
The QIcon class provides scalable icons in different modes and states.
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
virtual bool eventFilter(QObject *watched, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object.
qreal devicePixelRatio() const
The QPaintEvent class contains event parameters for paint events.
The QPainter class performs low-level painting on widgets and other paint devices.
void restore()
Restores the current painter state (pops a saved state off the stack).
void save()
Saves the current painter state (pushes the state onto a stack).
void setFont(const QFont &f)
Sets the painter's font to the given font.
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
The QResizeEvent class contains event parameters for resize events.
QPointF globalPosition() const
Returns the position of the point in this event on the screen or virtual desktop.
Qt::MouseButton button() const
Returns the button that caused the event.
\macro QT_RESTRICTED_CAST_FROM_ASCII
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
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 >
static QFont LOGFONT_to_QFont(const LOGFONT &lf, int verticalDPI=0)
The QWizard class provides a framework for wizards.
WizardStyle wizardStyle
the look and feel of the wizard
T toNativePixels(const T &value, const C *context)
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi)
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
GLboolean GLboolean GLboolean b
GLuint64 GLenum void * handle
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLint GLint yoffset
GLuint GLsizei const GLchar * message
GLenum GLuint GLintptr offset
HICON qt_pixmapToWinHICON(const QPixmap &p)
static constexpr QSize frameSize(const T &frame)
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
static bool isWindow(QObject *object)