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 <joerg.bornemann@digia.com>
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
Friedemann Kleint 2013-03-05 16:31:35 +01:00 committed by The Qt Project
parent 3c329b09fa
commit 872a84c2e6
3 changed files with 48 additions and 21 deletions

View File

@ -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
}
}

View File

@ -50,6 +50,7 @@
#include "qpaintengine.h"
#include "qapplication.h"
#include <QtCore/QVariant>
#include <QtCore/QDebug>
#include <QtGui/QMouseEvent>
#include <QtGui/QWindow>
#include <QtWidgets/QDesktopWidget>
@ -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<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;

View File

@ -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);