[COMCTL32] Sync with Wine Staging 1.7.47. CORE-9924
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 22 Jul 2015 19:30:27 +0000 (19:30 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 22 Jul 2015 19:30:27 +0000 (19:30 +0000)
svn path=/trunk/; revision=68553

14 files changed:
reactos/dll/win32/comctl32/comctl32_ros.diff
reactos/dll/win32/comctl32/dsa.c
reactos/dll/win32/comctl32/flatsb.c
reactos/dll/win32/comctl32/header.c
reactos/dll/win32/comctl32/listview.c
reactos/dll/win32/comctl32/monthcal.c
reactos/dll/win32/comctl32/rebar.c
reactos/dll/win32/comctl32/theme_button.c
reactos/dll/win32/comctl32/theme_scrollbar.c
reactos/dll/win32/comctl32/toolbar.c
reactos/dll/win32/comctl32/tooltips.c
reactos/dll/win32/comctl32/treeview.c
reactos/dll/win32/comctl32/updown.c
reactos/media/doc/README.WINE

index 41b61c8..a55ea03 100644 (file)
@@ -1,6 +1,6 @@
-diff -pudN E:\wine\dlls\comctl32/commctrl.c E:\reactos\dll\win32\comctl32/commctrl.c
---- E:\wine\dlls\comctl32/commctrl.c   2015-02-21 17:13:08.585542200 +0100
-+++ E:\reactos\dll\win32\comctl32/commctrl.c   2015-03-18 17:10:39.955584600 +0100
+diff -pudN e:\wine\dlls\comctl32/commctrl.c e:\reactos\dll\win32\comctl32/commctrl.c
+--- e:\wine\dlls\comctl32/commctrl.c   2015-02-21 17:13:08.585542200 +0100
++++ e:\reactos\dll\win32\comctl32/commctrl.c   2015-03-18 17:10:39.955584600 +0100
 @@ -52,25 +52,26 @@
   *   -- ICC_WIN95_CLASSES
   */
@@ -258,9 +258,9 @@ diff -pudN E:\wine\dlls\comctl32/commctrl.c E:\reactos\dll\win32\comctl32/commct
 +              comctl32 classes are registered by this module anyway */
 +    return TRUE;
 +}
-diff -pudN E:\wine\dlls\comctl32/imagelist.c E:\reactos\dll\win32\comctl32/imagelist.c
---- E:\wine\dlls\comctl32/imagelist.c  2015-02-21 17:13:08.589542200 +0100
-+++ E:\reactos\dll\win32\comctl32/imagelist.c  2015-03-18 17:15:00.458921400 +0100
+diff -pudN e:\wine\dlls\comctl32/imagelist.c e:\reactos\dll\win32\comctl32/imagelist.c
+--- e:\wine\dlls\comctl32/imagelist.c  2015-02-21 17:13:08.589542200 +0100
++++ e:\reactos\dll\win32\comctl32/imagelist.c  2015-03-18 17:15:00.458921400 +0100
 @@ -33,27 +33,14 @@
   *
   *  TODO:
@@ -429,23 +429,24 @@ diff -pudN E:\wine\dlls\comctl32/imagelist.c E:\reactos\dll\win32\comctl32/image
      if (fState & ILS_GLOW) FIXME("ILS_GLOW: unimplemented!\n");
      if (fState & ILS_SHADOW) FIXME("ILS_SHADOW: unimplemented!\n");
  
-diff -pudN E:\wine\dlls\comctl32/listview.c E:\reactos\dll\win32\comctl32/listview.c
---- E:\wine\dlls\comctl32/listview.c   2015-02-21 17:13:08.593542200 +0100
-+++ E:\reactos\dll\win32\comctl32/listview.c   2015-03-18 17:19:17.656744600 +0100
-@@ -307,6 +288,7 @@ typedef struct tagLISTVIEW_INFO
+diff -pudN e:\wine\dlls\comctl32/listview.c e:\reactos\dll\win32\comctl32/listview.c
+--- e:\wine\dlls\comctl32/listview.c   2015-04-05 20:44:56.799078500 +0100
++++ e:\reactos\dll\win32\comctl32/listview.c   2015-07-20 23:15:49.816768600 +0100
+@@ -306,6 +287,9 @@ typedef struct tagLISTVIEW_INFO
    COLORREF clrBk;
    COLORREF clrText;
    COLORREF clrTextBk;
++#ifdef __REACTOS__
 +  BOOL bDefaultBkColor;
++#endif
  
    /* font */
    HFONT hDefaultFont;
-@@ -1699,8 +1681,19 @@ static inline BOOL LISTVIEW_GetItemW(con
+@@ -1698,8 +1682,24 @@ static inline BOOL LISTVIEW_GetItemW(con
  /* used to handle collapse main item column case */
  static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
  {
--    return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ?
--            DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE;
++#ifdef __REACTOS__
 +    BOOL Ret = FALSE;
 +
 +    if (infoPtr->rcFocus.left < infoPtr->rcFocus.right)
@@ -459,10 +460,14 @@ diff -pudN E:\wine\dlls\comctl32/listview.c E:\reactos\dll\win32\comctl32/listvi
 +        SetBkColor(hdc, dwOldTextColor);
 +    }
 +    return Ret;
++#else
+     return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ?
+             DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE;
++#endif
  }
  
  /* Listview invalidation functions: use _only_ these functions to invalidate */
-@@ -4669,7 +4662,12 @@ static void LISTVIEW_DrawItemPart(LISTVI
+@@ -4682,7 +4682,12 @@ static void LISTVIEW_DrawItemPart(LISTVI
      if (infoPtr->uView == LV_VIEW_DETAILS && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES)
          rcLabel.bottom--;
  
@@ -476,7 +481,7 @@ diff -pudN E:\wine\dlls\comctl32/listview.c E:\reactos\dll\win32\comctl32/listvi
  }
  
  /***
-@@ -5214,7 +5212,11 @@ enddraw:
+@@ -5228,7 +5233,11 @@ enddraw:
  
      /* Draw marquee rectangle if appropriate */
      if (infoPtr->bMarqueeSelect)
@@ -488,15 +493,17 @@ diff -pudN E:\wine\dlls\comctl32/listview.c E:\reactos\dll\win32\comctl32/listvi
  
      if (cdmode & CDRF_NOTIFYPOSTPAINT)
        notify_postpaint(infoPtr, &nmlvcd);
-@@ -8017,6 +8019,7 @@ static BOOL LISTVIEW_SetBkColor(LISTVIEW
+@@ -8024,6 +8033,9 @@ static BOOL LISTVIEW_SetBkColor(LISTVIEW
  {
      TRACE("(color=%x)\n", color);
  
++#ifdef __REACTOS__
 +    infoPtr->bDefaultBkColor = FALSE;
++#endif
      if(infoPtr->clrBk != color) {
        if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
        infoPtr->clrBk = color;
-@@ -8678,7 +8681,7 @@ static DWORD LISTVIEW_SetIconSpacing(LIS
+@@ -8702,7 +8714,7 @@ static DWORD LISTVIEW_SetIconSpacing(LIS
      return oldspacing;
  }
  
@@ -505,7 +512,7 @@ diff -pudN E:\wine\dlls\comctl32/listview.c E:\reactos\dll\win32\comctl32/listvi
  {
      INT cx, cy;
      
-@@ -8689,8 +8692,8 @@ static inline void set_icon_size(SIZE *s
+@@ -8713,8 +8725,8 @@ static inline void set_icon_size(SIZE *s
      }
      else
      {
@@ -516,30 +523,34 @@ diff -pudN E:\wine\dlls\comctl32/listview.c E:\reactos\dll\win32\comctl32/listvi
      }
  }
  
-@@ -9427,6 +9430,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hw
+@@ -9451,6 +9463,9 @@ static LRESULT LISTVIEW_NCCreate(HWND hw
    infoPtr->clrText = CLR_DEFAULT;
    infoPtr->clrTextBk = CLR_DEFAULT;
    LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
++#ifdef __REACTOS__
 +  infoPtr->bDefaultBkColor = TRUE;
++#endif
  
    /* set default values */
    infoPtr->nFocusedItem = -1;
-@@ -11709,6 +11713,12 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
+@@ -11735,6 +11750,14 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
  
    case WM_SYSCOLORCHANGE:
      COMCTL32_RefreshSysColors();
++#ifdef __REACTOS__
 +    if (infoPtr->bDefaultBkColor)
 +    {
 +        LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
 +        infoPtr->bDefaultBkColor = TRUE;
 +        LISTVIEW_InvalidateList(infoPtr);
 +    }
++#endif
      return 0;
  
  /*    case WM_TIMER: */
-diff -pudN E:\wine\dlls\comctl32/propsheet.c E:\reactos\dll\win32\comctl32/propsheet.c
---- E:\wine\dlls\comctl32/propsheet.c  2015-02-21 17:13:08.597542200 +0100
-+++ E:\reactos\dll\win32\comctl32/propsheet.c  2015-03-18 17:24:03.692899000 +0100
+diff -pudN e:\wine\dlls\comctl32/propsheet.c e:\reactos\dll\win32\comctl32/propsheet.c
+--- e:\wine\dlls\comctl32/propsheet.c  2015-03-21 14:04:47.573770300 +0100
++++ e:\reactos\dll\win32\comctl32/propsheet.c  2015-03-18 17:24:03.692899000 +0100
 @@ -2432,12 +2416,19 @@ static void PROPSHEET_SetWizButtons(HWND
    HWND hwndFinish = GetDlgItem(hwndDlg, IDC_FINISH_BUTTON);
    BOOL enable_finish = ((dwFlags & PSWIZB_FINISH) || psInfo->hasFinish) && !(dwFlags & PSWIZB_DISABLEDFINISH);
@@ -594,9 +605,9 @@ diff -pudN E:\wine\dlls\comctl32/propsheet.c E:\reactos\dll\win32\comctl32/props
  }
  
  /******************************************************************************
-diff -pudN E:\wine\dlls\comctl32/rebar.c E:\reactos\dll\win32\comctl32/rebar.c
---- E:\wine\dlls\comctl32/rebar.c      2015-02-21 17:13:08.597542200 +0100
-+++ E:\reactos\dll\win32\comctl32/rebar.c      2015-02-26 09:25:01.687100100 +0100
+diff -pudN e:\wine\dlls\comctl32/rebar.c e:\reactos\dll\win32\comctl32/rebar.c
+--- e:\wine\dlls\comctl32/rebar.c      2015-04-05 20:44:56.800079100 +0100
++++ e:\reactos\dll\win32\comctl32/rebar.c      2015-07-20 23:20:27.952677100 +0100
 @@ -50,7 +50,6 @@
   *   - WM_QUERYNEWPALETTE
   *   - WM_RBUTTONDOWN
@@ -605,78 +616,126 @@ diff -pudN E:\wine\dlls\comctl32/rebar.c E:\reactos\dll\win32\comctl32/rebar.c
   *   - WM_VKEYTOITEM
   *   - WM_WININICHANGE
   *   Notifications:
-@@ -1844,16 +1828,24 @@ static LRESULT REBAR_EraseBkGnd (const R
+@@ -1844,16 +1828,43 @@ static LRESULT REBAR_EraseBkGnd (const R
      RECT cr;
      COLORREF old = CLR_NONE, new;
      HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
++#ifdef __REACTOS__
 +    HRGN hrgn;
++#endif
  
      GetClientRect (infoPtr->hwndSelf, &cr);
-+    hrgn = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
  
++#ifdef __REACTOS__
++
++    if (theme)
++    {
++        if (IsThemeBackgroundPartiallyTransparent(theme, RP_BACKGROUND, 0))
++        {
++            DrawThemeParentBackground (infoPtr->hwndSelf, hdc, &cr);
++        }
++        DrawThemeBackground (theme, hdc, 0, 0, &cr, NULL);
++    }
++
++    hrgn = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
++
++#endif
++
      oldrow = -1;
      for(i=0; i<infoPtr->uNumBands; i++) {
          RECT rcBand;
++#ifdef __REACTOS__
 +        RECT rcBandReal;
 +        HRGN hrgnBand;
++#endif
 +
          lpBand = REBAR_GetBand(infoPtr, i);
-+
        if (HIDDENBAND(lpBand)) continue;
          translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
  
++#ifdef __REACTOS__
 +        rcBandReal = rcBand;
++#endif
 +
        /* draw band separator between rows */
        if (lpBand->iRow != oldrow) {
            oldrow = lpBand->iRow;
-@@ -1878,6 +1870,7 @@ static LRESULT REBAR_EraseBkGnd (const R
+@@ -1878,6 +1889,9 @@ static LRESULT REBAR_EraseBkGnd (const R
                }
                  TRACE ("drawing band separator bottom (%s)\n",
                         wine_dbgstr_rect(&rcRowSep));
++#ifdef __REACTOS__
 +        rcBandReal = rcRowSep;
++#endif
            }
        }
  
-@@ -1888,6 +1881,7 @@ static LRESULT REBAR_EraseBkGnd (const R
+@@ -1888,6 +1902,9 @@ static LRESULT REBAR_EraseBkGnd (const R
            if (infoPtr->dwStyle & CCS_VERT) {
                  rcSep.bottom = rcSep.top;
                rcSep.top -= SEP_WIDTH_SIZE;
++#ifdef __REACTOS__
 +        rcBandReal.top -= SEP_WIDTH_SIZE;
++#endif
                  if (theme)
                      DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_BOTTOM, NULL);
                  else
-@@ -1896,6 +1890,7 @@ static LRESULT REBAR_EraseBkGnd (const R
+@@ -1896,6 +1913,9 @@ static LRESULT REBAR_EraseBkGnd (const R
            else {
                  rcSep.right = rcSep.left;
                rcSep.left -= SEP_WIDTH_SIZE;
++#ifdef __REACTOS__
 +        rcBandReal.left -= SEP_WIDTH_SIZE;
++#endif
                  if (theme)
                      DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_RIGHT, NULL);
                  else
-@@ -1943,7 +1938,21 @@ static LRESULT REBAR_EraseBkGnd (const R
+@@ -1926,6 +1946,9 @@ static LRESULT REBAR_EraseBkGnd (const R
+ #endif
+       }
++#ifdef __REACTOS__
++        if (!theme)
++#else
+         if (theme)
+         {
+             /* When themed, the background color is ignored (but not a
+@@ -1933,6 +1956,7 @@ static LRESULT REBAR_EraseBkGnd (const R
+             DrawThemeBackground (theme, hdc, 0, 0, &cr, &rcBand);
+         }
+         else
++#endif
+         {
+             old = SetBkColor (hdc, new);
+             TRACE("%s background color=0x%06x, band %s\n",
+@@ -1943,7 +1967,26 @@ static LRESULT REBAR_EraseBkGnd (const R
              if (lpBand->clrBack != CLR_NONE)
                  SetBkColor (hdc, old);
          }
 +
++#ifdef __REACTOS__
 +        hrgnBand = CreateRectRgn(rcBandReal.left, rcBandReal.top, rcBandReal.right, rcBandReal.bottom);
 +        CombineRgn(hrgn, hrgn, hrgnBand, RGN_DIFF);
 +        DeleteObject(hrgnBand);
-     }
++#endif
++    }
 +
 +#if 1
++#ifdef __REACTOS__
++    if (!theme)
++#endif
 +    {
 +        //FIXME: Apparently painting the remaining area is a v6 feature
 +        HBRUSH hbrush = CreateSolidBrush(new);
 +        FillRgn(hdc, hrgn, hbrush);
 +        DeleteObject(hbrush);
 +        DeleteObject(hrgn);
-+    }
+     }
 +#endif
      return TRUE;
  }
  
-@@ -2912,12 +2921,22 @@ REBAR_ShowBand (REBAR_INFO *infoPtr, INT
+@@ -2912,12 +2955,22 @@ REBAR_ShowBand (REBAR_INFO *infoPtr, INT
  
  
  static LRESULT
@@ -700,7 +759,19 @@ diff -pudN E:\wine\dlls\comctl32/rebar.c E:\reactos\dll\win32\comctl32/rebar.c
      return TRUE;
  }
  
-@@ -3675,7 +3694,7 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, 
+@@ -3224,7 +3277,11 @@ REBAR_NCCalcSize (const REBAR_INFO *info
+     else if ((theme = GetWindowTheme (infoPtr->hwndSelf)))
+     {
+         /* FIXME: should use GetThemeInt */
++#ifdef __REACTOS__
++        rect->top = (rect->top + 1 < rect->bottom) ? rect->top : rect->bottom;
++#else
+         rect->top = min(rect->top + 1, rect->bottom);
++#endif
+     }
+     TRACE("new client=(%s)\n", wine_dbgstr_rect(rect));
+     return 0;
+@@ -3675,7 +3732,7 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, 
            return REBAR_ShowBand (infoPtr, wParam, lParam);
  
        case RB_SIZETORECT:
@@ -709,7 +780,7 @@ diff -pudN E:\wine\dlls\comctl32/rebar.c E:\reactos\dll\win32\comctl32/rebar.c
  
  
  /*    Messages passed to parent */
-@@ -3758,6 +3777,11 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, 
+@@ -3758,6 +3815,11 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, 
  
          case WM_SYSCOLORCHANGE:
              COMCTL32_RefreshSysColors();
@@ -721,9 +792,9 @@ diff -pudN E:\wine\dlls\comctl32/rebar.c E:\reactos\dll\win32\comctl32/rebar.c
              return 0;
  
  /*      case WM_VKEYTOITEM:     supported according to ControlSpy */
-diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar.c
---- E:\wine\dlls\comctl32/toolbar.c    2015-02-21 17:13:08.617542200 +0100
-+++ E:\reactos\dll\win32\comctl32/toolbar.c    2015-03-18 17:50:35.210152200 +0100
+diff -pudN e:\wine\dlls\comctl32/toolbar.c e:\reactos\dll\win32\comctl32/toolbar.c
+--- e:\wine\dlls\comctl32/toolbar.c    2015-07-14 15:44:33.982074600 +0100
++++ e:\reactos\dll\win32\comctl32/toolbar.c    2015-07-20 23:37:43.996935400 +0100
 @@ -33,11 +33,9 @@
   *     - TBSTYLE_REGISTERDROP
   *     - TBSTYLE_EX_DOUBLEBUFFER
@@ -736,16 +807,18 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
   *     - WM_WININICHANGE
   *   - Notifications:
   *     - NM_CHAR
-@@ -140,6 +124,8 @@ typedef struct
+@@ -139,6 +123,10 @@ typedef struct
      INT      nOldHit;
      INT      nHotItem;        /* index of the "hot" item */
      SIZE     szPadding;       /* padding values around button */
++#ifdef __REACTOS__
 +    SIZE     szBarPadding;       /* padding values around the toolbar (NOT USED BUT STORED) */
 +    SIZE     szSpacing;       /* spacing values between buttons */
++#endif
      INT      iTopMargin;      /* the top margin */
      INT      iListGap;        /* default gap between text and image for toolbar with list style */
      HFONT    hDefaultFont;
-@@ -205,12 +191,18 @@ typedef enum
+@@ -204,12 +192,24 @@ typedef enum
  #define ARROW_HEIGHT       3
  #define INSERTMARK_WIDTH   2
  
@@ -753,19 +826,24 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
  #define DEFPAD_CX 7
  #define DEFPAD_CY 6
 +
++#ifdef __REACTOS__
 +/* default space between buttons and between rows */
 +#define DEFSPACE_CX 7
 +#define DEFSPACE_CY 6
++#endif
 +
  #define DEFLISTGAP 4
  
  /* vertical padding used in list mode when image is present */
--#define LISTPAD_CY 9
++#ifdef __REACTOS__
 +#define LISTPAD_CY 2
++#else
+ #define LISTPAD_CY 9
++#endif
  
  /* how wide to treat the bitmap if it isn't present */
  #define NONLIST_NOTEXT_OFFSET 2
-@@ -252,7 +244,12 @@ static void TOOLBAR_TooltipSetRect(const
+@@ -253,7 +253,12 @@ static LRESULT TOOLBAR_SetButtonInfo(TOO
  
  static inline int default_top_margin(const TOOLBAR_INFO *infoPtr)
  {
@@ -778,7 +856,7 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
  }
  
  static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle)
-@@ -699,10 +696,12 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *in
+@@ -737,10 +742,14 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *in
                    const NMTBCUSTOMDRAW *tbcd, DWORD dwItemCDFlag)
  {
      HIMAGELIST himl = NULL;
@@ -787,17 +865,19 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
      INT index;
      INT offset = 0;
      UINT draw_flags = ILD_TRANSPARENT;
++#ifdef __REACTOS__
 +    IMAGEINFO info = {0};
 +    BITMAP bm = {0};
++#endif
  
      if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
      {
-@@ -710,7 +709,18 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *in
+@@ -748,7 +757,22 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *in
          if (!himl)
          {
              himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
--            draw_masked = TRUE;
 +
++#ifdef __REACTOS__
 +            ImageList_GetImageInfo(himl, index, &info);
 +            GetObjectW(info.hbmImage, sizeof(bm), &bm);
 +
@@ -809,10 +889,13 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
 +            {
 +                draw_masked = TRUE;
 +            }
++#else
+             draw_masked = TRUE;
++#endif
          }
      }
      else if (tbcd->nmcd.uItemState & CDIS_CHECKED ||
-@@ -741,9 +751,34 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *in
+@@ -779,9 +803,34 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *in
        index, himl, left, top, offset);
  
      if (draw_masked)
@@ -847,7 +930,7 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
  }
  
  /* draws a blank frame for a toolbar button */
-@@ -862,14 +897,15 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *
+@@ -898,14 +947,15 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *
                  InflateRect(&rcsep, -infoPtr->szPadding.cx, -infoPtr->szPadding.cy);
                  TOOLBAR_DrawFlatHorizontalSeparator (&rcsep, hdc, infoPtr);
              }
@@ -871,517 +954,64 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
      }
  
      /* get a pointer to the text */
-@@ -1289,11 +1325,11 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPt
-     /*        When the toolbar window style is not TBSTYLE_WRAPABLE,  */
-     /*        no layout is necessary. Applications may use this style */
-     /*        to perform their own layout on the toolbar.             */
--    if( !(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
--      !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL) )  return;
-+    if (!(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
-+        !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))  return;
-     btnPtr = infoPtr->buttons;
--    x  = infoPtr->nIndent;
-+    x = infoPtr->nIndent;
-     if (GetParent(infoPtr->hwndSelf))
-     {
-@@ -1301,144 +1337,145 @@ TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPt
-          * this toolbar.  We cannot use its height, as there may be multiple
-          * toolbars in a rebar control
-          */
--        GetClientRect( GetParent(infoPtr->hwndSelf), &rc );
-+        GetClientRect(GetParent(infoPtr->hwndSelf), &rc);
-         infoPtr->nWidth = rc.right - rc.left;
-     }
-     else
-     {
--        GetWindowRect( infoPtr->hwndSelf, &rc );
-+        GetWindowRect(infoPtr->hwndSelf, &rc);
-         infoPtr->nWidth = rc.right - rc.left;
+@@ -1042,7 +1092,11 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *
+         }
      }
  
-     bButtonWrap = FALSE;
-     TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
--        infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth,
--        infoPtr->nIndent);
-+          infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth,
-+          infoPtr->nIndent);
--    for (i = 0; i < infoPtr->nNumButtons; i++ )
-+    for (i = 0; i < infoPtr->nNumButtons; i++)
++#ifdef __REACTOS__
++    if (theme && !(dwItemCDFlag & TBCDRF_NOBACKGROUND))
++#else
+     if (theme)
++#endif
      {
--      btnPtr[i].fsState &= ~TBSTATE_WRAP;
-+        btnPtr[i].fsState &= ~TBSTATE_WRAP;
--      if (btnPtr[i].fsState & TBSTATE_HIDDEN)
--          continue;
-+        if (btnPtr[i].fsState & TBSTATE_HIDDEN)
-+            continue;
-         if (btnPtr[i].cx > 0)
-             cx = btnPtr[i].cx;
-         /* horizontal separators are treated as buttons for width    */
--      else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
--            !(infoPtr->dwStyle & CCS_VERT))
-+        else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
-+                 !(infoPtr->dwStyle & CCS_VERT))
-             cx = (btnPtr[i].iBitmap > 0) ? btnPtr[i].iBitmap : SEPARATOR_WIDTH;
--      else
--          cx = infoPtr->nButtonWidth;
-+        else
-+            cx = infoPtr->nButtonWidth;
--      /* Two or more adjacent separators form a separator group.   */
--      /* The first separator in a group should be wrapped to the   */
--      /* next row if the previous wrapping is on a button.         */
--      if( bButtonWrap &&
--              (btnPtr[i].fsStyle & BTNS_SEP) &&
--              (i + 1 < infoPtr->nNumButtons ) &&
--              (btnPtr[i + 1].fsStyle & BTNS_SEP) )
--      {
--          TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
--          btnPtr[i].fsState |= TBSTATE_WRAP;
--          x = infoPtr->nIndent;
--          i++;
--          bButtonWrap = FALSE;
--          continue;
--      }
-+        /* Two or more adjacent separators form a separator group.   */
-+        /* The first separator in a group should be wrapped to the   */
-+        /* next row if the previous wrapping is on a button.       */
-+        if (bButtonWrap &&
-+            (btnPtr[i].fsStyle & BTNS_SEP) &&
-+            (i + 1 < infoPtr->nNumButtons) &&
-+            (btnPtr[i + 1].fsStyle & BTNS_SEP))
-+        {
-+            TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
-+            btnPtr[i].fsState |= TBSTATE_WRAP;
-+            x = infoPtr->nIndent;
-+            i++;
-+            bButtonWrap = FALSE;
-+            continue;
-+        }
--      /* The layout makes sure the bitmap is visible, but not the button. */
--      /* Test added to also wrap after a button that starts a row but     */
--      /* is bigger than the area.  - GA  8/01                             */
--      if (( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
--         > infoPtr->nWidth ) ||
--          ((x == infoPtr->nIndent) && (cx > infoPtr->nWidth)))
--      {
--          BOOL bFound = FALSE;
-+        /* The layout makes sure the bitmap is visible, but not the button. */
-+        /* Test added to also wrap after a button that starts a row but     */
-+        /* is bigger than the area.  - GA  8/01                             */
-+        if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
-+            > infoPtr->nWidth) ||
-+            ((x == infoPtr->nIndent) && (cx > infoPtr->nWidth)))
-+        {
-+            BOOL bFound = FALSE;
--          /*  If the current button is a separator and not hidden,  */
--          /*  go to the next until it reaches a non separator.      */
--          /*  Wrap the last separator if it is before a button.     */
--          while( ( ((btnPtr[i].fsStyle & BTNS_SEP) &&
--                    !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
--                   (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
--                      i < infoPtr->nNumButtons )
--          {
--              i++;
--              bFound = TRUE;
--          }
-+            /*        If the current button is a separator and not hidden,  */
-+            /*        go to the next until it reaches a non separator.      */
-+            /*        Wrap the last separator if it is before a button.     */
-+            while ((((btnPtr[i].fsStyle & BTNS_SEP) &&
-+                !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
-+                (btnPtr[i].fsState & TBSTATE_HIDDEN)) &&
-+                i < infoPtr->nNumButtons)
-+            {
-+                i++;
-+                bFound = TRUE;
-+            }
--          if( bFound && i < infoPtr->nNumButtons )
--          {
--              i--;
--              TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
--                    i, btnPtr[i].fsStyle, x, cx);
--              btnPtr[i].fsState |= TBSTATE_WRAP;
--              x = infoPtr->nIndent;
--              bButtonWrap = FALSE;
--              continue;
--          }
--          else if ( i >= infoPtr->nNumButtons)
--              break;
-+            if (bFound && i < infoPtr->nNumButtons)
-+            {
-+                i--;
-+                TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
-+                      i, btnPtr[i].fsStyle, x, cx);
-+                btnPtr[i].fsState |= TBSTATE_WRAP;
-+                x = infoPtr->nIndent;
-+                bButtonWrap = FALSE;
-+                continue;
-+            }
-+            else if (i >= infoPtr->nNumButtons)
-+                break;
--          /*  If the current button is not a separator, find the last  */
--          /*  separator and wrap it.                                   */
--          for ( j = i - 1; j >= 0  &&  !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
--          {
--              if ((btnPtr[j].fsStyle & BTNS_SEP) &&
--                      !(btnPtr[j].fsState & TBSTATE_HIDDEN))
--              {
--                  bFound = TRUE;
--                  i = j;
--                  TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
--                        i, btnPtr[i].fsStyle, x, cx);
--                  x = infoPtr->nIndent;
--                  btnPtr[j].fsState |= TBSTATE_WRAP;
--                  bButtonWrap = FALSE;
--                  break;
--              }
--          }
-+            /*        If the current button is not a separator, find the last  */
-+            /*        separator and wrap it.                                   */
-+            for (j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
-+            {
-+                if ((btnPtr[j].fsStyle & BTNS_SEP) &&
-+                    !(btnPtr[j].fsState & TBSTATE_HIDDEN))
-+                {
-+                    bFound = TRUE;
-+                    i = j;
-+                    TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
-+                          i, btnPtr[i].fsStyle, x, cx);
-+                    x = infoPtr->nIndent;
-+                    btnPtr[j].fsState |= TBSTATE_WRAP;
-+                    bButtonWrap = FALSE;
-+                    break;
-+                }
-+            }
--          /*  If no separator available for wrapping, wrap one of     */
--          /*  non-hidden previous button.                             */
--          if (!bFound)
--          {
--              for ( j = i - 1;
--                      j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
--              {
--                  if (btnPtr[j].fsState & TBSTATE_HIDDEN)
--                      continue;
-+            /*        If no separator available for wrapping, wrap one of     */
-+            /*  non-hidden previous button.                           */
-+            if (!bFound)
-+            {
-+                for (j = i - 1;
-+                     j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
-+                {
-+                    if (btnPtr[j].fsState & TBSTATE_HIDDEN)
-+                        continue;
--                  bFound = TRUE;
--                  i = j;
--                  TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
--                        i, btnPtr[i].fsStyle, x, cx);
--                  x = infoPtr->nIndent;
--                  btnPtr[j].fsState |= TBSTATE_WRAP;
--                  bButtonWrap = TRUE;
--                  break;
--              }
--          }
-+                    bFound = TRUE;
-+                    i = j;
-+                    TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
-+                          i, btnPtr[i].fsStyle, x, cx);
-+                    x = infoPtr->nIndent;
-+                    btnPtr[j].fsState |= TBSTATE_WRAP;
-+                    bButtonWrap = TRUE;
-+                    break;
-+                }
-+            }
--          /* If all above failed, wrap the current button. */
--          if (!bFound)
--          {
--              TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
--                    i, btnPtr[i].fsStyle, x, cx);
--              btnPtr[i].fsState |= TBSTATE_WRAP;
--              x = infoPtr->nIndent;
--              if (btnPtr[i].fsStyle & BTNS_SEP )
--                  bButtonWrap = FALSE;
--              else
--                  bButtonWrap = TRUE;
--          }
--      }
--      else {
--          TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
--                i, btnPtr[i].fsStyle, x, cx);
--          x += cx;
--      }
-+            /* If all above failed, wrap the current button. */
-+            if (!bFound)
-+            {
-+                TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
-+                      i, btnPtr[i].fsStyle, x, cx);
-+                btnPtr[i].fsState |= TBSTATE_WRAP;
-+                x = infoPtr->nIndent;
-+                if (btnPtr[i].fsStyle & BTNS_SEP)
-+                    bButtonWrap = FALSE;
-+                else
-+                    bButtonWrap = TRUE;
-+            }
-+        }
-+        else
-+        {
-+            TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
-+                  i, btnPtr[i].fsStyle, x, cx);
-+            x += cx;
-+        }
+         int partId = drawSepDropDownArrow ? TP_SPLITBUTTON : TP_BUTTON;
+         int stateId = TS_NORMAL;
+@@ -1059,7 +1113,12 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *
+             
+         DrawThemeBackground (theme, hdc, partId, stateId, &rc, NULL);
      }
- }
++
++#ifdef __REACTOS__
++    if (!theme)
++#else
+     else
++#endif
+         TOOLBAR_DrawFrame(infoPtr, &tbcd, &rc, dwItemCDFlag);
  
-@@ -1564,9 +1601,8 @@ static inline SIZE TOOLBAR_MeasureButton
+     if (drawSepDropDownArrow)
+@@ -1587,9 +1646,14 @@ static inline SIZE TOOLBAR_MeasureButton
          /* ... add on the necessary padding */
          if (bValidImageList)
          {
--            if (bHasBitmap)
--                sizeButton.cy += DEFPAD_CY;
--            else
++#ifdef __REACTOS__
 +            sizeButton.cy += infoPtr->szPadding.cy;
 +            if (!bHasBitmap)
++#else
+             if (bHasBitmap)
+                 sizeButton.cy += DEFPAD_CY;
+             else
++#endif
                  sizeButton.cy += LISTPAD_CY;
          }
          else
-@@ -1583,7 +1619,7 @@ static inline SIZE TOOLBAR_MeasureButton
+@@ -1606,7 +1670,11 @@ static inline SIZE TOOLBAR_MeasureButton
      {
          if (bHasBitmap)
          {
--            sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY;
++#ifdef __REACTOS__
 +            sizeButton.cy = infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
++#else
+             sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY;
++#endif
              if (sizeString.cy > 0)
                  sizeButton.cy += 1 + sizeString.cy;
              sizeButton.cx = infoPtr->szPadding.cx +
-@@ -1640,17 +1676,17 @@ static void
- TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
- {
-     TBUTTON_INFO *btnPtr;
--    SIZE sizeButton;
--    INT i, nRows, nSepRows;
--    INT x, y, cx, cy;
--    BOOL bWrap;
--    BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0);
--    BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
-+    SIZE          sizeButton;
-+    INT           i, nRows, nSepRows;
-+    INT           x, y, cx, cy;
-+    BOOL          bWrap;
-+    BOOL          validImageList    = TOOLBAR_IsValidImageList(infoPtr, 0);
-+    BOOL          hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
-     TOOLBAR_WrapToolbar(infoPtr);
--    x  = infoPtr->nIndent;
--    y  = infoPtr->iTopMargin;
-+    x = infoPtr->nIndent;
-+    y = infoPtr->iTopMargin;
-     cx = infoPtr->nButtonWidth;
-     cy = infoPtr->nButtonHeight;
-@@ -1665,106 +1701,112 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *info
-     TRACE("cy=%d\n", cy);
--    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
-+    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
-     {
--      bWrap = FALSE;
--      if (btnPtr->fsState & TBSTATE_HIDDEN)
--      {
--          SetRectEmpty (&btnPtr->rect);
--          continue;
--      }
-+        bWrap = FALSE;
-+        if (btnPtr->fsState & TBSTATE_HIDDEN)
-+        {
-+            SetRectEmpty(&btnPtr->rect);
-+            continue;
-+        }
--      cy = infoPtr->nButtonHeight;
-+        cy = infoPtr->nButtonHeight;
--      if (btnPtr->fsStyle & BTNS_SEP) {
--          if (infoPtr->dwStyle & CCS_VERT) {
-+        if (btnPtr->fsStyle & BTNS_SEP)
-+        {
-+            if (infoPtr->dwStyle & CCS_VERT)
-+            {
-                 cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
-                 cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth;
--          }
--          else
-+            }
-+            else
-+            {
-                 cx = (btnPtr->cx > 0) ? btnPtr->cx :
-                     (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
--      }
--      else
--      {
-+            }
-+        }
-+        else
-+        {
-             if (btnPtr->cx)
--              cx = btnPtr->cx;
--            else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || 
--                (btnPtr->fsStyle & BTNS_AUTOSIZE))
-             {
--              SIZE sz;
--            HDC hdc;
--            HFONT hOldFont;
-+                cx = btnPtr->cx;
-+            }
-+            else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
-+                     (btnPtr->fsStyle & BTNS_AUTOSIZE))
-+            {
-+                SIZE sz;
-+                HDC hdc;
-+                HFONT hOldFont;
--            hdc = GetDC (infoPtr->hwndSelf);
--            hOldFont = SelectObject (hdc, infoPtr->hFont);
-+                hdc = GetDC(infoPtr->hwndSelf);
-+                hOldFont = SelectObject(hdc, infoPtr->hFont);
--              TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
-+                TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
--            SelectObject (hdc, hOldFont);
--            ReleaseDC (infoPtr->hwndSelf, hdc);
-+                SelectObject(hdc, hOldFont);
-+                ReleaseDC(infoPtr->hwndSelf, hdc);
--              sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
--                  TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
--                  validImageList);
--              cx = sizeButton.cx;
-+                sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
-+                                                   TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
-+                                                   validImageList);
-+                cx = sizeButton.cx;
-             }
-             else
--            cx = infoPtr->nButtonWidth;
-+                cx = infoPtr->nButtonWidth;
-             /* if size has been set manually then don't add on extra space
-              * for the drop down arrow */
--          if (!btnPtr->cx && hasDropDownArrows && 
-+            if (!btnPtr->cx && hasDropDownArrows &&
-                 ((btnPtr->fsStyle & BTNS_DROPDOWN) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN)))
--            cx += DDARROW_WIDTH;
--      }
--      if (btnPtr->fsState & TBSTATE_WRAP )
--                  bWrap = TRUE;
-+                cx += DDARROW_WIDTH;
-+        }
-+        if (btnPtr->fsState & TBSTATE_WRAP)
-+            bWrap = TRUE;
--      SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
-+        SetRect(&btnPtr->rect, x, y, x + cx, y + cy);
--      if (infoPtr->rcBound.left > x)
--          infoPtr->rcBound.left = x;
--      if (infoPtr->rcBound.right < x + cx)
--          infoPtr->rcBound.right = x + cx;
--      if (infoPtr->rcBound.bottom < y + cy)
--          infoPtr->rcBound.bottom = y + cy;
-+        if (infoPtr->rcBound.left > x)
-+            infoPtr->rcBound.left = x;
-+        if (infoPtr->rcBound.right < x + cx)
-+            infoPtr->rcBound.right = x + cx;
-+        if (infoPtr->rcBound.bottom < y + cy)
-+            infoPtr->rcBound.bottom = y + cy;
-         TOOLBAR_TooltipSetRect(infoPtr, btnPtr);
--      /* btnPtr->nRow is zero based. The space between the rows is    */
--      /* also considered as a row.                                    */
--      btnPtr->nRow = nRows + nSepRows;
-+        /* btnPtr->nRow is zero based. The space between the rows is  */
-+        /* also considered as a row.                                  */
-+        btnPtr->nRow = nRows + nSepRows;
--      TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n",
--            i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow,
--            x, y, x+cx, y+cy);
-+        TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n",
-+              i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow,
-+              x, y, x + cx, y + cy);
--      if( bWrap )
--      {
--          if ( !(btnPtr->fsStyle & BTNS_SEP) )
--              y += cy;
--          else
--          {
--               if ( !(infoPtr->dwStyle & CCS_VERT))
--                    y += cy + ( (btnPtr->cx > 0 ) ?
--                                btnPtr->cx : SEPARATOR_WIDTH) * 2 /3;
--              else
--                  y += cy;
-+        if (bWrap)
-+        {
-+            if (!(btnPtr->fsStyle & BTNS_SEP))
-+                y += cy;
-+            else
-+            {
-+                if (!(infoPtr->dwStyle & CCS_VERT))
-+                    y += cy + ((btnPtr->cx > 0) ?
-+                    btnPtr->cx : SEPARATOR_WIDTH) * 2 / 3;
-+                else
-+                    y += cy;
--              /* nSepRows is used to calculate the extra height following  */
--              /* the last row.                                             */
--              nSepRows++;
--          }
--          x = infoPtr->nIndent;
-+                /* nSepRows is used to calculate the extra height following  */
-+                /* the last row.                                           */
-+                nSepRows++;
-+            }
-+            x = infoPtr->nIndent;
--          /* Increment row number unless this is the last button    */
--          /* and it has Wrap set.                                   */
--          if (i != infoPtr->nNumButtons-1)
--              nRows++;
--      }
--      else
--          x += cx;
-+            /* Increment row number unless this is the last button    */
-+            /* and it has Wrap set.                                   */
-+            if (i != infoPtr->nNumButtons - 1)
-+                nRows++;
-+        }
-+        else
-+            x += cx;
-     }
-     /* infoPtr->nRows is the number of rows on the toolbar */
-@@ -1954,6 +1996,16 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND h
+@@ -1970,6 +2038,17 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND h
      SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
  }
  
-+
-+static LRESULT 
++#ifdef __REACTOS__
++static LRESULT
 +TOOLBAR_ThemeChanged(HWND hwnd)
 +{
 +    HTHEME theme = GetWindowTheme(hwnd);
@@ -1389,16 +1019,18 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
 +    OpenThemeData(hwnd, themeClass);
 +    return 0;
 +}
++#endif
 +
  static void
  TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
  {
-@@ -3543,6 +3595,36 @@ TOOLBAR_GetMaxSize (const TOOLBAR_INFO *
+@@ -3551,6 +3630,36 @@ TOOLBAR_GetMaxSize (const TOOLBAR_INFO *
+     return TRUE;
  }
  
++#ifdef __REACTOS__
 +static LRESULT
-+TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
++TOOLBAR_GetMetrics(const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
 +{
 +    if (pMetrics == NULL)
 +        return FALSE;
@@ -1425,17 +1057,17 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
 +
 +    return TRUE;
 +}
-+
-+
- /* << TOOLBAR_GetObject >> */
++#endif
  
+ /* << TOOLBAR_GetObject >> */
  
-@@ -4724,6 +4806,43 @@ TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *in
+@@ -4806,6 +4915,44 @@ TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *in
+     return TRUE;
  }
  
++#ifdef __REACTOS__
 +static LRESULT
-+TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
++TOOLBAR_SetMetrics(TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
 +{
 +    BOOL changed = FALSE;
 +
@@ -1470,11 +1102,11 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
 +
 +    return TRUE;
 +}
-+
++#endif
  /* MSDN gives slightly wrong info on padding.
   * 1. It is not only used on buttons with the BTNS_AUTOSIZE style
-  * 2. It is not used to create a blank area between the edge of the button
-@@ -5937,6 +6056,8 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wPar
+@@ -6052,6 +6199,8 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wPar
      infoPtr->clrBtnShadow = CLR_DEFAULT;
      infoPtr->szPadding.cx = DEFPAD_CX;
      infoPtr->szPadding.cy = DEFPAD_CY;
@@ -1483,80 +1115,69 @@ diff -pudN E:\wine\dlls\comctl32/toolbar.c E:\reactos\dll\win32\comctl32/toolbar
      infoPtr->iListGap = DEFLISTGAP;
      infoPtr->iTopMargin = default_top_margin(infoPtr);
      infoPtr->dwStyle = lpcs->style;
-@@ -6370,16 +6491,6 @@ TOOLBAR_SysColorChange (void)
+@@ -6461,7 +6610,7 @@ TOOLBAR_SysColorChange (void)
+     return 0;
  }
  
--/* update theme after a WM_THEMECHANGED message */
--static LRESULT theme_changed (HWND hwnd)
--{
--    HTHEME theme = GetWindowTheme (hwnd);
--    CloseThemeData (theme);
--    OpenThemeData (hwnd, themeClass);
--    return 0;
--}
 -
++#ifndef __REACTOS__
+ /* update theme after a WM_THEMECHANGED message */
+ static LRESULT theme_changed (HWND hwnd)
+ {
+@@ -6470,7 +6619,7 @@ static LRESULT theme_changed (HWND hwnd)
+     OpenThemeData (hwnd, themeClass);
+     return 0;
+ }
 -
++#endif
  static LRESULT WINAPI
  ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
-@@ -6483,6 +6594,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
+@@ -6575,6 +6724,10 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
  
        case TB_GETMAXSIZE:
            return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam);
-+        
++#ifdef __REACTOS__
 +      case TB_GETMETRICS:
 +          return TOOLBAR_GetMetrics (infoPtr, (TBMETRICS*)lParam);
++#endif
  
  /*    case TB_GETOBJECT:                      */ /* 4.71 */
  
-@@ -6499,7 +6613,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
-           return TOOLBAR_GetState (infoPtr, wParam);
-       case TB_GETSTRINGA:
--            return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam);
-+        return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam);
-       case TB_GETSTRINGW:
-           return TOOLBAR_GetStringW (infoPtr, wParam, (LPWSTR)lParam);
-@@ -6624,6 +6738,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
+@@ -6716,6 +6869,11 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
        case TB_SETMAXTEXTROWS:
            return TOOLBAR_SetMaxTextRows (infoPtr, wParam);
  
++#ifdef __REACTOS__
 +      case TB_SETMETRICS:
 +          return TOOLBAR_SetMetrics (infoPtr, (TBMETRICS*)lParam);
++#endif
 +
        case TB_SETPADDING:
            return TOOLBAR_SetPadding (infoPtr, lParam);
  
-@@ -6749,7 +6866,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
-           return TOOLBAR_SetFocus (infoPtr);
-       case WM_SETFONT:
--            return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);
-+        return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);
-       case WM_SETREDRAW:
-           return TOOLBAR_SetRedraw (infoPtr, wParam);
-@@ -6763,8 +6880,8 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
+@@ -6855,8 +7013,12 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg,
        case WM_SYSCOLORCHANGE:
            return TOOLBAR_SysColorChange ();
              
 -        case WM_THEMECHANGED:
--            return theme_changed (hwnd);
 +    case WM_THEMECHANGED:
++#ifdef __REACTOS__
 +        return TOOLBAR_ThemeChanged(hwnd);
++#else
+             return theme_changed (hwnd);
++#endif
  
  /*    case WM_WININICHANGE: */
  
-diff -pudN E:\wine\dlls\comctl32/tooltips.c E:\reactos\dll\win32\comctl32/tooltips.c
---- E:\wine\dlls\comctl32/tooltips.c   2015-02-21 17:13:08.617542200 +0100
-+++ E:\reactos\dll\win32\comctl32/tooltips.c   2015-03-18 18:00:07.323512400 +0100
-@@ -2007,7 +1994,32 @@ TOOLTIPS_NCHitTest (const TOOLTIPS_INFO 
+diff -pudN e:\wine\dlls\comctl32/tooltips.c e:\reactos\dll\win32\comctl32/tooltips.c
+--- e:\wine\dlls\comctl32/tooltips.c   2015-05-25 19:35:12.759980900 +0100
++++ e:\reactos\dll\win32\comctl32/tooltips.c   2015-07-20 23:40:13.399480800 +0100
+@@ -2009,7 +1996,36 @@ TOOLTIPS_NCHitTest (const TOOLTIPS_INFO 
  static LRESULT
  TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
  {
--    FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
++#ifdef __REACTOS__
 +    TTTOOL_INFO *toolPtr = infoPtr->tools;
 +    LRESULT nResult;
 +
@@ -1583,23 +1204,27 @@ diff -pudN E:\wine\dlls\comctl32/tooltips.c E:\reactos\dll\win32\comctl32/toolti
 +        }
 +        return nResult;
 +    }
++#else
+     FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
++#endif
  
      return 0;
  }
-diff -pudN E:\wine\dlls\comctl32/treeview.c E:\reactos\dll\win32\comctl32/treeview.c
---- E:\wine\dlls\comctl32/treeview.c   2015-02-21 17:13:08.621542200 +0100
-+++ E:\reactos\dll\win32\comctl32/treeview.c   2014-09-27 00:41:17.418102200 +0100
-@@ -2890,7 +2868,12 @@ TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr,
+diff -pudN e:\wine\dlls\comctl32/treeview.c e:\reactos\dll\win32\comctl32/treeview.c
+--- e:\wine\dlls\comctl32/treeview.c   2015-07-14 15:44:33.989075000 +0100
++++ e:\reactos\dll\win32\comctl32/treeview.c   2015-07-20 23:42:19.453690600 +0100
+@@ -2890,7 +2868,14 @@ TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr,
        }
      }
  
--    TREEVIEW_UpdateScrollBars(infoPtr);
 +    //
-+    // This is correct, but is causes and infinite loop of WM_PAINT messages, resulting
-+    // in continuous painting of the scroll bar in reactos. Comment out until the real
-+    // bug is found
-+    // 
-+    //TREEVIEW_UpdateScrollBars(infoPtr);
++    // FIXME: This is correct, but is causes and infinite loop of WM_PAINT
++    // messages, resulting in continuous painting of the scroll bar in reactos.
++    // Comment out until the real bug is found
++    //
++#ifndef __REACTOS__
+     TREEVIEW_UpdateScrollBars(infoPtr);
++#endif
  
      if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
        infoPtr->cdmode =
index dc0d170..72a6435 100644 (file)
@@ -426,3 +426,59 @@ void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
     DSA_EnumCallback (hdsa, enumProc, lParam);
     DSA_Destroy (hdsa);
 }
+
+/**************************************************************************
+ * DSA_Clone [COMCTL32.@]
+ *
+ * Creates a copy of a dsa
+ *
+ * PARAMS
+ *     hdsa [I] handle to the dynamic storage array
+ *
+ * RETURNS
+ *     Cloned dsa
+ */
+HDSA WINAPI DSA_Clone(HDSA hdsa)
+{
+    HDSA dest;
+    INT i;
+
+    TRACE("(%p)\n", hdsa);
+
+    if (!hdsa)
+        return NULL;
+
+    dest = DSA_Create (hdsa->nItemSize, hdsa->nGrow);
+    if (!dest)
+        return NULL;
+
+    for (i = 0; i < hdsa->nItemCount; i++) {
+        void *ptr = DSA_GetItemPtr (hdsa, i);
+        if (DSA_InsertItem (dest, DA_LAST, ptr) == -1) {
+            DSA_Destroy (dest);
+            return NULL;
+        }
+    }
+
+    return dest;
+}
+
+/**************************************************************************
+ * DSA_GetSize [COMCTL32.@]
+ *
+ * Returns allocated memory size for this array
+ *
+ * PARAMS
+ *     hdsa [I] handle to the dynamic storage array
+ *
+ * RETURNS
+ *     Size
+ */
+ULONGLONG WINAPI DSA_GetSize(HDSA hdsa)
+{
+    TRACE("(%p)\n", hdsa);
+
+    if (!hdsa) return 0;
+
+    return sizeof(*hdsa) + (ULONGLONG)hdsa->nMaxCount*hdsa->nItemSize;
+}
index 5aed8a2..9dd7943 100644 (file)
@@ -55,7 +55,7 @@ typedef struct
 BOOL WINAPI InitializeFlatSB(HWND hwnd)
 {
     TRACE("[%p]\n", hwnd);
-    return FALSE;
+    return TRUE;
 }
 
 /***********************************************************************
index 50733fb..0502a3e 100644 (file)
@@ -319,6 +319,7 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
     INT  oldBkMode;
     HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
     NMCUSTOMDRAW nmcd;
+    int state = 0;
 
     TRACE("DrawItem(iItem %d bHotTrack %d unicode flag %d)\n", iItem, bHotTrack, (infoPtr->nNotifyFormat == NFR_UNICODE));
 
@@ -326,6 +327,9 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
     if (r.right - r.left == 0)
        return phdi->rect.right;
 
+    if (theme)
+        state = (phdi->bDown) ? HIS_PRESSED : (bHotTrack ? HIS_HOT : HIS_NORMAL);
+
     /* Set the colors before sending NM_CUSTOMDRAW so that it can change them */
     SetTextColor(hdc, (bHotTrack && !theme) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
     SetBkColor(hdc, comctl32_color.clr3dFace);
@@ -404,8 +408,14 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
            RECT textRect;
 
             SetRectEmpty(&textRect);
-           DrawTextW (hdc, phdi->pszText, -1,
-                      &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
+
+           if (theme) {
+               GetThemeTextExtent(theme, hdc, HP_HEADERITEM, state, phdi->pszText, -1,
+                   DT_LEFT|DT_VCENTER|DT_SINGLELINE, NULL, &textRect);
+           } else {
+               DrawTextW (hdc, phdi->pszText, -1,
+                       &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
+           }
            cw = textRect.right - textRect.left + 2 * infoPtr->iMargin;
        }
 
@@ -498,8 +508,14 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
            oldBkMode = SetBkMode(hdc, TRANSPARENT);
            r.left  = tx;
            r.right = tx + tw;
-           DrawTextW (hdc, phdi->pszText, -1,
-                      &r, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE);
+           if (theme) {
+               DrawThemeText(theme, hdc, HP_HEADERITEM, state, phdi->pszText,
+                           -1, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE,
+                           0, &r);
+           } else {
+               DrawTextW (hdc, phdi->pszText, -1,
+                       &r, DT_LEFT|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE);
+           }
            if (oldBkMode != TRANSPARENT)
                SetBkMode(hdc, oldBkMode);
         }
index e28f418..a1de8a6 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright 2000 Jason Mawdsley
  * Copyright 2001 CodeWeavers Inc.
  * Copyright 2002 Dimitrie O. Paun
- * Copyright 2009-2014 Nikolay Sivov
+ * Copyright 2009-2015 Nikolay Sivov
  * Copyright 2009 Owen Rudge for CodeWeavers
  * Copyright 2012-2013 Daniel Jelinski
  *
@@ -54,7 +54,6 @@
  *   -- Support CustomDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs).
  *   -- LVA_SNAPTOGRID not implemented
  *   -- LISTVIEW_ApproximateViewRect partially implemented
- *   -- LISTVIEW_SetColumnWidth ignores header images & bitmap
  *   -- LISTVIEW_StyleChanged doesn't handle some changes too well
  *
  * Speedups
@@ -288,7 +287,9 @@ typedef struct tagLISTVIEW_INFO
   COLORREF clrBk;
   COLORREF clrText;
   COLORREF clrTextBk;
+#ifdef __REACTOS__
   BOOL bDefaultBkColor;
+#endif
 
   /* font */
   HFONT hDefaultFont;
@@ -1681,6 +1682,7 @@ static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpL
 /* used to handle collapse main item column case */
 static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
 {
+#ifdef __REACTOS__
     BOOL Ret = FALSE;
 
     if (infoPtr->rcFocus.left < infoPtr->rcFocus.right)
@@ -1694,6 +1696,10 @@ static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
         SetBkColor(hdc, dwOldTextColor);
     }
     return Ret;
+#else
+    return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ?
+            DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE;
+#endif
 }
 
 /* Listview invalidation functions: use _only_ these functions to invalidate */
@@ -4543,6 +4549,7 @@ static inline BOOL LISTVIEW_FillBkgnd(const LISTVIEW_INFO *infoPtr, HDC hdc, con
 static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const NMLVCUSTOMDRAW *nmlvcd, const POINT *pos)
 {
     RECT rcSelect, rcLabel, rcBox, rcStateIcon, rcIcon;
+    const RECT *background;
     HIMAGELIST himl;
     UINT format;
     RECT *focus;
@@ -4557,13 +4564,22 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N
     OffsetRect(&rcIcon, pos->x, pos->y);
     OffsetRect(&rcStateIcon, pos->x, pos->y);
     OffsetRect(&rcLabel, pos->x, pos->y);
-    TRACE("    rcBox=%s, rcSelect=%s, rcIcon=%s. rcLabel=%s\n",
+    TRACE("%d: box=%s, select=%s, icon=%s. label=%s\n", item->iSubItem,
         wine_dbgstr_rect(&rcBox), wine_dbgstr_rect(&rcSelect),
         wine_dbgstr_rect(&rcIcon), wine_dbgstr_rect(&rcLabel));
 
     /* FIXME: temporary hack */
     rcSelect.left = rcLabel.left;
 
+    if (infoPtr->uView == LV_VIEW_DETAILS && item->iSubItem == 0)
+    {
+        if (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
+            OffsetRect(&rcSelect, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
+        OffsetRect(&rcIcon, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
+        OffsetRect(&rcStateIcon, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
+        OffsetRect(&rcLabel, LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left, 0);
+    }
+
     /* in icon mode, the label rect is really what we want to draw the
      * background for */
     /* in detail mode, we want to paint background for label rect when
@@ -4572,37 +4588,41 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N
     if ( infoPtr->uView == LV_VIEW_ICON ||
         (infoPtr->uView == LV_VIEW_DETAILS && (!(item->state & LVIS_SELECTED) ||
         (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))))
-        rcSelect = rcLabel;
+        background = &rcLabel;
+    else
+        background = &rcSelect;
 
     if (nmlvcd->clrTextBk != CLR_NONE)
-        ExtTextOutW(nmlvcd->nmcd.hdc, rcSelect.left, rcSelect.top, ETO_OPAQUE, &rcSelect, NULL, 0, NULL);
+        ExtTextOutW(nmlvcd->nmcd.hdc, background->left, background->top, ETO_OPAQUE, background, NULL, 0, NULL);
 
     if (item->state & LVIS_FOCUSED)
     {
-       if (infoPtr->uView == LV_VIEW_DETAILS && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
-       {
-           /* we have to update left focus bound too if item isn't in leftmost column
-              and reduce right box bound */
-           if (DPA_GetPtrCount(infoPtr->hdpaColumns) > 0)
-           {
-               INT leftmost;
-
-               if ((leftmost = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, 0, 0)))
-               {
-                   INT Originx = pos->x - LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left;
-                   INT index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX,
-                               DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0);
-
-                   rcBox.right   = LISTVIEW_GetColumnInfo(infoPtr, index)->rcHeader.right + Originx;
-                   rcSelect.left = LISTVIEW_GetColumnInfo(infoPtr, leftmost)->rcHeader.left + Originx;
-               }
-           }
+        if (infoPtr->uView == LV_VIEW_DETAILS)
+        {
+            if (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)
+            {
+                /* we have to update left focus bound too if item isn't in leftmost column
+                  and reduce right box bound */
+                if (DPA_GetPtrCount(infoPtr->hdpaColumns) > 0)
+                {
+                    INT leftmost;
 
-           rcSelect.right = rcBox.right;
-       }
+                    if ((leftmost = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, 0, 0)))
+                    {
+                        INT Originx = pos->x - LISTVIEW_GetColumnInfo(infoPtr, leftmost)->rcHeader.left;
+                        INT rightmost = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX,
+                            DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0);
 
-       /* store new focus rectangle */
-        infoPtr->rcFocus = rcSelect;
+                        rcBox.right   = LISTVIEW_GetColumnInfo(infoPtr, rightmost)->rcHeader.right + Originx;
+                        rcSelect.left = LISTVIEW_GetColumnInfo(infoPtr, leftmost)->rcHeader.left + Originx;
+                    }
+                }
+                rcSelect.right = rcBox.right;
+            }
+            infoPtr->rcFocus = rcSelect;
+        }
+        else
+            infoPtr->rcFocus = rcLabel;
     }
 
     /* state icons */
@@ -4893,9 +4913,9 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
 {
     INT rgntype;
     RECT rcClip, rcItem;
-    POINT Origin, Position;
+    POINT Origin;
     RANGES colRanges;
-    INT col, index;
+    INT col;
     ITERATOR j;
 
     TRACE("()\n");
@@ -4912,7 +4932,7 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
     /* narrow down the columns we need to paint */
     for(col = 0; col < DPA_GetPtrCount(infoPtr->hdpaColumns); col++)
     {
-       index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, col, 0);
+       INT index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, col, 0);
 
        LISTVIEW_GetHeaderRect(infoPtr, index, &rcItem);
        if ((rcItem.right + Origin.x >= rcClip.left) && (rcItem.left + Origin.x < rcClip.right))
@@ -4928,10 +4948,12 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
     while(iterator_next(i))
     {
         RANGES subitems;
+        POINT Position;
         ITERATOR k;
 
         SelectObject(hdc, infoPtr->hFont);
        LISTVIEW_GetItemOrigin(infoPtr, i->nItem, &Position);
+        Position.x = Origin.x;
        Position.y += Origin.y;
 
         subitems = ranges_create(DPA_GetPtrCount(infoPtr->hdpaColumns));
@@ -4940,7 +4962,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
        while(iterator_next(&j))
        {
            LISTVIEW_GetHeaderRect(infoPtr, j.nItem, &rcItem);
-           Position.x = (j.nItem == 0) ? rcItem.left + Origin.x : Origin.x;
 
            if (rgntype == COMPLEXREGION && !((infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) && j.nItem == 0))
            {
@@ -6489,14 +6510,9 @@ static BOOL LISTVIEW_GetColumnT(const LISTVIEW_INFO *infoPtr, INT nColumn, LPLVC
     return TRUE;
 }
 
-
-static BOOL LISTVIEW_GetColumnOrderArray(const LISTVIEW_INFO *infoPtr, INT iCount, LPINT lpiArray)
+static inline BOOL LISTVIEW_GetColumnOrderArray(const LISTVIEW_INFO *infoPtr, INT iCount, LPINT lpiArray)
 {
-    TRACE("iCount=%d, lpiArray=%p\n", iCount, lpiArray);
-
-    if (!lpiArray)
-       return FALSE;
-
+    if (!infoPtr->hwndHeader) return FALSE;
     return SendMessageW(infoPtr->hwndHeader, HDM_GETORDERARRAY, iCount, (LPARAM)lpiArray);
 }
 
@@ -6529,8 +6545,6 @@ static INT LISTVIEW_GetColumnWidth(const LISTVIEW_INFO *infoPtr, INT nColumn)
        /* We are not using LISTVIEW_GetHeaderRect as this data is updated only after a HDN_ITEMCHANGED.
         * There is an application that subclasses the listview, calls LVM_GETCOLUMNWIDTH in the
         * HDN_ITEMCHANGED handler and goes into infinite recursion if it receives old data.
-        *
-        * TODO: should we do the same in LVM_GETCOLUMN?
         */
        hdItem.mask = HDI_WIDTH;
        if (!SendMessageW(infoPtr->hwndHeader, HDM_GETITEMW, nColumn, (LPARAM)&hdItem))
@@ -8019,7 +8033,9 @@ static BOOL LISTVIEW_SetBkColor(LISTVIEW_INFO *infoPtr, COLORREF color)
 {
     TRACE("(color=%x)\n", color);
 
+#ifdef __REACTOS__
     infoPtr->bDefaultBkColor = FALSE;
+#endif
     if(infoPtr->clrBk != color) {
        if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
        infoPtr->clrBk = color;
@@ -8303,12 +8319,8 @@ static BOOL LISTVIEW_SetColumnT(const LISTVIEW_INFO *infoPtr, INT nColumn,
  */
 static BOOL LISTVIEW_SetColumnOrderArray(LISTVIEW_INFO *infoPtr, INT iCount, const INT *lpiArray)
 {
-    TRACE("iCount %d lpiArray %p\n", iCount, lpiArray);
-
-    if (!lpiArray || !IsWindow(infoPtr->hwndHeader)) return FALSE;
-
+    if (!infoPtr->hwndHeader) return FALSE;
     infoPtr->colRectsDirty = TRUE;
-
     return SendMessageW(infoPtr->hwndHeader, HDM_SETORDERARRAY, iCount, (LPARAM)lpiArray);
 }
 
@@ -8336,9 +8348,10 @@ static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn, INT cx)
     /* set column width only if in report or list mode */
     if (infoPtr->uView != LV_VIEW_DETAILS && infoPtr->uView != LV_VIEW_LIST) return FALSE;
 
-    /* take care of invalid cx values */
-    if(infoPtr->uView == LV_VIEW_DETAILS && cx < -2) cx = LVSCW_AUTOSIZE;
-    else if (infoPtr->uView == LV_VIEW_LIST && cx < 1) return FALSE;
+    /* take care of invalid cx values - LVSCW_AUTOSIZE_* values are negative,
+       with _USEHEADER being the lowest */
+    if (infoPtr->uView == LV_VIEW_DETAILS && cx < LVSCW_AUTOSIZE_USEHEADER) cx = LVSCW_AUTOSIZE;
+    else if (infoPtr->uView == LV_VIEW_LIST && cx <= 0) return FALSE;
 
     /* resize all columns if in LV_VIEW_LIST mode */
     if(infoPtr->uView == LV_VIEW_LIST)
@@ -8397,18 +8410,38 @@ static BOOL LISTVIEW_SetColumnWidth(LISTVIEW_INFO *infoPtr, INT nColumn, INT cx)
            cx = 0;
 
            /* retrieve header text */
-           hdi.mask = HDI_TEXT;
+           hdi.mask = HDI_TEXT|HDI_FORMAT|HDI_IMAGE|HDI_BITMAP;
            hdi.cchTextMax = DISP_TEXT_SIZE;
            hdi.pszText = szDispText;
            if (SendMessageW(infoPtr->hwndHeader, HDM_GETITEMW, nColumn, (LPARAM)&hdi))
            {
                HDC hdc = GetDC(infoPtr->hwndSelf);
                HFONT old_font = SelectObject(hdc, (HFONT)SendMessageW(infoPtr->hwndHeader, WM_GETFONT, 0, 0));
+               HIMAGELIST himl = (HIMAGELIST)SendMessageW(infoPtr->hwndHeader, HDM_GETIMAGELIST, 0, 0);
+               INT bitmap_margin = 0;
                SIZE size;
 
                if (GetTextExtentPoint32W(hdc, hdi.pszText, lstrlenW(hdi.pszText), &size))
                    cx = size.cx + TRAILING_HEADER_PADDING;
-               /* FIXME: Take into account the header image, if one is present */
+
+               if (hdi.fmt & (HDF_IMAGE|HDF_BITMAP))
+                   bitmap_margin = SendMessageW(infoPtr->hwndHeader, HDM_GETBITMAPMARGIN, 0, 0);
+
+               if ((hdi.fmt & HDF_IMAGE) && himl)
+               {
+                   INT icon_cx, icon_cy;
+
+                   if (!ImageList_GetIconSize(himl, &icon_cx, &icon_cy))
+                       cx += icon_cx + 2*bitmap_margin;
+               }
+               else if (hdi.fmt & HDF_BITMAP)
+               {
+                   BITMAP bmp;
+
+                   GetObjectW(hdi.hbm, sizeof(BITMAP), &bmp);
+                   cx += bmp.bmWidth + 2*bitmap_margin;
+               }
+
                SelectObject(hdc, old_font);
                ReleaseDC(infoPtr->hwndSelf, hdc);
            }
@@ -9430,7 +9463,9 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs)
   infoPtr->clrText = CLR_DEFAULT;
   infoPtr->clrTextBk = CLR_DEFAULT;
   LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
+#ifdef __REACTOS__
   infoPtr->bDefaultBkColor = TRUE;
+#endif
 
   /* set default values */
   infoPtr->nFocusedItem = -1;
@@ -11071,7 +11106,6 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
     if (wStyleType != GWL_STYLE) return 0;
 
     infoPtr->dwStyle = lpss->styleNew;
-    map_style_view(infoPtr);
 
     if (((lpss->styleOld & WS_HSCROLL) != 0)&&
         ((lpss->styleNew & WS_HSCROLL) == 0))
@@ -11084,7 +11118,10 @@ static INT LISTVIEW_StyleChanged(LISTVIEW_INFO *infoPtr, WPARAM wStyleType,
     if (uNewView != uOldView)
     {
        HIMAGELIST himl;
-    
+
+        /* LVM_SETVIEW doesn't change window style bits within LVS_TYPEMASK,
+           changing style updates current view only when view bits change. */
+        map_style_view(infoPtr);
         SendMessageW(infoPtr->hwndEdit, WM_KILLFOCUS, 0, 0);
        ShowWindow(infoPtr->hwndHeader, SW_HIDE);
 
@@ -11713,12 +11750,14 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
   case WM_SYSCOLORCHANGE:
     COMCTL32_RefreshSysColors();
+#ifdef __REACTOS__
     if (infoPtr->bDefaultBkColor)
     {
         LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
         infoPtr->bDefaultBkColor = TRUE;
         LISTVIEW_InvalidateList(infoPtr);
     }
+#endif
     return 0;
 
 /*     case WM_TIMER: */
index 2151e3c..a1005ff 100644 (file)
@@ -850,10 +850,16 @@ static void MONTHCAL_PaintButton(MONTHCAL_INFO *infoPtr, HDC hdc, enum nav_direc
 /* paint a title with buttons and month/year string */
 static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
 {
-  static const WCHAR fmt_monthW[] = { '%','s',' ','%','l','d',0 };
+  static const WCHAR mmmmW[] = {'M','M','M','M',0};
+  static const WCHAR mmmW[] = {'M','M','M',0};
+  static const WCHAR mmW[] = {'M','M',0};
+  static const WCHAR fmtyearW[] = {'%','l','d',0};
+  static const WCHAR fmtmmW[] = {'%','0','2','d',0};
+  static const WCHAR fmtmW[] = {'%','d',0};
   RECT *title = &infoPtr->calendars[calIdx].title;
   const SYSTEMTIME *st = &infoPtr->calendars[calIdx].month;
-  WCHAR buf_month[80], buf_fmt[80];
+  WCHAR monthW[80], strW[80], fmtW[80], yearW[6] /* valid year range is 1601-30827 */;
+  int yearoffset, monthoffset, shiftX;
   SIZE sz;
 
   /* fill header box */
@@ -864,21 +870,65 @@ static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRU
   SetTextColor(hdc, infoPtr->colors[MCSC_TITLETEXT]);
   SelectObject(hdc, infoPtr->hBoldFont);
 
-  GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1 + st->wMonth - 1,
-                 buf_month, countof(buf_month));
+  /* draw formatted date string */
+  GetDateFormatW(LOCALE_USER_DEFAULT, DATE_YEARMONTH, st, NULL, strW, countof(strW));
+  DrawTextW(hdc, strW, strlenW(strW), title, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+
+  GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SYEARMONTH, fmtW, countof(fmtW));
+  wsprintfW(yearW, fmtyearW, st->wYear);
+
+  /* month is trickier as it's possible to have different format pictures, we'll
+     test for M, MM, MMM, and MMMM */
+  if (strstrW(fmtW, mmmmW))
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SMONTHNAME1+st->wMonth-1, monthW, countof(monthW));
+  else if (strstrW(fmtW, mmmW))
+    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVMONTHNAME1+st->wMonth-1, monthW, countof(monthW));
+  else if (strstrW(fmtW, mmW))
+    wsprintfW(monthW, fmtmmW, st->wMonth);
+  else
+    wsprintfW(monthW, fmtmW, st->wMonth);
+
+  /* update hit boxes */
+  yearoffset = 0;
+  while (strW[yearoffset])
+  {
+    if (!strncmpW(&strW[yearoffset], yearW, strlenW(yearW)))
+        break;
+    yearoffset++;
+  }
+
+  monthoffset = 0;
+  while (strW[monthoffset])
+  {
+    if (!strncmpW(&strW[monthoffset], monthW, strlenW(monthW)))
+        break;
+    monthoffset++;
+  }
+
+  /* for left limits use offsets */
+  sz.cx = 0;
+  if (yearoffset)
+    GetTextExtentPoint32W(hdc, strW, yearoffset, &sz);
+  infoPtr->calendars[calIdx].titleyear.left = sz.cx;
 
-  wsprintfW(buf_fmt, fmt_monthW, buf_month, st->wYear);
-  DrawTextW(hdc, buf_fmt, strlenW(buf_fmt), title,
-                      DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+  sz.cx = 0;
+  if (monthoffset)
+    GetTextExtentPoint32W(hdc, strW, monthoffset, &sz);
+  infoPtr->calendars[calIdx].titlemonth.left = sz.cx;
 
-  /* update title rectangles with current month - used while testing hits */
-  GetTextExtentPoint32W(hdc, buf_fmt, strlenW(buf_fmt), &sz);
-  infoPtr->calendars[calIdx].titlemonth.left = title->right / 2 + title->left / 2 - sz.cx / 2;
-  infoPtr->calendars[calIdx].titleyear.right = title->right / 2 + title->left / 2 + sz.cx / 2;
+  /* for right limits use actual string parts lengths */
+  GetTextExtentPoint32W(hdc, &strW[yearoffset], strlenW(yearW), &sz);
+  infoPtr->calendars[calIdx].titleyear.right = infoPtr->calendars[calIdx].titleyear.left + sz.cx;
 
-  GetTextExtentPoint32W(hdc, buf_month, strlenW(buf_month), &sz);
+  GetTextExtentPoint32W(hdc, monthW, strlenW(monthW), &sz);
   infoPtr->calendars[calIdx].titlemonth.right = infoPtr->calendars[calIdx].titlemonth.left + sz.cx;
-  infoPtr->calendars[calIdx].titleyear.left   = infoPtr->calendars[calIdx].titlemonth.right;
+
+  /* Finally translate rectangles to match center aligned string,
+     hit rectangles are relative to title rectangle before translation. */
+  GetTextExtentPoint32W(hdc, strW, strlenW(strW), &sz);
+  shiftX = (title->right - title->left - sz.cx) / 2 + title->left;
+  OffsetRect(&infoPtr->calendars[calIdx].titleyear, shiftX, 0);
+  OffsetRect(&infoPtr->calendars[calIdx].titlemonth, shiftX, 0);
 }
 
 static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
@@ -1002,13 +1052,7 @@ static void MONTHCAL_PaintTodayTitle(const MONTHCAL_INFO *infoPtr, HDC hdc, cons
 
   if(infoPtr->dwStyle & MCS_NOTODAY) return;
 
-  if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW)))
-  {
-    static const WCHAR todayW[] = { 'T','o','d','a','y',':',0 };
-    WARN("Can't load resource\n");
-    strcpyW(buf_todayW, todayW);
-  }
-
+  LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW));
   col = infoPtr->dwStyle & MCS_NOTODAYCIRCLE ? 0 : 1;
   if (infoPtr->dwStyle & MCS_WEEKNUMBERS) col--;
   /* label is located below first calendar last row */
@@ -1968,17 +2012,12 @@ static void MONTHCAL_GoToMonth(MONTHCAL_INFO *infoPtr, enum nav_direction direct
 static LRESULT
 MONTHCAL_RButtonUp(MONTHCAL_INFO *infoPtr, LPARAM lParam)
 {
-  static const WCHAR todayW[] = { 'G','o',' ','t','o',' ','T','o','d','a','y',':',0 };
   HMENU hMenu;
   POINT menupoint;
   WCHAR buf[32];
 
   hMenu = CreatePopupMenu();
-  if (!LoadStringW(COMCTL32_hModule, IDM_GOTODAY, buf, countof(buf)))
-  {
-      WARN("Can't load resource\n");
-      strcpyW(buf, todayW);
-  }
+  LoadStringW(COMCTL32_hModule, IDM_GOTODAY, buf, countof(buf));
   AppendMenuW(hMenu, MF_STRING|MF_ENABLED, 1, buf);
   menupoint.x = (short)LOWORD(lParam);
   menupoint.y = (short)HIWORD(lParam);
index 52a1717..600e198 100644 (file)
@@ -1380,7 +1380,7 @@ REBAR_Layout(REBAR_INFO *infoPtr)
     adjcx = get_rect_cx(infoPtr, &rcAdj);
 
     if (infoPtr->uNumBands == 0) {
-        TRACE("No bands - setting size to (0,%d), vert: %x\n", adjcx, infoPtr->dwStyle & CCS_VERT);
+        TRACE("No bands - setting size to (0,%d), style: %x\n", adjcx, infoPtr->dwStyle);
         infoPtr->calcSize.cx = adjcx;
         /* the calcSize.cy won't change for a 0 band rebar */
         infoPtr->uNumRows = 0;
@@ -1828,11 +1828,14 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
     RECT cr;
     COLORREF old = CLR_NONE, new;
     HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
+#ifdef __REACTOS__
     HRGN hrgn;
+#endif
 
     GetClientRect (infoPtr->hwndSelf, &cr);
 
 #ifdef __REACTOS__
+
     if (theme)
     {
         if (IsThemeBackgroundPartiallyTransparent(theme, RP_BACKGROUND, 0))
@@ -1841,21 +1844,26 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
         }
         DrawThemeBackground (theme, hdc, 0, 0, &cr, NULL);
     }
-#endif
+
     hrgn = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
 
+#endif
+
     oldrow = -1;
     for(i=0; i<infoPtr->uNumBands; i++) {
         RECT rcBand;
+#ifdef __REACTOS__
         RECT rcBandReal;
         HRGN hrgnBand;
+#endif
 
         lpBand = REBAR_GetBand(infoPtr, i);
-
        if (HIDDENBAND(lpBand)) continue;
         translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
 
+#ifdef __REACTOS__
         rcBandReal = rcBand;
+#endif
 
        /* draw band separator between rows */
        if (lpBand->iRow != oldrow) {
@@ -1881,7 +1889,9 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
                }
                 TRACE ("drawing band separator bottom (%s)\n",
                        wine_dbgstr_rect(&rcRowSep));
+#ifdef __REACTOS__
         rcBandReal = rcRowSep;
+#endif
            }
        }
 
@@ -1892,7 +1902,9 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
            if (infoPtr->dwStyle & CCS_VERT) {
                 rcSep.bottom = rcSep.top;
                rcSep.top -= SEP_WIDTH_SIZE;
+#ifdef __REACTOS__
         rcBandReal.top -= SEP_WIDTH_SIZE;
+#endif
                 if (theme)
                     DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_BOTTOM, NULL);
                 else
@@ -1901,7 +1913,9 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
            else {
                 rcSep.right = rcSep.left;
                rcSep.left -= SEP_WIDTH_SIZE;
+#ifdef __REACTOS__
         rcBandReal.left -= SEP_WIDTH_SIZE;
+#endif
                 if (theme)
                     DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_RIGHT, NULL);
                 else
@@ -1954,9 +1968,11 @@ static LRESULT REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
                 SetBkColor (hdc, old);
         }
 
+#ifdef __REACTOS__
         hrgnBand = CreateRectRgn(rcBandReal.left, rcBandReal.top, rcBandReal.right, rcBandReal.bottom);
         CombineRgn(hrgn, hrgn, hrgnBand, RGN_DIFF);
         DeleteObject(hrgnBand);
+#endif
     }
 
 #if 1
index f06f512..7cc9b48 100644 (file)
@@ -142,8 +142,7 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UIN
         { RBS_CHECKEDNORMAL, RBS_CHECKEDDISABLED, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDNORMAL }
     };
 
-    static const int cb_size = 13;
-
+    SIZE sz;
     RECT bgRect, textRect;
     HFONT font, hPrevFont = NULL;
     LRESULT checkState = SendMessageW(hwnd, BM_GETCHECK, 0, 0);
@@ -173,15 +172,18 @@ static void CB_draw(HTHEME theme, HWND hwnd, HDC hDC, ButtonState drawState, UIN
         hPrevFont = SelectObject(hDC, font);
     }
 
+    if (FAILED(GetThemePartSize(theme, hDC, part, state, NULL, TS_DRAW, &sz)))
+        sz.cx = sz.cy = 13;
+
     GetClientRect(hwnd, &bgRect);
     GetThemeBackgroundContentRect(theme, hDC, part, state, &bgRect, &textRect);
 
     if (dtFlags & DT_SINGLELINE) /* Center the checkbox / radio button to the text. */
-        bgRect.top = bgRect.top + (textRect.bottom - textRect.top - cb_size) / 2;
+        bgRect.top = bgRect.top + (textRect.bottom - textRect.top - sz.cy) / 2;
 
     /* adjust for the check/radio marker */
-    bgRect.bottom = bgRect.top + cb_size;
-    bgRect.right = bgRect.left + cb_size;
+    bgRect.bottom = bgRect.top + sz.cy;
+    bgRect.right = bgRect.left + sz.cx;
     textRect.left = bgRect.right + 6;
 
     DrawThemeParentBackground(hwnd, hDC, NULL);
@@ -367,9 +369,11 @@ LRESULT CALLBACK THEMING_ButtonSubclassProc(HWND hwnd, UINT msg,
 
     case WM_ENABLE:
         theme = GetWindowTheme(hwnd);
-        if (theme) RedrawWindow(hwnd, NULL, NULL,
-                                RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
-        return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+        if (theme) {
+            RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
+            return 0;
+        } else
+            return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
 
     case WM_MOUSEMOVE:
     {
index c2ababd..9997787 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(theme_scroll);
 
+/* Minimum size of the thumb in pixels */
+#define SCROLL_MIN_THUMB 6
+
+/* Minimum size of the rectangle between the arrows */
+#define SCROLL_MIN_RECT  4
+
+enum SCROLL_HITTEST
+{
+    SCROLL_NOWHERE,      /* Outside the scroll bar */
+    SCROLL_TOP_ARROW,    /* Top or left arrow */
+    SCROLL_TOP_RECT,     /* Rectangle between the top arrow and the thumb */
+    SCROLL_THUMB,        /* Thumb rectangle */
+    SCROLL_BOTTOM_RECT,  /* Rectangle between the thumb and the bottom arrow */
+    SCROLL_BOTTOM_ARROW  /* Bottom or right arrow */
+};
+
+static HWND tracking_win = 0;
+static enum SCROLL_HITTEST tracking_hot_part = SCROLL_NOWHERE;
+
+static void calc_thumb_dimensions(unsigned int size, SCROLLINFO *si, unsigned int *thumbpos, unsigned int *thumbsize)
+{
+    if (size <= SCROLL_MIN_RECT)
+        *thumbpos = *thumbsize = 0;
+    else if (si->nPage > si->nMax - si->nMin)
+        *thumbpos = *thumbsize = 0;
+    else {
+        if (si->nPage > 0) {
+            *thumbsize = MulDiv(size, si->nPage, si->nMax - si->nMin + 1);
+            if (*thumbsize < SCROLL_MIN_THUMB) *thumbsize = SCROLL_MIN_THUMB;
+        }
+        else *thumbsize = GetSystemMetrics(SM_CXVSCROLL);
+
+        if (size < *thumbsize)
+            *thumbpos = *thumbsize = 0;
+        else {
+            int max = si->nMax - max(si->nPage - 1, 0);
+            size -= *thumbsize;
+            if (si->nMin >= max)
+                *thumbpos = 0;
+            else
+                *thumbpos = MulDiv(size, si->nTrackPos - si->nMin, max - si->nMin);
+        }
+    }
+}
+
+static enum SCROLL_HITTEST hit_test(HWND hwnd, HTHEME theme, POINT pt)
+{
+    RECT r;
+    DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+    BOOL vertical = style & SBS_VERT;
+    SIZE sz;
+    SCROLLINFO si;
+    unsigned int offset, size, upsize, downsize, thumbpos, thumbsize;
+
+    GetWindowRect(hwnd, &r);
+    OffsetRect(&r, -r.left, -r.top);
+
+    if (vertical) {
+        offset = pt.y;
+        size = r.bottom;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_UPNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get up arrow size.\n");
+            upsize = 0;
+        } else
+            upsize = sz.cy;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_DOWNNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get down arrow size.\n");
+            downsize = 0;
+        } else
+            downsize = sz.cy;
+    } else {
+        offset = pt.x;
+        size = r.right;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_LEFTNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get left arrow size.\n");
+            upsize = 0;
+        } else
+            upsize = sz.cx;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_RIGHTNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get right arrow size.\n");
+            downsize = 0;
+        } else
+            downsize = sz.cx;
+    }
+
+    if (pt.x < 0 || pt.x > r.right || pt.y < 0 || pt.y > r.bottom)
+        return SCROLL_NOWHERE;
+
+    if (size < SCROLL_MIN_RECT + upsize + downsize)
+        upsize = downsize = (size - SCROLL_MIN_RECT)/2;
+
+    if (offset < upsize)
+        return SCROLL_TOP_ARROW;
+
+    if (offset > size - downsize)
+        return SCROLL_BOTTOM_ARROW;
+
+    si.cbSize = sizeof(si);
+    si.fMask = SIF_ALL;
+    if (!GetScrollInfo(hwnd, SB_CTL, &si)) {
+        WARN("GetScrollInfo failed.\n");
+        return SCROLL_NOWHERE;
+    }
+
+    calc_thumb_dimensions(size - upsize - downsize, &si, &thumbpos, &thumbsize);
+
+    if (offset < upsize + thumbpos)
+        return SCROLL_TOP_RECT;
+    else if (offset < upsize + thumbpos + thumbsize)
+        return SCROLL_THUMB;
+    else
+        return SCROLL_BOTTOM_RECT;
+}
+
+static void redraw_part(HWND hwnd, HTHEME theme, enum SCROLL_HITTEST part)
+{
+    DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+    BOOL vertical = style & SBS_VERT;
+    SIZE sz;
+    RECT r, partrect;
+    unsigned int size, upsize, downsize;
+
+    if (part == SCROLL_NOWHERE) { /* redraw everything */
+        InvalidateRect(hwnd, NULL, TRUE);
+        return;
+    }
+
+    GetWindowRect(hwnd, &r);
+    OffsetRect(&r, -r.left, -r.top);
+
+    if (vertical) {
+        size = r.bottom;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_UPNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get up arrow size.\n");
+            upsize = 0;
+        } else
+            upsize = sz.cy;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_DOWNNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get down arrow size.\n");
+            downsize = 0;
+        } else
+            downsize = sz.cy;
+    } else {
+        size = r.right;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_LEFTNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get left arrow size.\n");
+            upsize = 0;
+        } else
+            upsize = sz.cx;
+
+        if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_RIGHTNORMAL, NULL, TS_DRAW, &sz))) {
+            WARN("Could not get right arrow size.\n");
+            downsize = 0;
+        } else
+            downsize = sz.cx;
+    }
+
+    if (size < SCROLL_MIN_RECT + upsize + downsize)
+        upsize = downsize = (size - SCROLL_MIN_RECT)/2;
+
+    partrect = r;
+
+    if (part == SCROLL_TOP_ARROW) {
+        if (vertical)
+            partrect.bottom = partrect.top + upsize;
+        else
+            partrect.right = partrect.left + upsize;
+    } else if (part == SCROLL_BOTTOM_ARROW) {
+        if (vertical)
+            partrect.top = partrect.bottom - downsize;
+        else
+            partrect.left = partrect.right - downsize;
+    } else {
+        unsigned int thumbpos, thumbsize;
+        SCROLLINFO si;
+
+        si.cbSize = sizeof(si);
+        si.fMask = SIF_ALL;
+        if (!GetScrollInfo(hwnd, SB_CTL, &si)) {
+            WARN("GetScrollInfo failed.\n");
+            return;
+        }
+
+        calc_thumb_dimensions(size - upsize - downsize, &si, &thumbpos, &thumbsize);
+
+        if (part == SCROLL_TOP_RECT) {
+            if (vertical) {
+                partrect.top = r.top + upsize;
+                partrect.bottom = partrect.top + thumbpos;
+            } else {
+                partrect.left = r.left + upsize;
+                partrect.right = partrect.left + thumbpos;
+            }
+        } else if (part == SCROLL_THUMB) {
+            if (vertical) {
+                partrect.top = r.top + upsize + thumbpos;
+                partrect.bottom = partrect.top + thumbsize;
+            } else {
+                partrect.left = r.left + upsize + thumbpos;
+                partrect.right = partrect.left + thumbsize;
+            }
+        } else if (part == SCROLL_BOTTOM_RECT) {
+            if (vertical) {
+                partrect.top = r.top + upsize + thumbpos + thumbsize;
+                partrect.bottom = r.bottom - downsize;
+            } else {
+                partrect.left = r.left + upsize + thumbpos + thumbsize;
+                partrect.right = r.right - downsize;
+            }
+        }
+    }
+
+    InvalidateRect(hwnd, &partrect, TRUE);
+}
+
+static void scroll_event(HWND hwnd, HTHEME theme, UINT msg, POINT pt)
+{
+    enum SCROLL_HITTEST hittest;
+    TRACKMOUSEEVENT tme;
+
+    if (GetWindowLongW(hwnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX))
+        return;
+
+    hittest = hit_test(hwnd, theme, pt);
+
+    switch (msg)
+    {
+        case WM_MOUSEMOVE:
+            hittest = hit_test(hwnd, theme, pt);
+            tracking_win = hwnd;
+            break;
+
+        case WM_MOUSELEAVE:
+            if (tracking_win == hwnd) {
+                hittest = SCROLL_NOWHERE;
+            }
+            break;
+    }
+
+    tme.cbSize = sizeof(tme);
+    tme.dwFlags = TME_QUERY;
+    TrackMouseEvent(&tme);
+
+    if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) {
+        tme.dwFlags = TME_LEAVE;
+        tme.hwndTrack = hwnd;
+        TrackMouseEvent(&tme);
+    }
+
+    if (tracking_win != hwnd && msg == WM_MOUSELEAVE) {
+        redraw_part(hwnd, theme, SCROLL_NOWHERE);
+        return;
+    }
+
+    if (tracking_win == hwnd && hittest != tracking_hot_part) {
+        enum SCROLL_HITTEST oldhotpart = tracking_hot_part;
+
+        tracking_hot_part = hittest;
+
+        if (hittest != SCROLL_NOWHERE)
+            redraw_part(hwnd, theme, hittest);
+        else
+            tracking_win = 0;
+
+        if (oldhotpart != SCROLL_NOWHERE)
+            redraw_part(hwnd, theme, oldhotpart);
+    }
+}
+
+static void paint_scrollbar(HWND hwnd, HTHEME theme)
+{
+    HDC dc;
+    PAINTSTRUCT ps;
+    RECT r;
+    DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+    BOOL vertical = style & SBS_VERT;
+    BOOL disabled = !IsWindowEnabled(hwnd);
+
+    GetWindowRect(hwnd, &r);
+    OffsetRect(&r, -r.left, -r.top);
+
+    dc = BeginPaint(hwnd, &ps);
+
+    if (style & SBS_SIZEBOX || style & SBS_SIZEGRIP) {
+        int state;
+
+        if (style & SBS_SIZEBOXTOPLEFTALIGN)
+            state = SZB_TOPLEFTALIGN;
+        else
+            state = SZB_RIGHTALIGN;
+
+        DrawThemeBackground(theme, dc, SBP_SIZEBOX, state, &r, NULL);
+    } else {
+        SCROLLBARINFO sbi;
+        SCROLLINFO si;
+        unsigned int thumbpos, thumbsize;
+        int uppertrackstate, lowertrackstate, thumbstate;
+        RECT partrect, trackrect;
+        SIZE grippersize;
+
+        sbi.cbSize = sizeof(sbi);
+        GetScrollBarInfo(hwnd, OBJID_CLIENT, &sbi);
+
+        si.cbSize = sizeof(si);
+        si.fMask = SIF_ALL;
+        GetScrollInfo(hwnd, SB_CTL, &si);
+
+        trackrect = r;
+
+        if (disabled) {
+            uppertrackstate = SCRBS_DISABLED;
+            lowertrackstate = SCRBS_DISABLED;
+            thumbstate = SCRBS_DISABLED;
+        } else {
+            uppertrackstate = SCRBS_NORMAL;
+            lowertrackstate = SCRBS_NORMAL;
+            thumbstate = SCRBS_NORMAL;
+
+            if (tracking_win == hwnd) {
+                if (tracking_hot_part == SCROLL_TOP_RECT)
+                    uppertrackstate = SCRBS_HOT;
+                else if (tracking_hot_part == SCROLL_BOTTOM_RECT)
+                    lowertrackstate = SCRBS_HOT;
+                else if (tracking_hot_part == SCROLL_THUMB)
+                    thumbstate = SCRBS_HOT;
+            }
+        }
+
+        if (vertical) {
+            SIZE upsize, downsize;
+            int uparrowstate, downarrowstate;
+
+            if (disabled) {
+                uparrowstate = ABS_UPDISABLED;
+                downarrowstate = ABS_DOWNDISABLED;
+            } else {
+                uparrowstate = ABS_UPNORMAL;
+                downarrowstate = ABS_DOWNNORMAL;
+
+                if (tracking_win == hwnd) {
+                    if (tracking_hot_part == SCROLL_TOP_ARROW)
+                        uparrowstate = ABS_UPHOT;
+                    else if (tracking_hot_part == SCROLL_BOTTOM_ARROW)
+                        downarrowstate = ABS_DOWNHOT;
+                }
+            }
+
+            if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, uparrowstate, NULL, TS_DRAW, &upsize))) {
+                WARN("Could not get up arrow size.\n");
+                return;
+            }
+
+            if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, downarrowstate, NULL, TS_DRAW, &downsize))) {
+                WARN("Could not get down arrow size.\n");
+                return;
+            }
+
+            if (r.bottom - r.top - upsize.cy - downsize.cy < SCROLL_MIN_RECT)
+                upsize.cy = downsize.cy = (r.bottom - r.top - SCROLL_MIN_RECT)/2;
+
+            partrect = r;
+            partrect.bottom = partrect.top + upsize.cy;
+            DrawThemeBackground(theme, dc, SBP_ARROWBTN, uparrowstate, &partrect, NULL);
+
+            trackrect.top = partrect.bottom;
+
+            partrect.bottom = r.bottom;
+            partrect.top = partrect.bottom - downsize.cy;
+            DrawThemeBackground(theme, dc, SBP_ARROWBTN, downarrowstate, &partrect, NULL);
+
+            trackrect.bottom = partrect.top;
+
+            calc_thumb_dimensions(trackrect.bottom - trackrect.top, &si, &thumbpos, &thumbsize);
+
+            if (thumbpos > 0) {
+                partrect.top = trackrect.top;
+                partrect.bottom = partrect.top + thumbpos;
+
+                DrawThemeBackground(theme, dc, SBP_UPPERTRACKVERT, uppertrackstate, &partrect, NULL);
+            }
+
+            if (thumbsize > 0) {
+                partrect.top = trackrect.top + thumbpos;
+                partrect.bottom = partrect.top + thumbsize;
+
+                DrawThemeBackground(theme, dc, SBP_THUMBBTNVERT, thumbstate, &partrect, NULL);
+
+                if (SUCCEEDED(GetThemePartSize(theme, dc, SBP_GRIPPERVERT, thumbstate, NULL, TS_DRAW, &grippersize))) {
+                    MARGINS margins;
+
+                    if (SUCCEEDED(GetThemeMargins(theme, dc, SBP_THUMBBTNVERT, thumbstate, TMT_CONTENTMARGINS, &partrect, &margins))) {
+                        if (grippersize.cy <= (thumbsize - margins.cyTopHeight - margins.cyBottomHeight))
+                            DrawThemeBackground(theme, dc, SBP_GRIPPERVERT, thumbstate, &partrect, NULL);
+                    }
+                }
+            }
+
+            if (thumbpos + thumbsize < trackrect.bottom - trackrect.top) {
+                partrect.bottom = trackrect.bottom;
+                partrect.top = trackrect.top + thumbsize + thumbpos;
+
+                DrawThemeBackground(theme, dc, SBP_LOWERTRACKVERT, lowertrackstate, &partrect, NULL);
+            }
+        } else {
+            SIZE leftsize, rightsize;
+            int leftarrowstate, rightarrowstate;
+
+            if (disabled) {
+                leftarrowstate = ABS_LEFTDISABLED;
+                rightarrowstate = ABS_RIGHTDISABLED;
+            } else {
+                leftarrowstate = ABS_LEFTNORMAL;
+                rightarrowstate = ABS_RIGHTNORMAL;
+
+                if (tracking_win == hwnd) {
+                    if (tracking_hot_part == SCROLL_TOP_ARROW)
+                        leftarrowstate = ABS_LEFTHOT;
+                    else if (tracking_hot_part == SCROLL_BOTTOM_ARROW)
+                        rightarrowstate = ABS_RIGHTHOT;
+                }
+            }
+
+            if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, leftarrowstate, NULL, TS_DRAW, &leftsize))) {
+                WARN("Could not get left arrow size.\n");
+                return;
+            }
+
+            if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, rightarrowstate, NULL, TS_DRAW, &rightsize))) {
+                WARN("Could not get right arrow size.\n");
+                return;
+            }
+
+            if (r.right - r.left - leftsize.cx - rightsize.cx < SCROLL_MIN_RECT)
+                leftsize.cx = rightsize.cx = (r.right - r.left - SCROLL_MIN_RECT)/2;
+
+            partrect = r;
+            partrect.right = partrect.left + leftsize.cx;
+            DrawThemeBackground(theme, dc, SBP_ARROWBTN, leftarrowstate, &partrect, NULL);
+
+            trackrect.left = partrect.right;
+
+            partrect.right = r.right;
+            partrect.left = partrect.right - rightsize.cx;
+            DrawThemeBackground(theme, dc, SBP_ARROWBTN, rightarrowstate, &partrect, NULL);
+
+            trackrect.right = partrect.left;
+
+            calc_thumb_dimensions(trackrect.right - trackrect.left, &si, &thumbpos, &thumbsize);
+
+            if (thumbpos > 0) {
+                partrect.left = trackrect.left;
+                partrect.right = partrect.left + thumbpos;
+
+                DrawThemeBackground(theme, dc, SBP_UPPERTRACKHORZ, uppertrackstate, &partrect, NULL);
+            }
+
+            if (thumbsize > 0) {
+                partrect.left = trackrect.left + thumbpos;
+                partrect.right = partrect.left + thumbsize;
+
+                DrawThemeBackground(theme, dc, SBP_THUMBBTNHORZ, thumbstate, &partrect, NULL);
+
+                if (SUCCEEDED(GetThemePartSize(theme, dc, SBP_GRIPPERHORZ, thumbstate, NULL, TS_DRAW, &grippersize))) {
+                    MARGINS margins;
+
+                    if (SUCCEEDED(GetThemeMargins(theme, dc, SBP_THUMBBTNHORZ, thumbstate, TMT_CONTENTMARGINS, &partrect, &margins))) {
+                        if (grippersize.cx <= (thumbsize - margins.cxLeftWidth - margins.cxRightWidth))
+                            DrawThemeBackground(theme, dc, SBP_GRIPPERHORZ, thumbstate, &partrect, NULL);
+                    }
+                }
+            }
+
+            if (thumbpos + thumbsize < trackrect.right - trackrect.left) {
+                partrect.right = trackrect.right;
+                partrect.left = trackrect.left + thumbsize + thumbpos;
+
+                DrawThemeBackground(theme, dc, SBP_LOWERTRACKHORZ, lowertrackstate, &partrect, NULL);
+            }
+        }
+    }
+
+    EndPaint(hwnd, &ps);
+}
+
 LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
                                                 WPARAM wParam, LPARAM lParam,
                                                 ULONG_PTR dwRefData)
 {
+    const WCHAR* themeClass = WC_SCROLLBARW;
+    HTHEME theme;
+    LRESULT result;
+    POINT pt;
+
     TRACE("(%p, 0x%x, %lu, %lu, %lu)\n", hwnd, msg, wParam, lParam, dwRefData);
 
-    return THEMING_CallOriginalClass (hwnd, msg, wParam, lParam);
+    switch (msg) {
+        case WM_CREATE:
+            result = THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            OpenThemeData(hwnd, themeClass);
+            return result;
+
+        case WM_DESTROY:
+            theme = GetWindowTheme(hwnd);
+            CloseThemeData(theme);
+            return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+
+        case WM_THEMECHANGED:
+            theme = GetWindowTheme(hwnd);
+            CloseThemeData(theme);
+            OpenThemeData(hwnd, themeClass);
+            break;
+
+        case WM_SYSCOLORCHANGE:
+            theme = GetWindowTheme(hwnd);
+            if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
+             * which will do the repaint. */
+            break;
+
+        case WM_PAINT:
+            theme = GetWindowTheme(hwnd);
+            if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+
+            paint_scrollbar(hwnd, theme);
+            break;
+
+        case WM_MOUSEMOVE:
+        case WM_MOUSELEAVE:
+            theme = GetWindowTheme(hwnd);
+            if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+
+            pt.x = (short)LOWORD(lParam);
+            pt.y = (short)HIWORD(lParam);
+            scroll_event(hwnd, theme, msg, pt);
+            break;
+
+        default:
+            return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+    }
+
+    return 0;
 }
index e13c90b..2756d24 100644 (file)
@@ -103,7 +103,6 @@ typedef struct
 typedef struct
 {
     DWORD    dwStructSize;    /* size of TBBUTTON struct */
-    INT      nWidth;          /* width of the toolbar */
     RECT     client_rect;
     RECT     rcBound;         /* bounding rectangle */
     INT      nButtonHeight;
@@ -124,8 +123,10 @@ typedef struct
     INT      nOldHit;
     INT      nHotItem;        /* index of the "hot" item */
     SIZE     szPadding;       /* padding values around button */
+#ifdef __REACTOS__
     SIZE     szBarPadding;       /* padding values around the toolbar (NOT USED BUT STORED) */
     SIZE     szSpacing;       /* spacing values between buttons */
+#endif
     INT      iTopMargin;      /* the top margin */
     INT      iListGap;        /* default gap between text and image for toolbar with list style */
     HFONT    hDefaultFont;
@@ -195,14 +196,20 @@ typedef enum
 #define DEFPAD_CX 7
 #define DEFPAD_CY 6
 
+#ifdef __REACTOS__
 /* default space between buttons and between rows */
 #define DEFSPACE_CX 7
 #define DEFSPACE_CY 6
+#endif
 
 #define DEFLISTGAP 4
 
 /* vertical padding used in list mode when image is present */
+#ifdef __REACTOS__
 #define LISTPAD_CY 2
+#else
+#define LISTPAD_CY 9
+#endif
 
 /* how wide to treat the bitmap if it isn't present */
 #define NONLIST_NOTEXT_OFFSET 2
@@ -240,6 +247,8 @@ static LRESULT TOOLBAR_AutoSize(TOOLBAR_INFO *infoPtr);
 static void TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr);
 static void TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button);
 static void TOOLBAR_TooltipSetRect(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button);
+static LRESULT TOOLBAR_SetButtonInfo(TOOLBAR_INFO *infoPtr, INT Id,
+                                     const TBBUTTONINFOW *lptbbi, BOOL isW);
 
 
 static inline int default_top_margin(const TOOLBAR_INFO *infoPtr)
@@ -257,6 +266,12 @@ static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle)
     return (exStyle & TBSTYLE_EX_DRAWDDARROWS) != 0;
 }
 
+static inline BOOL button_has_ddarrow(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
+{
+    return (TOOLBAR_HasDropDownArrows( infoPtr->dwExStyle ) && (btnPtr->fsStyle & BTNS_DROPDOWN)) ||
+        (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
+}
+
 static LPWSTR
 TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
 {
@@ -320,6 +335,37 @@ TOOLBAR_ButtonHasString(const TBUTTON_INFO *btnPtr)
     return HIWORD(btnPtr->iString) && btnPtr->iString != -1;
 }
 
+static void set_string_index( TBUTTON_INFO *btn, INT_PTR str, BOOL unicode )
+{
+    if (!IS_INTRESOURCE( str ) && str != -1)
+    {
+        if (!TOOLBAR_ButtonHasString( btn )) btn->iString = 0;
+
+        if (unicode)
+            Str_SetPtrW( (WCHAR **)&btn->iString, (WCHAR *)str );
+        else
+            Str_SetPtrAtoW( (WCHAR **)&btn->iString, (char *)str );
+    }
+    else
+    {
+        if (TOOLBAR_ButtonHasString( btn )) Free( (WCHAR *)btn->iString );
+
+        btn->iString  = str;
+    }
+}
+
+static void set_stringT( TBUTTON_INFO *btn, const WCHAR *str, BOOL unicode )
+{
+    if (IS_INTRESOURCE( (DWORD_PTR)str ) || (DWORD_PTR)str == -1) return;
+    set_string_index( btn, (DWORD_PTR)str, unicode );
+}
+
+static void free_string( TBUTTON_INFO *btn )
+{
+    set_string_index( btn, 0, TRUE );
+
+}
+
 /***********************************************************************
 *              TOOLBAR_CheckStyle
 *
@@ -700,8 +746,10 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
     INT index;
     INT offset = 0;
     UINT draw_flags = ILD_TRANSPARENT;
+#ifdef __REACTOS__
     IMAGEINFO info = {0};
     BITMAP bm = {0};
+#endif
 
     if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
     {
@@ -710,6 +758,7 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
         {
             himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
 
+#ifdef __REACTOS__
             ImageList_GetImageInfo(himl, index, &info);
             GetObjectW(info.hbmImage, sizeof(bm), &bm);
 
@@ -721,6 +770,9 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
             {
                 draw_masked = TRUE;
             }
+#else
+            draw_masked = TRUE;
+#endif
         }
     }
     else if (tbcd->nmcd.uItemState & CDIS_CHECKED ||
@@ -859,9 +911,7 @@ static void
 TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, DWORD dwBaseCustDraw)
 {
     DWORD dwStyle = infoPtr->dwStyle;
-    BOOL hasDropDownArrow = (TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
-                            (btnPtr->fsStyle & BTNS_DROPDOWN)) ||
-                            (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
+    BOOL hasDropDownArrow = button_has_ddarrow( infoPtr, btnPtr );
     BOOL drawSepDropDownArrow = hasDropDownArrow && 
                                 (~btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
     RECT rc, rcArrow, rcBitmap, rcText;
@@ -1327,164 +1377,150 @@ static void
 TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
 {
     TBUTTON_INFO *btnPtr;
-    INT x, cx, i, j;
-    RECT rc;
+    INT x, cx, i, j, width;
     BOOL bButtonWrap;
 
     /*         When the toolbar window style is not TBSTYLE_WRAPABLE,  */
     /* no layout is necessary. Applications may use this style */
     /* to perform their own layout on the toolbar.             */
-    if (!(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
-        !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))  return;
+    if!(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
+       !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL) )  return;
 
     btnPtr = infoPtr->buttons;
-    x = infoPtr->nIndent;
-
-    if (GetParent(infoPtr->hwndSelf))
-    {
-        /* this can get the parents width, to know how far we can extend
-         * this toolbar.  We cannot use its height, as there may be multiple
-         * toolbars in a rebar control
-         */
-        GetClientRect(GetParent(infoPtr->hwndSelf), &rc);
-        infoPtr->nWidth = rc.right - rc.left;
-    }
-    else
-    {
-        GetWindowRect(infoPtr->hwndSelf, &rc);
-        infoPtr->nWidth = rc.right - rc.left;
-    }
+    x  = infoPtr->nIndent;
+    width = infoPtr->client_rect.right - infoPtr->client_rect.left;
 
     bButtonWrap = FALSE;
 
-    TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
-          infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth,
-          infoPtr->nIndent);
+    TRACE("start ButtonWidth=%d, BitmapWidth=%d, width=%d, nIndent=%d\n",
+         infoPtr->nButtonWidth, infoPtr->nBitmapWidth, width,
+         infoPtr->nIndent);
 
-    for (i = 0; i < infoPtr->nNumButtons; i++)
+    for (i = 0; i < infoPtr->nNumButtons; i++ )
     {
-        btnPtr[i].fsState &= ~TBSTATE_WRAP;
+       btnPtr[i].fsState &= ~TBSTATE_WRAP;
 
-        if (btnPtr[i].fsState & TBSTATE_HIDDEN)
-            continue;
+       if (btnPtr[i].fsState & TBSTATE_HIDDEN)
+           continue;
 
         if (btnPtr[i].cx > 0)
             cx = btnPtr[i].cx;
         /* horizontal separators are treated as buttons for width    */
-        else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
-                 !(infoPtr->dwStyle & CCS_VERT))
+       else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
+            !(infoPtr->dwStyle & CCS_VERT))
             cx = (btnPtr[i].iBitmap > 0) ? btnPtr[i].iBitmap : SEPARATOR_WIDTH;
-        else
-            cx = infoPtr->nButtonWidth;
-
-        /* Two or more adjacent separators form a separator group.   */
-        /* The first separator in a group should be wrapped to the   */
-        /* next row if the previous wrapping is on a button.        */
-        if (bButtonWrap &&
-            (btnPtr[i].fsStyle & BTNS_SEP) &&
-            (i + 1 < infoPtr->nNumButtons) &&
-            (btnPtr[i + 1].fsStyle & BTNS_SEP))
-        {
-            TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
-            btnPtr[i].fsState |= TBSTATE_WRAP;
-            x = infoPtr->nIndent;
-            i++;
-            bButtonWrap = FALSE;
-            continue;
-        }
+       else
+           cx = infoPtr->nButtonWidth;
+
+        if (!btnPtr[i].cx && button_has_ddarrow( infoPtr, btnPtr + i ))
+            cx += DDARROW_WIDTH;
+
+       /* Two or more adjacent separators form a separator group.   */
+       /* The first separator in a group should be wrapped to the   */
+       /* next row if the previous wrapping is on a button.         */
+       if( bButtonWrap &&
+               (btnPtr[i].fsStyle & BTNS_SEP) &&
+               (i + 1 < infoPtr->nNumButtons ) &&
+               (btnPtr[i + 1].fsStyle & BTNS_SEP) )
+       {
+           TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
+           btnPtr[i].fsState |= TBSTATE_WRAP;
+           x = infoPtr->nIndent;
+           i++;
+           bButtonWrap = FALSE;
+           continue;
+       }
 
-        /* The layout makes sure the bitmap is visible, but not the button. */
-        /* Test added to also wrap after a button that starts a row but     */
-        /* is bigger than the area.  - GA  8/01                             */
-        if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
-            > infoPtr->nWidth) ||
-            ((x == infoPtr->nIndent) && (cx > infoPtr->nWidth)))
-        {
-            BOOL bFound = FALSE;
-
-            /*         If the current button is a separator and not hidden,  */
-            /* go to the next until it reaches a non separator.      */
-            /* Wrap the last separator if it is before a button.     */
-            while ((((btnPtr[i].fsStyle & BTNS_SEP) &&
-                !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
-                (btnPtr[i].fsState & TBSTATE_HIDDEN)) &&
-                i < infoPtr->nNumButtons)
-            {
-                i++;
-                bFound = TRUE;
-            }
+       /* The layout makes sure the bitmap is visible, but not the button. */
+       /* Test added to also wrap after a button that starts a row but     */
+       /* is bigger than the area.  - GA  8/01                             */
+        if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2 > width) ||
+            ((x == infoPtr->nIndent) && (cx > width)))
+       {
+           BOOL bFound = FALSE;
+
+           /*  If the current button is a separator and not hidden,  */
+           /*  go to the next until it reaches a non separator.      */
+           /*  Wrap the last separator if it is before a button.     */
+           while( ( ((btnPtr[i].fsStyle & BTNS_SEP) &&
+                     !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
+                    (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
+                       i < infoPtr->nNumButtons )
+           {
+               i++;
+               bFound = TRUE;
+           }
 
-            if (bFound && i < infoPtr->nNumButtons)
-            {
-                i--;
-                TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
-                      i, btnPtr[i].fsStyle, x, cx);
-                btnPtr[i].fsState |= TBSTATE_WRAP;
-                x = infoPtr->nIndent;
-                bButtonWrap = FALSE;
-                continue;
-            }
-            else if (i >= infoPtr->nNumButtons)
-                break;
+           if( bFound && i < infoPtr->nNumButtons )
+           {
+               i--;
+               TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
+                     i, btnPtr[i].fsStyle, x, cx);
+               btnPtr[i].fsState |= TBSTATE_WRAP;
+               x = infoPtr->nIndent;
+               bButtonWrap = FALSE;
+               continue;
+           }
+           else if ( i >= infoPtr->nNumButtons)
+               break;
 
-            /*         If the current button is not a separator, find the last  */
-            /* separator and wrap it.                                   */
-            for (j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
-            {
-                if ((btnPtr[j].fsStyle & BTNS_SEP) &&
-                    !(btnPtr[j].fsState & TBSTATE_HIDDEN))
-                {
-                    bFound = TRUE;
-                    i = j;
-                    TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
-                          i, btnPtr[i].fsStyle, x, cx);
-                    x = infoPtr->nIndent;
-                    btnPtr[j].fsState |= TBSTATE_WRAP;
-                    bButtonWrap = FALSE;
-                    break;
-                }
-            }
+           /*  If the current button is not a separator, find the last  */
+           /*  separator and wrap it.                                   */
+           for ( j = i - 1; j >= 0  &&  !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
+           {
+               if ((btnPtr[j].fsStyle & BTNS_SEP) &&
+                       !(btnPtr[j].fsState & TBSTATE_HIDDEN))
+               {
+                   bFound = TRUE;
+                   i = j;
+                   TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
+                         i, btnPtr[i].fsStyle, x, cx);
+                   x = infoPtr->nIndent;
+                   btnPtr[j].fsState |= TBSTATE_WRAP;
+                   bButtonWrap = FALSE;
+                   break;
+               }
+           }
 
-            /*         If no separator available for wrapping, wrap one of     */
-            /*  non-hidden previous button.                            */
-            if (!bFound)
-            {
-                for (j = i - 1;
-                     j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
-                {
-                    if (btnPtr[j].fsState & TBSTATE_HIDDEN)
-                        continue;
-
-                    bFound = TRUE;
-                    i = j;
-                    TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
-                          i, btnPtr[i].fsStyle, x, cx);
-                    x = infoPtr->nIndent;
-                    btnPtr[j].fsState |= TBSTATE_WRAP;
-                    bButtonWrap = TRUE;
-                    break;
-                }
-            }
+           /*  If no separator available for wrapping, wrap one of     */
+           /*  non-hidden previous button.                             */
+           if (!bFound)
+           {
+               for ( j = i - 1;
+                       j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
+               {
+                   if (btnPtr[j].fsState & TBSTATE_HIDDEN)
+                       continue;
+
+                   bFound = TRUE;
+                   i = j;
+                   TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
+                         i, btnPtr[i].fsStyle, x, cx);
+                   x = infoPtr->nIndent;
+                   btnPtr[j].fsState |= TBSTATE_WRAP;
+                   bButtonWrap = TRUE;
+                   break;
+               }
+           }
 
-            /* If all above failed, wrap the current button. */
-            if (!bFound)
-            {
-                TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
-                      i, btnPtr[i].fsStyle, x, cx);
-                btnPtr[i].fsState |= TBSTATE_WRAP;
-                x = infoPtr->nIndent;
-                if (btnPtr[i].fsStyle & BTNS_SEP)
-                    bButtonWrap = FALSE;
-                else
-                    bButtonWrap = TRUE;
-            }
-        }
-        else
-        {
-            TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
-                  i, btnPtr[i].fsStyle, x, cx);
-            x += cx;
-        }
+           /* If all above failed, wrap the current button. */
+           if (!bFound)
+           {
+               TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
+                     i, btnPtr[i].fsStyle, x, cx);
+               btnPtr[i].fsState |= TBSTATE_WRAP;
+               x = infoPtr->nIndent;
+               if (btnPtr[i].fsStyle & BTNS_SEP )
+                   bButtonWrap = FALSE;
+               else
+                   bButtonWrap = TRUE;
+           }
+       }
+       else {
+           TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
+                 i, btnPtr[i].fsStyle, x, cx);
+           x += cx;
+       }
     }
 }
 
@@ -1610,8 +1646,14 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
         /* ... add on the necessary padding */
         if (bValidImageList)
         {
+#ifdef __REACTOS__
             sizeButton.cy += infoPtr->szPadding.cy;
             if (!bHasBitmap)
+#else
+            if (bHasBitmap)
+                sizeButton.cy += DEFPAD_CY;
+            else
+#endif
                 sizeButton.cy += LISTPAD_CY;
         }
         else
@@ -1628,7 +1670,11 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
     {
         if (bHasBitmap)
         {
+#ifdef __REACTOS__
             sizeButton.cy = infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
+#else
+            sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY;
+#endif
             if (sizeString.cy > 0)
                 sizeButton.cy += 1 + sizeString.cy;
             sizeButton.cx = infoPtr->szPadding.cx +
@@ -1685,17 +1731,16 @@ static void
 TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
 {
     TBUTTON_INFO *btnPtr;
-    SIZE          sizeButton;
-    INT           i, nRows, nSepRows;
-    INT           x, y, cx, cy;
-    BOOL          bWrap;
-    BOOL          validImageList    = TOOLBAR_IsValidImageList(infoPtr, 0);
-    BOOL          hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
+    SIZE sizeButton;
+    INT i, nRows, nSepRows;
+    INT x, y, cx, cy;
+    BOOL bWrap;
+    BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0);
 
     TOOLBAR_WrapToolbar(infoPtr);
 
-    x = infoPtr->nIndent;
-    y = infoPtr->iTopMargin;
+    x  = infoPtr->nIndent;
+    y  = infoPtr->iTopMargin;
     cx = infoPtr->nButtonWidth;
     cy = infoPtr->nButtonHeight;
 
@@ -1710,112 +1755,104 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
 
     TRACE("cy=%d\n", cy);
 
-    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
+    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
     {
-        bWrap = FALSE;
-        if (btnPtr->fsState & TBSTATE_HIDDEN)
-        {
-            SetRectEmpty(&btnPtr->rect);
-            continue;
-        }
+       bWrap = FALSE;
+       if (btnPtr->fsState & TBSTATE_HIDDEN)
+       {
+           SetRectEmpty (&btnPtr->rect);
+           continue;
+       }
 
-        cy = infoPtr->nButtonHeight;
+       cy = infoPtr->nButtonHeight;
 
-        if (btnPtr->fsStyle & BTNS_SEP)
-        {
-            if (infoPtr->dwStyle & CCS_VERT)
-            {
+       if (btnPtr->fsStyle & BTNS_SEP) {
+           if (infoPtr->dwStyle & CCS_VERT) {
                 cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
                 cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth;
-            }
-            else
-            {
+           }
+           else
                 cx = (btnPtr->cx > 0) ? btnPtr->cx :
                     (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
-            }
-        }
-        else
-        {
+       }
+       else
+       {
             if (btnPtr->cx)
+              cx = btnPtr->cx;
+            else if (btnPtr->fsStyle & BTNS_AUTOSIZE)
             {
-                cx = btnPtr->cx;
-            }
-            else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
-                     (btnPtr->fsStyle & BTNS_AUTOSIZE))
-            {
-                SIZE sz;
-                HDC hdc;
-                HFONT hOldFont;
+              SIZE sz;
+             HDC hdc;
+             HFONT hOldFont;
 
-                hdc = GetDC(infoPtr->hwndSelf);
-                hOldFont = SelectObject(hdc, infoPtr->hFont);
+             hdc = GetDC (infoPtr->hwndSelf);
+             hOldFont = SelectObject (hdc, infoPtr->hFont);
 
-                TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
+              TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
 
-                SelectObject(hdc, hOldFont);
-                ReleaseDC(infoPtr->hwndSelf, hdc);
+             SelectObject (hdc, hOldFont);
+             ReleaseDC (infoPtr->hwndSelf, hdc);
 
-                sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
-                                                   TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
-                                                   validImageList);
-                cx = sizeButton.cx;
+              sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
+                  TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
+                  validImageList);
+              cx = sizeButton.cx;
             }
             else
-                cx = infoPtr->nButtonWidth;
+             cx = infoPtr->nButtonWidth;
 
             /* if size has been set manually then don't add on extra space
              * for the drop down arrow */
-            if (!btnPtr->cx && hasDropDownArrows &&
-                ((btnPtr->fsStyle & BTNS_DROPDOWN) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN)))
-                cx += DDARROW_WIDTH;
-        }
-        if (btnPtr->fsState & TBSTATE_WRAP)
-            bWrap = TRUE;
+            if (!btnPtr->cx && button_has_ddarrow( infoPtr, btnPtr ))
+              cx += DDARROW_WIDTH;
+       }
+       if (btnPtr->fsState & TBSTATE_WRAP)
+                   bWrap = TRUE;
 
-        SetRect(&btnPtr->rect, x, y, x + cx, y + cy);
+       SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
 
-        if (infoPtr->rcBound.left > x)
-            infoPtr->rcBound.left = x;
-        if (infoPtr->rcBound.right < x + cx)
-            infoPtr->rcBound.right = x + cx;
-        if (infoPtr->rcBound.bottom < y + cy)
-            infoPtr->rcBound.bottom = y + cy;
+       if (infoPtr->rcBound.left > x)
+           infoPtr->rcBound.left = x;
+       if (infoPtr->rcBound.right < x + cx)
+           infoPtr->rcBound.right = x + cx;
+       if (infoPtr->rcBound.bottom < y + cy)
+           infoPtr->rcBound.bottom = y + cy;
 
         TOOLBAR_TooltipSetRect(infoPtr, btnPtr);
 
-        /* btnPtr->nRow is zero based. The space between the rows is   */
-        /* also considered as a row.                                   */
-        btnPtr->nRow = nRows + nSepRows;
+       /* btnPtr->nRow is zero based. The space between the rows is    */
+       /* also considered as a row.                                    */
+       btnPtr->nRow = nRows + nSepRows;
 
-        TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n",
-              i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow,
-              x, y, x + cx, y + cy);
+       TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n",
+             i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow,
+             x, y, x+cx, y+cy);
 
-        if (bWrap)
-        {
-            if (!(btnPtr->fsStyle & BTNS_SEP))
-                y += cy;
-            else
-            {
-                if (!(infoPtr->dwStyle & CCS_VERT))
-                    y += cy + ((btnPtr->cx > 0) ?
-                    btnPtr->cx : SEPARATOR_WIDTH) * 2 / 3;
-                else
-                    y += cy;
+       if( bWrap )
+       {
+           if ( !(btnPtr->fsStyle & BTNS_SEP) )
+               y += cy;
+           else
+           {
+               if ( !(infoPtr->dwStyle & CCS_VERT))
+                    y += cy + ( (btnPtr->cx > 0 ) ?
+                                btnPtr->cx : SEPARATOR_WIDTH) * 2 /3;
+               else
+                   y += cy;
 
-                /* nSepRows is used to calculate the extra height following  */
-                /* the last row.                                            */
-                nSepRows++;
-            }
-            x = infoPtr->nIndent;
+               /* nSepRows is used to calculate the extra height following  */
+               /* the last row.                                             */
+               nSepRows++;
+           }
+           x = infoPtr->nIndent;
 
-            /* Increment row number unless this is the last button    */
-            /* and it has Wrap set.                                   */
-            if (i != infoPtr->nNumButtons - 1)
-                nRows++;
-        }
-        else
-            x += cx;
+           /* Increment row number unless this is the last button    */
+           /* and it has Wrap set.                                   */
+           if (i != infoPtr->nNumButtons-1)
+               nRows++;
+       }
+       else
+           x += cx;
     }
 
     /* infoPtr->nRows is the number of rows on the toolbar */
@@ -1881,6 +1918,7 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto
     /* insert new buttons data */
     for (iButton = 0; iButton < nAddButtons; iButton++) {
         TBUTTON_INFO *btnPtr = &infoPtr->buttons[iIndex + iButton];
+        INT_PTR str;
 
         TOOLBAR_DumpTBButton(lpTbb + iButton, fUnicode);
 
@@ -1891,18 +1929,13 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto
         btnPtr->fsState   = lpTbb[iButton].fsState;
         btnPtr->fsStyle   = lpTbb[iButton].fsStyle;
         btnPtr->dwData    = lpTbb[iButton].dwData;
+
         if (btnPtr->fsStyle & BTNS_SEP)
-            btnPtr->iString = -1;
-        else if(!IS_INTRESOURCE(lpTbb[iButton].iString) && lpTbb[iButton].iString != -1)
-        {
-            if (fUnicode)
-                Str_SetPtrW((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[iButton].iString );
-            else
-                Str_SetPtrAtoW((LPWSTR*)&btnPtr->iString, (LPSTR)lpTbb[iButton].iString);
-            fHasString = TRUE;
-        }
+            str = -1;
         else
-            btnPtr->iString   = lpTbb[iButton].iString;
+            str = lpTbb[iButton].iString;
+        set_string_index( btnPtr, str, fUnicode );
+        fHasString |= TOOLBAR_ButtonHasString( btnPtr );
 
         TOOLBAR_TooltipAddTool(infoPtr, btnPtr);
     }
@@ -2005,8 +2038,8 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
     SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
 }
 
-
-static LRESULT 
+#ifdef __REACTOS__
+static LRESULT
 TOOLBAR_ThemeChanged(HWND hwnd)
 {
     HTHEME theme = GetWindowTheme(hwnd);
@@ -2014,6 +2047,7 @@ TOOLBAR_ThemeChanged(HWND hwnd)
     OpenThemeData(hwnd, themeClass);
     return 0;
 }
+#endif
 
 static void
 TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
@@ -3079,38 +3113,28 @@ TOOLBAR_AddStringA (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam)
 static LRESULT
 TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr)
 {
-    RECT parent_rect;
-    HWND parent;
-    INT  x, y;
-    INT  cx, cy;
-
     TRACE("auto sizing, style=%x!\n", infoPtr->dwStyle);
+    TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight);
 
-    parent = GetParent (infoPtr->hwndSelf);
+    if (!(infoPtr->dwStyle & CCS_NORESIZE))
+    {
+        RECT window_rect, parent_rect;
+        UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE;
+        HWND parent;
+        INT  x, y, cx, cy;
 
-    if (!parent || !infoPtr->bDoRedraw)
-        return 0;
+        parent = GetParent (infoPtr->hwndSelf);
 
-    GetClientRect(parent, &parent_rect);
+        if (!parent || !infoPtr->bDoRedraw)
+            return 0;
 
-    x = parent_rect.left;
-    y = parent_rect.top;
+        GetClientRect(parent, &parent_rect);
 
-    TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight);
+        x = parent_rect.left;
+        y = parent_rect.top;
 
-    cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER;
-    cx = parent_rect.right - parent_rect.left;
-
-    if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))
-    {
-        TOOLBAR_LayoutToolbar(infoPtr);
-        InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
-    }
-
-    if (!(infoPtr->dwStyle & CCS_NORESIZE))
-    {
-        RECT window_rect;
-        UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE;
+        cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER;
+        cx = parent_rect.right - parent_rect.left;
 
         if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_NOMOVEY)
         {
@@ -3139,6 +3163,12 @@ TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr)
         SetWindowPos(infoPtr->hwndSelf, NULL, x, y, cx, cy, uPosFlags);
     }
 
+    if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))
+    {
+        TOOLBAR_LayoutToolbar(infoPtr);
+        InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
+    }
+
     return 0;
 }
 
@@ -3281,8 +3311,7 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
 
     if (infoPtr->nNumButtons == 1) {
        TRACE(" simple delete!\n");
-       if (TOOLBAR_ButtonHasString(infoPtr->buttons))
-           Free((LPWSTR)infoPtr->buttons[0].iString);
+        free_string( infoPtr->buttons );
        Free (infoPtr->buttons);
        infoPtr->buttons = NULL;
        infoPtr->nNumButtons = 0;
@@ -3303,8 +3332,7 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
                     (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
         }
 
-        if (TOOLBAR_ButtonHasString(&oldButtons[nIndex]))
-            Free((LPWSTR)oldButtons[nIndex].iString);
+        free_string( oldButtons + nIndex );
        Free (oldButtons);
     }
 
@@ -3425,8 +3453,7 @@ TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTb
     if (nIndex == -1)
        return -1;
 
-    if (!(btnPtr = &infoPtr->buttons[nIndex])) return -1;
-
+    btnPtr = &infoPtr->buttons[nIndex];
     if (lpTbInfo->dwMask & TBIF_COMMAND)
        lpTbInfo->idCommand = btnPtr->idCommand;
     if (lpTbInfo->dwMask & TBIF_IMAGE)
@@ -3603,9 +3630,9 @@ TOOLBAR_GetMaxSize (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize)
     return TRUE;
 }
 
-
+#ifdef __REACTOS__
 static LRESULT
-TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
+TOOLBAR_GetMetrics(const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
 {
     if (pMetrics == NULL)
         return FALSE;
@@ -3632,7 +3659,7 @@ TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
 
     return TRUE;
 }
-
+#endif
 
 /* << TOOLBAR_GetObject >> */
 
@@ -4155,12 +4182,55 @@ TOOLBAR_ReplaceBitmap (TOOLBAR_INFO *infoPtr, const TBREPLACEBITMAP *lpReplace)
 
 /* helper for TOOLBAR_SaveRestoreW */
 static BOOL
-TOOLBAR_Save(const TBSAVEPARAMSW *lpSave)
+TOOLBAR_Save(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *params)
 {
-    FIXME("save to %s %s\n", debugstr_w(lpSave->pszSubKey),
-        debugstr_w(lpSave->pszValueName));
+    NMTBSAVE save;
+    INT ret, i;
+    BOOL alloced = FALSE;
+    HKEY key;
 
-    return FALSE;
+    TRACE( "save to %s %s\n", debugstr_w(params->pszSubKey), debugstr_w(params->pszValueName) );
+
+    memset( &save, 0, sizeof(save) );
+    save.cbData = infoPtr->nNumButtons * sizeof(DWORD);
+    save.iItem = -1;
+    save.cButtons = infoPtr->nNumButtons;
+    save.tbButton.idCommand = -1;
+    TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE );
+
+    if (!save.pData)
+    {
+        save.pData = Alloc( save.cbData );
+        if (!save.pData) return FALSE;
+        alloced = TRUE;
+    }
+    if (!save.pCurrent) save.pCurrent = save.pData;
+
+    for (i = 0; i < infoPtr->nNumButtons; i++)
+    {
+        save.iItem = i;
+        save.tbButton.iBitmap = infoPtr->buttons[i].iBitmap;
+        save.tbButton.idCommand = infoPtr->buttons[i].idCommand;
+        save.tbButton.fsState = infoPtr->buttons[i].fsState;
+        save.tbButton.fsStyle = infoPtr->buttons[i].fsStyle;
+        memset( save.tbButton.bReserved, 0, sizeof(save.tbButton.bReserved) );
+        save.tbButton.dwData = infoPtr->buttons[i].dwData;
+        save.tbButton.iString = infoPtr->buttons[i].iString;
+
+        *save.pCurrent++ = save.tbButton.idCommand;
+
+        TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE );
+    }
+
+    ret = RegCreateKeyW( params->hkr, params->pszSubKey, &key );
+    if (ret == ERROR_SUCCESS)
+    {
+        ret = RegSetValueExW( key, params->pszValueName, 0, REG_BINARY, (BYTE *)save.pData, save.cbData );
+        RegCloseKey( key );
+    }
+
+    if (alloced) Free( save.pData );
+    return !ret;
 }
 
 
@@ -4172,6 +4242,7 @@ TOOLBAR_DeleteAllButtons(TOOLBAR_INFO *infoPtr)
 
     for (i = 0; i < infoPtr->nNumButtons; i++)
     {
+        free_string( infoPtr->buttons + i );
         TOOLBAR_TooltipDelTool(infoPtr, &infoPtr->buttons[i]);
     }
 
@@ -4191,6 +4262,7 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
     DWORD dwType;
     DWORD dwSize = 0;
     NMTBRESTORE nmtbr;
+    NMHDR hdr;
 
     /* restore toolbar information */
     TRACE("restore from %s %s\n", debugstr_w(lpSave->pszSubKey),
@@ -4223,30 +4295,30 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
 
         if (!TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE))
         {
-            INT i;
+            INT i, count = nmtbr.cButtons;
 
             /* remove all existing buttons as this function is designed to
              * restore the toolbar to a previously saved state */
             TOOLBAR_DeleteAllButtons(infoPtr);
 
-            for (i = 0; i < nmtbr.cButtons; i++)
+            for (i = 0; i < count; i++)
             {
                 nmtbr.iItem = i;
                 nmtbr.tbButton.iBitmap = -1;
                 nmtbr.tbButton.fsState = 0;
                 nmtbr.tbButton.fsStyle = 0;
-                nmtbr.tbButton.idCommand = 0;
-                if (*nmtbr.pCurrent == (DWORD)-1)
+                nmtbr.tbButton.dwData = 0;
+                nmtbr.tbButton.iString = 0;
+
+                if (*nmtbr.pCurrent & 0x80000000)
                 {
                     /* separator */
-                    nmtbr.tbButton.fsStyle = TBSTYLE_SEP;
-                    /* when inserting separators, iBitmap controls its size.
-                       0 sets default size (width) */
-                    nmtbr.tbButton.iBitmap = 0;
+                    nmtbr.tbButton.iBitmap = SEPARATOR_WIDTH;
+                    nmtbr.tbButton.idCommand = 0;
+                    nmtbr.tbButton.fsStyle = BTNS_SEP;
+                    if (*nmtbr.pCurrent != (DWORD)-1)
+                        nmtbr.tbButton.fsState = TBSTATE_HIDDEN;
                 }
-                else if (*nmtbr.pCurrent == (DWORD)-2)
-                    /* hidden button */
-                    nmtbr.tbButton.fsState = TBSTATE_HIDDEN;
                 else
                     nmtbr.tbButton.idCommand = (int)*nmtbr.pCurrent;
 
@@ -4254,21 +4326,51 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
                 
                 TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE);
 
-                /* can't contain real string as we don't know whether
-                 * the client put an ANSI or Unicode string in there */
+                /* All returned ptrs and -1 are ignored */
                 if (!IS_INTRESOURCE(nmtbr.tbButton.iString))
                     nmtbr.tbButton.iString = 0;
 
                 TOOLBAR_InsertButtonT(infoPtr, -1, &nmtbr.tbButton, TRUE);
             }
 
-            /* do legacy notifications */
-            if (infoPtr->iVersion < 5)
+            TOOLBAR_SendNotify( &hdr, infoPtr, TBN_BEGINADJUST );
+            for (i = 0; ; i++)
             {
-                /* FIXME: send TBN_BEGINADJUST */
-                FIXME("send TBN_GETBUTTONINFO for each button\n");
-                /* FIXME: send TBN_ENDADJUST */
+                NMTOOLBARW tb;
+                TBBUTTONINFOW bi;
+                WCHAR buf[128];
+                UINT code = infoPtr->bUnicode ? TBN_GETBUTTONINFOW : TBN_GETBUTTONINFOA;
+                INT idx;
+
+                memset( &tb, 0, sizeof(tb) );
+                tb.iItem = i;
+                tb.cchText = sizeof(buf) / sizeof(buf[0]);
+                tb.pszText = buf;
+
+                /* Use the same struct for both A and W versions since the layout is the same. */
+                if (!TOOLBAR_SendNotify( &tb.hdr, infoPtr, code ))
+                    break;
+
+                idx = TOOLBAR_GetButtonIndex( infoPtr, tb.tbButton.idCommand, FALSE );
+                if (idx == -1) continue;
+
+                /* tb.pszText is ignored - the string comes from tb.tbButton.iString, which may
+                   be an index or a ptr.  Either way it is simply copied.  There is no api to change
+                   the string index, so we set it manually.  The other properties can be set with SetButtonInfo. */
+                free_string( infoPtr->buttons + idx );
+                infoPtr->buttons[idx].iString = tb.tbButton.iString;
+
+                memset( &bi, 0, sizeof(bi) );
+                bi.cbSize = sizeof(bi);
+                bi.dwMask = TBIF_IMAGE | TBIF_STATE | TBIF_STYLE | TBIF_LPARAM;
+                bi.iImage = tb.tbButton.iBitmap;
+                bi.fsState = tb.tbButton.fsState;
+                bi.fsStyle = tb.tbButton.fsStyle;
+                bi.lParam = tb.tbButton.dwData;
+
+                TOOLBAR_SetButtonInfo( infoPtr, tb.tbButton.idCommand, &bi, TRUE );
             }
+            TOOLBAR_SendNotify( &hdr, infoPtr, TBN_ENDADJUST );
 
             /* remove all uninitialised buttons
              * note: loop backwards to avoid having to fixup i on a
@@ -4294,7 +4396,7 @@ TOOLBAR_SaveRestoreW (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSW
     if (lpSave == NULL) return 0;
 
     if (wParam)
-        return TOOLBAR_Save(lpSave);
+        return TOOLBAR_Save(infoPtr, lpSave);
     else
         return TOOLBAR_Restore(infoPtr, lpSave);
 }
@@ -4312,7 +4414,7 @@ TOOLBAR_SaveRestoreA (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSA
 
     len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, NULL, 0);
     pszSubKey = Alloc(len * sizeof(WCHAR));
-    if (pszSubKey) goto exit;
+    if (!pszSubKey) goto exit;
     MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, pszSubKey, len);
 
     len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszValueName, -1, NULL, 0);
@@ -4429,15 +4531,8 @@ TOOLBAR_SetButtonInfo (TOOLBAR_INFO *infoPtr, INT Id,
     if (lptbbi->dwMask & TBIF_STYLE)
        btnPtr->fsStyle = lptbbi->fsStyle;
 
-    if ((lptbbi->dwMask & TBIF_TEXT) && ((INT_PTR)lptbbi->pszText != -1)) {
-        /* iString is index, zero it to make Str_SetPtr succeed */
-        if (!TOOLBAR_ButtonHasString(btnPtr)) btnPtr->iString = 0;
-
-        if (isW)
-            Str_SetPtrW ((LPWSTR *)&btnPtr->iString, lptbbi->pszText);
-        else
-            Str_SetPtrAtoW ((LPWSTR *)&btnPtr->iString, (LPSTR)lptbbi->pszText);
-    }
+    if (lptbbi->dwMask & TBIF_TEXT)
+        set_stringT( btnPtr, lptbbi->pszText, isW );
 
     /* save the button rect to see if we need to redraw the whole toolbar */
     oldBtnRect = btnPtr->rect;
@@ -4456,6 +4551,7 @@ static LRESULT
 TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam)
 {
     INT cx = (short)LOWORD(lParam), cy = (short)HIWORD(lParam);
+    int top = default_top_margin(infoPtr);
 
     if ((cx < 0) || (cy < 0))
     {
@@ -4478,15 +4574,20 @@ TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam)
      */
     if (cx == 0) cx = 24;
     if (cy == 0) cy = 22;
-    
+
     cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth);
     cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight);
 
-    infoPtr->nButtonWidth = cx;
-    infoPtr->nButtonHeight = cy;
-    
-    infoPtr->iTopMargin = default_top_margin(infoPtr);
-    TOOLBAR_LayoutToolbar(infoPtr);
+    if (cx != infoPtr->nButtonWidth || cy != infoPtr->nButtonHeight ||
+        top != infoPtr->iTopMargin)
+    {
+        infoPtr->nButtonWidth = cx;
+        infoPtr->nButtonHeight = cy;
+        infoPtr->iTopMargin = top;
+
+        TOOLBAR_LayoutToolbar( infoPtr );
+        InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
+    }
     return TRUE;
 }
 
@@ -4814,9 +4915,9 @@ TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *infoPtr, INT nMaxRows)
     return TRUE;
 }
 
-
+#ifdef __REACTOS__
 static LRESULT
-TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
+TOOLBAR_SetMetrics(TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
 {
     BOOL changed = FALSE;
 
@@ -4851,6 +4952,7 @@ TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics)
 
     return TRUE;
 }
+#endif
 
 /* MSDN gives slightly wrong info on padding.
  * 1. It is not only used on buttons with the BTNS_AUTOSIZE style
@@ -5041,11 +5143,45 @@ TOOLBAR_SetState (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam)
     return TRUE;
 }
 
+static inline void unwrap(TOOLBAR_INFO *info)
+{
+    int i;
+
+    for (i = 0; i < info->nNumButtons; i++)
+       info->buttons[i].fsState &= ~TBSTATE_WRAP;
+}
 
 static LRESULT
 TOOLBAR_SetStyle (TOOLBAR_INFO *infoPtr, DWORD style)
 {
+    DWORD dwOldStyle = infoPtr->dwStyle;
+
+    TRACE("new style 0x%08x\n", style);
+
+    if (style & TBSTYLE_LIST)
+        infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
+    else
+        infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS;
+
     infoPtr->dwStyle = style;
+    TOOLBAR_CheckStyle(infoPtr);
+
+    if ((dwOldStyle ^ style) & TBSTYLE_WRAPABLE)
+    {
+        if (dwOldStyle & TBSTYLE_WRAPABLE)
+            unwrap(infoPtr);
+        TOOLBAR_CalcToolbar(infoPtr);
+    }
+    else if ((dwOldStyle ^ style) & CCS_VERT)
+        TOOLBAR_LayoutToolbar(infoPtr);
+
+    /* only resize if one of the CCS_* styles was changed */
+    if ((dwOldStyle ^ style) & COMMON_STYLES)
+    {
+        TOOLBAR_AutoSize(infoPtr);
+        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
+    }
+
     return 0;
 }
 
@@ -5319,8 +5455,7 @@ TOOLBAR_Destroy (TOOLBAR_INFO *infoPtr)
 
     /* delete button data */
     for (i = 0; i < infoPtr->nNumButtons; i++)
-        if (TOOLBAR_ButtonHasString(&infoPtr->buttons[i]))
-            Free ((LPWSTR)infoPtr->buttons[i].iString);
+        free_string( infoPtr->buttons + i );
     Free (infoPtr->buttons);
 
     /* delete strings */
@@ -6035,7 +6170,6 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
     /* paranoid!! */
     infoPtr->dwStructSize = sizeof(TBBUTTON);
     infoPtr->nRows = 1;
-    infoPtr->nWidth = 0;
 
     /* initialize info structure */
     infoPtr->nButtonWidth = 23;
@@ -6462,30 +6596,7 @@ static LRESULT
 TOOLBAR_StyleChanged (TOOLBAR_INFO *infoPtr, INT nType, const STYLESTRUCT *lpStyle)
 {
     if (nType == GWL_STYLE)
-    {
-        DWORD dwOldStyle = infoPtr->dwStyle;
-
-        if (lpStyle->styleNew & TBSTYLE_LIST)
-            infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
-        else
-            infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS;
-
-        TRACE("new style 0x%08x\n", lpStyle->styleNew);
-
-        infoPtr->dwStyle = lpStyle->styleNew;
-        TOOLBAR_CheckStyle (infoPtr);
-
-        if ((dwOldStyle ^ lpStyle->styleNew) & (TBSTYLE_WRAPABLE | CCS_VERT))
-            TOOLBAR_LayoutToolbar(infoPtr);
-
-        /* only resize if one of the CCS_* styles was changed */
-        if ((dwOldStyle ^ lpStyle->styleNew) & COMMON_STYLES)
-        {
-            TOOLBAR_AutoSize (infoPtr);
-    
-            InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
-        }
-    }
+        return TOOLBAR_SetStyle(infoPtr, lpStyle->styleNew);
 
     return 0;
 }
@@ -6499,6 +6610,16 @@ TOOLBAR_SysColorChange (void)
     return 0;
 }
 
+#ifndef __REACTOS__
+/* update theme after a WM_THEMECHANGED message */
+static LRESULT theme_changed (HWND hwnd)
+{
+    HTHEME theme = GetWindowTheme (hwnd);
+    CloseThemeData (theme);
+    OpenThemeData (hwnd, themeClass);
+    return 0;
+}
+#endif
 
 static LRESULT WINAPI
 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -6603,9 +6724,10 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
        case TB_GETMAXSIZE:
            return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam);
-        
+#ifdef __REACTOS__
        case TB_GETMETRICS:
            return TOOLBAR_GetMetrics (infoPtr, (TBMETRICS*)lParam);
+#endif
 
 /*     case TB_GETOBJECT:                      */ /* 4.71 */
 
@@ -6622,7 +6744,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_GetState (infoPtr, wParam);
 
        case TB_GETSTRINGA:
-        return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam);
+            return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam);
 
        case TB_GETSTRINGW:
            return TOOLBAR_GetStringW (infoPtr, wParam, (LPWSTR)lParam);
@@ -6747,8 +6869,10 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        case TB_SETMAXTEXTROWS:
            return TOOLBAR_SetMaxTextRows (infoPtr, wParam);
 
+#ifdef __REACTOS__
        case TB_SETMETRICS:
            return TOOLBAR_SetMetrics (infoPtr, (TBMETRICS*)lParam);
+#endif
 
        case TB_SETPADDING:
            return TOOLBAR_SetPadding (infoPtr, lParam);
@@ -6875,7 +6999,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_SetFocus (infoPtr);
 
        case WM_SETFONT:
-        return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);
+            return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);
 
        case WM_SETREDRAW:
            return TOOLBAR_SetRedraw (infoPtr, wParam);
@@ -6890,7 +7014,11 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_SysColorChange ();
             
     case WM_THEMECHANGED:
+#ifdef __REACTOS__
         return TOOLBAR_ThemeChanged(hwnd);
+#else
+            return theme_changed (hwnd);
+#endif
 
 /*     case WM_WININICHANGE: */
 
index 9a98203..20fe63b 100644 (file)
@@ -98,6 +98,7 @@ static HICON hTooltipIcons[TTI_ERROR+1];
 typedef struct
 {
     UINT      uFlags;
+    UINT      uInternalFlags;
     HWND      hwnd;
     BOOL      bNotifyUnicode;
     UINT_PTR  uId;
@@ -471,13 +472,12 @@ TOOLTIPS_GetTipText (const TOOLTIPS_INFO *infoPtr, INT nTool, WCHAR *buffer)
 {
     TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
 
-    /* always NULL-terminate the buffer, just in case we fail to load the string */
-    buffer[0] = '\0';
     if (IS_INTRESOURCE(toolPtr->lpszText)) {
-        HINSTANCE hinst = toolPtr->hinst ? toolPtr->hinst : GetModuleHandleW(NULL);
-        /* load a resource */
-        TRACE("load res string %p %x\n", hinst, LOWORD(toolPtr->lpszText));
-        LoadStringW (hinst, LOWORD(toolPtr->lpszText), buffer, INFOTIPSIZE);
+       /* load a resource */
+       TRACE("load res string %p %x\n",
+              toolPtr->hinst, LOWORD(toolPtr->lpszText));
+       if (!LoadStringW (toolPtr->hinst, LOWORD(toolPtr->lpszText), buffer, INFOTIPSIZE))
+           buffer[0] = '\0';
     }
     else if (toolPtr->lpszText) {
        if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW) {
@@ -493,6 +493,7 @@ TOOLTIPS_GetTipText (const TOOLTIPS_INFO *infoPtr, INT nTool, WCHAR *buffer)
     }
     else {
        /* no text available */
+        buffer[0] = '\0';
     }
 
     TRACE("%s\n", debugstr_w(buffer));
@@ -1044,11 +1045,12 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
     infoPtr->uNumTools++;
 
     /* copy tool data */
-    toolPtr->uFlags = ti->uFlags;
-    toolPtr->hwnd   = ti->hwnd;
-    toolPtr->uId    = ti->uId;
-    toolPtr->rect   = ti->rect;
-    toolPtr->hinst  = ti->hinst;
+    toolPtr->uFlags         = ti->uFlags;
+    toolPtr->uInternalFlags = (ti->uFlags & (TTF_SUBCLASS | TTF_IDISHWND));
+    toolPtr->hwnd           = ti->hwnd;
+    toolPtr->uId            = ti->uId;
+    toolPtr->rect           = ti->rect;
+    toolPtr->hinst          = ti->hinst;
 
     if (ti->cbSize >= TTTOOLINFOW_V1_SIZE) {
         if (IS_INTRESOURCE(ti->lpszText)) {
@@ -1079,8 +1081,8 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
        toolPtr->lParam = ti->lParam;
 
     /* install subclassing hook */
-    if (toolPtr->uFlags & TTF_SUBCLASS) {
-       if (toolPtr->uFlags & TTF_IDISHWND) {
+    if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
+       if (toolPtr->uInternalFlags & TTF_IDISHWND) {
            SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
                              (DWORD_PTR)infoPtr->hwndSelf);
        }
@@ -1139,8 +1141,8 @@ TOOLTIPS_DelToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
     }
 
     /* remove subclassing */
-    if (toolPtr->uFlags & TTF_SUBCLASS) {
-       if (toolPtr->uFlags & TTF_IDISHWND) {
+    if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
+       if (toolPtr->uInternalFlags & TTF_IDISHWND) {
            RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
        }
        else {
@@ -1905,8 +1907,8 @@ TOOLTIPS_Destroy (TOOLTIPS_INFO *infoPtr)
            }
 
            /* remove subclassing */
-        if (toolPtr->uFlags & TTF_SUBCLASS) {
-            if (toolPtr->uFlags & TTF_IDISHWND) {
+        if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
+            if (toolPtr->uInternalFlags & TTF_IDISHWND) {
                 RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
             }
             else {
@@ -1994,6 +1996,7 @@ TOOLTIPS_NCHitTest (const TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 static LRESULT
 TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
+#ifdef __REACTOS__
     TTTOOL_INFO *toolPtr = infoPtr->tools;
     LRESULT nResult;
 
@@ -2020,6 +2023,9 @@ TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
         }
         return nResult;
     }
+#else
+    FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
+#endif
 
     return 0;
 }
index 986b04f..ef9bd3c 100644 (file)
@@ -29,7 +29,7 @@
  *
  * TODO:
  *   missing notifications: TVN_GETINFOTIP, TVN_KEYDOWN,
- *      TVN_SETDISPINFO, TVN_SINGLEEXPAND
+ *      TVN_SETDISPINFO
  *
  *   missing styles: TVS_FULLROWSELECT, TVS_INFOTIP, TVS_RTLREADING,
  *
@@ -2869,11 +2869,13 @@ TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
     }
 
     //
-    // This is correct, but is causes and infinite loop of WM_PAINT messages, resulting
-    // in continuous painting of the scroll bar in reactos. Comment out until the real
-    // bug is found
-    // 
-    //TREEVIEW_UpdateScrollBars(infoPtr);
+    // FIXME: This is correct, but is causes and infinite loop of WM_PAINT
+    // messages, resulting in continuous painting of the scroll bar in reactos.
+    // Comment out until the real bug is found
+    //
+#ifndef __REACTOS__
+    TREEVIEW_UpdateScrollBars(infoPtr);
+#endif
 
     if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
        infoPtr->cdmode =
@@ -3491,47 +3493,31 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item,
 static void TREEVIEW_SingleExpand(TREEVIEW_INFO *infoPtr,
     HTREEITEM selection, HTREEITEM item)
 {
-    TREEVIEW_ITEM *SelItem;
+    TREEVIEW_ITEM *prev, *curr;
 
     if ((infoPtr->dwStyle & TVS_SINGLEEXPAND) == 0 || infoPtr->hwndEdit || !item) return;
 
     TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SINGLEEXPAND, TVC_UNKNOWN, TVIF_HANDLE | TVIF_PARAM, item, 0);
 
     /*
-     * Close the previous selection all the way to the root
-     * as long as the new selection is not a child
+     * Close the previous item and its ancestors as long as they are not
+     * ancestors of the current item
      */
-    if(selection && (selection != item))
+    for (prev = selection; prev && TREEVIEW_ValidItem(infoPtr, prev); prev = prev->parent)
     {
-        BOOL closeit = TRUE;
-        SelItem = item;
-
-        /* determine if the hitItem is a child of the currently selected item */
-        while(closeit && SelItem && TREEVIEW_ValidItem(infoPtr, SelItem) &&
-              (SelItem->parent != infoPtr->root))
+        for (curr = item; curr && TREEVIEW_ValidItem(infoPtr, curr); curr = curr->parent)
         {
-            closeit = (SelItem != selection);
-            SelItem = SelItem->parent;
-        }
-
-        if(closeit)
-        {
-            if(TREEVIEW_ValidItem(infoPtr, selection))
-                SelItem = selection;
-
-            while(SelItem && (SelItem != item) && TREEVIEW_ValidItem(infoPtr, SelItem) &&
-                  SelItem->parent != infoPtr->root)
-            {
-                TREEVIEW_Collapse(infoPtr, SelItem, FALSE, FALSE);
-                SelItem = SelItem->parent;
-            }
+            if (curr == prev)
+                goto finish;
         }
+        TREEVIEW_Collapse(infoPtr, prev, FALSE, TRUE);
     }
 
+finish:
     /*
      * Expand the current item
      */
-    TREEVIEW_Expand(infoPtr, item, FALSE, FALSE);
+    TREEVIEW_Expand(infoPtr, item, FALSE, TRUE);
 }
 
 static BOOL
@@ -4474,6 +4460,9 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
     if (item && !TREEVIEW_ValidItem(infoPtr, item))
        return FALSE;
 
+    if (item == infoPtr->selectedItem)
+       return TRUE;
+
     TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam);
 
     if (!TREEVIEW_DoSelectItem(infoPtr, wParam, item, TVC_UNKNOWN))
@@ -4659,7 +4648,7 @@ TREEVIEW_EnsureVisible(TREEVIEW_INFO *infoPtr, HTREEITEM item, BOOL bHScroll)
        while (parent != infoPtr->root)
        {
            if (!(parent->state & TVIS_EXPANDED))
-               TREEVIEW_Expand(infoPtr, parent, FALSE, FALSE);
+               TREEVIEW_Expand(infoPtr, parent, FALSE, TRUE);
 
            parent = parent->parent;
        }
index af41129..9aff605 100644 (file)
@@ -351,12 +351,18 @@ static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
  */
 static BOOL UPDOWN_DrawBuddyBackground (const UPDOWN_INFO *infoPtr, HDC hdc)
 {
-    RECT br;
+    RECT br, r;
     HTHEME buddyTheme = GetWindowTheme (infoPtr->Buddy);
     if (!buddyTheme) return FALSE;
 
-    GetClientRect (infoPtr->Buddy, &br);
-    MapWindowPoints (infoPtr->Buddy, infoPtr->Self, (POINT*)&br, 2);
+    GetWindowRect (infoPtr->Buddy, &br);
+    MapWindowPoints (NULL, infoPtr->Self, (POINT*)&br, 2);
+    GetClientRect (infoPtr->Self, &r);
+
+    if (infoPtr->dwStyle & UDS_ALIGNLEFT)
+        br.left = r.left;
+    else if (infoPtr->dwStyle & UDS_ALIGNRIGHT)
+        br.right = r.right;
     /* FIXME: take disabled etc. into account */
     DrawThemeBackground (buddyTheme, hdc, 0, 0, &br, NULL);
     return TRUE;
index f3f7f83..ea84c97 100644 (file)
@@ -55,7 +55,7 @@ reactos/dll/win32/browseui            # Out of sync
 reactos/dll/win32/cabinet             # Synced to WineStaging-1.7.37
 reactos/dll/win32/clusapi             # Synced to WineStaging-1.7.37
 reactos/dll/win32/comcat              # Synced to WineStaging-1.7.37
-reactos/dll/win32/comctl32            # Synced to WineStaging-1.7.37
+reactos/dll/win32/comctl32            # Synced to WineStaging-1.7.47
 reactos/dll/win32/comdlg32            # Synced to WineStaging-1.7.37
 reactos/dll/win32/compstui            # Synced to WineStaging-1.7.37
 reactos/dll/win32/credui              # Synced to WineStaging-1.7.37