From 872a84c2e66d151074caa602b0cab25358043621 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 5 Mar 2013 16:31:35 +0100 Subject: Aero-Style-QWizard: Do not use parent window handle. If no window exists at the time QWizard::setWizardStyle() is set, further delay initialization of the Aero style until show(). If the wizard is a child window, just adapt the geometry. Task-number: QTBUG-29904 Change-Id: I3805331ae726a0aa2020815d5bff571ca407efbc Reviewed-by: Joerg Bornemann Reviewed-by: Oliver Wolff --- src/widgets/dialogs/qwizard.cpp | 35 +++++++++++++++++++++++++---------- src/widgets/dialogs/qwizard_win.cpp | 33 ++++++++++++++++++++++----------- src/widgets/dialogs/qwizard_win_p.h | 1 + 3 files changed, 48 insertions(+), 21 deletions(-) (limited to 'src/widgets/dialogs') diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index f7669ba1cc..641c81b4cf 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -54,6 +54,7 @@ #include "qlabel.h" #include "qlineedit.h" #include "qpainter.h" +#include "qwindow.h" #include "qpushbutton.h" #include "qset.h" #include "qstyle.h" @@ -592,7 +593,7 @@ public: #if !defined(QT_NO_STYLE_WINDOWSVISTA) bool vistaDisabled() const; bool isVistaThemeEnabled(QVistaHelper::VistaState state) const; - void handleAeroStyleChange(); + bool handleAeroStyleChange(); #endif bool isVistaThemeEnabled() const; void disableUpdates(); @@ -1514,12 +1515,19 @@ bool QWizardPrivate::isVistaThemeEnabled(QVistaHelper::VistaState state) const && !vistaDisabled(); } -void QWizardPrivate::handleAeroStyleChange() +bool QWizardPrivate::handleAeroStyleChange() { Q_Q(QWizard); if (inHandleAeroStyleChange) - return; // prevent recursion + return false; // prevent recursion + // For top-level wizards, we need the platform window handle for the + // DWM changes. Delay aero initialization to the show event handling if + // it does not exist. If we are a child, skip DWM and just make room by + // moving the antiFlickerWidget. + const bool isWindow = q->isWindow(); + if (isWindow && (!q->windowHandle() || !q->windowHandle()->handle())) + return false; inHandleAeroStyleChange = true; vistaHelper->disconnectBackButton(); @@ -1529,8 +1537,10 @@ void QWizardPrivate::handleAeroStyleChange() if (isVistaThemeEnabled()) { if (isVistaThemeEnabled(QVistaHelper::VistaAero)) { - vistaHelper->setDWMTitleBar(QVistaHelper::ExtendedTitleBar); - q->installEventFilter(vistaHelper); + if (isWindow) { + vistaHelper->setDWMTitleBar(QVistaHelper::ExtendedTitleBar); + q->installEventFilter(vistaHelper); + } q->setMouseTracking(true); antiFlickerWidget->move(0, vistaHelper->titleBarSize() + vistaHelper->topOffset()); vistaHelper->backButton()->move( @@ -1538,12 +1548,14 @@ void QWizardPrivate::handleAeroStyleChange() - qMin(vistaHelper->topOffset(), vistaHelper->topPadding() + 1)); vistaMargins = true; } else { - vistaHelper->setDWMTitleBar(QVistaHelper::NormalTitleBar); + if (isWindow) + vistaHelper->setDWMTitleBar(QVistaHelper::NormalTitleBar); q->setMouseTracking(true); antiFlickerWidget->move(0, vistaHelper->topOffset()); vistaHelper->backButton()->move(0, -1); // ### should ideally work with (0, 0) } - vistaHelper->setTitleBarIconAndCaptionVisible(false); + if (isWindow) + vistaHelper->setTitleBarIconAndCaptionVisible(false); QObject::connect( vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots[QWizard::BackButton]); vistaHelper->backButton()->show(); @@ -1554,7 +1566,8 @@ void QWizardPrivate::handleAeroStyleChange() #endif antiFlickerWidget->move(0, 0); vistaHelper->hideBackButton(); - vistaHelper->setTitleBarIconAndCaptionVisible(true); + if (isWindow) + vistaHelper->setTitleBarIconAndCaptionVisible(true); } _q_updateButtonStates(); @@ -1562,6 +1575,7 @@ void QWizardPrivate::handleAeroStyleChange() vistaHelper->updateCustomMargins(vistaMargins); inHandleAeroStyleChange = false; + return true; } #endif @@ -2509,8 +2523,9 @@ void QWizard::setWizardStyle(WizardStyle style) updateGeometry(); d->enableUpdates(); #if !defined(QT_NO_STYLE_WINDOWSVISTA) - if (aeroStyleChange) - d->handleAeroStyleChange(); + // Delay initialization when activating Aero style fails due to missing native window. + if (aeroStyleChange && !d->handleAeroStyleChange() && d->wizStyle == AeroStyle) + d->vistaInitPending = true; #endif } } diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 42bdb8369f..2586ced60f 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -50,6 +50,7 @@ #include "qpaintengine.h" #include "qapplication.h" #include +#include #include #include #include @@ -345,9 +346,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; } @@ -405,8 +406,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)); } } @@ -585,8 +586,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; @@ -600,8 +600,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; @@ -616,8 +615,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; @@ -644,6 +642,19 @@ HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) return CreateFontIndirect(&lf); } +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(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; diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h index a568ef1eff..80d437bc23 100644 --- a/src/widgets/dialogs/qwizard_win_p.h +++ b/src/widgets/dialogs/qwizard_win_p.h @@ -109,6 +109,7 @@ public: private: static HFONT getCaptionFont(HANDLE hTheme); + HWND wizardHWND() const; bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc); static bool drawBlackRect(const QRect &rect, HDC hdc); -- cgit v1.2.3