summaryrefslogtreecommitdiffstats
path: root/src/widgets/dialogs/qwizard_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/dialogs/qwizard_win.cpp')
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp181
1 files changed, 106 insertions, 75 deletions
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
index 2bcb7a2167..001c21da61 100644
--- a/src/widgets/dialogs/qwizard_win.cpp
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -49,7 +49,10 @@
#include "qwizard.h"
#include "qpaintengine.h"
#include "qapplication.h"
+#include <QtCore/QVariant>
+#include <QtCore/QDebug>
#include <QtGui/QMouseEvent>
+#include <QtGui/QWindow>
#include <QtWidgets/QDesktopWidget>
// Note, these tests are duplicates in qwindowsxpstyle_p.h.
@@ -66,10 +69,12 @@
#include <uxtheme.h>
+Q_DECLARE_METATYPE(QMargins)
+
QT_BEGIN_NAMESPACE
//DWM related
-typedef struct { //MARGINS
+typedef struct { //MARGINS
int cxLeftWidth; // width of left border that retains its size
int cxRightWidth; // width of right border that retains its size
int cyTopHeight; // height of top border that retains its size
@@ -216,9 +221,11 @@ void QVistaBackButton::paintEvent(QPaintEvent *)
QRect r = rect();
HANDLE theme = pOpenThemeData(0, L"Navigation");
//RECT rect;
+ QPoint origin;
+ const HDC hdc = QVistaHelper::backingStoreDC(parentWidget(), &origin);
RECT clipRect;
- int xoffset = QWidget::mapToParent(r.topLeft()).x() - 1;
- int yoffset = QWidget::mapToParent(r.topLeft()).y() - 1;
+ int xoffset = origin.x() + QWidget::mapToParent(r.topLeft()).x() - 1;
+ int yoffset = origin.y() + QWidget::mapToParent(r.topLeft()).y() - 1;
clipRect.top = r.top() + yoffset;
clipRect.bottom = r.bottom() + yoffset;
@@ -233,8 +240,6 @@ void QVistaBackButton::paintEvent(QPaintEvent *)
else if (underMouse())
state = WIZ_NAV_BB_HOT;
- QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
- HDC hdc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore()));
pDrawThemeBackground(theme, hdc, WIZ_NAV_BACKBUTTON, state, &clipRect, &clipRect);
}
@@ -251,8 +256,10 @@ QVistaHelper::QVistaHelper(QWizard *wizard)
is_vista = resolveSymbols();
if (instanceCount++ == 0)
cachedVistaState = Dirty;
- if (is_vista)
+ if (is_vista) {
backButton_ = new QVistaBackButton(wizard);
+ backButton_->hide();
+ }
// Handle diff between Windows 7 and Vista
iconSpacing = QStyleHelper::dpiScaled(7);
@@ -265,6 +272,26 @@ QVistaHelper::~QVistaHelper()
--instanceCount;
}
+void QVistaHelper::updateCustomMargins(bool vistaMargins)
+{
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8)
+ return; // Negative margins are not supported on Windows 8.
+ if (QWindow *window = wizard->windowHandle()) {
+ // Reduce top frame to zero since we paint it ourselves.
+ const QMargins customMargins = vistaMargins ?
+ QMargins(0, -titleBarSize(), 0, 0) : QMargins();
+ const QVariant customMarginsV = qVariantFromValue(customMargins);
+ // The dynamic property takes effect when creating the platform window.
+ window->setProperty("_q_windowsCustomMargins", customMarginsV);
+ // If a platform window exists, change via native interface.
+ if (QPlatformWindow *platformWindow = window->handle()) {
+ QGuiApplication::platformNativeInterface()->
+ setWindowProperty(platformWindow, QStringLiteral("WindowsCustomMargins"),
+ customMarginsV);
+ }
+ }
+}
+
bool QVistaHelper::isCompositionEnabled()
{
bool value = is_vista;
@@ -291,6 +318,12 @@ QVistaHelper::VistaState QVistaHelper::vistaState()
return cachedVistaState;
}
+void QVistaHelper::disconnectBackButton()
+{
+ if (backButton_) // Leave QStyleSheetStyle's connections on destroyed() intact.
+ backButton_->disconnect(SIGNAL(clicked()));
+}
+
QColor QVistaHelper::basicWindowFrameColor()
{
DWORD rgb;
@@ -315,9 +348,9 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type)
mar.cyTopHeight = 0;
else
mar.cyTopHeight = titleBarSize() + topOffset();
- HWND wizardHandle = QApplicationPrivate::getHWNDForWidget(wizard);
- HRESULT hr = pDwmExtendFrameIntoClientArea(wizardHandle, &mar);
- value = SUCCEEDED(hr);
+ if (const HWND wizardHandle = wizardHWND())
+ if (SUCCEEDED(pDwmExtendFrameIntoClientArea(wizardHandle, &mar)))
+ value = true;
}
return value;
}
@@ -327,11 +360,11 @@ Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &);
void QVistaHelper::drawTitleBar(QPainter *painter)
{
Q_ASSERT(backButton_);
- QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
- QBackingStore *backingStore = backButton_->backingStore();
- HDC hdc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore));
+ QPoint origin;
+ const bool isWindow = wizard->isWindow();
+ const HDC hdc = QVistaHelper::backingStoreDC(wizard, &origin);
- if (vistaState() == VistaAero)
+ if (vistaState() == VistaAero && isWindow)
drawBlackRect(QRect(0, 0, wizard->width(),
titleBarSize() + topOffset()), hdc);
const int btnTop = backButton_->mapToParent(QPoint()).y();
@@ -352,14 +385,20 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
glowOffset = glowSize();
}
- drawTitleText(
- painter, text,
- QRect(titleOffset() - glowOffset, verticalCenter - textHeight / 2, textWidth, textHeight),
- hdc);
+ const QRect textRectangle(titleOffset() - glowOffset, verticalCenter - textHeight / 2, textWidth, textHeight);
+ if (isWindow) {
+ drawTitleText(painter, text, textRectangle, hdc);
+ } else {
+ painter->save();
+ painter->setFont(font);
+ painter->drawText(textRectangle, Qt::AlignVCenter | Qt::AlignHCenter, text);
+ painter->restore();
+ }
const QIcon windowIcon = wizard->windowIcon();
if (!windowIcon.isNull()) {
- QRect rect(leftMargin(), verticalCenter - iconSize() / 2, iconSize(), iconSize());
+ const QRect rect(origin.x() + leftMargin(),
+ origin.y() + verticalCenter - iconSize() / 2, iconSize(), iconSize());
const HICON hIcon = qt_pixmapToWinHICON(windowIcon.pixmap(iconSize()));
DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
DestroyIcon(hIcon);
@@ -375,8 +414,8 @@ void QVistaHelper::setTitleBarIconAndCaptionVisible(bool visible)
opt.dwMask = 0;
else
opt.dwMask = WIZ_WTNCA_NODRAWICON | WIZ_WTNCA_NODRAWCAPTION;
- HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
- pSetWindowThemeAttribute(handle, WIZ_WTA_NONCLIENT, &opt, sizeof(WIZ_WTA_OPTIONS));
+ if (const HWND handle = wizardHWND())
+ pSetWindowThemeAttribute(handle, WIZ_WTA_NONCLIENT, &opt, sizeof(WIZ_WTA_OPTIONS));
}
}
@@ -402,13 +441,6 @@ bool QVistaHelper::winEvent(MSG* msg, long* result)
}
break;
}
-// case WM_NCCALCSIZE: { #fixme: If the frame size is changed, it needs to be communicated to the QWindow.
-// NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam;
-// *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
-// lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0);
-//
-// break;
-// }
default:
LRESULT lResult;
// Pass to DWM to handle
@@ -449,38 +481,6 @@ void QVistaHelper::mouseEvent(QEvent *event)
}
}
-// The following hack ensures that the titlebar is updated correctly
-// when the wizard style changes to and from AeroStyle. Specifically,
-// this function causes a Windows message of type WM_NCCALCSIZE to
-// be triggered.
-void QVistaHelper::setWindowPosHack()
-{
- const int x = wizard->geometry().x(); // ignored by SWP_NOMOVE
- const int y = wizard->geometry().y(); // ignored by SWP_NOMOVE
- const int w = wizard->width();
- const int h = wizard->height();
- HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
- SetWindowPos(handle, 0, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
-}
-
-// The following hack allows any QWidget subclass to access
-// QWidgetPrivate::topData() without being declared as a
-// friend by QWidget.
-class QHackWidget : public QWidget
-{
-public:
- Q_DECLARE_PRIVATE(QWidget)
- QTLWExtra* topData() { return d_func()->topData(); }
-};
-
-void QVistaHelper::collapseTopFrameStrut()
-{
- QTLWExtra *top = ((QHackWidget *)wizard)->d_func()->topData();
- int x1, y1, x2, y2;
- top->frameStrut.getCoords(&x1, &y1, &x2, &y2);
- top->frameStrut.setCoords(x1, 0, x2, y2);
-}
-
bool QVistaHelper::handleWinEvent(MSG *message, long *result)
{
if (message->message == WIZ_WM_THEMECHANGED || message->message == WIZ_WM_DWMCOMPOSITIONCHANGED)
@@ -489,12 +489,8 @@ bool QVistaHelper::handleWinEvent(MSG *message, long *result)
bool status = false;
if (wizard->wizardStyle() == QWizard::AeroStyle && vistaState() == VistaAero) {
status = winEvent(message, result);
- if (message->message == WM_NCCALCSIZE) {
-// if (status) #fixme
-// collapseTopFrameStrut();
- } else if (message->message == WM_NCPAINT) {
+ if (message->message == WM_NCPAINT)
wizard->update();
- }
}
return status;
}
@@ -598,8 +594,7 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
msg.message = WM_NCHITTEST;
msg.wParam = 0;
msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
- HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
- msg.hwnd = handle;
+ msg.hwnd = wizardHWND();
winEvent(&msg, &result);
msg.wParam = result;
msg.message = WM_NCMOUSEMOVE;
@@ -613,8 +608,7 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
msg.message = WM_NCHITTEST;
msg.wParam = 0;
msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
- HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
- msg.hwnd = handle;
+ msg.hwnd = wizardHWND();
winEvent(&msg, &result);
msg.wParam = result;
msg.message = WM_NCLBUTTONDOWN;
@@ -629,8 +623,7 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
msg.message = WM_NCHITTEST;
msg.wParam = 0;
msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
- HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
- msg.hwnd = handle;
+ msg.hwnd = wizardHWND();
winEvent(&msg, &result);
msg.wParam = result;
msg.message = WM_NCLBUTTONUP;
@@ -657,6 +650,31 @@ HFONT QVistaHelper::getCaptionFont(HANDLE hTheme)
return CreateFontIndirect(&lf);
}
+// Return a HDC for the wizard along with the transformation if the
+// wizard is a child window.
+HDC QVistaHelper::backingStoreDC(const QWidget *wizard, QPoint *offset)
+{
+ HDC hdc = static_cast<HDC>(QGuiApplication::platformNativeInterface()->nativeResourceForBackingStore(QByteArrayLiteral("getDC"), wizard->backingStore()));
+ *offset = QPoint(0, 0);
+ if (!wizard->windowHandle())
+ if (QWidget *nativeParent = wizard->nativeParentWidget())
+ *offset = wizard->mapTo(nativeParent, *offset);
+ return hdc;
+}
+
+HWND QVistaHelper::wizardHWND() const
+{
+ // Obtain the HWND if the wizard is a top-level window.
+ // Do not use winId() as this enforces native children of the parent
+ // widget when called before show() as happens when calling setWizardStyle().
+ if (QWindow *window = wizard->windowHandle())
+ if (window->handle())
+ if (void *vHwnd = QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("handle"), window))
+ return static_cast<HWND>(vHwnd);
+ qWarning().nospace() << "Failed to obtain HWND for wizard.";
+ return 0;
+}
+
bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc)
{
bool value = false;
@@ -677,14 +695,14 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q
dib.bmiHeader.biPlanes = 1;
dib.bmiHeader.biBitCount = 32;
dib.bmiHeader.biCompression = BI_RGB;
-
+
bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
// Set up the DC
HFONT hCaptionFont = getCaptionFont(hTheme);
HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont);
-
+
// Draw the text!
WIZ_DTTOPTS dto;
dto.dwSize = sizeof(WIZ_DTTOPTS);
@@ -693,7 +711,7 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q
dto.dwFlags = WIZ_DTT_COMPOSITED|WIZ_DTT_GLOWSIZE;
dto.iGlowSize = glowSize();
-
+
pDrawThemeTextEx(hTheme, dcMem, 0, 0, (LPCWSTR)text.utf16(), -1, uFormat, &rctext, &dto );
BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
SelectObject(dcMem, (HGDIOBJ) hOldBmp);
@@ -725,7 +743,7 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
dib.bmiHeader.biPlanes = 1;
dib.bmiHeader.biBitCount = 32;
dib.bmiHeader.biCompression = BI_RGB;
-
+
bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
@@ -789,6 +807,19 @@ int QVistaHelper::titleOffset()
return leftMargin() + iconOffset;
}
+int QVistaHelper::topOffset()
+{
+ if (vistaState() != VistaAero)
+ return titleBarSize() + 3;
+ static const int aeroOffset =
+ QSysInfo::WindowsVersion == QSysInfo::WV_WINDOWS7 ?
+ QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13);
+ int result = aeroOffset;
+ if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8)
+ result += titleBarSize();
+ return result;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_STYLE_WINDOWSVISTA