Windows: Replace QString keys of XP themes by an enumeration.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 4 Apr 2012 12:02:27 +0000 (14:02 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 4 Apr 2012 16:10:11 +0000 (18:10 +0200)
Change-Id: I5323e9ed5bc3fe73f278d167acae6fa744b0a299
Reviewed-by: Marius Storm-Olsen <marius.storm-olsen@nokia.com>
src/widgets/styles/qwindowsvistastyle.cpp
src/widgets/styles/qwindowsxpstyle.cpp
src/widgets/styles/qwindowsxpstyle_p.h

index 78d4e7b..8954ce5 100644 (file)
@@ -482,14 +482,16 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
             int stateId = HSAS_SORTEDDOWN;
             if (header->sortIndicator & QStyleOptionHeader::SortDown)
                 stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours
-            XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect);
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::HeaderTheme,
+                              HP_HEADERSORTARROW, stateId, option->rect);
             d->drawBackground(theme);
         }
         break;
 
     case PE_IndicatorBranch:
         {
-            XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW"));
+            XPThemeData theme(d->treeViewHelper(), painter, QWindowsXPStylePrivate::TreeViewTheme);
             static int decoration_size = 0;
             if (theme.isValid() && !decoration_size) {
                 SIZE size;
@@ -546,7 +548,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
     case PE_FrameMenu:
         {
             int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE;
-            XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect);
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::MenuTheme,
+                              MENU_POPUPBORDERS, stateId, option->rect);
             d->drawBackground(theme);
         }
         break;
@@ -561,7 +565,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
                 stateId = ETS_READONLY;
             else if (state & State_HasFocus)
                 stateId = ETS_SELECTED;
-            XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect);
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::EditTheme,
+                              EP_EDITBORDER_HVSCROLL, stateId, option->rect);
             uint resolve_mask = option->palette.resolve();
             if (resolve_mask & (1 << QPalette::Base)) {
                 // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
@@ -611,7 +617,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
                 else if (state & State_MouseOver)
                     stateId = EBS_HOT;
 
-                XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect);
+                XPThemeData theme(0, painter, QWindowsXPStylePrivate::EditTheme,
+                                  partId, stateId, rect);
                 if (!theme.isValid()) {
                     QWindowsStyle::drawPrimitive(element, option, painter, widget);
                     return;
@@ -678,7 +685,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
                     stateId = ETS_HOT;
                 else if (state & State_HasFocus)
                     stateId = ETS_SELECTED;
-                XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect);
+                XPThemeData theme(widget, painter,
+                                  QWindowsXPStylePrivate::EditTheme,
+                                  EP_EDITBORDER_NOSCROLL, stateId, option->rect);
                 painter->save();
                 QRegion clipRegion = option->rect;
                 clipRegion -= option->rect.adjusted(2, 2, -2, -2);
@@ -694,11 +703,14 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
             XPThemeData theme;
             QRect rect;
             if (option->state & State_Horizontal) {
-                theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+                theme = XPThemeData(widget, painter,
+                                    QWindowsXPStylePrivate::RebarTheme,
+                                    RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
                 rect = option->rect.adjusted(0, 1, 0, -2);
                 rect.setWidth(4);
             } else {
-                theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+                theme = XPThemeData(widget, painter, QWindowsXPStylePrivate::RebarTheme,
+                                    RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
                 rect = option->rect.adjusted(1, 0, -1, 0);
                 rect.setHeight(4);
             }
@@ -724,7 +736,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
         break;
 
     case PE_PanelTipLabel: {
-        XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+        XPThemeData theme(widget, painter,
+                          QWindowsXPStylePrivate::ToolTipTheme,
+                          TTP_STANDARD, TTSS_NORMAL, option->rect);
         d->drawBackground(theme);
         break;
     }
@@ -788,7 +802,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
                             state = LISS_HOT;
 
                         QPainter pixmapPainter(&pixmap);
-                        XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"),
+                        XPThemeData theme(d->treeViewHelper(), &pixmapPainter,
+                                          QWindowsXPStylePrivate::TreeViewTheme,
                             LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
                         if (theme.isValid()) {
                             d->drawBackground(theme);
@@ -849,7 +864,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
 
             if (buttonBox) {
                 //draw white panel part
-                XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect);
+                XPThemeData theme(widget, painter,
+                                  QWindowsXPStylePrivate::TaskDialogTheme,
+                                  TDLG_PRIMARYPANEL, 0, option->rect);
                 QRect toprect = option->rect;
                 toprect.setBottom(buttonBox->geometry().top());
                 theme.rect = toprect;
@@ -891,7 +908,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
     bool disabled = !(option->state & State_Enabled);
 
     int state = option->state;
-    QString name;
+    int themeNumber  = -1;
 
     QRect rect(option->rect);
     State flags = option->state;
@@ -971,12 +988,11 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
     case CE_PushButtonBevel:
         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
         {
-
             QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
             if (anim && (btn->state & State_Enabled)) {
                 anim->paint(painter, option);
             } else {
-                name = QLatin1String("BUTTON");
+                themeNumber = QWindowsXPStylePrivate::ButtonTheme;
                 partId = BP_PUSHBUTTON;
                 if (btn->features & QStyleOptionButton::CommandLinkButton)
                     partId = BP_COMMANDLINK;
@@ -1011,7 +1027,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
 
                             QPainter startPainter(&startImage);
                             stateId = PBS_DEFAULTED;
-                            XPThemeData theme(widget, &startPainter, name, partId, stateId, rect);
+                            XPThemeData theme(widget, &startPainter, themeNumber, partId, stateId, rect);
                             d->drawBackground(theme);
 
                             QPainter alternatePainter(&alternateImage);
@@ -1029,20 +1045,21 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
                         if (anim)
                             anim->paint(painter, option);
                         else {
-                            XPThemeData theme(widget, painter, name, partId, stateId, rect);
+                            XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
                             d->drawBackground(theme);
                         }
                     }
                     else {
                         d->stopAnimation(widget);
-                        XPThemeData theme(widget, painter, name, partId, stateId, rect);
+                        XPThemeData theme(widget, painter, themeNumber, partId, stateId, rect);
                         d->drawBackground(theme);
                     }
                 }
             }
             if (btn->features & QStyleOptionButton::HasMenu) {
                 int mbiw = 0, mbih = 0;
-                XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON);
+                XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
+                                  TP_DROPDOWNBUTTON);
                 if (theme.isValid()) {
                     SIZE size;
                     if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
@@ -1086,7 +1103,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
                 }
             }
 
-            XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL);
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::ProgressTheme,
+                              vertical ? PP_FILLVERT : PP_FILL);
             theme.rect = option->rect;
             bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted);
             QTime current = QTime::currentTime();
@@ -1208,7 +1227,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
                 alignment |= Qt::TextHideMnemonic;
 
             //The rect adjustment is a workaround for the menu not really filling its background.
-            XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::MenuTheme,
+                              MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
             d->drawBackground(theme);
 
             int stateId = MBI_NORMAL;
@@ -1219,7 +1240,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
             else if (selected)
                 stateId = MBI_HOT;
 
-            XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect);
+            XPThemeData theme2(widget, painter,
+                               QWindowsXPStylePrivate::MenuTheme,
+                               MENU_BARITEM, stateId, option->rect);
             d->drawBackground(theme2);
 
             if (!pix.isNull())
@@ -1237,7 +1260,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
             {
                 SIZE    size;
                 MARGINS margins;
-                XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+                XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme,
+                                  MENU_POPUPCHECKBACKGROUND, MBI_HOT);
                 pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
                 pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
                 checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
@@ -1248,7 +1272,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
             QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
             QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
             QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
-            XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect);
+            XPThemeData theme2(widget, painter, QWindowsXPStylePrivate::MenuTheme,
+                               MENU_POPUPGUTTER, stateId, gutterRect);
             d->drawBackground(theme2);
 
             int x, y, w, h;
@@ -1266,7 +1291,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
                 stateId = MBI_HOT;
                 QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
                 subRect  = QStyle::visualRect(option->direction, option->rect, subRect );
-                XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect);
+                XPThemeData theme2(widget, painter,
+                                   QWindowsXPStylePrivate::MenuTheme,
+                                   MENU_POPUPSEPARATOR, stateId, subRect);
                 d->drawBackground(theme2);
                 return;
             }
@@ -1276,12 +1303,16 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
 
             if (act) {
                 stateId = MBI_HOT;
-                XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect);
+                XPThemeData theme2(widget, painter,
+                                   QWindowsXPStylePrivate::MenuTheme,
+                                   MENU_POPUPITEM, stateId, option->rect);
                 d->drawBackground(theme2);
             }
 
             if (checked) {
-                XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND,
+                XPThemeData theme(widget, painter,
+                                  QWindowsXPStylePrivate::MenuTheme,
+                                  MENU_POPUPCHECKBACKGROUND,
                                   menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
                 SIZE    size;
                 MARGINS margins;
@@ -1377,7 +1408,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
 #endif // QT_NO_MENU
     case CE_HeaderSection:
         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
-            name = QLatin1String("HEADER");
             partId = HP_HEADERITEM;
             if (flags & State_Sunken)
                 stateId = HIS_PRESSED;
@@ -1389,7 +1419,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
             if (header->sortIndicator != QStyleOptionHeader::None)
                 stateId += 3;
 
-            XPThemeData theme(widget, painter, name, partId, stateId, option->rect);
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::HeaderTheme,
+                              partId, stateId, option->rect);
             d->drawBackground(theme);
         }
         break;
@@ -1398,7 +1430,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
             stateId = MBI_NORMAL;
             if (!(state & State_Enabled))
                 stateId = MBI_DISABLED;
-            XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect);
+            XPThemeData theme(widget, painter,
+                              QWindowsXPStylePrivate::MenuTheme,
+                              MENU_BARBACKGROUND, stateId, option->rect);
             d->drawBackground(theme);
         }
         break;
@@ -1669,13 +1703,15 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
                     else
                         stateId = ETS_NORMAL;
 
-                    XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+                    XPThemeData theme(widget, painter,
+                                      QWindowsXPStylePrivate::EditTheme,
+                                      partId, stateId, r);
 
                     d->drawBackground(theme);
                 }
                 if (sub & SC_ComboBoxArrow) {
                     QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
-                    XPThemeData theme(widget, painter, QLatin1String("COMBOBOX"));
+                    XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ComboboxTheme);
                     theme.rect = subRect;
                     partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
 
@@ -1708,8 +1744,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
     case CC_ScrollBar:
         if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
         {
-            XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR"));
-
+            XPThemeData theme(widget, painter, QWindowsXPStylePrivate::ScrollBarTheme);
             bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
             if (maxedOut)
                 flags &= ~State_Enabled;
@@ -1855,7 +1890,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
     case CC_SpinBox:
         if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
         {
-            XPThemeData theme(widget, painter, QLatin1String("SPIN"));
+            XPThemeData theme(widget, painter, QWindowsXPStylePrivate::SpinTheme);
             if (sb->frame && (sub & SC_SpinBoxFrame)) {
                 partId = EP_EDITBORDER_NOSCROLL;
                 if (!(flags & State_Enabled))
@@ -1867,7 +1902,9 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
                 else
                     stateId = ETS_NORMAL;
 
-                XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+                XPThemeData ftheme(widget, painter,
+                                   QWindowsXPStylePrivate::EditTheme,
+                                   partId, stateId, r);
                 ftheme.noContent = true;
                 d->drawBackground(ftheme);
             }
@@ -1927,7 +1964,9 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption
         {
             SIZE    size;
             MARGINS margins;
-            XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+            XPThemeData theme(widget, 0,
+                              QWindowsXPStylePrivate::MenuTheme,
+                              MENU_POPUPCHECKBACKGROUND, MBI_HOT);
             pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
             pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
             minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height());
@@ -2019,7 +2058,9 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
             int y = option->rect.y();
             int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
 
-            XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
+            XPThemeData theme(widget, 0,
+                              QWindowsXPStylePrivate::HeaderTheme,
+                              HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
 
             int arrowWidth = 13;
             int arrowHeight = 5;
@@ -2148,7 +2189,9 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
         if (option) {
             if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
                 ret = true;
-                XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+                XPThemeData themeData(widget, 0,
+                                      QWindowsXPStylePrivate::ToolTipTheme,
+                                      TTP_STANDARD, TTSS_NORMAL, option->rect);
                 mask->region = d->region(themeData);
             }
         }
@@ -2626,7 +2669,9 @@ QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon
     switch(standardIcon) {
     case SP_CommandLink:
         {
-            XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
+            XPThemeData theme(0, 0,
+                              QWindowsXPStylePrivate::ButtonTheme,
+                              BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
             if (theme.isValid()) {
                 SIZE size;
                 pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
index f40bd22..336d93e 100644 (file)
@@ -136,6 +136,15 @@ static const int windowsRightBorder      = 12; // right border on windows
 extern Q_WIDGETS_EXPORT HDC qt_win_display_dc();
 extern QRegion qt_region_from_HRGN(HRGN rgn);
 
+// Theme names matching the QWindowsXPStylePrivate::Theme enumeration.
+static const wchar_t *themeNames[QWindowsXPStylePrivate::NThemes] =
+{
+    L"BUTTON",   L"COMBOBOX",   L"EDIT",    L"HEADER",    L"LISTVIEW",
+    L"MENU",     L"PROGRESS",   L"REBAR",   L"SCROLLBAR", L"SPIN",
+    L"TAB",      L"TASKDIALOG", L"TOOLBAR", L"TOOLTIP",   L"TRACKBAR",
+    L"TREEVIEW", L"WINDOW",     L"STATUS"
+};
+
 static inline QBackingStore *backingStoreForWidget(const QWidget *widget)
 {
     if (QBackingStore *backingStore = widget->backingStore())
@@ -161,7 +170,7 @@ static inline HDC hdcForWidgetBackingStore(const QWidget *widget)
 */
 bool XPThemeData::isValid()
 {
-    return QWindowsXPStylePrivate::useXP() && name.size() && handle();
+    return QWindowsXPStylePrivate::useXP() && theme >= 0 && handle();
 }
 
 
@@ -175,18 +184,8 @@ HTHEME XPThemeData::handle()
     if (!QWindowsXPStylePrivate::useXP())
         return 0;
 
-    if (!htheme && QWindowsXPStylePrivate::handleMap)
-        htheme = QWindowsXPStylePrivate::handleMap->value(name);
-
-    if (!htheme) {
-        htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16());
-        if (htheme) {
-            if (!QWindowsXPStylePrivate::handleMap)
-                QWindowsXPStylePrivate::handleMap = new QWindowsXPStylePrivate::ThemeHandleMap;
-            QWindowsXPStylePrivate::handleMap->insert(name, htheme);
-        }
-    }
-
+    if (!htheme)
+        htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(widget));
     return htheme;
 }
 
@@ -224,7 +223,7 @@ HRGN XPThemeData::mask(QWidget *widget)
 // QWindowsXPStylePrivate -------------------------------------------------------------------------
 // Static initializations
 QPixmap *QWindowsXPStylePrivate::tabbody = 0;
-QMap<QString,HTHEME> *QWindowsXPStylePrivate::handleMap = 0;
+HTHEME QWindowsXPStylePrivate::m_themes[NThemes];
 bool QWindowsXPStylePrivate::use_xp = false;
 QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
 
@@ -277,6 +276,7 @@ void QWindowsXPStylePrivate::init(bool force)
         ref.ref();
 
     useXP(true);
+    qFill(m_themes, m_themes + NThemes, HTHEME(0));
 }
 
 /* \internal
@@ -313,16 +313,34 @@ void QWindowsXPStylePrivate::cleanup(bool force)
 */
 void QWindowsXPStylePrivate::cleanupHandleMap()
 {
-    typedef ThemeHandleMap::const_iterator ConstIterator;
+    for (int i = 0; i < NThemes; ++i)
+        if (m_themes[i]) {
+            pCloseThemeData(m_themes[i]);
+            m_themes[i] = 0;
+        }
+}
 
-    if (!handleMap)
-        return;
+HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd)
+{
+    if (theme < 0 || theme >= NThemes || !hwnd) {
+        qWarning("%s: Invalid parameters #%d, %p", theme, hwnd);
+        return 0;
+    }
+    if (!m_themes[theme]) {
+        const wchar_t *name = themeNames[theme];
+        m_themes[theme] = pOpenThemeData(hwnd, name);
+        if (!m_themes[theme])
+            qErrnoWarning("%s: OpenThemeData() failed for theme %d (%s).",
+                          Q_FUNC_INFO, theme, qPrintable(themeName(theme)));
+    }
+    return m_themes[theme];
+}
 
-    const ConstIterator cend = handleMap->constEnd();
-    for (ConstIterator it = handleMap->constBegin(); it != cend; ++it)
-        pCloseThemeData(it.value());
-    delete handleMap;
-    handleMap = 0;
+QString QWindowsXPStylePrivate::themeName(int theme)
+{
+    return theme >= 0 && theme < NThemes ?
+           QString::fromWCharArray(themeNames[theme]) :
+           QString();
 }
 
 /*! \internal
@@ -361,7 +379,7 @@ const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *)
 {
     if (!tabbody) {
         SIZE sz;
-        XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY);
+        XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY);
         pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
 
         tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
@@ -828,9 +846,21 @@ void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
     bool inspectData;
     bool potentialInvalidAlpha;
 
-    QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
-                             .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
-                             .arg(w).arg(h);
+    QString pixmapCacheKey = QStringLiteral("$qt_xp_");
+    pixmapCacheKey.append(themeName(themeData.theme));
+    pixmapCacheKey.append(QLatin1Char('p'));
+    pixmapCacheKey.append(QString::number(partId));
+    pixmapCacheKey.append(QLatin1Char('s'));
+    pixmapCacheKey.append(QString::number(stateId));
+    pixmapCacheKey.append(QLatin1Char('s'));
+    pixmapCacheKey.append(themeData.noBorder ? QLatin1Char('0') : QLatin1Char('1'));
+    pixmapCacheKey.append(QLatin1Char('b'));
+    pixmapCacheKey.append(themeData.noContent ? QLatin1Char('0') : QLatin1Char('1'));
+    pixmapCacheKey.append(QString::number(w));
+    pixmapCacheKey.append(QLatin1Char('w'));
+    pixmapCacheKey.append(QString::number(h));
+    pixmapCacheKey.append(QLatin1Char('h'));
+
     QPixmap cachedPixmap;
     ThemeMapKey key(themeData);
     ThemeMapData data = alphaCache.value(key);
@@ -1195,7 +1225,7 @@ void QWindowsXPStyle::polish(QWidget *widget)
     if (!d->hasInitColors) {
         // Get text color for group box labels
         COLORREF cref;
-        XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0);
+        XPThemeData theme(0, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0);
         pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
         d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
         pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
@@ -1305,7 +1335,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option,
         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
             MARGINS borderSize;
             if (widget) {
-                XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+                XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme);
                 HTHEME theme = buttontheme.handle();
                 if (theme) {
                     int stateId;
@@ -1366,7 +1396,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt
         return;
     }
 
-    QString name;
+    int themeNumber = -1;
     int partId = 0;
     int stateId = 0;
     QRect rect = option->rect;
@@ -1412,7 +1442,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt
         }
         return;
     case PE_PanelButtonBevel:
-        name = QLatin1String("BUTTON");
+        themeNumber = QWindowsXPStylePrivate::ButtonTheme;
         partId = BP_PUSHBUTTON;
         if (!(flags & State_Enabled))
             stateId = PBS_DISABLED;
@@ -1432,7 +1462,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt
                 if (dw->isWindow())
                     return;
         }
-        name = QLatin1String("TOOLBAR");
+        themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
         partId = TP_BUTTON;
         if (!(flags & State_Enabled))
             stateId = TS_DISABLED;
@@ -1449,7 +1479,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt
         break;
 
     case PE_IndicatorButtonDropDown:
-        name = QLatin1String("TOOLBAR");
+        themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
         partId = TP_SPLITBUTTONDROPDOWN;
         if (!(flags & State_Enabled))
             stateId = TS_DISABLED;
@@ -1468,7 +1498,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt
         break;
 
     case PE_IndicatorCheckBox:
-        name = QLatin1String("BUTTON");
+        themeNumber = QWindowsXPStylePrivate::ButtonTheme;
         partId = BP_CHECKBOX;
         if (!(flags & State_Enabled))
             stateId = CBS_UNCHECKEDDISABLED;
@@ -1487,7 +1517,7 @@ void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt
         break;
 
     case PE_IndicatorRadioButton:
-        name = QLatin1String("BUTTON");
+        themeNumber = QWindowsXPStylePrivate::ButtonTheme;
         partId = BP_RADIOBUTTON;
         if (!(flags & State_Enabled))
             stateId = RBS_UNCHECKEDDISABLED;
@@ -1509,9 +1539,9 @@ case PE_Frame:
     {
         if (flags & State_Raised)
             return;
-        name = QLatin1String("LISTVIEW");
+        themeNumber = QWindowsXPStylePrivate::ListViewTheme;
         partId = LVP_LISTGROUP;
-        XPThemeData theme(0, 0, name, partId, 0);
+        XPThemeData theme(0, 0, themeNumber, partId, 0);
 
         if (!(flags & State_Enabled))
             stateId = ETS_DISABLED;
@@ -1561,7 +1591,7 @@ case PE_Frame:
             p->setPen(oldPen);
             return;
         } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
-            name = QLatin1String("EDIT");
+            themeNumber = QWindowsXPStylePrivate::EditTheme;
             partId = EP_EDITTEXT;
             noContent = true;
             if (!(flags & State_Enabled))
@@ -1574,7 +1604,7 @@ case PE_Frame:
 
     case PE_PanelLineEdit:
         if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
-            name = QLatin1String("EDIT");
+            themeNumber = QWindowsXPStylePrivate::EditTheme;
             partId = EP_EDITTEXT;
             noBorder = true;
             QBrush bg;
@@ -1602,7 +1632,7 @@ case PE_Frame:
             if (usePalette) {
                 p->fillRect(panel->rect, bg);
             } else {
-                XPThemeData theme(0, p, name, partId, stateId, rect);
+                XPThemeData theme(0, p, themeNumber, partId, stateId, rect);
                 if (!theme.isValid()) {
                     QWindowsStyle::drawPrimitive(pe, option, p, widget);
                     return;
@@ -1646,7 +1676,7 @@ case PE_Frame:
     case PE_FrameTabWidget:
         if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
         {
-            name = QLatin1String("TAB");
+            themeNumber = QWindowsXPStylePrivate::TabTheme;
             partId = TABP_PANE;
 
             if (widget) {
@@ -1673,7 +1703,7 @@ case PE_Frame:
                     QRegion reg = option->rect;
                     reg -= contentsRect;
                     p->setClipRegion(reg);
-                    XPThemeData theme(widget, p, name, partId, stateId, rect);
+                    XPThemeData theme(widget, p, themeNumber, partId, stateId, rect);
                     theme.mirrorHorizontally = hMirrored;
                     theme.mirrorVertically = vMirrored;
                     d->drawBackground(theme);
@@ -1717,7 +1747,7 @@ case PE_Frame:
  case PE_FrameDockWidget:
      if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
         {
-            name = QLatin1String("WINDOW");
+            themeNumber = QWindowsXPStylePrivate::WindowTheme;
             if (flags & State_Active)
                 stateId = FS_ACTIVE;
             else
@@ -1725,7 +1755,7 @@ case PE_Frame:
 
             int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget);
 
-            XPThemeData theme(widget, p, name, 0, stateId);
+            XPThemeData theme(widget, p, themeNumber, 0, stateId);
             if (!theme.isValid())
                 break;
             theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth);           theme.partId = WP_SMALLFRAMELEFT;
@@ -1743,7 +1773,7 @@ case PE_Frame:
     case PE_IndicatorHeaderArrow:
         {
 #if 0 // XP theme engine doesn't know about this :(
-            name = QLatin1String("HEADER");
+            name = QWindowsXPStylePrivate::HEADER");
             partId = HP_HEADERSORTARROW;
             if (flags & State_Down)
                 stateId = HSAS_SORTEDDOWN;
@@ -1775,12 +1805,12 @@ case PE_Frame:
         break;
 
     case PE_FrameStatusBarItem:
-        name = QLatin1String("STATUS");
+        themeNumber = QWindowsXPStylePrivate::StatusTheme;
         partId = SP_PANE;
         break;
 
     case PE_FrameGroupBox:
-        name = QLatin1String("BUTTON");
+        themeNumber = QWindowsXPStylePrivate::ButtonTheme;
         partId = BP_GROUPBOX;
         if (!(flags & State_Enabled))
             stateId = GBS_DISABLED;
@@ -1794,7 +1824,7 @@ case PE_Frame:
                 QPoint p1(fr.x(), fr.y() + 1);
                 QPoint p2(fr.x() + fr.width(), p1.y() + 1);
                 rect = QRect(p1, p2);
-                name = QLatin1String("");
+                themeNumber = -1;
             }
         }
         break;
@@ -1817,13 +1847,13 @@ case PE_Frame:
             partId = PP_CHUNKVERT;
             rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
         }
-        name = QLatin1String("PROGRESS");
+        themeNumber = QWindowsXPStylePrivate::ProgressTheme;
         stateId = 1;
         }
         break;
 
     case PE_Q3DockWindowSeparator:
-        name = QLatin1String("TOOLBAR");
+        themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
         if (flags & State_Horizontal)
             partId = TP_SEPARATOR;
         else
@@ -1833,7 +1863,7 @@ case PE_Frame:
     case PE_FrameWindow:
         if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
         {
-            name = QLatin1String("WINDOW");
+            themeNumber = QWindowsXPStylePrivate::WindowTheme;
             if (flags & State_Active)
                 stateId = FS_ACTIVE;
             else
@@ -1841,7 +1871,7 @@ case PE_Frame:
 
             int fwidth = frm->lineWidth + frm->midLineWidth;
 
-            XPThemeData theme(0, p, name, 0, stateId);
+            XPThemeData theme(0, p, themeNumber, 0, stateId);
             if (!theme.isValid())
                 break;
 
@@ -1887,7 +1917,7 @@ case PE_Frame:
                 bef_v -= delta;
                 aft_h += delta;
                 aft_v += delta;
-                XPThemeData theme(0, p, QLatin1String("TREEVIEW"));
+                XPThemeData theme(0, p, QWindowsXPStylePrivate::TreeViewTheme);
                 theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
                 theme.partId = TVP_GLYPH;
                 theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
@@ -1903,7 +1933,7 @@ case PE_Frame:
             QWindowsStyle::drawPrimitive(pe, option, p, widget);
             return;
         }
-        name = QLatin1String("TOOLBAR");
+        themeNumber = QWindowsXPStylePrivate::ToolBarTheme;
         partId = TP_SEPARATOR;
 
         if (option->state & State_Horizontal)
@@ -1915,7 +1945,7 @@ case PE_Frame:
 
     case PE_IndicatorToolBarHandle:
 
-        name = QLatin1String("REBAR");
+        themeNumber = QWindowsXPStylePrivate::RebarTheme;
         partId = RP_GRIPPER;
         if (option->state & State_Horizontal) {
             partId = RP_GRIPPER;
@@ -1939,7 +1969,7 @@ case PE_Frame:
         break;
     }
 
-    XPThemeData theme(0, p, name, partId, stateId, rect);
+    XPThemeData theme(0, p, themeNumber, partId, stateId, rect);
     if (!theme.isValid()) {
         QWindowsStyle::drawPrimitive(pe, option, p, widget);
         return;
@@ -1971,16 +2001,16 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
     bool hMirrored = false;
     bool vMirrored = false;
 
-    QString name;
+    int themeNumber = -1;
     int partId = 0;
     int stateId = 0;
     switch (element) {
     case CE_SizeGrip:
         {
-            name = QLatin1String("STATUS");
+            themeNumber = QWindowsXPStylePrivate::StatusTheme;
             partId = SP_GRIPPER;
             SIZE sz;
-            XPThemeData theme(0, p, name, partId, 0);
+            XPThemeData theme(0, p, themeNumber, partId, 0);
             pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz);
             --sz.cy;
             if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
@@ -2005,7 +2035,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
         break;
 
     case CE_HeaderSection:
-        name = QLatin1String("HEADER");
+        themeNumber = QWindowsXPStylePrivate::HeaderTheme;
         partId = HP_HEADERITEM;
         if (flags & State_Sunken)
             stateId = HIS_PRESSED;
@@ -2022,7 +2052,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
     case CE_PushButtonBevel:
         if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
         {
-            name = QLatin1String("BUTTON");
+            themeNumber = QWindowsXPStylePrivate::ButtonTheme;
             partId = BP_PUSHBUTTON;
             bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
                 || ((btn->features & QStyleOptionButton::CommandLinkButton)
@@ -2042,13 +2072,15 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
                 stateId = PBS_NORMAL;
 
             if (!justFlat) {
-                XPThemeData theme(widget, p, name, partId, stateId, rect);
+                XPThemeData theme(widget, p, themeNumber, partId, stateId, rect);
                 d->drawBackground(theme);
             }
 
             if (btn->features & QStyleOptionButton::HasMenu) {
                 int mbiw = 0, mbih = 0;
-                XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN);
+                XPThemeData theme(widget, 0,
+                                  QWindowsXPStylePrivate::ToolBarTheme,
+                                  TP_SPLITBUTTONDROPDOWN);
                 if (theme.isValid()) {
                     SIZE size;
                     pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -2074,7 +2106,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
     case CE_TabBarTabShape:
         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
         {
-            name = QLatin1String("TAB");
+            themeNumber = QWindowsXPStylePrivate::TabTheme;
             bool isDisabled = !(tab->state & State_Enabled);
             bool hasFocus = tab->state & State_HasFocus;
             bool isHot = tab->state & State_MouseOver;
@@ -2153,7 +2185,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
                 }
                 break;
             default:
-                name = QLatin1String("");  // Do our own painting for triangular
+                themeNumber = -1; // Do our own painting for triangular
                 break;
             }
 
@@ -2184,7 +2216,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
         if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
             orient = pb2->orientation;
         partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
-        name = QLatin1String("PROGRESS");
+        themeNumber = QWindowsXPStylePrivate::ProgressTheme;
         stateId = 1;
         }
         break;
@@ -2406,7 +2438,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
 
                 p->setPen(oldPen);
             } else {
-                name = QLatin1String("WINDOW");
+                themeNumber = QWindowsXPStylePrivate::WindowTheme;
                 if (isActive)
                     stateId = CS_ACTIVE;
                 else
@@ -2415,7 +2447,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
                 int titleHeight = rect.height() - 2;
                 rect = rect.adjusted(-fw, -fw, fw, 0);
 
-                XPThemeData theme(widget, p, name, 0, stateId);
+                XPThemeData theme(widget, p, themeNumber, 0, stateId);
                 if (!theme.isValid())
                     break;
 
@@ -2491,7 +2523,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
     case CE_HeaderEmptyArea:
         if (option->state & State_Horizontal)
         {
-            name = QLatin1String("HEADER");
+            themeNumber = QWindowsXPStylePrivate::HeaderTheme;
             stateId = HIS_NORMAL;
         }
         else {
@@ -2503,7 +2535,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
         break;
     }
 
-    XPThemeData theme(widget, p, name, partId, stateId, rect);
+    XPThemeData theme(widget, p, themeNumber, partId, stateId, rect);
     if (!theme.isValid()) {
         QWindowsStyle::drawControl(element, option, p, widget);
         return;
@@ -2543,7 +2575,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
     case CC_SpinBox:
         if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
         {
-            XPThemeData theme(widget, p, QLatin1String("SPIN"));
+            XPThemeData theme(widget, p, QWindowsXPStylePrivate::SpinTheme);
 
             if (sb->frame && (sub & SC_SpinBoxFrame)) {
                 partId = EP_EDITTEXT;
@@ -2554,7 +2586,8 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
                 else
                     stateId = ETS_NORMAL;
 
-                XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+                XPThemeData ftheme(widget, p, QWindowsXPStylePrivate::EditTheme,
+                                   partId, stateId, r);
                 ftheme.noContent = true;
                 d->drawBackground(ftheme);
             }
@@ -2604,7 +2637,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
                         stateId = ETS_FOCUSED;
                     else
                         stateId = ETS_NORMAL;
-                    XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+                    XPThemeData theme(widget, p, QWindowsXPStylePrivate::EditTheme, partId, stateId, r);
                     d->drawBackground(theme);
                 } else {
                     QBrush editBrush = cmb->palette.brush(QPalette::Base);
@@ -2625,7 +2658,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
             }
 
             if (sub & SC_ComboBoxArrow) {
-                XPThemeData theme(widget, p, QLatin1String("COMBOBOX"));
+                XPThemeData theme(widget, p, QWindowsXPStylePrivate::ComboboxTheme);
                 theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
                 partId = CP_DROPDOWNBUTTON;
                 if (!(flags & State_Enabled))
@@ -2646,7 +2679,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
     case CC_ScrollBar:
         if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
         {
-            XPThemeData theme(widget, p, QLatin1String("SCROLLBAR"));
+            XPThemeData theme(widget, p, QWindowsXPStylePrivate::ScrollBarTheme);
             bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
             if (maxedOut)
                 flags &= ~State_Enabled;
@@ -2784,7 +2817,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
     case CC_Slider:
         if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option))
         {
-            XPThemeData theme(widget, p, QLatin1String("TRACKBAR"));
+            XPThemeData theme(widget, p, QWindowsXPStylePrivate::TrackBarTheme);
             QRect slrect = slider->rect;
             QRegion tickreg = slrect;
             if (sub & SC_SliderGroove) {
@@ -2947,7 +2980,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
             if (toolbutton->subControls & SC_ToolButton) {
                 if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
                     if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
-                        XPThemeData theme(widget, p, QLatin1String("TOOLBAR"));
+                        XPThemeData theme(widget, p, QWindowsXPStylePrivate::ToolBarTheme);
                         theme.partId = TP_SPLITBUTTON;
                         theme.rect = button;
                         if (!(bflags & State_Enabled))
@@ -3037,7 +3070,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
             if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
             {
                 bool isActive = tb->titleBarState & QStyle::State_Active;
-                XPThemeData theme(widget, p, QLatin1String("WINDOW"));
+                XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme);
                 if (sub & SC_TitleBarLabel) {
 
                         partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
@@ -3239,7 +3272,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
     case CC_MdiControls:
         {
             QRect buttonRect;
-            XPThemeData theme(widget, p, QLatin1String("WINDOW"), WP_MDICLOSEBUTTON, CBS_NORMAL);
+            XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme, WP_MDICLOSEBUTTON, CBS_NORMAL);
 
             if (option->subControls & SC_MdiCloseButton) {
                 buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
@@ -3363,7 +3396,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
     case PM_IndicatorWidth:
     case PM_IndicatorHeight:
         {
-            XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
+            XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
             if (theme.isValid()) {
                 SIZE size;
                 pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -3375,7 +3408,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
     case PM_ExclusiveIndicatorWidth:
     case PM_ExclusiveIndicatorHeight:
         {
-            XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
+            XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
             if (theme.isValid()) {
                 SIZE size;
                 pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -3389,7 +3422,8 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
             Qt::Orientation orient = Qt::Horizontal;
             if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
                 orient = pb2->orientation;
-            XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
+            XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ProgressTheme,
+                              (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
             if (theme.isValid()) {
                 SIZE size;
                 pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -3400,7 +3434,8 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
 
     case PM_SliderThickness:
         {
-            XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB);
+            XPThemeData theme(widget, 0, QWindowsXPStylePrivate::TrackBarTheme,
+                              TKP_THUMB);
             if (theme.isValid()) {
                 SIZE size;
                 pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -3420,7 +3455,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
 
     case PM_MdiSubWindowFrameWidth:
         {
-            XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE);
+            XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE);
             if (theme.isValid()) {
                 SIZE size;
                 pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size);
@@ -3441,7 +3476,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
 #endif // QT_NO_TOOLBAR
     case PM_DockWidgetFrameWidth:
     {
-        XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE);
+        XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE);
         if (theme.isValid()) {
             SIZE size;
             pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -3738,7 +3773,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
     case CT_LineEdit:
     case CT_ComboBox:
         {
-            XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+            XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme);
             HTHEME theme = buttontheme.handle();
             MARGINS borderSize;
             if (theme) {
@@ -3864,9 +3899,13 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const
                 titleBarRect.setHeight(tbHeight);
                 XPThemeData themeData;
                 if (titlebar->titleBarState & Qt::WindowMinimized) {
-                    themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect);
+                    themeData = XPThemeData(widget, 0,
+                                            QWindowsXPStylePrivate::WindowTheme,
+                                            WP_MINCAPTION, CS_ACTIVE, titleBarRect);
                 } else
-                    themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect);
+                    themeData = XPThemeData(widget, 0,
+                                            QWindowsXPStylePrivate::WindowTheme,
+                                            WP_CAPTION, CS_ACTIVE, titleBarRect);
                 mask->region = d->region(themeData) +
                                QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight);
             }
@@ -3915,7 +3954,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt
         if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
         {
             if (widget && widget->isWindow()) {
-                XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
                 if (theme.isValid()) {
                     SIZE sz;
                     pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz);
@@ -3947,8 +3986,10 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
         if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
         {
             if (d->dockFloat.isNull()) {
-                XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
-                XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL);
+                XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme,
+                                      WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+                                  WP_MAXBUTTON, MAXBS_NORMAL);
                 if (theme.isValid()) {
                     SIZE size;
                     pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
@@ -3982,7 +4023,8 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
         if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
         {
             if (d->dockClose.isNull()) {
-                XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+                                  WP_SMALLCLOSEBUTTON, CBS_NORMAL);
                 if (theme.isValid()) {
                     SIZE size;
                     pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
@@ -4016,8 +4058,10 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
         if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
         {
             if (d->dockFloat.isNull()) {
-                XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
-                XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL);
+                XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme,
+                                      WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+                XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
+                                  WP_RESTOREBUTTON, RBS_NORMAL);
                 if (theme.isValid()) {
                     SIZE size;
                     pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
index 0e42bbf..058668d 100644 (file)
@@ -209,9 +209,9 @@ QT_BEGIN_NAMESPACE
 class XPThemeData
 {
 public:
-    XPThemeData(const QWidget *w = 0, QPainter *p = 0, const QString &theme = QString(),
+    XPThemeData(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
                 int part = 0, int state = 0, const QRect &r = QRect())
-        : widget(w), painter(p), name(theme), htheme(0), partId(part), stateId(state),
+        : widget(w), painter(p), theme(themeIn), htheme(0), partId(part), stateId(state),
           mirrorHorizontally(false), mirrorVertically(false), noBorder(false),
           noContent(false), rotate(0), rect(r)
     {}
@@ -224,7 +224,8 @@ public:
 
     const QWidget *widget;
     QPainter *painter;
-    QString name;
+
+    int theme;
     HTHEME htheme;
     int partId;
     int stateId;
@@ -238,7 +239,7 @@ public:
 };
 
 struct ThemeMapKey {
-    QString name;
+    int theme;
     int partId;
     int stateId;
     bool noBorder;
@@ -246,17 +247,17 @@ struct ThemeMapKey {
 
     ThemeMapKey() : partId(-1), stateId(-1) {}
     ThemeMapKey(const XPThemeData &data)
-        : name(data.name), partId(data.partId), stateId(data.stateId),
+        : theme(data.theme), partId(data.partId), stateId(data.stateId),
         noBorder(data.noBorder), noContent(data.noContent) {}
 
 };
 
 inline uint qHash(const ThemeMapKey &key)
-{ return qHash(key.name) ^ key.partId ^ key.stateId; }
+{ return key.theme ^ key.partId ^ key.stateId; }
 
 inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2)
 {
-    return k1.name == k2.name
+    return k1.theme == k2.theme
            && k1.partId == k2.partId
            && k1.stateId == k2.stateId;
 }
@@ -286,7 +287,27 @@ class QWindowsXPStylePrivate : public QWindowsStylePrivate
 {
     Q_DECLARE_PUBLIC(QWindowsXPStyle)
 public:
-    typedef QMap<QString, HTHEME> ThemeHandleMap;
+    enum Theme {
+        ButtonTheme,
+        ComboboxTheme,
+        EditTheme,
+        HeaderTheme,
+        ListViewTheme,
+        MenuTheme,
+        ProgressTheme,
+        RebarTheme,
+        ScrollBarTheme,
+        SpinTheme,
+        TabTheme,
+        TaskDialogTheme,
+        ToolBarTheme,
+        ToolTipTheme,
+        TrackBarTheme,
+        TreeViewTheme,
+        WindowTheme,
+        StatusTheme,
+        NThemes
+    };
 
     QWindowsXPStylePrivate()
         : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
@@ -328,7 +349,8 @@ public:
     QRgb sliderTickColor;
     bool hasInitColors;
 
-    static ThemeHandleMap *handleMap;
+    static HTHEME createTheme(int theme, HWND hwnd);
+    static QString themeName(int theme);
 
     QIcon dockFloat, dockClose;
 
@@ -348,6 +370,8 @@ private:
     HBITMAP nullBitmap;
     uchar *bufferPixels;
     int bufferW, bufferH;
+
+    static HTHEME m_themes[NThemes];
 };
 
 #endif // QT_NO_STYLE_WINDOWS