diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2012-04-04 14:56:45 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-04 18:10:11 +0200 |
commit | b1a02ce010e01d69639ae829754c71b39e3371bc (patch) | |
tree | d85ecf4f098e519d1dea38e8a667137c8a42409d /src | |
parent | 58b8ea716197516657d03f19b0d986fd180d43fa (diff) |
Windows Vista: Fix painting of item view items.
The old QWidget-based treeViewHelper() function silently failed
since the widget no longer had a HWND.
Use a native Window handle instead.
Change-Id: I6902677c565bb165f29b9d1c6fd0d28d9870d567
Reviewed-by: Marius Storm-Olsen <marius.storm-olsen@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/styles/qwindowsvistastyle.cpp | 56 | ||||
-rw-r--r-- | src/widgets/styles/qwindowsvistastyle_p.h | 5 |
2 files changed, 46 insertions, 15 deletions
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 8954ce5482..86574f2587 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -491,9 +491,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_IndicatorBranch: { - XPThemeData theme(d->treeViewHelper(), painter, QWindowsXPStylePrivate::TreeViewTheme); + XPThemeData theme(0, painter, QWindowsXPStylePrivate::TreeViewTheme); static int decoration_size = 0; - if (theme.isValid() && !decoration_size) { + if (d->initTreeViewTheming() && theme.isValid() && !decoration_size) { SIZE size; pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size); decoration_size = qMax(size.cx, size.cy); @@ -802,10 +802,10 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt state = LISS_HOT; QPainter pixmapPainter(&pixmap); - XPThemeData theme(d->treeViewHelper(), &pixmapPainter, + XPThemeData theme(0, &pixmapPainter, QWindowsXPStylePrivate::TreeViewTheme, LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height())); - if (theme.isValid()) { + if (d->initTreeViewTheming() && theme.isValid()) { d->drawBackground(theme); } else { QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget); @@ -2532,7 +2532,8 @@ QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() : QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate() { qDeleteAll(animations); - delete m_treeViewHelper; + if (m_treeViewHelper) + DestroyWindow(m_treeViewHelper); } void QWindowsVistaStylePrivate::timerEvent() @@ -2640,19 +2641,48 @@ bool QWindowsVistaStylePrivate::resolveSymbols() } /* - * We need to set the windows explorer theme explicitly on a native widget - * in order to get Vista-style item view themes + * We need to set the windows "explorer" theme explicitly on a native + * window and open the "TREEVIEW" theme handle passing its window handle + * in order to get Vista-style item view themes (particulary drawBackground() + * for selected items needs this). + * We invoke a service of the native Windows interface to create + * a non-visible window handle, open the theme on it and insert it into + * the cache so that it is found by XPThemeData::handle() first. */ -QWidget *QWindowsVistaStylePrivate::treeViewHelper() + +static inline HWND createTreeViewHelperWindow() { - if (!m_treeViewHelper) { - m_treeViewHelper = new QWidget(0); - HWND handle = QApplicationPrivate::getHWNDForWidget(m_treeViewHelper); - pSetWindowTheme(handle, L"explorer", NULL); + if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) { + void *hwnd = 0; + void *wndProc = reinterpret_cast<void *>(DefWindowProc); + if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection, + Q_RETURN_ARG(void *, hwnd), + Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")), + Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")), + Q_ARG(void *, wndProc)) && hwnd) { + return reinterpret_cast<HWND>(hwnd); + } } - return m_treeViewHelper; + return 0; } +bool QWindowsVistaStylePrivate::initTreeViewTheming() +{ + if (m_treeViewHelper) + return true; + + m_treeViewHelper = createTreeViewHelperWindow(); + if (!m_treeViewHelper) { + qWarning("%s: Unable to create the treeview helper window.", Q_FUNC_INFO); + return false; + } + const HRESULT hr = pSetWindowTheme(m_treeViewHelper, L"explorer", NULL); + if (hr != S_OK) { + qErrnoWarning("%s: SetWindowTheme() failed.", Q_FUNC_INFO); + return false; + } + return QWindowsXPStylePrivate::createTheme(QWindowsXPStylePrivate::TreeViewTheme, m_treeViewHelper); +} /*! \internal diff --git a/src/widgets/styles/qwindowsvistastyle_p.h b/src/widgets/styles/qwindowsvistastyle_p.h index 7205ad2d19..78282d01ef 100644 --- a/src/widgets/styles/qwindowsvistastyle_p.h +++ b/src/widgets/styles/qwindowsvistastyle_p.h @@ -205,12 +205,13 @@ public: QWindowsVistaAnimation* widgetAnimation(const QWidget *) const; void timerEvent(); bool transitionsEnabled() const; - QWidget *treeViewHelper(); private: + bool initTreeViewTheming(); + QList <QWindowsVistaAnimation*> animations; QBasicTimer animationTimer; - QWidget *m_treeViewHelper; + HWND m_treeViewHelper; }; QT_END_NAMESPACE |