Index: trunk/src/comctl32/listview.c
===================================================================
--- trunk/src/comctl32/listview.c	(revision 10533)
+++ trunk/src/comctl32/listview.c	(revision 10535)
@@ -8937,5 +8937,5 @@
 #ifdef __WIN32OS2__
 #ifdef DEBUG
-void dprintfMsg(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+static void dprintfMsg(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
  char *msg = NULL;
Index: trunk/src/comctl32/rebar.c
===================================================================
--- trunk/src/comctl32/rebar.c	(revision 10533)
+++ trunk/src/comctl32/rebar.c	(revision 10535)
@@ -120,5 +120,5 @@
  *    Still to do:
  *  2. Following still not handled: RBBS_FIXEDBMP,
- *            RBBS_USECHEVRON, CCS_NORESIZE,
+ *            CCS_NORESIZE,
  *            CCS_NOMOVEX, CCS_NOMOVEY
  *  3. Following are only partially handled:
@@ -137,15 +137,19 @@
  *  7. The following notifications are not implemented:
  *        NM_CUSTOMDRAW, NM_RELEASEDCAPTURE
- *        RB_CHEVRONPUSHED, RBN_MINMAX
+ *        RBN_MINMAX
  */
 
+#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "windef.h"
 #include "winbase.h"
 #include "wingdi.h"
 #include "wine/unicode.h"
+#include "winuser.h"
+#include "winnls.h"
 #include "commctrl.h"
-/* #include "spy.h" */
+#include "comctl32.h"
 #include "wine/debug.h"
 
@@ -191,4 +195,5 @@
     RECT    rcCapText;      /* calculated caption text rectangle */
     RECT    rcChild;        /* calculated child rectangle */
+    RECT    rcChevron;      /* calculated chevron rectangle */
 
     LPWSTR    lpText;
@@ -207,12 +212,9 @@
 #define DRAW_RIGHTSEP   0x00000010
 #define DRAW_BOTTOMSEP  0x00000020
+#define DRAW_CHEVRONHOT 0x00000040
+#define DRAW_CHEVRONPUSHED 0x00000080
+#define DRAW_LAST_IN_ROW   0x00000100
+#define DRAW_FIRST_IN_ROW  0x00000200
 #define NTF_INVALIDATE  0x01000000
-
-typedef struct
-{
-    INT      istartband;  /* index of first band in row */
-    INT      iendband;    /* index of last band in row */
-} REBAR_ROW;
-
 
 typedef struct
@@ -245,9 +247,10 @@
     POINTS   dragStart;   /* x,y of button down */
     POINTS   dragNow;     /* x,y of this MouseMove */
-    INT      ihitBand;    /* band number of band whose gripper was grabbed */
+    INT      iOldBand;    /* last band that had the mouse cursor over it */
     INT      ihitoffset;  /* offset of hotspot from gripper.left */
     POINT    origin;      /* left/upper corner of client */
-
-    REBAR_ROW  *rows;       /* pointer to row indexes              */
+    INT      ichevronhotBand; /* last band that had a hot chevron */
+    INT      iGrabbedBand;/* band number of band whose gripper was grabbed */
+
     REBAR_BAND *bands;      /* pointer to the array of rebar bands */
 } REBAR_INFO;
@@ -290,4 +293,7 @@
 #define GRIPPER_WIDTH  3
 
+/* Width of the chevron button if present */
+#define CHEVRON_WIDTH  10
+
 /* Height of divider for Rebar if not disabled (CCS_NODIVIDER)     */
 /* either top or bottom                                            */
@@ -299,4 +305,5 @@
 /* ----   End of REBAR layout constants.                      ---- */
 
+#define RB_GETBANDINFO_OLD (WM_USER+5) /* obsoleted after IE3, but we have to support it anyway */
 
 /*  The following 6 defines return the proper rcBand element       */
@@ -331,5 +338,5 @@
 static UINT mindragy = 0;
 
-static char *band_stylename[] = {
+static const char *band_stylename[] = {
     "RBBS_BREAK",              /* 0001 */
     "RBBS_FIXEDSIZE",          /* 0002 */
@@ -343,5 +350,5 @@
     NULL };
 
-static char *band_maskname[] = {
+static const char *band_maskname[] = {
     "RBBIM_STYLE",         /*    0x00000001 */
     "RBBIM_COLORS",        /*    0x00000002 */
@@ -408,12 +415,12 @@
 	TRACE("band info:");
 	if (pB->fMask & RBBIM_SIZE)
-	    DPRINTF(" cx=%u", pB->cx);
+	    TRACE(" cx=%u", pB->cx);
 	if (pB->fMask & RBBIM_IDEALSIZE)
-	    DPRINTF(" xIdeal=%u", pB->cxIdeal);
+	    TRACE(" xIdeal=%u", pB->cxIdeal);
 	if (pB->fMask & RBBIM_HEADERSIZE)
-	    DPRINTF(" xHeader=%u", pB->cxHeader);
+	    TRACE(" xHeader=%u", pB->cxHeader);
 	if (pB->fMask & RBBIM_LPARAM)
-	    DPRINTF(" lParam=0x%08lx", pB->lParam);
-	DPRINTF("\n");
+	    TRACE(" lParam=0x%08lx", pB->lParam);
+	TRACE("\n");
     }
     if (pB->fMask & RBBIM_CHILDSIZE)
@@ -434,8 +441,8 @@
 	  iP->hwndSelf, iP->clrText, iP->clrBk, iP->uNumBands, iP->uNumRows,
 	  iP->calcSize.cx, iP->calcSize.cy);
-    TRACE("hwnd=%p: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, ihitBand=%d\n",
+    TRACE("hwnd=%p: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, iGrabbedBand=%d\n",
 	  iP->hwndSelf, iP->fStatus, iP->dragStart.x, iP->dragStart.y,
 	  iP->dragNow.x, iP->dragNow.y,
-	  iP->ihitBand);
+	  iP->iGrabbedBand);
     TRACE("hwnd=%p: style=%08lx, I'm Unicode=%s, notify in Unicode=%s, redraw=%s\n",
 	  iP->hwndSelf, iP->dwStyle, (iP->bUnicode)?"TRUE":"FALSE",
@@ -453,11 +460,11 @@
 	if (pB->fMask & (RBBIM_SIZE | RBBIM_IDEALSIZE | RBBIM_LPARAM )) {
 	    if (pB->fMask & RBBIM_SIZE)
-		DPRINTF(" cx=%u", pB->cx);
+		TRACE(" cx=%u", pB->cx);
 	    if (pB->fMask & RBBIM_IDEALSIZE)
-		DPRINTF(" xIdeal=%u", pB->cxIdeal);
+		TRACE(" xIdeal=%u", pB->cxIdeal);
 	    if (pB->fMask & RBBIM_LPARAM)
-		DPRINTF(" lParam=0x%08lx", pB->lParam);
-	}
-	DPRINTF("\n");
+		TRACE(" lParam=0x%08lx", pB->lParam);
+	}
+	TRACE("\n");
 	if (RBBIM_CHILDSIZE)
 	    TRACE("band # %u: xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
@@ -468,9 +475,9 @@
 	TRACE("band # %u: lcx=%u, ccx=%u, hcx=%u, lcy=%u, ccy=%u, hcy=%u, offChild=%ld,%ld\n",
 	      i, pB->lcx, pB->ccx, pB->hcx, pB->lcy, pB->ccy, pB->hcy, pB->offChild.cx, pB->offChild.cy);
-	TRACE("band # %u: fStatus=%08x, fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
+	TRACE("band # %u: fStatus=%08x, fDraw=%08x, Band=(%ld,%ld)-(%ld,%ld), Grip=(%ld,%ld)-(%ld,%ld)\n",
 	      i, pB->fStatus, pB->fDraw,
 	      pB->rcBand.left, pB->rcBand.top, pB->rcBand.right, pB->rcBand.bottom,
 	      pB->rcGripper.left, pB->rcGripper.top, pB->rcGripper.right, pB->rcGripper.bottom);
-	TRACE("band # %u: Img=(%d,%d)-(%d,%d), Txt=(%d,%d)-(%d,%d), Child=(%d,%d)-(%d,%d)\n",
+	TRACE("band # %u: Img=(%ld,%ld)-(%ld,%ld), Txt=(%ld,%ld)-(%ld,%ld), Child=(%ld,%ld)-(%ld,%ld)\n",
 	      i,
 	      pB->rcCapImage.left, pB->rcCapImage.top, pB->rcCapImage.right, pB->rcCapImage.bottom,
@@ -481,4 +488,23 @@
 }
 
+static void
+REBAR_DrawChevron (HDC hdc, INT left, INT top, INT colorRef)
+{
+    INT x, y;
+    HPEN hPen, hOldPen;
+
+    if (!(hPen = CreatePen( PS_SOLID, 1, GetSysColor( colorRef )))) return;
+    hOldPen = SelectObject ( hdc, hPen );
+    x = left + 2;
+    y = top;
+    MoveToEx (hdc, x, y, NULL);
+    LineTo (hdc, x+5, y++); x++;
+    MoveToEx (hdc, x, y, NULL);
+    LineTo (hdc, x+3, y++); x++;
+    MoveToEx (hdc, x, y, NULL);
+    LineTo (hdc, x+1, y++);
+    SelectObject( hdc, hOldPen );
+    DeleteObject( hPen );
+}
 
 static HWND
@@ -610,4 +636,20 @@
     }
 
+    if (!IsRectEmpty(&lpBand->rcChevron))
+    {
+        if (lpBand->fDraw & DRAW_CHEVRONPUSHED)
+        {
+            DrawEdge(hdc, &lpBand->rcChevron, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE);
+            REBAR_DrawChevron(hdc, lpBand->rcChevron.left+1, lpBand->rcChevron.top + 11, COLOR_WINDOWFRAME);
+        }
+        else if (lpBand->fDraw & DRAW_CHEVRONHOT)
+        {
+            DrawEdge(hdc, &lpBand->rcChevron, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
+            REBAR_DrawChevron(hdc, lpBand->rcChevron.left, lpBand->rcChevron.top + 10, COLOR_WINDOWFRAME);
+        }
+        else
+            REBAR_DrawChevron(hdc, lpBand->rcChevron.left, lpBand->rcChevron.top + 10, COLOR_WINDOWFRAME);
+    }
+
     if (lpBand->uCDret == (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW)) {
 	nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
@@ -628,9 +670,8 @@
 {
     REBAR_BAND *lpBand;
-    UINT i, oldrow;
+    UINT i;
 
     if (!infoPtr->DoRedraw) return;
 
-    oldrow = infoPtr->bands[0].iRow;
     for (i = 0; i < infoPtr->uNumBands; i++) {
 	lpBand = &infoPtr->bands[i];
@@ -681,5 +722,5 @@
 	    (lpBand->rcoldBand.bottom !=lpBand->rcBand.bottom)) {
 	    lpBand->fDraw |= NTF_INVALIDATE;
-	    TRACE("band %d row=%d: changed to (%d,%d)-(%d,%d) from (%d,%d)-(%d,%d)\n",
+	    TRACE("band %d row=%d: changed to (%ld,%ld)-(%ld,%ld) from (%ld,%ld)-(%ld,%ld)\n",
 		  i, lpBand->iRow,
 		  lpBand->rcBand.left, lpBand->rcBand.top,
@@ -689,5 +730,5 @@
 	}
 	else
-	    TRACE("band %d row=%d: unchanged (%d,%d)-(%d,%d)\n",
+	    TRACE("band %d row=%d: unchanged (%ld,%ld)-(%ld,%ld)\n",
 		  i, lpBand->iRow,
 		  lpBand->rcBand.left, lpBand->rcBand.top,
@@ -765,5 +806,5 @@
 	else
 	    lpBand->rcBand.right = lpBand->rcBand.left + curwidth;
-	TRACE("Phase 1 band %d, (%d,%d)-(%d,%d), orig x=%d, xsep=%d\n",
+	TRACE("Phase 1 band %d, (%ld,%ld)-(%ld,%ld), orig x=%d, xsep=%d\n",
 	      i, lpBand->rcBand.left, lpBand->rcBand.top,
 	      lpBand->rcBand.right, lpBand->rcBand.bottom, x, xsep);
@@ -835,5 +876,5 @@
 	else
 	    lpBand->rcBand.right = lpBand->rcBand.left + curwidth;
-	TRACE("Phase 2 band %d, (%d,%d)-(%d,%d), orig x=%d, xsep=%d\n",
+	TRACE("Phase 2 band %d, (%ld,%ld)-(%ld,%ld), orig x=%d, xsep=%d\n",
 	      i, lpBand->rcBand.left, lpBand->rcBand.top,
 	      lpBand->rcBand.right, lpBand->rcBand.bottom, x, xsep);
@@ -951,4 +992,11 @@
 		   lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top+yoff,
 		   lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
+	  if ((lpBand->fStyle & RBBS_USECHEVRON) && (lpBand->rcChild.right - lpBand->rcChild.left < lpBand->cxIdeal))
+	  {
+	      lpBand->rcChild.right -= CHEVRON_WIDTH;
+	      SetRect(&lpBand->rcChevron, lpBand->rcChild.right,
+	              lpBand->rcChild.top, lpBand->rcChild.right + CHEVRON_WIDTH,
+	              lpBand->rcChild.bottom);
+	  }
       }
       else {
@@ -963,5 +1011,5 @@
 	   (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
 	  TRACE("Child rectangle changed for band %u\n", i);
-	  TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
+	  TRACE("    from (%ld,%ld)-(%ld,%ld)  to (%ld,%ld)-(%ld,%ld)\n",
 		oldChild.left, oldChild.top,
 	        oldChild.right, oldChild.bottom,
@@ -970,5 +1018,5 @@
       }
       if (lpBand->fDraw & NTF_INVALIDATE) {
-	  TRACE("invalidating (%d,%d)-(%d,%d)\n",
+	  TRACE("invalidating (%ld,%ld)-(%ld,%ld)\n",
 		lpBand->rcBand.left,
 		lpBand->rcBand.top,
@@ -1102,5 +1150,5 @@
 	     (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
 	    TRACE("Child rectangle changed for band %u\n", i);
-	    TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
+	    TRACE("    from (%ld,%ld)-(%ld,%ld)  to (%ld,%ld)-(%ld,%ld)\n",
 		  oldChild.left, oldChild.top,
 		  oldChild.right, oldChild.bottom,
@@ -1109,5 +1157,5 @@
 	}
 	if (lpBand->fDraw & NTF_INVALIDATE) {
-	    TRACE("invalidating (%d,%d)-(%d,%d)\n",
+	    TRACE("invalidating (%ld,%ld)-(%ld,%ld)\n",
 		  lpBand->rcBand.left,
 		  lpBand->rcBand.top,
@@ -1142,5 +1190,5 @@
     GetClientRect (infoPtr->hwndSelf, &rc);
 
-    TRACE( " old [%ld x %ld], new [%ld x %ld], client [%d x %d]\n",
+    TRACE( " old [%ld x %ld], new [%ld x %ld], client [%ld x %ld]\n",
 	   infoPtr->oldSize.cx, infoPtr->oldSize.cy,
 	   infoPtr->calcSize.cx, infoPtr->calcSize.cy,
@@ -1228,5 +1276,4 @@
 	infoPtr->hwndSelf, infoPtr->dwStyle,
 	x, y, width, height);
-
 #ifdef __WIN32OS2__
 //NOTE: this one is causing problems!!!!
@@ -1271,5 +1318,5 @@
 	    if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
 		TRACE("Child rect changed by NOTIFY for band %u\n", i);
-		TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
+		TRACE("    from (%ld,%ld)-(%ld,%ld)  to (%ld,%ld)-(%ld,%ld)\n",
 		      lpBand->rcChild.left, lpBand->rcChild.top,
 		      lpBand->rcChild.right, lpBand->rcChild.bottom,
@@ -1302,5 +1349,5 @@
 
 		/* center combo box inside child area */
-		TRACE("moving child (Combo(Ex)) %p to (%d,%d) for (%d,%d)\n",
+		TRACE("moving child (Combo(Ex)) %p to (%ld,%d) for (%ld,%d)\n",
 		      lpBand->hwndChild,
 		      lpBand->rcChild.left, yPos,
@@ -1317,5 +1364,5 @@
 	    }
 	    else {
-		TRACE("moving child (Other) %p to (%d,%d) for (%d,%d)\n",
+		TRACE("moving child (Other) %p to (%ld,%ld) for (%ld,%ld)\n",
 		      lpBand->hwndChild,
 		      lpBand->rcChild.left, lpBand->rcChild.top,
@@ -1377,10 +1424,10 @@
 
     GetClientRect (infoPtr->hwndSelf, &rcClient);
-    TRACE("Client is (%d,%d)-(%d,%d)\n",
+    TRACE("Client is (%ld,%ld)-(%ld,%ld)\n",
 	  rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
 
     if (lpRect) {
 	rcAdj = *lpRect;
-	TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
+	TRACE("adjustment rect is (%ld,%ld)-(%ld,%ld)\n",
 	      rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
     }
@@ -1433,4 +1480,6 @@
 	lpBand->iRow = row;
 
+	SetRectEmpty(&lpBand->rcChevron);
+
 	if (HIDDENBAND(lpBand)) continue;
 
@@ -1446,8 +1495,5 @@
 	/* separator from previous band */
 	cxsep = (cntonrow == 0) ? 0 : SEP_WIDTH;
-
-	/* Header: includes gripper, text, image */
-	cx = lpBand->cxHeader;
-	if (lpBand->fStyle & RBBS_FIXEDSIZE) cx = lpBand->lcx;
+	cx = lpBand->lcx;
 
 	if (infoPtr->dwStyle & CCS_VERT)
@@ -1538,5 +1584,5 @@
 	    x = rightx;
 	}
-	TRACE("P1 band %u, row %d, (%d,%d)-(%d,%d)\n",
+	TRACE("P1 band %u, row %d, (%ld,%ld)-(%ld,%ld)\n",
 	      i, row,
 	      lpBand->rcBand.left, lpBand->rcBand.top,
@@ -1617,6 +1663,7 @@
     /*   y/x     current height/width of all rows                    */
     if (lpRect) {
-        INT i, j, prev_rh, new_rh, adj_rh, prev_idx, current_idx;
+        INT i, prev_rh, new_rh, adj_rh, prev_idx, current_idx;
 	REBAR_BAND *prev, *current, *walk;
+	UINT j;
 
 /* FIXME:  problem # 2 */
@@ -1625,5 +1672,5 @@
 	     (x < adjcx) : (y < adjcy)
 #else
-	     (adjcx - x > 4) : (adjcy - y > 4)
+	     (adjcx - x > 5) : (adjcy - y > 4)
 #endif
 	     ) &&
@@ -1678,9 +1725,9 @@
 			y += adj_rh;
 		    }
-		    TRACE("P2 moving band %d to own row at (%d,%d)-(%d,%d)\n",
+		    TRACE("P2 moving band %d to own row at (%ld,%ld)-(%ld,%ld)\n",
 			  current_idx,
 			  current->rcBand.left, current->rcBand.top,
 			  current->rcBand.right, current->rcBand.bottom);
-		    TRACE("P2 prev band %d at (%d,%d)-(%d,%d)\n",
+		    TRACE("P2 prev band %d at (%ld,%ld)-(%ld,%ld)\n",
 			  prev_idx,
 			  prev->rcBand.left, prev->rcBand.top,
@@ -1713,37 +1760,27 @@
 
 
-    /* ******* Start Phase 2a - create array of start and end  ******* */
-    /*                          indexes by row                         */
-
-    if (infoPtr->uNumRows != origrows) {
-	if (infoPtr->rows) COMCTL32_Free (infoPtr->rows);
-	infoPtr->rows = COMCTL32_Alloc (sizeof (REBAR_ROW) * infoPtr->uNumRows);
-    }
-
-    row = 0;
-    for (i = 0; i < infoPtr->uNumBands; i++) {
-	lpBand = &infoPtr->bands[i];
-	if (HIDDENBAND(lpBand)) continue;
-
-	if (lpBand->iRow > row) {
-	    row++;
-	    infoPtr->rows[row-1].istartband = i;
-	}
-	if (row == 0) {
-	    ERR("P2a bug!!!!!!\n");
-	}
-	infoPtr->rows[row-1].iendband = i;
-    }
-
-    for (i = 0; i < infoPtr->uNumRows; i++) {
-	REBAR_ROW *p;
-
-	p = &infoPtr->rows[i];
-	TRACE("P2a row %d, starts %d, ends %d\n",
-	      i+1, p->istartband, p->iendband);
-    }
-
-    /* ******* End Phase 2a - create array of start and end    ******* */
-    /*                          indexes by row                         */
+    /* ******* Start Phase 2a - mark first and last band in each ******* */
+
+    prevBand = NULL;
+    for (i = 0; i < infoPtr->uNumBands; i++) { 	 
+        lpBand = &infoPtr->bands[i]; 	 
+        if (HIDDENBAND(lpBand))
+            continue;
+        if( !prevBand ) {
+            lpBand->fDraw |= DRAW_FIRST_IN_ROW;
+            prevBand = lpBand;
+        }
+        else if( prevBand->iRow == lpBand->iRow )
+            prevBand = lpBand;
+        else {
+            prevBand->fDraw |= DRAW_LAST_IN_ROW;
+            lpBand->fDraw |= DRAW_FIRST_IN_ROW;
+            prevBand = lpBand;
+        }
+    }
+    if( prevBand )
+        prevBand->fDraw |= DRAW_LAST_IN_ROW;
+
+    /* ******* End Phase 2a - mark first and last band in each ******* */
 
 
@@ -1755,15 +1792,20 @@
     if (((infoPtr->dwStyle & CCS_VERT) ? clientcx > x : clientcy > y) &&
 	infoPtr->uNumBands) {
-	INT diff, i, iband, j;
+	INT diff, i;
+	UINT j;
 
 	diff = (infoPtr->dwStyle & CCS_VERT) ? clientcx - x : clientcy - y;
-	for (i = infoPtr->uNumRows; i >= 1; i--) {
-	    /* if row has more than 1 band, ignore row   */
-	    if (infoPtr->rows[i-1].istartband != infoPtr->rows[i-1].iendband)
-		continue;
-	    /* point to only band in row  */
-	    iband = infoPtr->rows[i-1].istartband;
-	    lpBand = &infoPtr->bands[iband];
+
+        /* iterate backwards thru the rows */
+        for (i = infoPtr->uNumBands-1; i>=0; i--) {
+	    lpBand = &infoPtr->bands[i];
 	    if(HIDDENBAND(lpBand)) continue;
+
+	    /* if row has more than 1 band, ignore it */
+            if( !(lpBand->fDraw&DRAW_FIRST_IN_ROW) )
+                continue;
+            if( !(lpBand->fDraw&DRAW_LAST_IN_ROW) )
+                continue;
+
 	    if (lpBand->fMask & RBBS_VARIABLEHEIGHT) continue;
 	    if (((INT)lpBand->cyMaxChild < 1) ||
@@ -1771,5 +1813,5 @@
 		if (lpBand->cyMaxChild + lpBand->cyIntegral == 0) continue;
 		ERR("P2b band %u RBBS_VARIABLEHEIGHT set but cyMax=%d, cyInt=%d\n",
-		    iband, lpBand->cyMaxChild, lpBand->cyIntegral);
+		    i, lpBand->cyMaxChild, lpBand->cyIntegral);
 		continue;
 	    }
@@ -1784,6 +1826,6 @@
 	    else
 		lpBand->rcBand.bottom = lpBand->rcBand.top + j;
-	    TRACE("P2b band %d, row %d changed to (%d,%d)-(%d,%d)\n",
-		  iband, lpBand->iRow,
+	    TRACE("P2b band %d, row %d changed to (%ld,%ld)-(%ld,%ld)\n",
+		  i, lpBand->iRow,
 		  lpBand->rcBand.left, lpBand->rcBand.top,
 		  lpBand->rcBand.right, lpBand->rcBand.bottom);
@@ -1806,5 +1848,5 @@
 
     if (infoPtr->uNumBands) {
-	REBAR_ROW *p;
+        int startband;
 
 	/* If RBS_BANDBORDERS set then indicate to draw bottom separator */
@@ -1814,14 +1856,16 @@
 	if (infoPtr->dwStyle & RBS_BANDBORDERS) {
 
-	    for(i = 0; i < infoPtr->uNumRows; i++) {
-		p = &infoPtr->rows[i];
-		for (j = p->istartband; j <= p->iendband; j++) {
-		    lpBand = &infoPtr->bands[j];
-		    if (HIDDENBAND(lpBand)) continue;
-		    if (j != p->iendband)
-			lpBand->fDraw |= DRAW_RIGHTSEP;
-		    if (i != infoPtr->uNumRows-1)
-			lpBand->fDraw |= DRAW_BOTTOMSEP;
-		}
+            for (i=0; i<infoPtr->uNumBands; i++) {
+	        lpBand = &infoPtr->bands[i];
+		if (HIDDENBAND(lpBand))
+                    continue;
+
+                /* not righthand bands */
+                if( !(lpBand->fDraw & DRAW_LAST_IN_ROW) )
+		    lpBand->fDraw |= DRAW_RIGHTSEP;
+
+                /* not the last row */
+                if( lpBand->iRow != infoPtr->uNumRows )
+		    lpBand->fDraw |= DRAW_BOTTOMSEP;
 	    }
 	}
@@ -1829,22 +1873,30 @@
 	/* Distribute the extra space on the horizontal and adjust  */
 	/* all bands in row to same height.                         */
-	for (i=1; i<=infoPtr->uNumRows; i++) {
-	    p = &infoPtr->rows[i-1];
-	    mcy = 0;
-
-	    TRACE("P3 processing row %d, starting band %d, ending band %d\n",
-		  i, p->istartband, p->iendband);
-
-	    /* Find the largest height of the bands in the row */
-	    for (j = p->istartband; j <= p->iendband; j++) {
-		lpBand = &infoPtr->bands[j];
-		if (HIDDENBAND(lpBand)) continue;
-		if (mcy < ircBw(lpBand))
-		    mcy = ircBw(lpBand);
-	    }
-
-	    REBAR_AdjustBands (infoPtr, p->istartband, p->iendband,
+	mcy = 0;
+        startband = -1;
+        for (i=0; i<infoPtr->uNumBands; i++) {
+
+            lpBand = &infoPtr->bands[i];
+
+            if( lpBand->fDraw & DRAW_FIRST_IN_ROW )
+            {
+                startband = i;
+                mcy = 0;
+            }
+
+            if ( (mcy < ircBw(lpBand)) && !HIDDENBAND(lpBand) )
+                mcy = ircBw(lpBand);
+
+            if( lpBand->fDraw & DRAW_LAST_IN_ROW )
+            {
+	        TRACE("P3 processing row %d, starting band %d, ending band %d\n",
+		      lpBand->iRow, startband, i);
+                if( startband < 0 )
+                    ERR("Last band %d with no first, row %d\n", i, lpBand->iRow);
+
+	        REBAR_AdjustBands (infoPtr, startband, i,
 			       (infoPtr->dwStyle & CCS_VERT) ?
 			       clientcy : clientcx, mcy);
+            }
 	}
 
@@ -1900,5 +1952,5 @@
     UINT header=0;
     UINT textheight=0;
-    INT i, nonfixed;
+    UINT i, nonfixed;
     REBAR_BAND *tBand;
 
@@ -2038,23 +2090,40 @@
 }
 
-static void
+static BOOL
 REBAR_CommonSetupBand (HWND hwnd, LPREBARBANDINFOA lprbbi, REBAR_BAND *lpBand)
      /* Function:  This routine copies the supplied values from   */
      /*  user input (lprbbi) to the internal band structure.      */
-{
+     /*  It returns true if something changed and false if not.   */
+{
+    BOOL bChanged = FALSE;
+
     lpBand->fMask |= lprbbi->fMask;
 
-    if (lprbbi->fMask & RBBIM_STYLE)
+    if( (lprbbi->fMask & RBBIM_STYLE) &&
+        (lpBand->fStyle != lprbbi->fStyle ) )
+    {
 	lpBand->fStyle = lprbbi->fStyle;
-
-    if (lprbbi->fMask & RBBIM_COLORS) {
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_COLORS) &&
+       ( ( lpBand->clrFore != lprbbi->clrFore ) ||
+         ( lpBand->clrBack != lprbbi->clrBack ) ) )
+    {
 	lpBand->clrFore = lprbbi->clrFore;
 	lpBand->clrBack = lprbbi->clrBack;
-    }
-
-    if (lprbbi->fMask & RBBIM_IMAGE)
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_IMAGE) &&
+       ( lpBand->iImage != lprbbi->iImage ) )
+    {
 	lpBand->iImage = lprbbi->iImage;
-
-    if (lprbbi->fMask & RBBIM_CHILD) {
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_CHILD) &&
+       (lprbbi->hwndChild != lpBand->hwndChild ) )
+    {
 	if (lprbbi->hwndChild) {
 	    lpBand->hwndChild = lprbbi->hwndChild;
@@ -2071,7 +2140,19 @@
 	    lpBand->hwndPrevParent = 0;
 	}
-    }
-
-    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_CHILDSIZE) &&
+        ( (lpBand->cxMinChild != lprbbi->cxMinChild) ||
+          (lpBand->cyMinChild != lprbbi->cyMinChild ) ||
+          ( (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) &&
+            ( (lpBand->cyChild    != lprbbi->cyChild ) ||
+              (lpBand->cyMaxChild != lprbbi->cyMaxChild ) ||
+              (lpBand->cyIntegral != lprbbi->cyIntegral ) ) ) ||
+          ( (lprbbi->cbSize < sizeof (REBARBANDINFOA)) &&
+            ( (lpBand->cyChild || 
+               lpBand->cyMaxChild || 
+               lpBand->cyIntegral ) ) ) ) )
+    {
 	lpBand->cxMinChild = lprbbi->cxMinChild;
 	lpBand->cyMinChild = lprbbi->cyMinChild;
@@ -2087,26 +2168,53 @@
 	    lpBand->cyIntegral = 0;
 	}
-    }
-
-    if (lprbbi->fMask & RBBIM_SIZE)
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_SIZE) &&
+        (lpBand->cx != lprbbi->cx ) )
+    {
 	lpBand->cx = lprbbi->cx;
-
-    if (lprbbi->fMask & RBBIM_BACKGROUND)
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_BACKGROUND) &&
+       ( lpBand->hbmBack != lprbbi->hbmBack ) )
+    {
 	lpBand->hbmBack = lprbbi->hbmBack;
-
-    if (lprbbi->fMask & RBBIM_ID)
+        bChanged = TRUE;
+    }
+
+    if( (lprbbi->fMask & RBBIM_ID) &&
+        (lpBand->wID != lprbbi->wID ) )
+    {
 	lpBand->wID = lprbbi->wID;
+        bChanged = TRUE;
+    }
 
     /* check for additional data */
     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
-	if (lprbbi->fMask & RBBIM_IDEALSIZE)
+	if( (lprbbi->fMask & RBBIM_IDEALSIZE) &&
+            ( lpBand->cxIdeal != lprbbi->cxIdeal ) )
+        {
 	    lpBand->cxIdeal = lprbbi->cxIdeal;
-
-	if (lprbbi->fMask & RBBIM_LPARAM)
+            bChanged = TRUE;
+        }
+
+	if( (lprbbi->fMask & RBBIM_LPARAM) &&
+            (lpBand->lParam != lprbbi->lParam ) )
+        {
 	    lpBand->lParam = lprbbi->lParam;
-
-	if (lprbbi->fMask & RBBIM_HEADERSIZE)
+            bChanged = TRUE;
+        }
+
+	if( (lprbbi->fMask & RBBIM_HEADERSIZE) &&
+            (lpBand->cxHeader != lprbbi->cxHeader ) )
+        {
 	    lpBand->cxHeader = lprbbi->cxHeader;
-    }
+            bChanged = TRUE;
+        }
+    }
+
+    return bChanged;
 }
 
@@ -2119,5 +2227,6 @@
 {
     REBAR_BAND *lpBand;
-    INT i, oldrow;
+    UINT i;
+    INT oldrow;
     HDC hdc = (HDC)wParam;
     RECT rect;
@@ -2145,5 +2254,5 @@
 		    DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_BOTTOM);
 		}
-		TRACE ("drawing band separator bottom (%d,%d)-(%d,%d)\n",
+		TRACE ("drawing band separator bottom (%ld,%ld)-(%ld,%ld)\n",
 		       rcRowSep.left, rcRowSep.top,
 		       rcRowSep.right, rcRowSep.bottom);
@@ -2163,5 +2272,5 @@
 		DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_RIGHT);
 	    }
-	    TRACE("drawing band separator right (%d,%d)-(%d,%d)\n",
+	    TRACE("drawing band separator right (%ld,%ld)-(%ld,%ld)\n",
 		  rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
 	}
@@ -2190,5 +2299,5 @@
 
 	rect = lpBand->rcBand;
-	TRACE("%s background color=0x%06lx, band (%d,%d)-(%d,%d), clip (%d,%d)-(%d,%d)\n",
+	TRACE("%s background color=0x%06lx, band (%ld,%ld)-(%ld,%ld), clip (%ld,%ld)-(%ld,%ld)\n",
 	      (lpBand->clrBack == CLR_NONE) ? "none" :
 	        ((lpBand->clrBack == CLR_DEFAULT) ? "dft" : ""),
@@ -2206,9 +2315,9 @@
 
 static void
-REBAR_InternalHitTest (REBAR_INFO *infoPtr, LPPOINT lpPt, UINT *pFlags, INT *pBand)
+REBAR_InternalHitTest (REBAR_INFO *infoPtr, const LPPOINT lpPt, UINT *pFlags, INT *pBand)
 {
     REBAR_BAND *lpBand;
     RECT rect;
-    INT  iCount;
+    UINT  iCount;
 
     GetClientRect (infoPtr->hwndSelf, &rect);
@@ -2226,5 +2335,4 @@
 	else {
 	    /* somewhere inside */
-	    infoPtr->ihitBand = -1;
 	    for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
 		lpBand = &infoPtr->bands[iCount];
@@ -2235,5 +2343,4 @@
 		    if (PtInRect (&lpBand->rcGripper, *lpPt)) {
 			*pFlags = RBHT_GRABBER;
-			infoPtr->ihitBand = iCount;
 			TRACE("ON GRABBER %d\n", iCount);
 			return;
@@ -2254,4 +2361,9 @@
 			return;
 		    }
+		    else if (PtInRect (&lpBand->rcChevron, *lpPt)) {
+			*pFlags = RBHT_CHEVRON;
+			TRACE("ON CHEVRON %d\n", iCount);
+			return;
+		    }
 		    else {
 			*pFlags = RBHT_NOWHERE;
@@ -2277,7 +2389,4 @@
 	return;
     }
-
-    TRACE("flags=0x%X\n", *pFlags);
-    return;
 }
 
@@ -2344,5 +2453,5 @@
     READJ(band, Readjust);
 
-    TRACE("band %d:  left=%d, right=%d, move=%d, rtn=%d, rcBand=(%d,%d)-(%d,%d)\n",
+    TRACE("band %d:  left=%d, right=%d, move=%d, rtn=%d, rcBand=(%ld,%ld)-(%ld,%ld)\n",
 	  i, Leadjust, Readjust, movement, ret,
 	  band->rcBand.left, band->rcBand.top,
@@ -2375,5 +2484,5 @@
 	    infoPtr->dragStart.y = 0;
 	    infoPtr->dragNow = infoPtr->dragStart;
-	    infoPtr->ihitBand = -1;
+	    infoPtr->iGrabbedBand = -1;
 	    ReleaseCapture ();
 	    return ;
@@ -2382,5 +2491,5 @@
     }
 
-    ihitBand = infoPtr->ihitBand;
+    ihitBand = infoPtr->iGrabbedBand;
     hitBand = &infoPtr->bands[ihitBand];
     imaxdBand = ihitBand; /* to suppress warning message */
@@ -2527,5 +2636,5 @@
 	if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild)
 	    childhwnd = lpBand->hwndChild;
-	COMCTL32_Free (infoPtr->bands);
+	Free (infoPtr->bands);
 	infoPtr->bands = NULL;
 	infoPtr->uNumBands = 0;
@@ -2539,5 +2648,5 @@
 
 	infoPtr->uNumBands--;
-	infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
+	infoPtr->bands = Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
         if (uBand > 0) {
             memcpy (&infoPtr->bands[0], &oldBands[0],
@@ -2550,5 +2659,5 @@
         }
 
-	COMCTL32_Free (oldBands);
+	Free (oldBands);
     }
 
@@ -2631,5 +2740,5 @@
     if (lprbbi == NULL)
 	return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
+    if (lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
 	return FALSE;
     if ((UINT)wParam >= infoPtr->uNumBands)
@@ -2717,5 +2826,5 @@
     if (lprbbi == NULL)
 	return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
+    if (lprbbi->cbSize < REBARBANDINFOW_V3_SIZE)
 	return FALSE;
     if ((UINT)wParam >= infoPtr->uNumBands)
@@ -2868,5 +2977,5 @@
     CopyRect (lprc, &lpBand->rcBand);
 
-    TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand,
+    TRACE("band %d, (%ld,%ld)-(%ld,%ld)\n", iBand,
 	  lprc->left, lprc->top, lprc->right, lprc->bottom);
 
@@ -2888,6 +2997,6 @@
 {
     INT iRow = (INT)wParam;
-    int ret = 0;
-    int i, j = 0;
+    int j = 0, ret = 0;
+    UINT i;
     REBAR_BAND *lpBand;
 
@@ -2991,5 +3100,5 @@
     if (lprbbi == NULL)
 	return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
+    if (lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
 	return FALSE;
 
@@ -2999,5 +3108,5 @@
 
     if (infoPtr->uNumBands == 0) {
-	infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
+	infoPtr->bands = (REBAR_BAND *)Alloc (sizeof (REBAR_BAND));
 	uIndex = 0;
     }
@@ -3005,5 +3114,5 @@
 	REBAR_BAND *oldBands = infoPtr->bands;
 	infoPtr->bands =
-	    (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
+	    (REBAR_BAND *)Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
 	if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
 	    uIndex = infoPtr->uNumBands;
@@ -3021,5 +3130,5 @@
 	}
 
-	COMCTL32_Free (oldBands);
+	Free (oldBands);
     }
 
@@ -3042,5 +3151,5 @@
         INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
         if (len > 1) {
-            lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
+            lpBand->lpText = (LPWSTR)Alloc (len*sizeof(WCHAR));
             MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
 	}
@@ -3072,5 +3181,5 @@
     if (lprbbi == NULL)
 	return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
+    if (lprbbi->cbSize < REBARBANDINFOW_V3_SIZE)
 	return FALSE;
 
@@ -3080,5 +3189,5 @@
 
     if (infoPtr->uNumBands == 0) {
-	infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
+	infoPtr->bands = (REBAR_BAND *)Alloc (sizeof (REBAR_BAND));
 	uIndex = 0;
     }
@@ -3086,5 +3195,5 @@
 	REBAR_BAND *oldBands = infoPtr->bands;
 	infoPtr->bands =
-	    (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
+	    (REBAR_BAND *)Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
 	if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
 	    uIndex = infoPtr->uNumBands;
@@ -3097,10 +3206,10 @@
 
 	/* post copy */
-	if (uIndex < infoPtr->uNumBands - 1) {
+	if (uIndex <= infoPtr->uNumBands - 1) {
 	    memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
-		    (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
-	}
-
-	COMCTL32_Free (oldBands);
+		    (infoPtr->uNumBands - uIndex) * sizeof(REBAR_BAND));
+	}
+
+	Free (oldBands);
     }
 
@@ -3123,5 +3232,5 @@
 	INT len = lstrlenW (lprbbi->lpText);
 	if (len > 0) {
-	    lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
+	    lpBand->lpText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
 	    strcpyW (lpBand->lpText, lprbbi->lpText);
 	}
@@ -3131,5 +3240,5 @@
     /* On insert of second band, revalidate band 1 to possible add gripper */
     if (infoPtr->uNumBands == 2)
-	REBAR_ValidateBand (infoPtr, &infoPtr->bands[0]);
+	REBAR_ValidateBand (infoPtr, &infoPtr->bands[uIndex ? 0 : 1]);
 
     REBAR_DumpBand (infoPtr);
@@ -3212,5 +3321,5 @@
 	    lpBand->cxHeader;
     if (movement < 0) {
-	ERR("something is wrong, band=(%d,%d)-(%d,%d), cxheader=%d\n",
+	ERR("something is wrong, band=(%ld,%ld)-(%ld,%ld), cxheader=%d\n",
 	    lpBand->rcBand.left, lpBand->rcBand.top,
 	    lpBand->rcBand.right, lpBand->rcBand.bottom,
@@ -3333,5 +3442,5 @@
     memcpy (&holder, &oldBands[uFrom], sizeof(REBAR_BAND));
 
-    /* close up rest of bands (psuedo delete) */
+    /* close up rest of bands (pseudo delete) */
     if (uFrom < infoPtr->uNumBands - 1) {
 	memcpy (&oldBands[uFrom], &oldBands[uFrom+1],
@@ -3341,5 +3450,5 @@
     /* allocate new space and copy rest of bands into it */
     infoPtr->bands =
-	(REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands)*sizeof(REBAR_BAND));
+	(REBAR_BAND *)Alloc ((infoPtr->uNumBands)*sizeof(REBAR_BAND));
 
     /* pre insert copy */
@@ -3358,5 +3467,5 @@
     }
 
-    COMCTL32_Free (oldBands);
+    Free (oldBands);
 
     TRACE("moved band %d to index %d\n", uFrom, uTo);
@@ -3377,4 +3486,11 @@
 
 
+/* return TRUE if two strings are different */
+static BOOL
+REBAR_strdifW( LPCWSTR a, LPCWSTR b )
+{
+    return ( (a && !b) || (b && !a) || (a && b && lstrcmpW(a, b) ) );
+}
+
 static LRESULT
 REBAR_SetBandInfoA (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
@@ -3382,8 +3498,9 @@
     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
     REBAR_BAND *lpBand;
+    BOOL bChanged;
 
     if (lprbbi == NULL)
 	return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
+    if (lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
 	return FALSE;
     if ((UINT)wParam >= infoPtr->uNumBands)
@@ -3396,15 +3513,30 @@
     lpBand = &infoPtr->bands[(UINT)wParam];
 
-    REBAR_CommonSetupBand (infoPtr->hwndSelf, lprbbi, lpBand);
+    bChanged = REBAR_CommonSetupBand (infoPtr->hwndSelf, lprbbi, lpBand);
     if (lprbbi->fMask & RBBIM_TEXT) {
-	if (lpBand->lpText) {
-	    COMCTL32_Free (lpBand->lpText);
-	    lpBand->lpText = NULL;
-	}
-	if (lprbbi->lpText) {
-            INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
-            lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
-            MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
-	}
+        LPWSTR wstr = NULL;
+
+        if (lprbbi->lpText)
+        {
+            INT len;
+            len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
+            if (len > 1)
+                wstr = (LPWSTR)Alloc (len*sizeof(WCHAR));
+            if (wstr)
+                MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, wstr, len );
+        }
+        if (REBAR_strdifW(lpBand->lpText, wstr)) {
+	    if (lpBand->lpText) {
+	        Free (lpBand->lpText);
+	        lpBand->lpText = NULL;
+	    }
+	    if (wstr) {
+                lpBand->lpText = wstr;
+                wstr = NULL;
+	    }
+            bChanged = TRUE;
+        }
+        if (wstr)
+	    Free (wstr);
     }
 
@@ -3413,5 +3545,5 @@
     REBAR_DumpBand (infoPtr);
 
-    if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
+    if (bChanged && (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE))) {
 	  REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
 	  InvalidateRect(infoPtr->hwndSelf, 0, 1);
@@ -3421,5 +3553,4 @@
 }
 
-
 static LRESULT
 REBAR_SetBandInfoW (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
@@ -3427,8 +3558,9 @@
     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
     REBAR_BAND *lpBand;
+    BOOL bChanged;
 
     if (lprbbi == NULL)
 	return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
+    if (lprbbi->cbSize < REBARBANDINFOW_V3_SIZE)
 	return FALSE;
     if ((UINT)wParam >= infoPtr->uNumBands)
@@ -3441,15 +3573,20 @@
     lpBand = &infoPtr->bands[(UINT)wParam];
 
-    REBAR_CommonSetupBand (infoPtr->hwndSelf, (LPREBARBANDINFOA)lprbbi, lpBand);
-    if (lprbbi->fMask & RBBIM_TEXT) {
+    bChanged = REBAR_CommonSetupBand (infoPtr->hwndSelf, (LPREBARBANDINFOA)lprbbi, lpBand);
+    if( (lprbbi->fMask & RBBIM_TEXT) && 
+        REBAR_strdifW( lpBand->lpText, lprbbi->lpText ) ) {
 	if (lpBand->lpText) {
-	    COMCTL32_Free (lpBand->lpText);
+	    Free (lpBand->lpText);
 	    lpBand->lpText = NULL;
 	}
 	if (lprbbi->lpText) {
 	    INT len = lstrlenW (lprbbi->lpText);
-	    lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
-	    strcpyW (lpBand->lpText, lprbbi->lpText);
-	}
+	    if (len > 0)
+	    {
+	        lpBand->lpText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+	        strcpyW (lpBand->lpText, lprbbi->lpText);
+	    }
+	}
+        bChanged = TRUE;
     }
 
@@ -3458,5 +3595,5 @@
     REBAR_DumpBand (infoPtr);
 
-    if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
+    if ( bChanged && (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) ) {
       REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
       InvalidateRect(infoPtr->hwndSelf, 0, 1);
@@ -3608,4 +3745,5 @@
     }
 
+    infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
     REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
     InvalidateRect(infoPtr->hwndSelf, 0, 1);
@@ -3624,13 +3762,13 @@
        return FALSE;
 
-    TRACE("[%d %d %d %d]\n",
+    TRACE("[%ld %ld %ld %ld]\n",
 	  lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
 
     /*  what is going on???? */
     GetWindowRect(infoPtr->hwndSelf, &t1);
-    TRACE("window rect [%d %d %d %d]\n",
+    TRACE("window rect [%ld %ld %ld %ld]\n",
 	  t1.left, t1.top, t1.right, t1.bottom);
     GetClientRect(infoPtr->hwndSelf, &t1);
-    TRACE("client rect [%d %d %d %d]\n",
+    TRACE("client rect [%ld %ld %ld %ld]\n",
 	  t1.left, t1.top, t1.right, t1.bottom);
 
@@ -3654,5 +3792,5 @@
 	GetWindowRect(infoPtr->hwndSelf, &wnrc1);
 	GetClientRect(infoPtr->hwndSelf, &clrc1);
-	TRACE("window=(%d,%d)-(%d,%d) client=(%d,%d)-(%d,%d) cs=(%d,%d %dx%d)\n",
+	TRACE("window=(%ld,%ld)-(%ld,%ld) client=(%ld,%ld)-(%ld,%ld) cs=(%d,%d %dx%d)\n",
 	      wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom,
 	      clrc1.left, clrc1.top, clrc1.right, clrc1.bottom,
@@ -3669,5 +3807,5 @@
 {
     REBAR_BAND *lpBand;
-    INT i;
+    UINT i;
 
 
@@ -3680,5 +3818,5 @@
 	    /* delete text strings */
 	    if (lpBand->lpText) {
-		COMCTL32_Free (lpBand->lpText);
+		Free (lpBand->lpText);
 		lpBand->lpText = NULL;
 	    }
@@ -3688,5 +3826,5 @@
 
 	/* free band array */
-	COMCTL32_Free (infoPtr->bands);
+	Free (infoPtr->bands);
 	infoPtr->bands = NULL;
     }
@@ -3700,5 +3838,5 @@
 
     /* free rebar info data */
-    COMCTL32_Free (infoPtr);
+    Free (infoPtr);
     TRACE("destroyed!\n");
     return 0;
@@ -3723,4 +3861,35 @@
 }
 
+static LRESULT
+REBAR_PushChevron(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+{
+    if (wParam >= 0 && (UINT)wParam < infoPtr->uNumBands)
+    {
+        NMREBARCHEVRON nmrbc;
+        REBAR_BAND *lpBand = &infoPtr->bands[wParam];
+
+        TRACE("Pressed chevron on band %d\n", wParam);
+
+        /* redraw chevron in pushed state */
+        lpBand->fDraw |= DRAW_CHEVRONPUSHED;
+        RedrawWindow(infoPtr->hwndSelf, &lpBand->rcChevron,0,
+          RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
+
+        /* notify app so it can display a popup menu or whatever */
+        nmrbc.uBand = wParam;
+        nmrbc.wID = lpBand->wID;
+        nmrbc.lParam = lpBand->lParam;
+        nmrbc.rc = lpBand->rcChevron;
+        nmrbc.lParamNM = lParam;
+        REBAR_Notify((NMHDR*)&nmrbc, infoPtr, RBN_CHEVRONPUSHED);
+
+        /* redraw chevron in previous state */
+        lpBand->fDraw &= ~DRAW_CHEVRONPUSHED;
+        InvalidateRect(infoPtr->hwndSelf, &lpBand->rcChevron, TRUE);
+
+        return TRUE;
+    }
+    return FALSE;
+}
 
 static LRESULT
@@ -3728,96 +3897,181 @@
 {
     REBAR_BAND *lpBand;
-
-    /* If InternalHitTest did not find a hit on the Gripper, */
-    /* then ignore the button click.                         */
-    if (infoPtr->ihitBand == -1) return 0;
-
-    SetCapture (infoPtr->hwndSelf);
-
-    /* save off the LOWORD and HIWORD of lParam as initial x,y */
-    lpBand = &infoPtr->bands[infoPtr->ihitBand];
-    infoPtr->dragStart = MAKEPOINTS(lParam);
-    infoPtr->dragNow = infoPtr->dragStart;
-    if (infoPtr->dwStyle & CCS_VERT)
-        infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.top+REBAR_PRE_GRIPPER);
-    else
-        infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left+REBAR_PRE_GRIPPER);
-
+    UINT htFlags;
+    UINT iHitBand;
+    POINT ptMouseDown;
+    ptMouseDown.x = (INT)LOWORD(lParam);
+    ptMouseDown.y = (INT)HIWORD(lParam);
+
+    REBAR_InternalHitTest(infoPtr, &ptMouseDown, &htFlags, &iHitBand);
+    lpBand = &infoPtr->bands[iHitBand];
+
+    if (htFlags == RBHT_CHEVRON)
+    {
+        REBAR_PushChevron(infoPtr, iHitBand, 0);
+    }
+    else if (htFlags == RBHT_GRABBER || htFlags == RBHT_CAPTION)
+    {
+        TRACE("Starting drag\n");
+
+        SetCapture (infoPtr->hwndSelf);
+        infoPtr->iGrabbedBand = iHitBand;
+
+        /* save off the LOWORD and HIWORD of lParam as initial x,y */
+        infoPtr->dragStart = MAKEPOINTS(lParam);
+        infoPtr->dragNow = infoPtr->dragStart;
+        if (infoPtr->dwStyle & CCS_VERT)
+            infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.top+REBAR_PRE_GRIPPER);
+        else
+            infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left+REBAR_PRE_GRIPPER);
+    }
     return 0;
 }
-
 
 static LRESULT
 REBAR_LButtonUp (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-    NMHDR layout;
-    RECT rect;
-    INT ihitBand;
-
-    /* If InternalHitTest did not find a hit on the Gripper, */
-    /* then ignore the button click.                         */
-    if (infoPtr->ihitBand == -1) return 0;
-
-    ihitBand = infoPtr->ihitBand;
-    infoPtr->dragStart.x = 0;
-    infoPtr->dragStart.y = 0;
-    infoPtr->dragNow = infoPtr->dragStart;
-    infoPtr->ihitBand = -1;
-
-    ReleaseCapture ();
-
-    if (infoPtr->fStatus & BEGIN_DRAG_ISSUED) {
-        REBAR_Notify((NMHDR *) &layout, infoPtr, RBN_LAYOUTCHANGED);
-	REBAR_Notify_NMREBAR (infoPtr, ihitBand, RBN_ENDDRAG);
-	infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
-    }
-
-    GetClientRect(infoPtr->hwndSelf, &rect);
-    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
+    if (infoPtr->iGrabbedBand >= 0)
+    {
+        NMHDR layout;
+        RECT rect;
+
+        infoPtr->dragStart.x = 0;
+        infoPtr->dragStart.y = 0;
+        infoPtr->dragNow = infoPtr->dragStart;
+
+        ReleaseCapture ();
+
+        if (infoPtr->fStatus & BEGIN_DRAG_ISSUED) {
+            REBAR_Notify(&layout, infoPtr, RBN_LAYOUTCHANGED);
+            REBAR_Notify_NMREBAR (infoPtr, infoPtr->iGrabbedBand, RBN_ENDDRAG);
+            infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
+        }
+
+        infoPtr->iGrabbedBand = -1;
+
+        GetClientRect(infoPtr->hwndSelf, &rect);
+        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
+    }
 
     return 0;
 }
 
+static LRESULT
+REBAR_MouseLeave (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+{
+    if (infoPtr->ichevronhotBand >= 0)
+    {
+        REBAR_BAND *lpChevronBand = &infoPtr->bands[infoPtr->ichevronhotBand];
+        if (lpChevronBand->fDraw & DRAW_CHEVRONHOT)
+        {
+            lpChevronBand->fDraw &= ~DRAW_CHEVRONHOT;
+            InvalidateRect(infoPtr->hwndSelf, &lpChevronBand->rcChevron, TRUE);
+        }
+    }
+    infoPtr->iOldBand = -1;
+    infoPtr->ichevronhotBand = -2;
+
+    return TRUE;
+}
 
 static LRESULT
 REBAR_MouseMove (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-    REBAR_BAND *band1, *band2;
+    REBAR_BAND *lpChevronBand;
     POINTS ptsmove;
 
-    /* Validate entry as hit on Gripper has occurred */
-    if (GetCapture() != infoPtr->hwndSelf) return 0;
-    if (infoPtr->ihitBand == -1) return 0;
-
     ptsmove = MAKEPOINTS(lParam);
 
-    /* if mouse did not move much, exit */
-    if ((abs(ptsmove.x - infoPtr->dragNow.x) <= mindragx) &&
-	(abs(ptsmove.y - infoPtr->dragNow.y) <= mindragy)) return 0;
-
-    band1 = &infoPtr->bands[infoPtr->ihitBand-1];
-    band2 = &infoPtr->bands[infoPtr->ihitBand];
-
-    /* Test for valid drag case - must not be first band in row */
-    if (infoPtr->dwStyle & CCS_VERT) {
-	if ((ptsmove.x < band2->rcBand.left) ||
-	    (ptsmove.x > band2->rcBand.right) ||
-	    ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
-	    FIXME("Cannot drag to other rows yet!!\n");
-	}
-	else {
-	    REBAR_HandleLRDrag (infoPtr, &ptsmove);
-	}
-    }
-    else {
-	if ((ptsmove.y < band2->rcBand.top) ||
-	    (ptsmove.y > band2->rcBand.bottom) ||
-	    ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
-	    FIXME("Cannot drag to other rows yet!!\n");
-	}
-	else {
-	    REBAR_HandleLRDrag (infoPtr, &ptsmove);
-	}
-    }
+    /* if we are currently dragging a band */
+    if (infoPtr->iGrabbedBand >= 0)
+    {
+        REBAR_BAND *band1, *band2;
+    
+        if (GetCapture() != infoPtr->hwndSelf)
+            ERR("We are dragging but haven't got capture?!?\n");
+
+        band1 = &infoPtr->bands[infoPtr->iGrabbedBand-1];
+        band2 = &infoPtr->bands[infoPtr->iGrabbedBand];
+
+        /* if mouse did not move much, exit */
+        if ((abs(ptsmove.x - infoPtr->dragNow.x) <= mindragx) &&
+            (abs(ptsmove.y - infoPtr->dragNow.y) <= mindragy)) return 0;
+
+        /* Test for valid drag case - must not be first band in row */
+        if (infoPtr->dwStyle & CCS_VERT) {
+            if ((ptsmove.x < band2->rcBand.left) ||
+	      (ptsmove.x > band2->rcBand.right) ||
+              ((infoPtr->iGrabbedBand > 0) && (band1->iRow != band2->iRow))) {
+                FIXME("Cannot drag to other rows yet!!\n");
+            }
+            else {
+                REBAR_HandleLRDrag (infoPtr, &ptsmove);
+            }
+        }
+        else {
+            if ((ptsmove.y < band2->rcBand.top) ||
+              (ptsmove.y > band2->rcBand.bottom) ||
+              ((infoPtr->iGrabbedBand > 0) && (band1->iRow != band2->iRow))) {
+                FIXME("Cannot drag to other rows yet!!\n");
+            }
+            else {
+                REBAR_HandleLRDrag (infoPtr, &ptsmove);
+            }
+        }
+    }
+    else
+    {
+        POINT ptMove;
+        INT iHitBand;
+        UINT htFlags;
+        TRACKMOUSEEVENT trackinfo;
+
+        ptMove.x = (INT)ptsmove.x;
+        ptMove.y = (INT)ptsmove.y;
+        REBAR_InternalHitTest(infoPtr, &ptMove, &htFlags, &iHitBand);
+
+        if (infoPtr->iOldBand >= 0 && infoPtr->iOldBand == infoPtr->ichevronhotBand)
+        {
+            lpChevronBand = &infoPtr->bands[infoPtr->ichevronhotBand];
+            if (lpChevronBand->fDraw & DRAW_CHEVRONHOT)
+            {
+                lpChevronBand->fDraw &= ~DRAW_CHEVRONHOT;
+                InvalidateRect(infoPtr->hwndSelf, &lpChevronBand->rcChevron, TRUE);
+            }
+            infoPtr->ichevronhotBand = -2;
+        }
+
+        if (htFlags == RBHT_CHEVRON)
+        {
+            /* fill in the TRACKMOUSEEVENT struct */
+            trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
+            trackinfo.dwFlags = TME_QUERY;
+            trackinfo.hwndTrack = infoPtr->hwndSelf;
+            trackinfo.dwHoverTime = 0;
+
+            /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
+            _TrackMouseEvent(&trackinfo);
+
+            /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
+            if(!(trackinfo.dwFlags & TME_LEAVE))
+            {
+                trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
+
+                /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
+                /* and can properly deactivate the hot chevron */
+                _TrackMouseEvent(&trackinfo);
+            }
+
+            lpChevronBand = &infoPtr->bands[iHitBand];
+            if (!(lpChevronBand->fDraw & DRAW_CHEVRONHOT))
+            {
+                lpChevronBand->fDraw |= DRAW_CHEVRONHOT;
+                InvalidateRect(infoPtr->hwndSelf, &lpChevronBand->rcChevron, TRUE);
+                infoPtr->ichevronhotBand = iHitBand;
+            }
+        }
+        infoPtr->iOldBand = iHitBand;
+    }
+
     return 0;
 }
@@ -3831,5 +4085,5 @@
 		    -GetSystemMetrics(SM_CYEDGE));
     }
-    TRACE("new client=(%d,%d)-(%d,%d)\n",
+    TRACE("new client=(%ld,%ld)-(%ld,%ld)\n",
 	  ((LPRECT)lParam)->left, ((LPRECT)lParam)->top,
 	  ((LPRECT)lParam)->right, ((LPRECT)lParam)->bottom);
@@ -3856,5 +4110,5 @@
 	GetWindowRect(hwnd, &wnrc1);
 	GetClientRect(hwnd, &clrc1);
-	TRACE("window=(%d,%d)-(%d,%d) client=(%d,%d)-(%d,%d) cs=(%d,%d %dx%d)\n",
+	TRACE("window=(%ld,%ld)-(%ld,%ld) client=(%ld,%ld)-(%ld,%ld) cs=(%d,%d %dx%d)\n",
 	      wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom,
 	      clrc1.left, clrc1.top, clrc1.right, clrc1.bottom,
@@ -3863,5 +4117,5 @@
 
     /* allocate memory for info structure */
-    infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
+    infoPtr = (REBAR_INFO *)Alloc (sizeof(REBAR_INFO));
     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
 
@@ -3871,11 +4125,13 @@
     infoPtr->clrBtnText = GetSysColor (COLOR_BTNTEXT);
     infoPtr->clrBtnFace = GetSysColor (COLOR_BTNFACE);
-    infoPtr->ihitBand = -1;
+    infoPtr->iOldBand = -1;
+    infoPtr->ichevronhotBand = -2;
+    infoPtr->iGrabbedBand = -1;
     infoPtr->hwndSelf = hwnd;
     infoPtr->DoRedraw = TRUE;
-    infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
-    infoPtr->hcurHorz  = LoadCursorA (0, IDC_SIZEWEA);
-    infoPtr->hcurVert  = LoadCursorA (0, IDC_SIZENSA);
-    infoPtr->hcurDrag  = LoadCursorA (0, IDC_SIZEA);
+    infoPtr->hcurArrow = LoadCursorA (0, (LPSTR)IDC_ARROWA);
+    infoPtr->hcurHorz  = LoadCursorA (0, (LPSTR)IDC_SIZEWEA);
+    infoPtr->hcurVert  = LoadCursorA (0, (LPSTR)IDC_SIZENSA);
+    infoPtr->hcurDrag  = LoadCursorA (0, (LPSTR)IDC_SIZEA);
     infoPtr->bUnicode = IsWindowUnicode (hwnd);
     infoPtr->fStatus = CREATE_RUNNING;
@@ -3989,5 +4245,5 @@
 	GetWindowRect (infoPtr->hwndSelf, &rcWindow);
 	OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
-	TRACE("rect (%d,%d)-(%d,%d)\n",
+	TRACE("rect (%ld,%ld)-(%ld,%ld)\n",
 	      rcWindow.left, rcWindow.top,
 	      rcWindow.right, rcWindow.bottom);
@@ -4030,5 +4286,5 @@
     hdc = wParam==0 ? BeginPaint (infoPtr->hwndSelf, &ps) : (HDC)wParam;
 
-    TRACE("painting (%d,%d)-(%d,%d) client (%d,%d)-(%d,%d)\n",
+    TRACE("painting (%ld,%ld)-(%ld,%ld) client (%ld,%ld)-(%ld,%ld)\n",
 	  ps.rcPaint.left, ps.rcPaint.top,
 	  ps.rcPaint.right, ps.rcPaint.bottom,
@@ -4155,5 +4411,5 @@
 	infoPtr->fStatus &= ~CREATE_RUNNING;
 	GetWindowRect ( infoPtr->hwndSelf, &rcWin);
-	TRACE("win rect (%d,%d)-(%d,%d)\n",
+	TRACE("win rect (%ld,%ld)-(%ld,%ld)\n",
 	      rcWin.left, rcWin.top, rcWin.right, rcWin.bottom);
 
@@ -4162,5 +4418,5 @@
 	    /* native control seems to do this */
 	    GetClientRect (GetParent(infoPtr->hwndSelf), &rcClient);
-	    TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n",
+	    TRACE("sizing rebar, message and client zero, parent client (%ld,%ld)\n",
 		  rcClient.right, rcClient.bottom);
 	}
@@ -4176,5 +4432,5 @@
 	    /* do the actual WM_SIZE request */
 	    GetClientRect (infoPtr->hwndSelf, &rcClient);
-	    TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%d,%d)\n",
+	    TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%ld,%ld)\n",
 		  infoPtr->calcSize.cx, infoPtr->calcSize.cy,
 		  LOWORD(lParam), HIWORD(lParam),
@@ -4196,9 +4452,28 @@
 	    /* native seems to use the current client rect for the size      */
 	    infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
-	    TRACE("sizing rebar to client (%d,%d) size is zero but AUTOSIZE set\n",
+	    TRACE("sizing rebar to client (%ld,%ld) size is zero but AUTOSIZE set\n",
 		  rcClient.right, rcClient.bottom);
 	}
 	else {
-	    TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%d,%d)\n",
+#ifdef __WIN32OS2__
+            INT  width, x, y, height;
+            RECT parent_rect, rcWin;
+
+            if(HIWORD(lParam) != (rcClient.bottom - rcClient.top) ||
+               LOWORD(lParam) != (rcClient.right  - rcClient.left))
+            {
+                /* Need to resize width to match parent */
+                GetWindowRect ( infoPtr->hwndSelf, &rcWin);
+                height = (rcWin.bottom - rcWin.top);
+ 
+                /* width and height don't apply */
+                GetClientRect (GetParent(infoPtr->hwndSelf), &parent_rect);
+                width = parent_rect.right - parent_rect.left;
+                TRACE("Rebar: resize to match parent");
+                SetWindowPos (infoPtr->hwndSelf, 0, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
+                return 0;;
+            }
+#endif
+	    TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%ld,%ld)\n",
 		  infoPtr->calcSize.cx, infoPtr->calcSize.cy,
 		  LOWORD(lParam), HIWORD(lParam),
@@ -4214,5 +4489,5 @@
 	autosize.rcActual = autosize.rcTarget;  /* ??? */
 	REBAR_Notify((NMHDR *) &autosize, infoPtr, RBN_AUTOSIZE);
-	TRACE("RBN_AUTOSIZE client=(%d,%d), lp=%08lx\n",
+	TRACE("RBN_AUTOSIZE client=(%ld,%ld), lp=%08lx\n",
 	      autosize.rcTarget.right, autosize.rcTarget.bottom, lParam);
     }
@@ -4255,9 +4530,139 @@
 			 wParam, lParam);
     GetWindowRect(infoPtr->hwndSelf, &rc);
-    TRACE("hwnd %p new pos (%d,%d)-(%d,%d)\n",
+    TRACE("hwnd %p new pos (%ld,%ld)-(%ld,%ld)\n",
 	  infoPtr->hwndSelf, rc.left, rc.top, rc.right, rc.bottom);
     return ret;
 }
 
+#ifdef __WIN32OS2__
+#ifdef DEBUG
+static void dprintfMsg(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ char *msg = NULL;
+
+  switch (uMsg)
+  {
+  case RB_DELETEBAND:
+      msg = "RB_DELETEBAND";
+      break;
+  case RB_GETBANDBORDERS:
+      msg = "RB_GETBANDBORDERS";
+      break;
+  case RB_GETBANDCOUNT:
+      msg = "RB_GETBANDCOUNT";
+      break;
+  case RB_GETBANDINFO_OLD:
+      msg = "RB_GETBANDINFO_OLD";
+      break;
+  case RB_GETBANDINFOA:
+      msg = "RB_GETBANDINFOA";
+      break;
+  case RB_GETBANDINFOW:
+      msg = "RB_GETBANDINFOW";
+      break;
+  case RB_GETBARHEIGHT:
+      msg = "RB_GETBARHEIGHT";
+      break;
+  case RB_GETBARINFO:
+      msg = "RB_GETBARINFO";
+      break;
+  case RB_GETBKCOLOR:
+      msg = "RB_GETBKCOLOR";
+      break;
+  case RB_GETPALETTE:
+      msg = "RB_GETPALETTE";
+      break;
+  case RB_GETRECT:
+      msg = "RB_GETRECT";
+      break;
+  case RB_GETROWCOUNT:
+      msg = "RB_GETROWCOUNT";
+      break;
+  case RB_GETROWHEIGHT:
+      msg = "RB_GETROWHEIGHT";
+      break;
+  case RB_GETTEXTCOLOR:
+      msg = "RB_GETTEXTCOLOR";
+      break;
+  case RB_GETTOOLTIPS:
+      msg = "RB_GETTOOLTIPS";
+      break;
+  case RB_GETUNICODEFORMAT:
+      msg = "RB_GETUNICODEFORMAT";
+      break;
+  case CCM_GETVERSION:
+      msg = "CCM_GETVERSION";
+      break;
+  case RB_HITTEST:
+      msg = "RB_HITTEST";
+      break;
+  case RB_IDTOINDEX:
+      msg = "RB_IDTOINDEX";
+      break;
+  case RB_INSERTBANDA:
+      msg = "RB_INSERTBANDA";
+      break;
+  case RB_INSERTBANDW:
+      msg = "RB_INSERTBANDW";
+      break;
+  case RB_MAXIMIZEBAND:
+      msg = "RB_MAXIMIZEBAND";
+      break;
+  case RB_MINIMIZEBAND:
+      msg = "RB_MINIMIZEBAND";
+      break;
+  case RB_MOVEBAND:
+      msg = "RB_MOVEBAND";
+      break;
+  case RB_PUSHCHEVRON:
+      msg = "RB_PUSHCHEVRON";
+      break;
+  case RB_SETBANDINFOA:
+      msg = "RB_SETBANDINFOA";
+      break;
+  case RB_SETBANDINFOW:
+      msg = "RB_SETBANDINFOW";
+      break;
+  case RB_SETBARINFO:
+      msg = "RB_SETBARINFO";
+      break;
+  case RB_SETBKCOLOR:
+      msg = "RB_SETBKCOLOR";
+      break;
+  case RB_SETPARENT:
+      msg = "RB_SETPARENT";
+      break;
+  case RB_SETTEXTCOLOR:
+      msg = "RB_SETTEXTCOLOR";
+      break;
+  case RB_SETUNICODEFORMAT:
+      msg = "RB_SETUNICODEFORMAT";
+      break;
+  case CCM_SETVERSION:
+      msg = "CCM_SETVERSION";
+      break;
+  case RB_SHOWBAND:
+      msg = "RB_SHOWBAND";
+      break;
+  case RB_SIZETORECT:
+      msg = "RB_SIZETORECT";
+      break;
+/*	case RB_BEGINDRAG: */
+/*	case RB_DRAGMOVE: */
+/*	case RB_ENDDRAG: */
+/*	case RB_GETCOLORSCHEME: */
+/*	case RB_GETDROPTARGET: */
+/*	case RB_SETCOLORSCHEME: */
+/*	case RB_SETPALETTE: */
+/*	    return REBAR_GetPalette (infoPtr, wParam, lParam); */
+/*	case RB_SETTOOLTIPS: */
+
+  default:
+      return;
+  }
+  dprintf(("Rebar %x %s %x %x", hwnd, msg, wParam, lParam));
+}
+#endif
+#endif //__WIN32OS2__
 
 static LRESULT WINAPI
@@ -4266,6 +4671,10 @@
     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
 
+#if defined(DEBUG) && defined(__WIN32OS2__)
+    dprintfMsg(hwnd, uMsg, wParam, lParam);
+#else
     TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n",
-	  hwnd, uMsg, /* SPY_GetMsgName(uMsg), */ wParam, lParam);
+	  hwnd, uMsg, wParam, lParam);
+#endif
     if (!infoPtr && (uMsg != WM_NCCREATE))
 	    return DefWindowProcA (hwnd, uMsg, wParam, lParam);
@@ -4286,6 +4695,5 @@
 	    return REBAR_GetBandCount (infoPtr);
 
-	case RB_GETBANDINFO:	/* obsoleted after IE3, but we have to
-				   support it anyway. */
+	case RB_GETBANDINFO_OLD:
 	case RB_GETBANDINFOA:
 	    return REBAR_GetBandInfoA (infoPtr, wParam, lParam);
@@ -4350,4 +4758,7 @@
 	case RB_MOVEBAND:
 	    return REBAR_MoveBand (infoPtr, wParam, lParam);
+
+	case RB_PUSHCHEVRON:
+	    return REBAR_PushChevron (infoPtr, wParam, lParam);
 
 	case RB_SETBANDINFOA:
@@ -4426,4 +4837,7 @@
 	case WM_MOUSEMOVE:
 	    return REBAR_MouseMove (infoPtr, wParam, lParam);
+
+	case WM_MOUSELEAVE:
+	    return REBAR_MouseLeave (infoPtr, wParam, lParam);
 
 	case WM_NCCALCSIZE:
@@ -4515,4 +4929,4 @@
 REBAR_Unregister (void)
 {
-    UnregisterClassA (REBARCLASSNAMEA, (HINSTANCE)NULL);
-}
+    UnregisterClassA (REBARCLASSNAMEA, NULL);
+}
Index: trunk/src/comctl32/status.c
===================================================================
--- trunk/src/comctl32/status.c	(revision 10533)
+++ trunk/src/comctl32/status.c	(revision 10535)
@@ -20,14 +20,36 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * FIXME:
- * 1) Implement all CCS_* styles.
- * 2) Should we hide grip if the parent window is maximized?
+ * NOTE
+ * 
+ * This code was audited for completeness against the documented features
+ * of Comctl32.dll version 6.0 on Sep. 24, 2002, by Dimitrie O. Paun.
+ * 
+ * Unless otherwise noted, we believe this code to be complete, as per
+ * the specification mentioned above.
+ * If you discover missing features, or bugs, please note them below.
+ * 
+ * TODO:
+ * 	-- CCS_BOTTOM (default)
+ * 	-- CCS_LEFT
+ * 	-- CCS_NODEVIDER
+ * 	-- CCS_NOMOVEX
+ * 	-- CCS_NOMOVEY
+ * 	-- CCS_NOPARENTALIGN
+ * 	-- CCS_RIGHT
+ * 	-- CCS_TOP
+ * 	-- CCS_VERT (defaults to RIGHT)
  */
 
+#include <stdarg.h>
 #include <string.h>
 
+#include "windef.h"
 #include "winbase.h"
 #include "wine/unicode.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
 #include "commctrl.h"
+#include "comctl32.h"
 #include "wine/debug.h"
 
@@ -46,4 +68,5 @@
 {
     HWND              Self;
+    HWND              Notify;
     WORD              numParts;
     UINT              height;
@@ -87,5 +110,5 @@
     INT i;
 
-    TRACE("draw size grip %d,%d - %d,%d\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
+    TRACE("draw size grip %ld,%ld - %ld,%ld\n", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
 
     pt.x = lpRect->right - 1;
@@ -125,5 +148,5 @@
 
 
-static void 
+static void
 STATUSBAR_DrawPart (HDC hdc, const STATUSWINDOWPART *part, const STATUSWINDOWINFO *infoPtr, int itemID)
 {
@@ -131,5 +154,5 @@
     UINT border = BDR_SUNKENOUTER;
 
-    TRACE("part bound %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom);
+    TRACE("part bound %ld,%ld - %ld,%ld\n", r.left, r.top, r.right, r.bottom);
     if (part->style & SBT_POPOUT)
         border = BDR_RAISEDOUTER;
@@ -138,5 +161,5 @@
 
     DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);
-	
+
     if (part->style & SBT_OWNERDRAW)
 	{
@@ -149,7 +172,6 @@
 	    dis.rcItem = r;
 	    dis.itemData = (INT)part->text;
-	    SendMessageW (GetParent (infoPtr->Self), WM_DRAWITEM,
-		    (WPARAM)dis.CtlID, (LPARAM)&dis);
-    } 
+	    SendMessageW (infoPtr->Notify, WM_DRAWITEM, (WPARAM)dis.CtlID, (LPARAM)&dis);
+    }
     else
 	{
@@ -158,5 +180,5 @@
 	        INT cy = r.bottom - r.top;
 
-	        r.left += 2; 
+	        r.left += 2;
 	        DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);
 	        r.left += cy;
@@ -257,5 +279,5 @@
     /* get our window size */
     GetClientRect (infoPtr->Self, &rect);
-    TRACE("client wnd size is %d,%d - %d,%d\n", rect.left, rect.top, rect.right, rect.bottom);
+    TRACE("client wnd size is %ld,%ld - %ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom);
 
     rect.top += VERT_BORDER;
@@ -540,5 +562,5 @@
 	RECT parent_rect;
 
-	GetClientRect (GetParent (infoPtr->Self), &parent_rect);
+	GetClientRect (infoPtr->Notify, &parent_rect);
 	infoPtr->height = height + VERT_BORDER;
 	width = parent_rect.right - parent_rect.left;
@@ -568,8 +590,8 @@
 	for (i = infoPtr->numParts ; i < oldNumParts; i++) {
 	    if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
-		COMCTL32_Free (infoPtr->parts[i].text);
+		Free (infoPtr->parts[i].text);
 	}
     } else if (oldNumParts < infoPtr->numParts) {
-	tmp = COMCTL32_Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts);
+	tmp = Alloc (sizeof(STATUSWINDOWPART) * infoPtr->numParts);
 	if (!tmp) return FALSE;
 	for (i = 0; i < oldNumParts; i++) {
@@ -577,5 +599,5 @@
 	}
 	if (infoPtr->parts)
-	    COMCTL32_Free (infoPtr->parts);
+	    Free (infoPtr->parts);
 	infoPtr->parts = tmp;
     }
@@ -587,5 +609,5 @@
 	    return TRUE;
     }
-    
+
     for (i = 0; i < infoPtr->numParts; i++)
 	infoPtr->parts[i].x = parts[i];
@@ -626,5 +648,5 @@
 
 static BOOL
-STATUSBAR_SetTextT (STATUSWINDOWINFO *infoPtr, INT nPart, WORD style, 
+STATUSBAR_SetTextT (STATUSWINDOWINFO *infoPtr, INT nPart, WORD style,
 		    LPCWSTR text, BOOL isW)
 {
@@ -632,6 +654,6 @@
     BOOL changed = FALSE;
 
-    if (style & SBT_OWNERDRAW) {    
-         TRACE("part %d, text %x\n",nPart,text);
+    if (style & SBT_OWNERDRAW) {
+         TRACE("part %d, text %p\n",nPart,text);
     }
     else TRACE("part %d, text %s\n", nPart, debugstr_t(text, isW));
@@ -663,9 +685,9 @@
 	    LPCSTR atxt = (LPCSTR)text;
             DWORD len = MultiByteToWideChar( CP_ACP, 0, atxt, -1, NULL, 0 );
-	    ntext = COMCTL32_Alloc( (len + 1)*sizeof(WCHAR) );
+	    ntext = Alloc( (len + 1)*sizeof(WCHAR) );
 	    if (!ntext) return FALSE;
             MultiByteToWideChar( CP_ACP, 0, atxt, -1, ntext, len );
 	} else if (text) {
-	    ntext = COMCTL32_Alloc( (strlenW(text) + 1)*sizeof(WCHAR) );
+	    ntext = Alloc( (strlenW(text) + 1)*sizeof(WCHAR) );
 	    if (!ntext) return FALSE;
 	    strcpyW (ntext, text);
@@ -675,14 +697,14 @@
 	if (text) {
 	    if (!changed && part->text && !lstrcmpW(ntext, part->text)) {
-		if (!isW) COMCTL32_Free(ntext);
+		if (!isW) Free(ntext);
 		return TRUE;
 	    }
 	} else {
-	    if (!changed && !part->text) 
+	    if (!changed && !part->text)
 		return TRUE;
 	}
 
 	if (part->text)
-	    COMCTL32_Free (part->text);
+	    Free (part->text);
 	part->text = ntext;
     }
@@ -758,5 +780,5 @@
     nmhdr.idFrom = GetWindowLongW (infoPtr->Self, GWL_ID);
     nmhdr.code = SBN_SIMPLEMODECHANGE;
-    SendMessageW (GetParent (infoPtr->Self), WM_NOTIFY, 0, (LPARAM)&nmhdr);
+    SendMessageW (infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nmhdr);
     InvalidateRect(infoPtr->Self, NULL, FALSE);
     return TRUE;
@@ -772,9 +794,9 @@
     for (i = 0; i < infoPtr->numParts; i++) {
 	if (infoPtr->parts[i].text && !(infoPtr->parts[i].style & SBT_OWNERDRAW))
-	    COMCTL32_Free (infoPtr->parts[i].text);
+	    Free (infoPtr->parts[i].text);
     }
     if (infoPtr->part0.text && !(infoPtr->part0.style & SBT_OWNERDRAW))
-	COMCTL32_Free (infoPtr->part0.text);
-    COMCTL32_Free (infoPtr->parts);
+	Free (infoPtr->part0.text);
+    Free (infoPtr->parts);
 
     /* delete default font */
@@ -786,6 +808,6 @@
 	DestroyWindow (infoPtr->hwndToolTip);
 
-    COMCTL32_Free (infoPtr);
     SetWindowLongW(infoPtr->Self, 0, 0);
+    Free (infoPtr);
     return 0;
 }
@@ -803,9 +825,10 @@
 
     TRACE("\n");
-    infoPtr = (STATUSWINDOWINFO*)COMCTL32_Alloc (sizeof(STATUSWINDOWINFO));
+    infoPtr = (STATUSWINDOWINFO*)Alloc (sizeof(STATUSWINDOWINFO));
     if (!infoPtr) goto create_fail;
     SetWindowLongW (hwnd, 0, (DWORD)infoPtr);
 
     infoPtr->Self = hwnd;
+    infoPtr->Notify = lpCreate->hwndParent;
     infoPtr->numParts = 1;
     infoPtr->parts = 0;
@@ -814,5 +837,5 @@
     infoPtr->hFont = 0;
 
-    i = SendMessageW(GetParent (hwnd), WM_NOTIFYFORMAT, hwnd, NF_QUERY);
+    i = SendMessageW(infoPtr->Notify, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
     infoPtr->NtfUnicode = (i == NFR_UNICODE);
 
@@ -834,5 +857,5 @@
 
     /* initialize first part */
-    infoPtr->parts = COMCTL32_Alloc (sizeof(STATUSWINDOWPART));
+    infoPtr->parts = Alloc (sizeof(STATUSWINDOWPART));
     if (!infoPtr->parts) goto create_fail;
     infoPtr->parts[0].bound = rect;
@@ -846,5 +869,5 @@
 	if (lpCreate->lpszName &&
 	    (len = strlenW ((LPCWSTR)lpCreate->lpszName))) {
-	    infoPtr->parts[0].text = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
+	    infoPtr->parts[0].text = Alloc ((len + 1)*sizeof(WCHAR));
 	    if (!infoPtr->parts[0].text) goto create_fail;
 	    strcpyW (infoPtr->parts[0].text, (LPCWSTR)lpCreate->lpszName);
@@ -855,5 +878,5 @@
 	    (len = strlen((LPCSTR)lpCreate->lpszName))) {
             DWORD lenW = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1, NULL, 0 );
-	    infoPtr->parts[0].text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
+	    infoPtr->parts[0].text = Alloc (lenW*sizeof(WCHAR));
 	    if (!infoPtr->parts[0].text) goto create_fail;
             MultiByteToWideChar( CP_ACP, 0, (LPCSTR)lpCreate->lpszName, -1,
@@ -871,5 +894,5 @@
 #endif
 
-    if ((hdc = GetDC (0))) {
+    if ((hdc = GetDC (hwnd))) {
 	TEXTMETRICW tm;
 	HFONT hOldFont;
@@ -879,5 +902,5 @@
 	textHeight = tm.tmHeight;
 	SelectObject (hdc, hOldFont);
-	ReleaseDC (0, hdc);
+	ReleaseDC (hwnd, hdc);
     }
     TRACE("    textHeight=%d\n", textHeight);
@@ -886,8 +909,7 @@
 	infoPtr->hwndToolTip =
 	    CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, 0,
-			       CW_USEDEFAULT, CW_USEDEFAULT,
-			       CW_USEDEFAULT, CW_USEDEFAULT,
-			     hwnd, 0,
-			     GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);
+			     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+			     CW_USEDEFAULT, hwnd, 0,
+			     (HINSTANCE)GetWindowLongW(hwnd, GWL_HINSTANCE), NULL);
 
 	if (infoPtr->hwndToolTip) {
@@ -901,9 +923,9 @@
 	    SendMessageW (lpCreate->hwndParent, WM_NOTIFY,
 			    (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
-	} 
+	}
     }
 
     if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */
-        GetClientRect (GetParent (hwnd), &rect);
+        GetClientRect (infoPtr->Notify, &rect);
         width = rect.right - rect.left;
         infoPtr->height = textHeight + 4 + VERT_BORDER;
@@ -914,5 +936,5 @@
 
     return 0;
-    
+
 create_fail:
     TRACE("    failed!\n");
@@ -993,5 +1015,5 @@
 {
     infoPtr->hFont = font;
-    TRACE("%04x\n", infoPtr->hFont);
+    TRACE("%p\n", infoPtr->hFont);
     if (redraw)
         InvalidateRect(infoPtr->Self, NULL, FALSE);
@@ -1014,9 +1036,9 @@
     /* duplicate string */
     if (part->text)
-        COMCTL32_Free (part->text);
+        Free (part->text);
     part->text = 0;
     if (infoPtr->bUnicode) {
 	if (text && (len = strlenW((LPCWSTR)text))) {
-	    part->text = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
+	    part->text = Alloc ((len+1)*sizeof(WCHAR));
 	    if (!part->text) return FALSE;
 	    strcpyW (part->text, (LPCWSTR)text);
@@ -1026,5 +1048,5 @@
 	if (text && (len = lstrlenA(text))) {
             DWORD lenW = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
-            part->text = COMCTL32_Alloc (lenW*sizeof(WCHAR));
+            part->text = Alloc (lenW*sizeof(WCHAR));
 	    if (!part->text) return FALSE;
             MultiByteToWideChar( CP_ACP, 0, text, -1, part->text, lenW );
@@ -1039,5 +1061,9 @@
 
 static BOOL
+#ifdef __WIN32OS2__
+STATUSBAR_WMSize (STATUSWINDOWINFO *infoPtr, WORD flags, LPARAM lParam)
+#else
 STATUSBAR_WMSize (STATUSWINDOWINFO *infoPtr, WORD flags)
+#endif
 {
     INT  width, x, y;
@@ -1047,8 +1073,10 @@
     TRACE("flags %04x\n", flags);
 
-    if (flags != SIZE_RESTORED) {
-	WARN("flags MUST be SIZE_RESTORED\n");
+    if (flags != SIZE_RESTORED && flags != SIZE_MAXIMIZED)
+    {
+	WARN("flags MUST be SIZE_RESTORED or SIZE_MAXIMIZED\n");
 	return FALSE;
     }
+
 #ifdef __WIN32OS2__
     if (GetWindowLongW(infoPtr->Self, GWL_STYLE) & CCS_NORESIZE) {
@@ -1057,4 +1085,19 @@
         return FALSE;
     }
+
+    /* Invalidate the window if we need to draw a size grip */
+    /* TODO: The size grip area would be sufficient though */
+    if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) 
+    {
+        RECT rcWin;
+
+        GetClientRect(infoPtr->Self, &rcWin);
+        if(HIWORD(lParam) != (rcWin.bottom - rcWin.top) ||
+           LOWORD(lParam) != (rcWin.right  - rcWin.left))
+        {
+            TRACE("SBARS_SIZEGRIP && height/width changed -> invalidate window");
+            InvalidateRect(infoPtr->Self,NULL,TRUE);
+        }
+    }
 #else
     if (GetWindowLongW(infoPtr->Self, GWL_STYLE) & CCS_NORESIZE) return FALSE;
@@ -1062,9 +1105,9 @@
 
     /* width and height don't apply */
-    GetClientRect (GetParent(infoPtr->Self), &parent_rect);
+    GetClientRect (infoPtr->Notify, &parent_rect);
     width = parent_rect.right - parent_rect.left;
     x = parent_rect.left;
     y = parent_rect.bottom - infoPtr->height;
-    MoveWindow (infoPtr->Self, parent_rect.left, 
+    MoveWindow (infoPtr->Self, parent_rect.left,
 		parent_rect.bottom - infoPtr->height,
 		width, infoPtr->height, TRUE);
@@ -1074,9 +1117,9 @@
 
 
-static LRESULT 
+static LRESULT
 STATUSBAR_NotifyFormat (STATUSWINDOWINFO *infoPtr, HWND from, INT cmd)
 {
     if (cmd == NF_REQUERY) {
-	INT i = SendMessageW(from, WM_NOTIFYFORMAT, infoPtr->Self, NF_QUERY);
+	INT i = SendMessageW(from, WM_NOTIFYFORMAT, (WPARAM)infoPtr->Self, NF_QUERY);
 	infoPtr->NtfUnicode = (i == NFR_UNICODE);
     }
@@ -1088,4 +1131,5 @@
 STATUSBAR_SendNotify (HWND hwnd, UINT code)
 {
+    STATUSWINDOWINFO *infoPtr = STATUSBAR_GetInfoPtr(hwnd);
     NMHDR  nmhdr;
 
@@ -1094,5 +1138,5 @@
     nmhdr.idFrom = GetWindowLongW (hwnd, GWL_ID);
     nmhdr.code = code;
-    SendMessageW (GetParent (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
+    SendMessageW (infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nmhdr);
     return 0;
 }
@@ -1107,5 +1151,5 @@
     LRESULT res;
 
-    TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
+    TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hwnd, msg, wParam, lParam);
     if (!infoPtr && msg != WM_CREATE)
         return DefWindowProcW (hwnd, msg, wParam, lParam);
@@ -1116,5 +1160,5 @@
 
 	case SB_GETICON:
-	    return STATUSBAR_GetIcon (infoPtr, nPart);
+	    return (LRESULT)STATUSBAR_GetIcon (infoPtr, nPart);
 
 	case SB_GETPARTS:
@@ -1155,5 +1199,5 @@
 	    return STATUSBAR_SetMinHeight (infoPtr, (INT)wParam);
 
-	case SB_SETPARTS:	
+	case SB_SETPARTS:
 	    return STATUSBAR_SetParts (infoPtr, (INT)wParam, (LPINT)lParam);
 
@@ -1183,5 +1227,5 @@
 
 	case WM_GETFONT:
-	    return infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont;
+	    return (LRESULT)(infoPtr->hFont? infoPtr->hFont : infoPtr->hDefaultFont);
 
 	case WM_GETTEXT:
@@ -1208,10 +1252,10 @@
 	case WM_NCLBUTTONUP:
 	case WM_NCLBUTTONDOWN:
-    	    PostMessageW (GetParent (hwnd), msg, wParam, lParam);
+    	    PostMessageW (infoPtr->Notify, msg, wParam, lParam);
 	    return 0;
 
 	case WM_NOTIFYFORMAT:
 	    return STATUSBAR_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);
-	    
+
 	case WM_PAINT:
 	    return STATUSBAR_WMPaint (infoPtr, (HDC)wParam);
@@ -1230,9 +1274,13 @@
 
 	case WM_SIZE:
+#ifdef __WIN32OS2__
+	    if (STATUSBAR_WMSize (infoPtr, (WORD)wParam, lParam)) return 0;
+#else
 	    if (STATUSBAR_WMSize (infoPtr, (WORD)wParam)) return 0;
+#endif
             return DefWindowProcW (hwnd, msg, wParam, lParam);
 
 	default:
-	    if (msg >= WM_USER)
+	    if ((msg >= WM_USER) && (msg < WM_APP))
 		ERR("unknown msg %04x wp=%04x lp=%08lx\n",
 		     msg, wParam, lParam);
@@ -1259,8 +1307,8 @@
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(STATUSWINDOWINFO *);
-    wndClass.hCursor       = LoadCursorW (0, IDC_ARROWW);
+    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROWW);
     wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
     wndClass.lpszClassName = STATUSCLASSNAMEW;
- 
+
     RegisterClassW (&wndClass);
 }
@@ -1276,5 +1324,4 @@
 STATUS_Unregister (void)
 {
-    UnregisterClassW (STATUSCLASSNAMEW, (HINSTANCE)NULL);
-}
-
+    UnregisterClassW (STATUSCLASSNAMEW, NULL);
+}
Index: trunk/src/comctl32/toolbar.c
===================================================================
--- trunk/src/comctl32/toolbar.c	(revision 10533)
+++ trunk/src/comctl32/toolbar.c	(revision 10535)
@@ -19,4 +19,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
+ * NOTES
+ *
  *  Differences between MSDN and actual native control operation:
  *   1. MSDN says: "TBSTYLE_LIST: Creates a flat toolbar with button text
@@ -28,23 +30,42 @@
  *      *not* imply TBSTYLE_FLAT as documented.  (GA 8/2001)
  *
- *
+ * This code was audited for completeness against the documented features
+ * of Comctl32.dll version 6.0 on Mar. 14, 2004, by Robert Shearman.
+ * 
+ * Unless otherwise noted, we believe this code to be complete, as per
+ * the specification mentioned above.
+ * If you discover missing features or bugs please note them below.
+ * 
  * TODO:
  *   - Button wrapping (under construction).
- *   - Messages.
- *   - Notifications (under construction).
+ *   - Messages:
+ *     - TB_GETINSERTMARK
+ *     - TB_GETINSERTMARKCOLOR
+ *     - TB_GETMETRICS
+ *     - TB_GETOBJECT
+ *     - TB_INSERTMARKHITTEST
+ *     - TB_MOVEBUTTON
+ *     - TB_SETINSERTMARK
+ *     - TB_SETMETRICS
+ *   - Notifications:
+ *     - NM_CHAR
+ *     - NM_KEYDOWN
+ *     - NM_LDOWN
+ *     - NM_RCLICK
+ *     - NM_RDBLCLICK
+ *     - TBN_DELETINGBUTTON
+ *     - TBN_DRAGOUT
+ *     - TBN_GETOBJECT
+ *     - TBN_RESTORE
+ *     - TBN_SAVE
+ *     - TBN_TOOLBARCHANGE
  *   - Fix TB_SETROWS.
- *   - Tooltip support (almost complete).
- *   - Unicode suppport (under construction).
  *   - Fix TOOLBAR_SetButtonInfo32A/W.
- *   - TBSTYLE_AUTOSIZE for toolbar and buttons.
- *   - I_IMAGECALLBACK support.
- *   - iString of -1 is undocumented
+ *   - iListGap custom draw support.
  *   - Customization dialog:
- *      - Add flat look.
  *      - Minor buglet in 'available buttons' list:
- *        Buttons are not listed in M$-like order. M$ seems to use a single
+ *        Buttons are not listed in MS-like order. MS seems to use a single
  *        internal list to store the button information of both listboxes.
  *      - Drag list support.
- *      - Help and Reset button support.
  *
  * Testing:
@@ -59,11 +80,13 @@
  */
 
+#include <stdarg.h>
 #include <string.h>
 
+#include "windef.h"
 #include "winbase.h"
-#include "windef.h"
 #include "wingdi.h"
 #include "winuser.h"
 #include "wine/unicode.h"
+#include "winnls.h"
 #include "commctrl.h"
 #include "imagelist.h"
@@ -105,4 +128,5 @@
     INT      nHeight;        /* height of the toolbar */
     INT      nWidth;         /* width of the toolbar */
+    RECT     client_rect;
     INT      nButtonHeight;
     INT      nButtonWidth;
@@ -127,4 +151,5 @@
     DWORD    dwItemCDFlag;    /* TBCDRF_ flags from last ITEMPREPAINT    */
     SIZE     szPadding;       /* padding values around button */
+    INT      iListGap;        /* default gap between text and image for toolbar with list style */
     HFONT    hDefaultFont;
     HFONT    hFont;           /* text font */
@@ -153,5 +178,6 @@
     RECT     rcBound;         /* bounding rectangle */
     INT      iVersion;
-
+    LPWSTR   pszTooltipText;    /* temporary store for a string > 80 characters
+                                 * for TTN_GETDISPINFOW notification */
     TBUTTON_INFO *buttons;      /* pointer to button array */
     LPWSTR       *strings;      /* pointer to string array */
@@ -175,4 +201,10 @@
 } CUSTOMBUTTON, *PCUSTOMBUTTON;
 
+typedef enum
+{
+    IMAGE_LIST_DEFAULT,
+    IMAGE_LIST_HOT,
+    IMAGE_LIST_DISABLED
+} IMAGE_LIST_TYPE;
 
 #define SEPARATOR_WIDTH    8
@@ -180,8 +212,27 @@
 #define BOTTOM_BORDER      2
 #define DDARROW_WIDTH      11
+#define ARROW_HEIGHT       3
+
+/* gap between border of button and text/image */
+#define OFFSET_X 1
+#define OFFSET_Y 1
+/* how wide to treat the bitmap if it isn't present */
+#define LIST_IMAGE_ABSENT_WIDTH 2
 
 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
 #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
+
+#ifdef __WIN32OS2__
+static inline const char *wine_dbgstr_rect( const RECT *rect )
+{
+    return "rect (null)";
+}
+#endif
+
+static inline int TOOLBAR_GetListTextOffset(TOOLBAR_INFO *infoPtr, INT iListGap)
+{
+    return GetSystemMetrics(SM_CXEDGE) + iListGap - infoPtr->szPadding.cx/2;
+}
 
 /* Used to find undocumented extended styles */
@@ -355,13 +406,60 @@
 
 /***********************************************************************
-* 		TOOLBAR_DrawImageList
+* 		TOOLBAR_GetImageListForDrawing
 *
 * This function validates the bitmap index (including I_IMAGECALLBACK
-* functionality). It then draws the image via the ImageList_Draw
-* function. It returns TRUE if the image was drawn, FALSE otherwise.
+* functionality) and returns the corresponding image list.
+*/
+static HIMAGELIST
+TOOLBAR_GetImageListForDrawing (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, IMAGE_LIST_TYPE imagelist, INT * index)
+{
+    HIMAGELIST himl;
+
+    if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
+	if (btnPtr->iBitmap == I_IMAGENONE) return NULL;
+	ERR("index %d,%d is not valid, max %d\n",
+	    HIWORD(btnPtr->iBitmap), LOWORD(btnPtr->iBitmap), infoPtr->nNumBitmaps);
+	return NULL;
+    }
+
+    if ((*index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
+	if ((*index == I_IMAGECALLBACK) ||
+	    (*index == I_IMAGENONE)) return NULL;
+	ERR("TBN_GETDISPINFO returned invalid index %d\n",
+	    *index);
+	return NULL;
+    }
+
+    switch(imagelist)
+    {
+    case IMAGE_LIST_DEFAULT:
+        himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
+        break;
+    case IMAGE_LIST_HOT:
+        himl = GETHOTIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
+        break;
+    case IMAGE_LIST_DISABLED:
+        himl = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
+        break;
+    default:
+        himl = NULL;
+        FIXME("Shouldn't reach here\n");
+    }
+
+    if (!himl)
+       TRACE("no image list\n");
+
+    return himl;
+}
+
+
+/***********************************************************************
+* 		TOOLBAR_TestImageExist
+*
+* This function is similar to TOOLBAR_GetImageListForDrawing, except it does not
+* return the image list. The I_IMAGECALLBACK functionality is implemented.
 */
 static BOOL
-TOOLBAR_DrawImageList (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl,
-		        HDC hdc, UINT left, UINT top, UINT draw_flags)
+TOOLBAR_TestImageExist (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl)
 {
     INT index;
@@ -383,39 +481,4 @@
 	return FALSE;
     }
-    TRACE("drawing index=%d, himl=%p, left=%d, top=%d, flags=%08x\n",
-	  index, himl, left, top, draw_flags);
-
-    ImageList_Draw (himl, index, hdc, left, top, draw_flags);
-    return TRUE;
-}
-
-
-/***********************************************************************
-* 		TOOLBAR_TestImageExist
-*
-* This function is similar to TOOLBAR_DrawImageList, except it does not
-* draw the image. The I_IMAGECALLBACK functionality is implemented.
-*/
-static BOOL
-TOOLBAR_TestImageExist (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl)
-{
-    INT index;
-
-    if (!himl) return FALSE;
-
-    if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
-	if (btnPtr->iBitmap == I_IMAGENONE) return FALSE;
-	ERR("index %d is not valid, max %d\n",
-	    btnPtr->iBitmap, infoPtr->nNumBitmaps);
-	return FALSE;
-    }
-
-    if ((index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
-	if ((index == I_IMAGECALLBACK) ||
-	    (index == I_IMAGENONE)) return FALSE;
-	ERR("TBN_GETDISPINFO returned invalid index %d\n",
-	    index);
-	return FALSE;
-    }
     return TRUE;
 }
@@ -453,5 +516,5 @@
 * 		TOOLBAR_DrawDDFlatSeparator
 *
-* This function draws the separator that was flaged as TBSTYLE_DROPDOWN.
+* This function draws the separator that was flagged as BTNS_DROPDOWN.
 * In this case, the separator is a pixel high line of COLOR_BTNSHADOW,
 * followed by a pixel high line of COLOR_BTNHIGHLIGHT. These separators
@@ -495,13 +558,13 @@
 
 static void
-TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, INT colorRef)
+TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, COLORREF clr)
 {
     INT x, y;
     HPEN hPen, hOldPen;
 
-    if (!(hPen = CreatePen( PS_SOLID, 1, GetSysColor( colorRef )))) return;
+    if (!(hPen = CreatePen( PS_SOLID, 1, clr))) return;
     hOldPen = SelectObject ( hdc, hPen );
     x = left + 2;
-    y = top + 8;
+    y = top;
     MoveToEx (hdc, x, y, NULL);
     LineTo (hdc, x+5, y++); x++;
@@ -521,18 +584,24 @@
  */
 static void
-TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
-		    HDC hdc, INT nState, DWORD dwStyle,
-                    RECT *rcText, LPWSTR lpText, NMTBCUSTOMDRAW *tbcd)
-{
+TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, RECT *rcText, LPWSTR lpText,
+                    NMTBCUSTOMDRAW *tbcd)
+{
+    HDC hdc = tbcd->nmcd.hdc;
     HFONT  hOldFont = 0;
     COLORREF clrOld = 0;
+    COLORREF clrOldBk = 0;
+    int oldBkMode = 0;
+    UINT state = tbcd->nmcd.uItemState;
 
     /* draw text */
     if (lpText) {
-	TRACE("string rect=(%ld,%ld)-(%ld,%ld)\n",
+	TRACE("string=%s rect=(%ld,%ld)-(%ld,%ld)\n", debugstr_w(lpText),
 	      rcText->left, rcText->top, rcText->right, rcText->bottom);
 
 	hOldFont = SelectObject (hdc, infoPtr->hFont);
-	if (!(nState & TBSTATE_ENABLED)) {
+	if ((state & CDIS_HOT) && (infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) {
+	    clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
+	}
+	else if (state & CDIS_DISABLED) {
 	    clrOld = SetTextColor (hdc, tbcd->clrBtnHighlight);
 	    OffsetRect (rcText, 1, 1);
@@ -541,9 +610,11 @@
 	    OffsetRect (rcText, -1, -1);
 	}
-	else if (nState & TBSTATE_INDETERMINATE) {
+	else if (state & CDIS_INDETERMINATE) {
 	    clrOld = SetTextColor (hdc, comctl32_color.clr3dShadow);
 	}
-	else if (btnPtr->bHot && (infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) {
+	else if ((state & CDIS_MARKED) && !(infoPtr->dwItemCDFlag & TBCDRF_NOMARK)) {
 	    clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
+	    clrOldBk = SetBkColor (hdc, tbcd->clrMark);
+	    oldBkMode = SetBkMode (hdc, OPAQUE); /* FIXME: should this be in the NMTBCUSTOMDRAW structure? */
 	}
 	else {
@@ -553,4 +624,9 @@
 	DrawTextW (hdc, lpText, -1, rcText, infoPtr->dwDTFlags);
 	SetTextColor (hdc, clrOld);
+	if ((state & CDIS_MARKED) && !(infoPtr->dwItemCDFlag & TBCDRF_NOMARK))
+	{
+	    SetBkColor (hdc, clrOldBk);
+	    SetBkMode (hdc, oldBkMode);
+	}
 	SelectObject (hdc, hOldFont);
     }
@@ -559,47 +635,66 @@
 
 static void
-TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
-{
-    HBRUSH hbr = SelectObject (hdc, COMCTL32_hPattern55AABrush);
+TOOLBAR_DrawPattern (LPRECT lpRect, NMTBCUSTOMDRAW *tbcd)
+{
+    HDC hdc = tbcd->nmcd.hdc;
+    HBRUSH hbr = SelectObject (hdc, tbcd->hbrMonoDither);
+    COLORREF clrTextOld;
+    COLORREF clrBkOld;
     INT cx = lpRect->right - lpRect->left;
     INT cy = lpRect->bottom - lpRect->top;
-    PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
+    clrTextOld = SetTextColor(hdc, tbcd->clrBtnHighlight);
+    clrBkOld = SetBkColor(hdc, tbcd->clrBtnFace);
+    PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, PATCOPY);
+    SetBkColor(hdc, clrBkOld);
+    SetTextColor(hdc, clrTextOld);
     SelectObject (hdc, hbr);
 }
 
 
-static void
-TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
-		    HDC hdc, INT x, INT y)
+static void TOOLBAR_DrawMasked(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
+                               HDC hdc, INT x, INT y)
 {
     HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, 0);
-    INT cx, cy;
-    HBITMAP hbmMask;
-    HDC hdcMask;
-
-    if (!himl)
-	return;
-
-    ImageList_GetIconSize(himl, &cx, &cy);
-
-    /* create new dc's */
-    hdcMask = CreateCompatibleDC (0);
-
-    /* create new bitmap */
-    hbmMask = CreateBitmap (cx, cy, 1, 1, NULL);
-    SelectObject (hdcMask, hbmMask);
-
-    /* copy the mask bitmap */
-    ImageList_DrawEx(himl, btnPtr->iBitmap, hdcMask, 0, 0, 0, 0, RGB(255, 255, 255), RGB(0, 0, 0), ILD_MASK);
-
-    /* draw the new mask */
-    SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
-    BitBlt (hdc, x+1, y+1, cx, cy, hdcMask, 0, 0, 0xB8074A);
-
-    SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
-    BitBlt (hdc, x, y, cx, cy, hdcMask, 0, 0, 0xB8074A);
-
-    DeleteObject (hbmMask);
-    DeleteDC (hdcMask);
+
+    if (himl)
+    {
+        INT cx, cy;
+        HBITMAP hbmMask, hbmImage;
+        HDC hdcMask, hdcImage;
+
+        ImageList_GetIconSize(himl, &cx, &cy);
+
+        /* Create src image */
+        hdcImage = CreateCompatibleDC(hdc);
+        hbmImage = CreateBitmap(cx, cy, GetDeviceCaps(hdc,PLANES),
+                                GetDeviceCaps(hdc,BITSPIXEL), NULL);
+        SelectObject(hdcImage, hbmImage);
+        ImageList_DrawEx(himl, btnPtr->iBitmap, hdcImage, 0, 0, cx, cy,
+                         RGB(0xff, 0xff, 0xff), RGB(0,0,0), ILD_NORMAL);
+
+        /* Create Mask */
+        hdcMask = CreateCompatibleDC(0);
+        hbmMask = CreateBitmap(cx, cy, 1, 1, NULL);
+        SelectObject(hdcMask, hbmMask);
+
+        /* Remove the background and all white pixels */
+        SetBkColor(hdcImage, ImageList_GetBkColor(himl));
+        BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, SRCCOPY);
+        SetBkColor(hdcImage, RGB(0xff, 0xff, 0xff));
+        BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, NOTSRCERASE);
+
+        /* draw the new mask 'etched' to hdc */
+        SetBkColor(hdc, RGB(255, 255, 255));
+        SelectObject(hdc, GetSysColorBrush(COLOR_3DHILIGHT));
+        BitBlt(hdc, x + 1, y + 1, cx, cy, hdcMask, 0, 0, 0xE20746);
+        SelectObject(hdc, GetSysColorBrush(COLOR_3DSHADOW));
+        BitBlt(hdc, x, y, cx, cy, hdcMask, 0, 0, 0xE20746);
+
+        /* Cleanup */
+        DeleteObject(hbmImage);
+        DeleteDC(hdcImage);
+        DeleteObject (hbmMask);
+        DeleteDC(hdcMask);
+    }
 }
 
@@ -621,5 +716,120 @@
 }
 
-
+/* draws the image on a toolbar button */
+static void
+TOOLBAR_DrawImage(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, INT top, const NMTBCUSTOMDRAW *tbcd)
+{
+    HIMAGELIST himl = NULL;
+    BOOL draw_masked = FALSE;
+    INT index;
+    INT offset = 0;
+    UINT draw_flags = ILD_NORMAL;
+
+    if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
+    {
+        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DISABLED, &index);
+        if (!himl)
+           draw_masked = TRUE;
+    }
+    else if ((tbcd->nmcd.uItemState & CDIS_HOT) && (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & TBSTYLE_FLAT))
+    {
+        /* if hot, attempt to draw with hot image list, if fails, 
+           use default image list */
+        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_HOT, &index);
+        if (!himl)
+            himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
+	}
+    else
+        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
+
+    if (!(infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) && 
+        (tbcd->nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED)))
+        offset = 1;
+
+    if (!(infoPtr->dwItemCDFlag & TBCDRF_NOMARK) &&
+        (tbcd->nmcd.uItemState & CDIS_MARKED))
+        draw_flags |= ILD_BLEND50;
+
+    TRACE("drawing index=%d, himl=%p, left=%d, top=%d, offset=%d\n",
+      index, himl, left, top, offset);
+
+    if (draw_masked)
+        TOOLBAR_DrawMasked (infoPtr, btnPtr, tbcd->nmcd.hdc, left + offset, top + offset);
+    else if (himl)
+        ImageList_Draw (himl, index, tbcd->nmcd.hdc, left + offset, top + offset, draw_flags);
+}
+
+/* draws a blank frame for a toolbar button */
+static void
+TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, BOOL flat, const NMTBCUSTOMDRAW *tbcd)
+{
+    HDC hdc = tbcd->nmcd.hdc;
+    RECT rc = tbcd->nmcd.rc;
+    /* if the state is disabled or indeterminate then the button
+     * cannot have an interactive look like pressed or hot */
+    BOOL non_interactive_state = (tbcd->nmcd.uItemState & CDIS_DISABLED) ||
+                                 (tbcd->nmcd.uItemState & CDIS_INDETERMINATE);
+    BOOL pressed_look = !non_interactive_state &&
+                        ((tbcd->nmcd.uItemState & CDIS_SELECTED) || 
+                         (tbcd->nmcd.uItemState & CDIS_CHECKED));
+
+    /* app don't want us to draw any edges */
+    if (infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)
+        return;
+
+    if (flat)
+    {
+        if (pressed_look)
+            DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT);
+        else if ((tbcd->nmcd.uItemState & CDIS_HOT) && !non_interactive_state)
+            DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT);
+    }
+    else
+    {
+        if (pressed_look)
+            DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE);
+        else
+            DrawEdge (hdc, &rc, EDGE_RAISED,
+              BF_SOFT | BF_RECT | BF_MIDDLE);
+    }
+}
+
+static void
+TOOLBAR_DrawSepDDArrow(const TOOLBAR_INFO *infoPtr, BOOL flat, const NMTBCUSTOMDRAW *tbcd, RECT *rcArrow)
+{
+    HDC hdc = tbcd->nmcd.hdc;
+    int offset = 0;
+
+    if (flat)
+    {
+        if ((tbcd->nmcd.uItemState & CDIS_SELECTED) || (tbcd->nmcd.uItemState & CDIS_CHECKED))
+            DrawEdge (hdc, rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
+        else if ( (tbcd->nmcd.uItemState & CDIS_HOT) &&
+                 !(tbcd->nmcd.uItemState & CDIS_DISABLED) &&
+                 !(tbcd->nmcd.uItemState & CDIS_INDETERMINATE))
+            DrawEdge (hdc, rcArrow, BDR_RAISEDINNER, BF_RECT);
+    }
+    else
+    {
+        if ((tbcd->nmcd.uItemState & CDIS_SELECTED) || (tbcd->nmcd.uItemState & CDIS_CHECKED))
+            DrawEdge (hdc, rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
+        else
+            DrawEdge (hdc, rcArrow, EDGE_RAISED,
+              BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+    }
+
+    if (tbcd->nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED))
+        offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
+
+    if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
+    {
+        TOOLBAR_DrawArrow(hdc, rcArrow->left+1, rcArrow->top+1 + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight);
+        TOOLBAR_DrawArrow(hdc, rcArrow->left, rcArrow->top + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow);
+    }
+    else
+        TOOLBAR_DrawArrow(hdc, rcArrow->left + offset, rcArrow->top + offset + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
+}
+
+/* draws a complete toolbar button */
 static void
 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
@@ -627,21 +837,18 @@
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-    BOOL hasDropDownArrow = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
-	                    (btnPtr->fsStyle & TBSTYLE_DROPDOWN);
-    RECT rc, rcArrow, rcBitmap, rcText, rcFill;
+    BOOL hasDropDownArrow = (TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
+                            (btnPtr->fsStyle & BTNS_DROPDOWN)) ||
+                            (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
+    BOOL drawSepDropDownArrow = hasDropDownArrow && 
+                                (~btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
+    RECT rc, rcArrow, rcBitmap, rcText;
     LPWSTR lpText = NULL;
     NMTBCUSTOMDRAW tbcd;
     DWORD ntfret;
     INT offset;
-    HIMAGELIST himlDef;
-
-    if (btnPtr->fsState & TBSTATE_HIDDEN)
-	return;
 
     rc = btnPtr->rect;
-    CopyRect (&rcFill, &rc);
     CopyRect (&rcArrow, &rc);
     CopyRect(&rcBitmap, &rc);
-    CopyRect(&rcText, &rc);
 
     /* get a pointer to the text */
@@ -650,25 +857,36 @@
     if (hasDropDownArrow)
     {
-	if (dwStyle & TBSTYLE_FLAT)
-            rc.right = max(rc.left, rc.right - DDARROW_WIDTH);
-	else
-            rc.right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
-	rcArrow.left = rc.right;
-    }
+        int right;
+
+        if (dwStyle & TBSTYLE_FLAT)
+            right = max(rc.left, rc.right - DDARROW_WIDTH);
+        else
+            right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
+
+        if (drawSepDropDownArrow)
+           rc.right = right;
+
+        rcArrow.left = right;
+    }
+
+    /* copy text rect after adjusting for drop-down arrow
+     * so that text is centred in the rectangle not containing
+     * the arrow */
+    CopyRect(&rcText, &rc);
 
     /* Center the bitmap horizontally and vertically */
     if (dwStyle & TBSTYLE_LIST)
-	rcBitmap.left += 3;
+        rcBitmap.left += GetSystemMetrics(SM_CXEDGE) + OFFSET_X;
     else
-	rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
+        rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
 
     if(lpText)
-        rcBitmap.top+=2; /* this looks to be the correct value from vmware comparison - cmm */
+        rcBitmap.top+= GetSystemMetrics(SM_CYEDGE) + OFFSET_Y;
     else
         rcBitmap.top+=(infoPtr->nButtonHeight - infoPtr->nBitmapHeight) / 2;
 
     TRACE("iBitmap: %d, start=(%ld,%ld) w=%d, h=%d\n",
-	  btnPtr->iBitmap, rcBitmap.left, rcBitmap.top,
-	  infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
+      btnPtr->iBitmap, rcBitmap.left, rcBitmap.top,
+      infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
     TRACE ("iString: %x\n", btnPtr->iString);
     TRACE ("Stringtext: %s\n", debugstr_w(lpText));
@@ -676,38 +894,25 @@
     /* draw text */
     if (lpText) {
-
-	InflateRect (&rcText, -3, -3);
-
-	if (GETDEFIMAGELIST(infoPtr, 0) &&
-            TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
-	        /* The following test looked like this before
-		 * I changed it. IE4 "Links" toolbar would not
-		 * draw correctly with the original code.  - GA 8/01
-		 *   ((dwStyle & TBSTYLE_LIST) &&
-		 *    ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
-		 *       (btnPtr->iBitmap != I_IMAGENONE))
-		 */
-	        if (dwStyle & TBSTYLE_LIST) {
-		    /* LIST style w/ ICON offset is by matching native. */
-		    /* Matches IE4 "Links" bar.   - GA 8/01             */
-		    rcText.left += (infoPtr->nBitmapWidth + 2);
-		}
-		else {
-		    rcText.top += infoPtr->nBitmapHeight + 1;
-		}
-	}
-	else {
-	        if (dwStyle & TBSTYLE_LIST) {
-		    /* LIST style w/o ICON offset is by matching native. */
-		    /* Matches IE4 "menu" bar.   - GA  8/01              */
-		    rcText.left += 4;
-		}
-	}
-
-	if (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
-	    OffsetRect (&rcText, 1, 1);
-    }
-
-    /* Initialize fields in all cases, because we use these later */
+        rcText.left += GetSystemMetrics(SM_CXEDGE) + OFFSET_X;
+        rcText.right -= GetSystemMetrics(SM_CXEDGE) + OFFSET_X;
+        if (GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr,btnPtr->iBitmap)) &&
+                TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
+        {
+            if (dwStyle & TBSTYLE_LIST)
+                rcText.left += infoPtr->nBitmapWidth + TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap);
+            else
+                rcText.top += GetSystemMetrics(SM_CYEDGE) + OFFSET_Y + infoPtr->nBitmapHeight + infoPtr->szPadding.cy/2;
+        }
+        else
+            if (dwStyle & TBSTYLE_LIST)
+                rcText.left += LIST_IMAGE_ABSENT_WIDTH + TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap);
+
+        if (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
+            OffsetRect (&rcText, 1, 1);
+    }
+
+    /* Initialize fields in all cases, because we use these later
+     * NOTE: applications can and do alter these to customize their
+     * toolbars */
     ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
     tbcd.clrText = comctl32_color.clrBtnText;
@@ -719,16 +924,19 @@
     tbcd.nStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
     tbcd.nHLStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
-    /* MSDN says that this is the text rectangle.              */
-    /* But (why always a but) tracing of v5.7 of native shows  */
-    /* that this is really a *relative* rectangle based on the */
-    /* the nmcd.rc. Also the left and top are always 0 ignoring*/
-    /* any bitmap that might be present.                       */
+    /* MSDN says that this is the text rectangle.
+     * But (why always a but) tracing of v5.7 of native shows
+     * that this is really a *relative* rectangle based on the
+     * the nmcd.rc. Also the left and top are always 0 ignoring
+     * any bitmap that might be present. */
     tbcd.rcText.left = 0;
     tbcd.rcText.top = 0;
     tbcd.rcText.right = rcText.right - rc.left;
     tbcd.rcText.bottom = rcText.bottom - rc.top;
-
-    /* FIXME: what should these be set to ????? */
-    tbcd.hbrMonoDither = 0;
+    tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
+    tbcd.nmcd.hdc = hdc;
+    tbcd.nmcd.rc = rc;
+    tbcd.hbrMonoDither = COMCTL32_hPattern55AABrush;
+
+    /* FIXME: what are these used for? */
     tbcd.hbrLines = 0;
     tbcd.hpenLines = 0;
@@ -740,10 +948,11 @@
     {
 	tbcd.nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
-	tbcd.nmcd.hdc = hdc;
-	tbcd.nmcd.rc = rc;
 	tbcd.nmcd.dwItemSpec = btnPtr->idCommand;
-	tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
 	tbcd.nmcd.lItemlParam = btnPtr->dwData;
 	ntfret = TOOLBAR_SendNotify ((NMHDR *)&tbcd, infoPtr, NM_CUSTOMDRAW);
+        /* reset these fields so the user can't alter the behaviour like native */
+        tbcd.nmcd.hdc = hdc;
+        tbcd.nmcd.rc = rc;
+
 	infoPtr->dwItemCustDraw = ntfret & 0xffff;
 	infoPtr->dwItemCDFlag = ntfret & 0xffff0000;
@@ -755,9 +964,6 @@
     }
 
-    if (!infoPtr->bBtnTranspnt)
-	FillRect( hdc, &rcFill, GetSysColorBrush(COLOR_BTNFACE));
-
     /* separator */
-    if (btnPtr->fsStyle & TBSTYLE_SEP) {
+    if (btnPtr->fsStyle & BTNS_SEP) {
         /* with the FLAT style, iBitmap is the width and has already */
         /* been taken into consideration in calculating the width    */
@@ -766,10 +972,10 @@
         /* when drawing the vertical bar...      */
         if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */) {
-	    if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
+	    if (btnPtr->fsStyle & BTNS_DROPDOWN)
 		TOOLBAR_DrawDDFlatSeparator (&rc, hdc, btnPtr, infoPtr);
 	    else
 		TOOLBAR_DrawFlatSeparator (&rc, hdc, infoPtr);
 	}
-	else if (btnPtr->fsStyle != TBSTYLE_SEP) {
+	else if (btnPtr->fsStyle != BTNS_SEP) {
 	    FIXME("Draw some kind of separator: fsStyle=%x\n",
 		  btnPtr->fsStyle);
@@ -778,178 +984,49 @@
     }
 
-    /* Determine index of image list */
-    himlDef = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
-
-    /* disabled */
-    if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
-	HIMAGELIST himlDis = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
-	if (!(dwStyle & TBSTYLE_FLAT) && !(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-	{
-	    DrawEdge (hdc, &rc, EDGE_RAISED,
-		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+    if (!(tbcd.nmcd.uItemState & CDIS_HOT) && 
+        ((tbcd.nmcd.uItemState & CDIS_CHECKED) || (tbcd.nmcd.uItemState & CDIS_INDETERMINATE)))
+        TOOLBAR_DrawPattern (&rc, &tbcd);
+
+    if ((dwStyle & TBSTYLE_FLAT) && (tbcd.nmcd.uItemState & CDIS_HOT))
+    {
+        if ( infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )
+        {
+            COLORREF oldclr;
+
+            oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack);
+            ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
             if (hasDropDownArrow)
-            DrawEdge (hdc, &rcArrow, EDGE_RAISED,
-		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
-	}
-
-        if (hasDropDownArrow)
-	{
-	    TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1, COLOR_3DHIGHLIGHT);
-	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_3DSHADOW);
-	}
-
-	if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDis,
-				   hdc, rcBitmap.left, rcBitmap.top,
-				   ILD_NORMAL))
-	    TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
-
-	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
-	goto FINALNOTIFY;
-    }
-
-    /* pressed TBSTYLE_BUTTON */
-    if (btnPtr->fsState & TBSTATE_PRESSED) {
-	offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
-	if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-	{
-	    if (dwStyle & TBSTYLE_FLAT)
-	    {
-		DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
-		if (hasDropDownArrow)
-		    DrawEdge (hdc, &rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
-	    }
-	    else
-	    {
-		DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
-		if (hasDropDownArrow)
-		    DrawEdge (hdc, &rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
-	    }
-	}
-
-        if (hasDropDownArrow)
-	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
-
-	TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
-			       hdc, rcBitmap.left+offset, rcBitmap.top+offset,
-			       ILD_NORMAL);
-
-	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
-	goto FINALNOTIFY;
-    }
-
-    /* checked TBSTYLE_CHECK */
-    if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
-	(btnPtr->fsState & TBSTATE_CHECKED)) {
-	if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-	{
-	    if (dwStyle & TBSTYLE_FLAT)
-		DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
-			  BF_RECT | BF_ADJUST);
-	    else
-		DrawEdge (hdc, &rc, EDGE_SUNKEN,
-			  BF_RECT | BF_MIDDLE | BF_ADJUST);
-	}
-
-	TOOLBAR_DrawPattern (hdc, &rc);
-
-	TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
-			       hdc, rcBitmap.left+1, rcBitmap.top+1,
-			       ILD_NORMAL);
-
-	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
-	goto FINALNOTIFY;
-    }
-
-    /* indeterminate */
-    if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
-	if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-	    DrawEdge (hdc, &rc, EDGE_RAISED,
-		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
-
-	TOOLBAR_DrawPattern (hdc, &rc);
-	TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
-	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
-	goto FINALNOTIFY;
-    }
-
-    /* normal state */
-    if (dwStyle & TBSTYLE_FLAT)
+                ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0);
+            SetBkColor(hdc, oldclr);
+        }
+    }
+
+    TOOLBAR_DrawFrame(infoPtr, dwStyle & TBSTYLE_FLAT, &tbcd);
+
+    if (drawSepDropDownArrow)
+        TOOLBAR_DrawSepDDArrow(infoPtr, dwStyle & TBSTYLE_FLAT, &tbcd, &rcArrow);
+
+    if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
+        TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
+
+    TOOLBAR_DrawImage(infoPtr, btnPtr, rcBitmap.left, rcBitmap.top, &tbcd);
+
+    if (hasDropDownArrow && !drawSepDropDownArrow)
     {
-	if (btnPtr->bHot)
-	{
-	    if ( infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )
-	    {
-		COLORREF oldclr;
-
-		oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack);
-		ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
-		if (hasDropDownArrow)
-		    ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0);
-		SetBkColor(hdc, oldclr);
-	    }
-	    else
-	    {
-		if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-		{
-		    DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT);
-		    if (hasDropDownArrow)
-			DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT);
-		}
-	    }
-	}
-#if 1
-        else /* The following code needs to be removed after
-	      * "hot item" support has been implemented for the
-	      * case where it is being de-selected.
-	      */
-	{
-            FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
-            if (hasDropDownArrow)
-            FrameRect(hdc, &rcArrow, GetSysColorBrush(COLOR_BTNFACE));
-	}
-#endif
-
-        if (hasDropDownArrow)
-	    TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top, COLOR_WINDOWFRAME);
-
-	if (btnPtr->bHot) {
-            HIMAGELIST himlHot = GETHOTIMAGELIST(infoPtr, 
-                GETHIMLID(infoPtr, btnPtr->iBitmap));
-	    /* if hot, attempt to draw with himlHot, if fails, use himlDef */
-	    if (!TOOLBAR_DrawImageList (infoPtr, btnPtr,
-					himlHot,
-					hdc, rcBitmap.left,
-					rcBitmap.top, ILD_NORMAL))
-		TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
-				       hdc, rcBitmap.left, rcBitmap.top,
-				       ILD_NORMAL);
-	}
-	else
-	    TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
-				   hdc, rcBitmap.left, rcBitmap.top,
-				   ILD_NORMAL);
-    }
-    else
-    {
-	if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-	    DrawEdge (hdc, &rc, EDGE_RAISED,
-		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
-
-        if (hasDropDownArrow)
-	{
-	    if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
-		DrawEdge (hdc, &rcArrow, EDGE_RAISED,
-			  BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
-	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
-	}
-
-	TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
-			       hdc, rcBitmap.left, rcBitmap.top,
-			       ILD_NORMAL);}
-
-
-    TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
-
- FINALNOTIFY:
+        if (tbcd.nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
+        {
+            TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1 + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight);
+            TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow);
+        }
+        else if (tbcd.nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED))
+        {
+            offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
+            TOOLBAR_DrawArrow(hdc, rcArrow.left + offset, rcArrow.top + offset + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
+        }
+        else
+            TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
+    }
+
+FINALNOTIFY:
     if (infoPtr->dwItemCustDraw & CDRF_NOTIFYPOSTPAINT)
     {
@@ -975,7 +1052,11 @@
     TBUTTON_INFO *btnPtr;
     INT i, oldBKmode = 0;
-    RECT rcTemp;
+    RECT rcTemp, rcClient;
     NMTBCUSTOMDRAW tbcd;
     DWORD ntfret;
+
+    /* the app has told us not to redraw the toolbar */
+    if (!infoPtr->bDoRedraw)
+        return;
 
     /* if imagelist belongs to the app, it can be changed
@@ -1001,9 +1082,21 @@
 	oldBKmode = SetBkMode (hdc, TRANSPARENT);
 
+    GetClientRect(hwnd, &rcClient);
+
     /* redraw necessary buttons */
     btnPtr = infoPtr->buttons;
     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
     {
-        if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
+        BOOL bDraw;
+        if (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
+        {
+            IntersectRect(&rcTemp, &rcClient, &btnPtr->rect);
+            bDraw = EqualRect(&rcTemp, &btnPtr->rect);
+        }
+        else
+            bDraw = TRUE;
+        bDraw &= IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect));
+        bDraw = (btnPtr->fsState & TBSTATE_HIDDEN) ? FALSE : bDraw;
+        if (bDraw)
             TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
     }
@@ -1032,5 +1125,5 @@
 * indicates where the underline goes, except for the string "&&" which
 * is reduced to a single "&". GetTextExtentPoint does not process these
-* only DrawText does. Note that the TBSTYLE_NOPREFIX is handled here.
+* only DrawText does. Note that the BTNS_NOPREFIX is handled here.
 */
 static void
@@ -1043,5 +1136,8 @@
     lpSize->cy = 0;
 
-    if (!(btnPtr->fsState & TBSTATE_HIDDEN) )
+    if (infoPtr->nMaxTextRows > 0 &&
+        !(btnPtr->fsState & TBSTATE_HIDDEN) &&
+        (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
+        (btnPtr->fsStyle & BTNS_SHOWTEXT)) )
     {
         LPWSTR lpText = TOOLBAR_GetText(infoPtr, btnPtr);
@@ -1058,5 +1154,5 @@
 	    /* Use DrawText to get true size as drawn (less pesky "&") */
 	    DrawTextW (hdc, lpText, -1, &myrect, DT_VCENTER | DT_SINGLELINE |
-	    	   DT_CALCRECT | ((btnPtr->fsStyle & TBSTYLE_NOPREFIX) ?
+	    	   DT_CALCRECT | ((btnPtr->fsStyle & BTNS_NOPREFIX) ?
 				  DT_NOPREFIX : 0));
 
@@ -1088,4 +1184,7 @@
     lpSize->cx = 0;
     lpSize->cy = 0;
+
+    if(infoPtr->nMaxTextRows == 0)
+        return;
 
     hdc = GetDC (hwnd);
@@ -1113,5 +1212,5 @@
 * 		TOOLBAR_WrapToolbar
 *
-* This function walks through the buttons and seperators in the
+* This function walks through the buttons and separators in the
 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
 * wrapping should occur based on the width of the toolbar window.
@@ -1167,8 +1266,8 @@
 	/* custom controls in toolbars.                              */
 	/*                                                           */
-	/* TBSTYLE_DROPDOWN separators are treated as buttons for    */
+	/* BTNS_DROPDOWN separators are treated as buttons for    */
 	/* width.  - GA 8/01                                         */
-	if ((btnPtr[i].fsStyle & TBSTYLE_SEP) &&
-	    !(btnPtr[i].fsStyle & TBSTYLE_DROPDOWN))
+	if ((btnPtr[i].fsStyle & BTNS_SEP) &&
+	    !(btnPtr[i].fsStyle & BTNS_DROPDOWN))
 	    cx = (btnPtr[i].iBitmap > 0) ?
 			btnPtr[i].iBitmap : SEPARATOR_WIDTH;
@@ -1180,7 +1279,7 @@
 	/* next row if the previous wrapping is on a button.	     */
 	if( bButtonWrap &&
-		(btnPtr[i].fsStyle & TBSTYLE_SEP) &&
+		(btnPtr[i].fsStyle & BTNS_SEP) &&
 		(i + 1 < infoPtr->nNumButtons ) &&
-		(btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
+		(btnPtr[i + 1].fsStyle & BTNS_SEP) )
 	{
 	    TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
@@ -1204,6 +1303,6 @@
 	    /*	go to the next until it reaches a non separator.      */
 	    /*	Wrap the last separator if it is before a button.     */
-	    while( ( ((btnPtr[i].fsStyle & TBSTYLE_SEP) &&
-		      !(btnPtr[i].fsStyle & TBSTYLE_DROPDOWN)) ||
+	    while( ( ((btnPtr[i].fsStyle & BTNS_SEP) &&
+		      !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
 		     (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
 			i < infoPtr->nNumButtons )
@@ -1230,5 +1329,5 @@
 	    for ( j = i - 1; j >= 0  &&  !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
 	    {
-		if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
+		if ((btnPtr[j].fsStyle & BTNS_SEP) &&
 			!(btnPtr[j].fsState & TBSTATE_HIDDEN))
 		{
@@ -1273,5 +1372,5 @@
 		bFound = TRUE;
 		x = infoPtr->nIndent;
-		if (btnPtr[i].fsStyle & TBSTYLE_SEP )
+		if (btnPtr[i].fsStyle & BTNS_SEP )
 		    bButtonWrap = FALSE;
 		else
@@ -1314,4 +1413,6 @@
     TOOLBAR_CalcStrings (hwnd, &sizeString);
 
+    TOOLBAR_DumpToolbar (infoPtr, __LINE__);
+
     for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
     {
@@ -1324,9 +1425,10 @@
 				     0, sizeString.cy) + infoPtr->szPadding.cy;
 	infoPtr->nButtonWidth = ((usesBitmaps) ? infoPtr->nBitmapWidth :
-				 0) + sizeString.cx + 6;
+				 LIST_IMAGE_ABSENT_WIDTH) + sizeString.cx + infoPtr->szPadding.cx;
+        if (sizeString.cx > 0)
+            infoPtr->nButtonWidth += TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap) + infoPtr->szPadding.cx/2;
 	TRACE("LIST style, But w=%d h=%d, useBitmaps=%d, Bit w=%d h=%d\n",
 	      infoPtr->nButtonWidth, infoPtr->nButtonHeight, usesBitmaps,
 	      infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
-	TOOLBAR_DumpToolbar (infoPtr, __LINE__);
     }
     else {
@@ -1335,16 +1437,16 @@
             if (usesBitmaps)
 		infoPtr->nButtonHeight = sizeString.cy +
-		    2 + /* this is the space to separate text from bitmap */
-                  infoPtr->nBitmapHeight + 6;
+		    infoPtr->szPadding.cy/2 + /* this is the space to separate text from bitmap */
+                  infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
             else
-                infoPtr->nButtonHeight = sizeString.cy + 6;
+                infoPtr->nButtonHeight = sizeString.cy + infoPtr->szPadding.cy;
         }
-        else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
-	    infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
+        else
+	    infoPtr->nButtonHeight = infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
 
         if (sizeString.cx > infoPtr->nBitmapWidth)
-	    infoPtr->nButtonWidth = sizeString.cx + 6;
-        else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
-	    infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
+	    infoPtr->nButtonWidth = sizeString.cx + infoPtr->szPadding.cx;
+        else
+            infoPtr->nButtonWidth = infoPtr->nBitmapWidth + infoPtr->szPadding.cx;
     }
 
@@ -1359,15 +1461,4 @@
     y  = 0;
 
-   /*
-    * We will set the height below, and we set the width on entry
-    * so we do not reset them here..
-    */
-#if 0
-    GetClientRect( hwnd, &rc );
-    /* get initial values for toolbar */
-    infoPtr->nWidth  = rc.right - rc.left;
-    infoPtr->nHeight = rc.bottom - rc.top;
-#endif
-
     /* from above, minimum is a button, and possible text */
     cx = infoPtr->nButtonWidth;
@@ -1387,10 +1478,4 @@
 
     btnPtr = infoPtr->buttons;
-
-    /* do not base height/width on parent, if the parent is a */
-    /* rebar control it could have multiple rows of toolbars  */
-/*    GetClientRect( GetParent(hwnd), &rc ); */
-/*    cx = rc.right - rc.left; */
-/*    cy = rc.bottom - rc.top; */
 
     TRACE("cy=%d\n", cy);
@@ -1410,6 +1495,6 @@
 	/* it is the actual width of the separator. This is used for */
 	/* custom controls in toolbars.                              */
-	if (btnPtr->fsStyle & TBSTYLE_SEP) {
-	    if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
+	if (btnPtr->fsStyle & BTNS_SEP) {
+	    if (btnPtr->fsStyle & BTNS_DROPDOWN) {
 		cy = (btnPtr->iBitmap > 0) ?
 		     btnPtr->iBitmap : SEPARATOR_WIDTH;
@@ -1422,5 +1507,6 @@
 	else
 	{
-            if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
+            if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || 
+                (btnPtr->fsStyle & BTNS_AUTOSIZE))
             {
               SIZE sz;
@@ -1436,15 +1522,25 @@
 	      ReleaseDC (hwnd, hdc);
 
-	      /* Fudge amount measured against IE4 "menu" and "Links" */
-	      /* toolbars with native control (v4.71).  -  GA 8/01    */
-              cx = sz.cx + 6 + 5 + 5;
-	      if ((dwStyle & TBSTYLE_LIST) &&
-		  (TOOLBAR_TestImageExist (infoPtr, btnPtr, GETDEFIMAGELIST(infoPtr,0))))
-		  cx += infoPtr->nBitmapWidth;
+              /* add space on for button frame, etc */
+              cx = sz.cx + infoPtr->szPadding.cx;
+              
+              /* add list padding */
+              if ((dwStyle & TBSTYLE_LIST) && sz.cx > 0)
+                  cx += TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap) + infoPtr->szPadding.cx/2;
+
+              if (TOOLBAR_TestImageExist (infoPtr, btnPtr, GETDEFIMAGELIST(infoPtr,0)))
+              {
+                if (dwStyle & TBSTYLE_LIST)
+                  cx += infoPtr->nBitmapWidth;
+                else if (cx < (infoPtr->nBitmapWidth+infoPtr->szPadding.cx))
+                  cx = infoPtr->nBitmapWidth+infoPtr->szPadding.cx;
+              }
+              else if (dwStyle & TBSTYLE_LIST)
+                  cx += LIST_IMAGE_ABSENT_WIDTH;
             }
             else
 	      cx = infoPtr->nButtonWidth;
 
-	    if (hasDropDownArrows && (btnPtr->fsStyle & TBSTYLE_DROPDOWN))
+	    if ((hasDropDownArrows && (btnPtr->fsStyle & BTNS_DROPDOWN)) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN))
 	      cx += DDARROW_WIDTH;
 	}
@@ -1462,5 +1558,5 @@
 
 	/* Set the toolTip only for non-hidden, non-separator button */
-	if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
+	if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & BTNS_SEP ))
 	{
 	    TTTOOLINFOA ti;
@@ -1485,5 +1581,5 @@
 	if( bWrap )
 	{
-	    if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
+	    if ( !(btnPtr->fsStyle & BTNS_SEP) )
 	        y += cy;
 	    else
@@ -1492,5 +1588,5 @@
 		/* it is the actual width of the separator. This is used for */
 		/* custom controls in toolbars. 			     */
-		if ( !(btnPtr->fsStyle & TBSTYLE_DROPDOWN))
+		if ( !(btnPtr->fsStyle & BTNS_DROPDOWN))
 		    y += cy + ( (btnPtr->iBitmap > 0 ) ?
 				btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
@@ -1552,5 +1648,5 @@
 	    continue;
 
-	if (btnPtr->fsStyle & TBSTYLE_SEP) {
+	if (btnPtr->fsStyle & BTNS_SEP) {
 	    if (PtInRect (&btnPtr->rect, *lpPt)) {
 		TRACE(" ON SEPARATOR %d!\n", i);
@@ -1605,5 +1701,5 @@
     /* check index button */
     btnPtr = &infoPtr->buttons[nIndex];
-    if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
+    if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
 	if (btnPtr->fsState & TBSTATE_CHECKED)
 	    return nIndex;
@@ -1614,5 +1710,5 @@
     while (nRunIndex >= 0) {
 	btnPtr = &infoPtr->buttons[nRunIndex];
-	if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
+	if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
 	    if (btnPtr->fsState & TBSTATE_CHECKED)
 		return nRunIndex;
@@ -1627,5 +1723,5 @@
     while (nRunIndex < infoPtr->nNumButtons) {
 	btnPtr = &infoPtr->buttons[nRunIndex];
-	if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
+	if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
 	    if (btnPtr->fsState & TBSTATE_CHECKED)
 		return nRunIndex;
@@ -1690,9 +1786,12 @@
 		    return FALSE;
 
+		/* UNDOCUMENTED: dialog hwnd immediately follows NMHDR */
+		nmtb.iItem = (int)hwnd;
 		/* Send TBN_INITCUSTOMIZE notification */
 		if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_INITCUSTOMIZE) ==
-                    TBNRF_HIDEHELP)
+		    TBNRF_HIDEHELP)
                 {
-                    FIXME("TBNRF_HIDEHELP not supported\n");
+                    TRACE("TBNRF_HIDEHELP requested\n");
+                    ShowWindow(GetDlgItem(hwnd, IDC_HELP_BTN), SW_HIDE);
                 }
 
@@ -1700,7 +1799,7 @@
 		for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
                 {
-		    btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
+		    btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
                     memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
-                    btnInfo->btn.fsStyle = TBSTYLE_SEP;
+                    btnInfo->btn.fsStyle = BTNS_SEP;
                     btnInfo->bVirtual = FALSE;
 		    LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
@@ -1714,7 +1813,7 @@
 
 		/* insert separator button into 'available buttons' list */
-		btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
+		btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
 		memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
-		btnInfo->btn.fsStyle = TBSTYLE_SEP;
+		btnInfo->btn.fsStyle = BTNS_SEP;
 		btnInfo->bVirtual = FALSE;
 		btnInfo->bRemovable = TRUE;
@@ -1749,5 +1848,5 @@
 		    if (index == -1)
 		    {
-			btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
+			btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
 			btnInfo->bVirtual = FALSE;
 			btnInfo->bRemovable = TRUE;
@@ -1764,5 +1863,5 @@
 
                     memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
-                    if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
+                    if (!(nmtb.tbButton.fsStyle & BTNS_SEP))
                     {
                         if (lstrlenW(nmtb.pszText))
@@ -1781,7 +1880,7 @@
 
 		/* append 'virtual' separator button to the 'toolbar buttons' list */
-		btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
+		btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
 		memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
-		btnInfo->btn.fsStyle = TBSTYLE_SEP;
+		btnInfo->btn.fsStyle = BTNS_SEP;
 		btnInfo->bVirtual = TRUE;
 		btnInfo->bRemovable = FALSE;
@@ -1953,5 +2052,5 @@
 
 			    /* insert into 'available button' list */
-			    if (!(btnInfo->btn.fsStyle & TBSTYLE_SEP))
+			    if (!(btnInfo->btn.fsStyle & BTNS_SEP))
 			    {
 				index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
@@ -1959,8 +2058,14 @@
 			    }
 			    else
-				COMCTL32_Free (btnInfo);
+				Free (btnInfo);
 			}
 		    }
 		    break;
+		case IDC_HELP_BTN:
+			TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_CUSTHELP);
+			break;
+		case IDC_RESET_BTN:
+			TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_RESET);
+			break;
 
 		case IDOK: /* Add button */
@@ -1994,5 +2099,5 @@
 
 				/* duplicate 'separator' button */
-				btnNew = (PCUSTOMBUTTON)COMCTL32_Alloc (sizeof(CUSTOMBUTTON));
+				btnNew = (PCUSTOMBUTTON)Alloc (sizeof(CUSTOMBUTTON));
 				memcpy (btnNew, btnInfo, sizeof(CUSTOMBUTTON));
 				btnInfo = btnNew;
@@ -2025,5 +2130,5 @@
 		{
 		    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
-		    COMCTL32_Free(btnInfo);
+		    Free(btnInfo);
 		    SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
 		}
@@ -2036,5 +2141,5 @@
 		{
 		    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
-		    COMCTL32_Free(btnInfo);
+		    Free(btnInfo);
 		    SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
 		}
@@ -2094,5 +2199,5 @@
 
 		/* draw image and text */
-		if ((btnInfo->btn.fsStyle & TBSTYLE_SEP) == 0) {
+		if ((btnInfo->btn.fsStyle & BTNS_SEP) == 0) {
 			HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, 
 				btnInfo->btn.iBitmap));
@@ -2199,8 +2304,8 @@
 	TRACE ("creating default image list!\n");
 
-    himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, 
-		ILC_COLOR | ILC_MASK, nButtons, 2);
+        himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
+                                    ILC_COLORDDB | ILC_MASK, nButtons, 2);
 	TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0);
-    infoPtr->himlInt = himlDef;
+        infoPtr->himlInt = himlDef;
     }
     else {
@@ -2244,5 +2349,5 @@
        DeleteDC (hdcBitmap);
 
-       nIndex = ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
+       nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace);
        DeleteObject (hbmLoad);
     }
@@ -2256,5 +2361,5 @@
 				       MAKEINTRESOURCEA(IDB_STD_SMALL));
 		nIndex = ImageList_AddMasked (himlDef,
-					      hbmLoad, CLR_DEFAULT);
+					      hbmLoad, comctl32_color.clrBtnFace);
 		DeleteObject (hbmLoad);
 		break;
@@ -2264,5 +2369,5 @@
 				       MAKEINTRESOURCEA(IDB_STD_LARGE));
 		nIndex = ImageList_AddMasked (himlDef,
-					      hbmLoad, CLR_DEFAULT);
+					      hbmLoad, comctl32_color.clrBtnFace);
 		DeleteObject (hbmLoad);
 		break;
@@ -2272,5 +2377,5 @@
 				       MAKEINTRESOURCEA(IDB_VIEW_SMALL));
 		nIndex = ImageList_AddMasked (himlDef,
-					      hbmLoad, CLR_DEFAULT);
+					      hbmLoad, comctl32_color.clrBtnFace);
 		DeleteObject (hbmLoad);
 		break;
@@ -2280,5 +2385,5 @@
 				       MAKEINTRESOURCEA(IDB_VIEW_LARGE));
 		nIndex = ImageList_AddMasked (himlDef,
-					      hbmLoad, CLR_DEFAULT);
+					      hbmLoad, comctl32_color.clrBtnFace);
 		DeleteObject (hbmLoad);
 		break;
@@ -2288,5 +2393,5 @@
 				       MAKEINTRESOURCEA(IDB_HIST_SMALL));
 		nIndex = ImageList_AddMasked (himlDef,
-					      hbmLoad, CLR_DEFAULT);
+					      hbmLoad, comctl32_color.clrBtnFace);
 		DeleteObject (hbmLoad);
 		break;
@@ -2296,5 +2401,5 @@
 				       MAKEINTRESOURCEA(IDB_HIST_LARGE));
 		nIndex = ImageList_AddMasked (himlDef,
-					      hbmLoad, CLR_DEFAULT);
+					      hbmLoad, comctl32_color.clrBtnFace);
 		DeleteObject (hbmLoad);
 		break;
@@ -2309,5 +2414,5 @@
     {
 	hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
-	nIndex = ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
+	nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace);
 	DeleteObject (hbmLoad);
     }
@@ -2317,10 +2422,10 @@
     if (infoPtr->nNumBitmapInfos == 0)
     {
-        infoPtr->bitmaps = COMCTL32_Alloc(sizeof(TBITMAP_INFO));
+        infoPtr->bitmaps = Alloc(sizeof(TBITMAP_INFO));
     }
     else
     {
         TBITMAP_INFO *oldBitmaps = infoPtr->bitmaps;
-        infoPtr->bitmaps = COMCTL32_Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
+        infoPtr->bitmaps = Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
         memcpy(&infoPtr->bitmaps[0], &oldBitmaps[0], infoPtr->nNumBitmapInfos);
     }
@@ -2349,5 +2454,5 @@
     }
 
-    InvalidateRect(hwnd, NULL, FALSE);
+    InvalidateRect(hwnd, NULL, TRUE);
 
     return nIndex;
@@ -2370,13 +2475,13 @@
     if (infoPtr->nNumButtons == 0) {
 	infoPtr->buttons =
-	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
+	    Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     }
     else {
 	TBUTTON_INFO *oldButtons = infoPtr->buttons;
 	infoPtr->buttons =
-	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
+	    Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
 	memcpy (&infoPtr->buttons[0], &oldButtons[0],
 		nOldButtons * sizeof(TBUTTON_INFO));
-        COMCTL32_Free (oldButtons);
+        Free (oldButtons);
     }
 
@@ -2391,8 +2496,11 @@
 	btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
 	btnPtr->dwData    = lpTbb[nCount].dwData;
-	btnPtr->iString   = lpTbb[nCount].iString;
+        if(HIWORD(lpTbb[nCount].iString) && lpTbb[nCount].iString != -1)
+            Str_SetPtrAtoW ((LPWSTR*)&btnPtr->iString, (LPSTR)lpTbb[nCount].iString );
+        else
+            btnPtr->iString   = lpTbb[nCount].iString;
 	btnPtr->bHot      = FALSE;
 
-	if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
+	if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & BTNS_SEP)) {
 	    TTTOOLINFOA ti;
 
@@ -2413,5 +2521,5 @@
     TOOLBAR_DumpToolbar (infoPtr, __LINE__);
 
-    InvalidateRect(hwnd, NULL, FALSE);
+    InvalidateRect(hwnd, NULL, TRUE);
 
     return TRUE;
@@ -2434,13 +2542,13 @@
     if (infoPtr->nNumButtons == 0) {
 	infoPtr->buttons =
-	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
+	    Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     }
     else {
 	TBUTTON_INFO *oldButtons = infoPtr->buttons;
 	infoPtr->buttons =
-	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
+	    Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
 	memcpy (&infoPtr->buttons[0], &oldButtons[0],
 		nOldButtons * sizeof(TBUTTON_INFO));
-        COMCTL32_Free (oldButtons);
+        Free (oldButtons);
     }
 
@@ -2455,8 +2563,11 @@
 	btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
 	btnPtr->dwData    = lpTbb[nCount].dwData;
-	btnPtr->iString   = lpTbb[nCount].iString;
+        if(HIWORD(lpTbb[nCount].iString) && lpTbb[nCount].iString != -1)
+            Str_SetPtrW ((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[nCount].iString );
+        else
+            btnPtr->iString   = lpTbb[nCount].iString;
 	btnPtr->bHot      = FALSE;
 
-	if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
+	if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & BTNS_SEP)) {
 	    TTTOOLINFOW ti;
 
@@ -2478,5 +2589,5 @@
     TOOLBAR_DumpToolbar (infoPtr, __LINE__);
 
-    InvalidateRect(hwnd, NULL, FALSE);
+    InvalidateRect(hwnd, NULL, TRUE);
 
     return TRUE;
@@ -2502,16 +2613,16 @@
 	if (infoPtr->nNumStrings == 0) {
 	    infoPtr->strings =
-		COMCTL32_Alloc (sizeof(LPWSTR));
+		Alloc (sizeof(LPWSTR));
 	}
 	else {
 	    LPWSTR *oldStrings = infoPtr->strings;
 	    infoPtr->strings =
-		COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
+		Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
 	    memcpy (&infoPtr->strings[0], &oldStrings[0],
 		    sizeof(LPWSTR) * infoPtr->nNumStrings);
-	    COMCTL32_Free (oldStrings);
+	    Free (oldStrings);
 	}
 
-        /*COMCTL32_Alloc zeros out the allocated memory*/
+        /*Alloc zeros out the allocated memory*/
         Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], szString );
 	infoPtr->nNumStrings++;
@@ -2532,13 +2643,13 @@
 	    if (infoPtr->nNumStrings == 0) {
 		infoPtr->strings =
-		    COMCTL32_Alloc (sizeof(LPWSTR));
+		    Alloc (sizeof(LPWSTR));
 	    }
 	    else {
 		LPWSTR *oldStrings = infoPtr->strings;
 		infoPtr->strings =
-		    COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
+		    Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
 		memcpy (&infoPtr->strings[0], &oldStrings[0],
 			sizeof(LPWSTR) * infoPtr->nNumStrings);
-		COMCTL32_Free (oldStrings);
+		Free (oldStrings);
 	    }
 
@@ -2580,16 +2691,16 @@
 
                 if (infoPtr->nNumStrings == 0) {
-                    infoPtr->strings = COMCTL32_Alloc (sizeof(LPWSTR));
+                    infoPtr->strings = Alloc (sizeof(LPWSTR));
                 }
                 else
                 {
                     LPWSTR *oldStrings = infoPtr->strings;
-                    infoPtr->strings = COMCTL32_Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
+                    infoPtr->strings = Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
                     memcpy(&infoPtr->strings[0], &oldStrings[0],
                            sizeof(LPWSTR) * infoPtr->nNumStrings);
-                    COMCTL32_Free(oldStrings);
+                    Free(oldStrings);
                 }
 
-                np=COMCTL32_StrChrW (p, L'|');
+                np=strchrW (p, '|');
                 if (np!=NULL) {
                     len = np - p;
@@ -2601,5 +2712,5 @@
                 TRACE("len=%d %s\n", len, debugstr_w(p));
                 infoPtr->strings[infoPtr->nNumStrings] =
-                    COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
+                    Alloc (sizeof(WCHAR)*(len+1));
                 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len+1);
                 infoPtr->nNumStrings++;
@@ -2613,13 +2724,13 @@
             if (infoPtr->nNumStrings == 0) {
                 infoPtr->strings =
-                    COMCTL32_Alloc (sizeof(LPWSTR));
+                    Alloc (sizeof(LPWSTR));
             }
             else {
                 LPWSTR *oldStrings = infoPtr->strings;
                 infoPtr->strings =
-                    COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
+                    Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
                 memcpy (&infoPtr->strings[0], &oldStrings[0],
                         sizeof(LPWSTR) * infoPtr->nNumStrings);
-                COMCTL32_Free (oldStrings);
+                Free (oldStrings);
             }
 
@@ -2642,13 +2753,13 @@
 	    if (infoPtr->nNumStrings == 0) {
 		infoPtr->strings =
-		    COMCTL32_Alloc (sizeof(LPWSTR));
+		    Alloc (sizeof(LPWSTR));
 	    }
 	    else {
 		LPWSTR *oldStrings = infoPtr->strings;
 		infoPtr->strings =
-		    COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
+		    Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
 		memcpy (&infoPtr->strings[0], &oldStrings[0],
 			sizeof(LPWSTR) * infoPtr->nNumStrings);
-		COMCTL32_Free (oldStrings);
+		Free (oldStrings);
 	    }
 
@@ -2700,9 +2811,13 @@
 	cx = infoPtr->nWidth;
 
-	if (dwStyle & CCS_NOMOVEY) {
+	if ((dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) {
 		GetWindowRect(hwnd, &window_rect);
 		ScreenToClient(parent, (LPPOINT)&window_rect.left);
 		y = window_rect.top;
 	}
+	if ((dwStyle & CCS_BOTTOM) == CCS_BOTTOM) {
+            GetWindowRect(hwnd, &window_rect);
+            y = parent_rect.bottom - ( window_rect.bottom - window_rect.top);
+        }
     }
 
@@ -2721,8 +2836,7 @@
 
     infoPtr->bAutoSize = TRUE;
-    SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
-                        cx, cy, uPosFlags);
-    /* The following line makes sure that the infoPtr->bAutoSize is turned off after
-     * the setwindowpos calls */
+    SetWindowPos (hwnd, HWND_TOP,  x, y, cx, cy, uPosFlags);
+    /* The following line makes sure that the infoPtr->bAutoSize is turned off
+     * after the setwindowpos calls */
     infoPtr->bAutoSize = FALSE;
 
@@ -2764,4 +2878,6 @@
     INT nIndex;
 
+    TRACE("button %d, iBitmap now %d\n", wParam, LOWORD(lParam));
+
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     if (nIndex == -1)
@@ -2789,11 +2905,11 @@
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
+
+    TRACE("hwnd=%p, btn index=%d, lParam=0x%08lx\n", hwnd, nIndex, lParam);
+
     if (nIndex == -1)
 	return FALSE;
 
     btnPtr = &infoPtr->buttons[nIndex];
-
-    if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
-	return FALSE;
 
     bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
@@ -2802,5 +2918,5 @@
 	btnPtr->fsState &= ~TBSTATE_CHECKED;
     else {
-	if (btnPtr->fsStyle & TBSTYLE_GROUP) {
+	if (btnPtr->fsStyle & BTNS_GROUP) {
 	    nOldIndex =
 		TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
@@ -2815,9 +2931,6 @@
     if( bChecked != LOWORD(lParam) )
     {
-	if (nOldIndex != -1)
-        {
-            InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
-                TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
-        }
+        if (nOldIndex != -1)
+            InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, TRUE);
         InvalidateRect(hwnd, &btnPtr->rect, TRUE);
     }
@@ -2857,5 +2970,5 @@
     if (!(hRes = FindResourceA (COMCTL32_hModule,
                                 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
-                                RT_DIALOGA)))
+                                (LPSTR)RT_DIALOGA)))
 	return FALSE;
 
@@ -2887,5 +3000,5 @@
 
     if ((infoPtr->hwndToolTip) &&
-	!(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
+	!(infoPtr->buttons[nIndex].fsStyle & BTNS_SEP)) {
 	TTTOOLINFOA ti;
 
@@ -2900,5 +3013,5 @@
     if (infoPtr->nNumButtons == 1) {
 	TRACE(" simple delete!\n");
-	COMCTL32_Free (infoPtr->buttons);
+	Free (infoPtr->buttons);
 	infoPtr->buttons = NULL;
 	infoPtr->nNumButtons = 0;
@@ -2909,5 +3022,5 @@
 
 	infoPtr->nNumButtons--;
-	infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+	infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
         if (nIndex > 0) {
             memcpy (&infoPtr->buttons[0], &oldButtons[0],
@@ -2920,5 +3033,5 @@
         }
 
-	COMCTL32_Free (oldButtons);
+	Free (oldButtons);
     }
 
@@ -2940,4 +3053,7 @@
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
+
+    TRACE("hwnd=%p, btn index=%d, lParam=0x%08lx\n", hwnd, wParam, lParam);
+
     if (nIndex == -1)
 	return FALSE;
@@ -2956,8 +3072,5 @@
     /* redraw the button only if the state of the button changed */
     if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
-    {
-        InvalidateRect(hwnd, &btnPtr->rect,
-            TOOLBAR_HasText(infoPtr, btnPtr));
-    }
+        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
 
     return TRUE;
@@ -3047,49 +3160,4 @@
 
     if (!(btnPtr = &infoPtr->buttons[nIndex])) return -1;
-
-    if (lpTbInfo->dwMask & TBIF_COMMAND)
-	lpTbInfo->idCommand = btnPtr->idCommand;
-    if (lpTbInfo->dwMask & TBIF_IMAGE)
-	lpTbInfo->iImage = btnPtr->iBitmap;
-    if (lpTbInfo->dwMask & TBIF_LPARAM)
-	lpTbInfo->lParam = btnPtr->dwData;
-    if (lpTbInfo->dwMask & TBIF_SIZE)
-	lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
-    if (lpTbInfo->dwMask & TBIF_STATE)
-	lpTbInfo->fsState = btnPtr->fsState;
-    if (lpTbInfo->dwMask & TBIF_STYLE)
-	lpTbInfo->fsStyle = btnPtr->fsStyle;
-     if (lpTbInfo->dwMask & TBIF_TEXT) {
-         LPWSTR lpText = TOOLBAR_GetText(infoPtr,btnPtr);
-	 Str_GetPtrWtoA (lpText, lpTbInfo->pszText,lpTbInfo->cchText);
-         }
-    return nIndex;
-}
-
-
-static LRESULT
-TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
-    LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
-    TBUTTON_INFO *btnPtr;
-    INT nIndex;
-
-    if (infoPtr == NULL)
-	return -1;
-    if (lpTbInfo == NULL)
-	return -1;
-    if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
-	return -1;
-
-    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam,
-				     lpTbInfo->dwMask & 0x80000000);
-    if (nIndex == -1)
-	return -1;
-
-    btnPtr = &infoPtr->buttons[nIndex];
-
-    if(!btnPtr)
-        return -1;
 
     if (lpTbInfo->dwMask & TBIF_COMMAND)
@@ -3106,6 +3174,63 @@
 	lpTbInfo->fsStyle = btnPtr->fsStyle;
     if (lpTbInfo->dwMask & TBIF_TEXT) {
-	LPWSTR lpText = TOOLBAR_GetText(infoPtr,btnPtr);
-	Str_GetPtrW (lpText,lpTbInfo->pszText,lpTbInfo->cchText);
+        /* TB_GETBUTTONINFO doesn't retrieve text from the string list, so we
+           can't use TOOLBAR_GetText here */
+        LPWSTR lpText;
+        if (HIWORD(btnPtr->iString) && (btnPtr->iString != -1)) {
+            lpText = (LPWSTR)btnPtr->iString;
+            Str_GetPtrWtoA (lpText, lpTbInfo->pszText,lpTbInfo->cchText);
+        } else
+            lpTbInfo->pszText[0] = '\0';
+    }
+    return nIndex;
+}
+
+
+static LRESULT
+TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+    LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
+    TBUTTON_INFO *btnPtr;
+    INT nIndex;
+
+    if (infoPtr == NULL)
+	return -1;
+    if (lpTbInfo == NULL)
+	return -1;
+    if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
+	return -1;
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam,
+				     lpTbInfo->dwMask & 0x80000000);
+    if (nIndex == -1)
+	return -1;
+
+    btnPtr = &infoPtr->buttons[nIndex];
+
+    if(!btnPtr)
+        return -1;
+
+    if (lpTbInfo->dwMask & TBIF_COMMAND)
+	lpTbInfo->idCommand = btnPtr->idCommand;
+    if (lpTbInfo->dwMask & TBIF_IMAGE)
+	lpTbInfo->iImage = btnPtr->iBitmap;
+    if (lpTbInfo->dwMask & TBIF_LPARAM)
+	lpTbInfo->lParam = btnPtr->dwData;
+    if (lpTbInfo->dwMask & TBIF_SIZE)
+	lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
+    if (lpTbInfo->dwMask & TBIF_STATE)
+	lpTbInfo->fsState = btnPtr->fsState;
+    if (lpTbInfo->dwMask & TBIF_STYLE)
+	lpTbInfo->fsStyle = btnPtr->fsStyle;
+    if (lpTbInfo->dwMask & TBIF_TEXT) {
+        /* TB_GETBUTTONINFO doesn't retrieve text from the string list, so we
+           can't use TOOLBAR_GetText here */
+        LPWSTR lpText;
+        if (HIWORD(btnPtr->iString) && (btnPtr->iString != -1)) {
+            lpText = (LPWSTR)btnPtr->iString;
+            Str_GetPtrW (lpText,lpTbInfo->pszText,lpTbInfo->cchText);
+        } else
+            lpTbInfo->pszText[0] = '\0';
     }
 
@@ -3173,5 +3298,7 @@
 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
+    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
+    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
+    return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), wParam);
 }
 
@@ -3182,4 +3309,6 @@
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
 
+    TRACE("\n");
+
     return infoPtr->dwExStyle;
 }
@@ -3189,5 +3318,7 @@
 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
+    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
+    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
+    return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), wParam);
 }
 
@@ -3211,5 +3342,7 @@
 TOOLBAR_GetDefImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), 0);
+    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
+    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
+    return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), wParam);
 }
 
@@ -3432,4 +3565,5 @@
     TBUTTON_INFO *btnPtr;
     INT nIndex;
+    DWORD oldState;
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
@@ -3438,4 +3572,5 @@
 
     btnPtr = &infoPtr->buttons[nIndex];
+    oldState = btnPtr->fsState;
     if (LOWORD(lParam) == FALSE)
 	btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
@@ -3443,5 +3578,6 @@
 	btnPtr->fsState |= TBSTATE_INDETERMINATE;
 
-    InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
+    if(oldState != btnPtr->fsState)
+        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
 
     return TRUE;
@@ -3484,9 +3620,9 @@
               debugstr_a((LPSTR)lpTbb->iString));
         len = strlen((LPSTR)lpTbb->iString) + 2;
-        ptr = COMCTL32_Alloc(len);
+        ptr = Alloc(len);
         strcpy(ptr, (LPSTR)lpTbb->iString);
         ptr[len - 1] = 0; /* ended by two '\0' */
         lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
-        COMCTL32_Free(ptr);
+        Free(ptr);
     }
 
@@ -3499,5 +3635,5 @@
     oldButtons = infoPtr->buttons;
     infoPtr->nNumButtons++;
-    infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+    infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
     /* pre insert copy */
     if (nIndex > 0) {
@@ -3519,5 +3655,5 @@
         infoPtr->buttons[nIndex].iString   = lpTbb->iString;
 
-    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
+    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
 	TTTOOLINFOA ti;
 
@@ -3539,5 +3675,5 @@
     }
 
-    COMCTL32_Free (oldButtons);
+    Free (oldButtons);
 
     TOOLBAR_CalcToolbar (hwnd);
@@ -3584,9 +3720,9 @@
 	      debugstr_w((LPWSTR)lpTbb->iString));
 	len = strlenW((LPWSTR)lpTbb->iString) + 2;
-	ptr = COMCTL32_Alloc(len*sizeof(WCHAR));
+	ptr = Alloc(len*sizeof(WCHAR));
 	strcpyW(ptr, (LPWSTR)lpTbb->iString);
 	ptr[len - 1] = 0; /* ended by two '\0' */
 	lpTbb->iString = TOOLBAR_AddStringW(hwnd, 0, (LPARAM)ptr);
-	COMCTL32_Free(ptr);
+	Free(ptr);
     }
 
@@ -3599,5 +3735,5 @@
     oldButtons = infoPtr->buttons;
     infoPtr->nNumButtons++;
-    infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
+    infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
     /* pre insert copy */
     if (nIndex > 0) {
@@ -3619,5 +3755,5 @@
         infoPtr->buttons[nIndex].iString   = lpTbb->iString;
 
-    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
+    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
 	TTTOOLINFOW ti;
 
@@ -3639,5 +3775,5 @@
     }
 
-    COMCTL32_Free (oldButtons);
+    Free (oldButtons);
 
     TOOLBAR_CalcToolbar (hwnd);
@@ -3736,7 +3872,81 @@
 
 
-/* << TOOLBAR_LoadImages >> */
-/* << TOOLBAR_MapAccelerator >> */
-/* << TOOLBAR_MarkButton >> */
+static LRESULT
+TOOLBAR_LoadImages (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TBADDBITMAP tbab;
+    tbab.hInst = (HINSTANCE)lParam;
+    tbab.nID = (UINT_PTR)wParam;
+
+    TRACE("hwnd = %p, hInst = %p, nID = %u\n", hwnd, tbab.hInst, tbab.nID);
+
+    return TOOLBAR_AddBitmap(hwnd, 0, (LPARAM)&tbab);
+}
+
+
+static LRESULT
+TOOLBAR_MapAccelerator (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+    WCHAR wAccel = (WCHAR)wParam;
+    UINT* pIDButton = (UINT*)lParam;
+    WCHAR wszAccel[] = {'&',wAccel,0};
+    int i;
+    
+    TRACE("hwnd = %p, wAccel = %x(%s), pIDButton = %p\n",
+        hwnd, wAccel, debugstr_wn(&wAccel,1), pIDButton);
+    
+    for (i = 0; i < infoPtr->nNumButtons; i++)
+    {
+        TBUTTON_INFO *btnPtr = infoPtr->buttons+i;
+        if (!(btnPtr->fsStyle & BTNS_NOPREFIX) &&
+            !(btnPtr->fsState & TBSTATE_HIDDEN))
+        {
+            int iLen = strlenW(wszAccel);
+            LPCWSTR lpszStr = TOOLBAR_GetText(infoPtr, btnPtr);
+            
+            if (!lpszStr)
+                continue;
+
+            while (*lpszStr)
+            {
+                if ((lpszStr[0] == '&') && (lpszStr[1] == '&'))
+                {
+                    lpszStr += 2;
+                    continue;
+                }
+                if (!strncmpiW(lpszStr, wszAccel, iLen))
+                {
+                    *pIDButton = btnPtr->idCommand;
+                    return TRUE;
+                }
+                lpszStr++;
+            }
+        }
+    }
+    return FALSE;
+}
+
+
+static LRESULT
+TOOLBAR_MarkButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+    INT nIndex;
+
+    TRACE("hwnd = %p, wParam = %d, lParam = 0x%08lx\n", hwnd, wParam, lParam);
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
+    if (nIndex == -1)
+        return FALSE;
+
+    if (LOWORD(lParam))
+        infoPtr->buttons[nIndex].fsState |= TBSTATE_MARKED;
+    else
+        infoPtr->buttons[nIndex].fsState &= ~TBSTATE_MARKED;
+
+    return TRUE;
+}
+
 /* << TOOLBAR_MoveButton >> */
 
@@ -3748,4 +3958,5 @@
     TBUTTON_INFO *btnPtr;
     INT nIndex;
+    DWORD oldState;
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
@@ -3754,4 +3965,5 @@
 
     btnPtr = &infoPtr->buttons[nIndex];
+    oldState = btnPtr->fsState;
     if (LOWORD(lParam) == FALSE)
 	btnPtr->fsState &= ~TBSTATE_PRESSED;
@@ -3759,10 +3971,12 @@
 	btnPtr->fsState |= TBSTATE_PRESSED;
 
-    InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
+    if(oldState != btnPtr->fsState)
+        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
 
     return TRUE;
 }
 
-
+/* FIXME: there might still be some confusion her between number of buttons
+ * and number of bitmaps */
 static LRESULT
 TOOLBAR_ReplaceBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -3772,4 +3986,5 @@
     HBITMAP hBitmap;
     int i = 0, nOldButtons = 0, pos = 0;
+    int nOldBitmaps, nNewBitmaps;
     HIMAGELIST himlDef = 0;
 
@@ -3815,14 +4030,12 @@
         return FALSE;
     }
-
-    infoPtr->nNumBitmaps = infoPtr->nNumBitmaps - nOldButtons + lpReplace->nButtons;
+    
+    himlDef = GETDEFIMAGELIST(infoPtr, 0); /* fixme: correct? */
+    nOldBitmaps = ImageList_GetImageCount(himlDef);
 
     /* ImageList_Replace(GETDEFIMAGELIST(), pos, hBitmap, NULL); */
 
-
-    himlDef = GETDEFIMAGELIST(infoPtr, 0);
-    for (i = pos + nOldButtons - 1; i >= pos; i--) {
+    for (i = pos + nOldBitmaps - 1; i >= pos; i--)
         ImageList_Remove(himlDef, i);
-    }
 
     {
@@ -3853,9 +4066,15 @@
        DeleteDC (hdcBitmap);
 
-       ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
+       ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace);
+       nNewBitmaps = ImageList_GetImageCount(himlDef);
        DeleteObject (hbmLoad);
     }
 
-    InvalidateRect(hwnd, NULL, FALSE);
+    infoPtr->nNumBitmaps = infoPtr->nNumBitmaps - nOldBitmaps + nNewBitmaps;
+
+    TRACE(" pos %d  %d old bitmaps replaced by %d new ones.\n",
+            pos, nOldBitmaps, nNewBitmaps);
+
+    InvalidateRect(hwnd, NULL, TRUE);
 
     return TRUE;
@@ -4174,4 +4393,10 @@
 }
 
+/* This function differs a bit from what MSDN says it does:
+ * 1. lParam contains extended style flags to OR with current style
+ *  (MSDN isn't clear on the OR bit)
+ * 2. wParam appears to contain extended style flags to be reset
+ *  (MSDN says that this parameter is reserved)
+ */
 static LRESULT
 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -4181,18 +4406,18 @@
 
     dwTemp = infoPtr->dwExStyle;
-    infoPtr->dwExStyle = (DWORD)lParam;
-
-    if (infoPtr->dwExStyle & (TBSTYLE_EX_MIXEDBUTTONS |
-			      TBSTYLE_EX_HIDECLIPPEDBUTTONS)) {
-	FIXME("Extended style not implemented %s %s\n",
-	      (infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ?
-	      "TBSTYLE_EX_MIXEDBUTTONS" : "",
-	      (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS) ?
-	      "TBSTYLE_EX_HIDECLIPPEDBUTTONS" : "");
-    }
+    infoPtr->dwExStyle &= ~wParam;
+    infoPtr->dwExStyle |= (DWORD)lParam;
+
+    TRACE("new style 0x%08lx\n", infoPtr->dwExStyle);
 
     if (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL)
 	FIXME("Unknown Toolbar Extended Style 0x%08lx. Please report.\n",
 	      (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL));
+
+    TOOLBAR_CalcToolbar (hwnd);
+
+    TOOLBAR_AutoSize(hwnd);
+
+    InvalidateRect(hwnd, NULL, TRUE);
 
     return (LRESULT)dwTemp;
@@ -4210,4 +4435,6 @@
     if (infoPtr->iVersion >= 5)
         id = wParam;
+
+    TRACE("hwnd = %p, himl = %p, id = %d\n", hwnd, himl, id);
 
     himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlHot, 
@@ -4238,6 +4465,5 @@
             btnPtr = &infoPtr->buttons[(INT)wParam];
             btnPtr->bHot = TRUE;
-	        InvalidateRect (hwnd, &btnPtr->rect,
-                    TOOLBAR_HasText(infoPtr, btnPtr));
+	        InvalidateRect (hwnd, &btnPtr->rect, TRUE);
         }
         if (nOldHotItem>=0)
@@ -4245,6 +4471,5 @@
             btnPtr = &infoPtr->buttons[nOldHotItem];
             btnPtr->bHot = FALSE;
-	        InvalidateRect (hwnd, &btnPtr->rect,
-                    TOOLBAR_HasText(infoPtr, btnPtr));
+	        InvalidateRect (hwnd, &btnPtr->rect, TRUE);
         }
     }
@@ -4281,5 +4506,4 @@
 	  infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
 
-    /* FIXME: redraw ? */
     InvalidateRect(hwnd, NULL, TRUE);
 
@@ -4335,8 +4559,19 @@
     infoPtr->nMaxTextRows = (INT)wParam;
 
+    TOOLBAR_CalcToolbar(hwnd);
     return TRUE;
 }
 
 
+/* 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
+ *    and the text or image if TBSTYLE_LIST is set. It is used to control
+ *    the gap between the image and text. 
+ * 3. It is not applied to both sides. If TBSTYLE_LIST is set it is used 
+ *    to control the bottom and right borders [with the border being
+ *    szPadding.cx - (GetSystemMetrics(SM_CXEDGE)+1)], otherwise the padding
+ *    is shared evenly on both sides of the button.
+ */
 static LRESULT
 TOOLBAR_SetPadding (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -4348,5 +4583,5 @@
     infoPtr->szPadding.cx = LOWORD((DWORD)lParam);
     infoPtr->szPadding.cy = HIWORD((DWORD)lParam);
-    FIXME("stub - nothing done with values, cx=%ld, cy=%ld\n",
+    TRACE("cx=%ld, cy=%ld\n",
 	  infoPtr->szPadding.cx, infoPtr->szPadding.cy);
     return (LRESULT) oldPad;
@@ -4391,5 +4626,5 @@
 
         /* repaint toolbar */
-        InvalidateRect(hwnd, NULL, FALSE);
+        InvalidateRect(hwnd, NULL, TRUE);
     }
 
@@ -4423,5 +4658,5 @@
 	btnPtr->fsState = LOWORD(lParam);
 	TOOLBAR_CalcToolbar (hwnd);
-	InvalidateRect(hwnd, 0, TOOLBAR_HasText(infoPtr, btnPtr));
+	InvalidateRect(hwnd, 0, TRUE);
 	return TRUE;
     }
@@ -4431,6 +4666,5 @@
     {
         btnPtr->fsState = LOWORD(lParam);
-        InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
-            btnPtr));
+        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
     }
 
@@ -4442,25 +4676,5 @@
 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
-    TBUTTON_INFO *btnPtr;
-    INT nIndex;
-
-    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
-    if (nIndex == -1)
-	return FALSE;
-
-    btnPtr = &infoPtr->buttons[nIndex];
-
-    /* process style change if current style doesn't match new style */
-    if(btnPtr->fsStyle != LOWORD(lParam))
-    {
-        btnPtr->fsStyle = LOWORD(lParam);
-        InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
-            btnPtr));
-
-        if (infoPtr->hwndToolTip) {
-  	    FIXME("change tool tip!\n");
-        }
-    }
+    SetWindowLongW(hwnd, GWL_STYLE, lParam);
 
     return TRUE;
@@ -4472,4 +4686,6 @@
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+
+    TRACE("hwnd=%p, hwndTooltip=%p, lParam=0x%lx\n", hwnd, (HWND)wParam, lParam);
 
     if (infoPtr == NULL)
@@ -4521,5 +4737,5 @@
     infoPtr->clrBtnHighlight = lParam->clrBtnHighlight;
     infoPtr->clrBtnShadow = lParam->clrBtnShadow;
-    InvalidateRect(hwnd, 0, 0);
+    InvalidateRect(hwnd, NULL, TRUE);
     return 0;
 }
@@ -4540,4 +4756,63 @@
 }
 
+
+static LRESULT
+TOOLBAR_GetStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+    WORD iString = HIWORD(wParam);
+    WORD buffersize = LOWORD(wParam);
+    LPSTR str = (LPSTR)lParam;
+    LRESULT ret = -1;
+
+    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", hwnd, iString, buffersize, str);
+
+    if (iString < infoPtr->nNumStrings)
+    {
+        ret = WideCharToMultiByte(CP_ACP, 0, infoPtr->strings[iString], -1, str, buffersize, NULL, NULL);
+
+        TRACE("returning %s\n", debugstr_a(str));
+    }
+    else
+        ERR("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);
+
+    return ret;
+}
+
+
+static LRESULT
+TOOLBAR_GetStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+    WORD iString = HIWORD(wParam);
+    WORD len = LOWORD(wParam)/sizeof(WCHAR) - 1;
+    LPWSTR str = (LPWSTR)lParam;
+    LRESULT ret = -1;
+
+    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", hwnd, iString, LOWORD(wParam), str);
+
+    if (iString < infoPtr->nNumStrings)
+    {
+        len = min(len, strlenW(infoPtr->strings[iString]));
+        ret = (len+1)*sizeof(WCHAR);
+        memcpy(str, infoPtr->strings[iString], ret);
+        str[len] = '\0';
+
+        TRACE("returning %s\n", debugstr_w(str));
+    }
+    else
+        ERR("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);
+
+    return ret;
+}
+
+/* UNDOCUMENTED MESSAGE: This appears to set some kind of size. Perhaps it
+ * is the maximum size of the toolbar? */
+static LRESULT TOOLBAR_Unkwn45D(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    SIZE * pSize = (SIZE*)lParam;
+    FIXME("hwnd=%p, wParam=0x%08x, size.cx=%ld, size.cy=%ld stub!\n", hwnd, wParam, pSize->cx, pSize->cy);
+    return 0;
+}
 
 /*********************************************************************/
@@ -4574,12 +4849,10 @@
 	btnPtr = &infoPtr->buttons[(INT)wParam];
 	btnPtr->bHot = (no_hi) ? FALSE : TRUE;
-	InvalidateRect (hwnd, &btnPtr->rect,
-			TOOLBAR_HasText(infoPtr, btnPtr));
+	InvalidateRect (hwnd, &btnPtr->rect, TRUE);
     }
     if (nOldHotItem>=0) {
 	btnPtr = &infoPtr->buttons[nOldHotItem];
 	btnPtr->bHot = FALSE;
-	InvalidateRect (hwnd, &btnPtr->rect,
-			TOOLBAR_HasText(infoPtr, btnPtr));
+	InvalidateRect (hwnd, &btnPtr->rect, TRUE);
     }
     GetFocus();
@@ -4593,4 +4866,34 @@
 }
 
+/* UNDOCUMENTED MESSAGE: This sets the toolbar global iListGap parameter
+ * which controls the amount of spacing between the image and the text
+ * of buttons for TBSTYLE_LIST toolbars. */
+static LRESULT TOOLBAR_Unkwn460(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+
+    TRACE("hwnd=%p iListGap=%d\n", hwnd, wParam);
+    
+    if (lParam != 0)
+        FIXME("lParam = 0x%08lx. Please report\n", lParam);
+    
+    infoPtr->iListGap = (INT)wParam;
+
+    TOOLBAR_CalcToolbar(hwnd);
+    InvalidateRect(hwnd, NULL, TRUE);
+
+    return 0;
+}
+
+/* UNDOCUMENTED MESSAGE: This returns the number of maximum number
+ * of image lists associated with the various states. */
+static LRESULT TOOLBAR_Unkwn462(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+
+    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+
+    return max(infoPtr->cimlDef, max(infoPtr->cimlHot, infoPtr->cimlDis));
+}
 
 static LRESULT
@@ -4623,5 +4926,4 @@
 	    HWND hwndParent = GetParent(hwnd);
 
-	    InvalidateRect(hwnd, 0, 1);
 	    GetWindowRect(hwnd, &rc);
 	    MapWindowPoints(0, hwndParent, (LPPOINT)&rc, 2);
@@ -4649,4 +4951,12 @@
 }
 
+static LRESULT TOOLBAR_Unkwn464(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    FIXME("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+
+    InvalidateRect(hwnd, NULL, TRUE);
+    return 1;
+}
+
 
 static LRESULT
@@ -4656,4 +4966,6 @@
     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     LOGFONTA logFont;
+
+    TRACE("hwnd = %p\n", hwnd);
 
     /* initialize info structure */
@@ -4664,5 +4976,4 @@
 
     infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
-    infoPtr->nRows = 1;
     infoPtr->nMaxTextRows = 1;
     infoPtr->cxMin = -1;
@@ -4676,5 +4987,5 @@
     infoPtr->nOldHit = -1;
     infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
-    infoPtr->hwndNotify = GetParent (hwnd);
+    infoPtr->hwndNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
     infoPtr->bTransparent = (dwStyle & TBSTYLE_TRANSPARENT);
     infoPtr->bBtnTranspnt = (dwStyle & (TBSTYLE_FLAT | TBSTYLE_LIST));
@@ -4686,6 +4997,10 @@
     infoPtr->clrBtnHighlight = CLR_DEFAULT;
     infoPtr->clrBtnShadow = CLR_DEFAULT;
-    infoPtr->szPadding.cx = 7;
-    infoPtr->szPadding.cy = 6;
+    /* not sure where the +1 comes from, but this comes to the same value
+     * as native so this is probably correct */
+    infoPtr->szPadding.cx = 2*(GetSystemMetrics(SM_CXEDGE)+OFFSET_X) + 1;
+    infoPtr->szPadding.cy = 2*(GetSystemMetrics(SM_CYEDGE)+OFFSET_Y);
+    infoPtr->iListGap = infoPtr->szPadding.cx / 2;
+    GetClientRect(hwnd, &infoPtr->client_rect);
     TOOLBAR_NotifyFormat(infoPtr, (WPARAM)hwnd, (LPARAM)NF_REQUERY);
 
@@ -4729,7 +5044,11 @@
 	DestroyWindow (infoPtr->hwndToolTip);
 
+    /* delete temporary buffer for tooltip text */
+    if (infoPtr->pszTooltipText)
+        HeapFree(GetProcessHeap(), 0, infoPtr->pszTooltipText);
+
     /* delete button data */
     if (infoPtr->buttons)
-	COMCTL32_Free (infoPtr->buttons);
+	Free (infoPtr->buttons);
 
     /* delete strings */
@@ -4738,7 +5057,7 @@
 	for (i = 0; i < infoPtr->nNumStrings; i++)
 	    if (infoPtr->strings[i])
-		COMCTL32_Free (infoPtr->strings[i]);
-
-	COMCTL32_Free (infoPtr->strings);
+		Free (infoPtr->strings[i]);
+
+	Free (infoPtr->strings);
     }
 
@@ -4756,5 +5075,5 @@
 
     /* free toolbar info data */
-    COMCTL32_Free (infoPtr);
+    Free (infoPtr);
     SetWindowLongA (hwnd, 0, 0);
 
@@ -4864,6 +5183,5 @@
 	btnPtr->fsState |= TBSTATE_PRESSED;
 
-        InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
-            btnPtr));
+        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
     }
     else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
@@ -4900,7 +5218,9 @@
 
 	/* for EX_DRAWDDARROWS style,  click must be in the drop-down arrow rect */
-	if ((btnPtr->fsState & TBSTATE_ENABLED) && (btnPtr->fsStyle & TBSTYLE_DROPDOWN) &&
-	     ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) ||
-	      (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle))))
+	if ((btnPtr->fsState & TBSTATE_ENABLED) && 
+	     ((btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) ||
+	      ((btnPtr->fsStyle & BTNS_DROPDOWN) &&
+	       ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) ||
+	       (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle))))))
 	{
 	    LRESULT res;
@@ -4916,5 +5236,5 @@
 	    nmtb.cchText = 0;
 	    nmtb.pszText = 0;
-	    memset(&nmtb.rcButton, 0, sizeof(RECT));
+	    CopyRect(&nmtb.rcButton, &btnPtr->rect);
 	    res = TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
 				  TBN_DROPDOWN);
@@ -4932,5 +5252,5 @@
 
         if (btnPtr->fsState & TBSTATE_ENABLED)
-	    InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
+	    InvalidateRect(hwnd, &btnPtr->rect, TRUE);
 	UpdateWindow(hwnd);
 	SetCapture (hwnd);
@@ -4979,9 +5299,10 @@
         infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
 
+    if (0 <= infoPtr->nButtonDown) {
 	btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
 	btnPtr->fsState &= ~TBSTATE_PRESSED;
 
-	if (btnPtr->fsStyle & TBSTYLE_CHECK) {
-		if (btnPtr->fsStyle & TBSTYLE_GROUP) {
+	if (btnPtr->fsStyle & BTNS_CHECK) {
+		if (btnPtr->fsStyle & BTNS_GROUP) {
 		    nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
 			nHit);
@@ -5001,9 +5322,6 @@
 	}
 
-	if (nOldIndex != -1)
-        {
-            InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
-                TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
-        }
+        if (nOldIndex != -1)
+            InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, TRUE);
 
 	/*
@@ -5048,4 +5366,5 @@
 	    TOOLBAR_SendNotify ((NMHDR *) &nmmouse, infoPtr, NM_CLICK);
 	}
+    }
     return 0;
 }
@@ -5067,6 +5386,5 @@
 
         if (btnPtr->fsState & TBSTATE_ENABLED)
-            InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
-              btnPtr));
+            InvalidateRect(hwnd, &btnPtr->rect, TRUE);
     }
     return 0;
@@ -5092,6 +5410,5 @@
 	rc1 = hotBtnPtr->rect;
 	InflateRect (&rc1, 1, 1);
-        InvalidateRect (hwnd, &rc1, TOOLBAR_HasText(infoPtr,
-            hotBtnPtr));
+        InvalidateRect (hwnd, &rc1, TRUE);
     }
 
@@ -5154,8 +5471,7 @@
     if (infoPtr->nOldHit != nHit)
     {
-	/* Remove the effect of an old hot button if the button was enabled and was
+	/* Remove the effect of an old hot button if the button was
 	   drawn with the hot button effect */
-	if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
-		(infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
+	if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem)
 	{
 	    oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
@@ -5170,9 +5486,5 @@
 	    infoPtr->nHotItem = nHit;
 
-            /* only enabled buttons show hot effect */
-            if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
-            {
-                btnPtr->bHot = TRUE;
-            }
+            btnPtr->bHot = TRUE;
 	}
 
@@ -5190,9 +5502,7 @@
 	/* now invalidate the old and new buttons so they will be painted */
 	if (oldBtnPtr)
-	    InvalidateRect (hwnd, &oldBtnPtr->rect,
-			    TOOLBAR_HasText(infoPtr, oldBtnPtr));
-	if (btnPtr && (btnPtr->fsState & TBSTATE_ENABLED))
-	    InvalidateRect(hwnd, &btnPtr->rect,
-			   TOOLBAR_HasText(infoPtr, btnPtr));
+	    InvalidateRect (hwnd, &oldBtnPtr->rect, TRUE);
+	if (btnPtr)
+	    InvalidateRect(hwnd, &btnPtr->rect, TRUE);
 
 	if (infoPtr->bCaptured) {
@@ -5241,9 +5551,10 @@
 
     /* allocate memory for info structure */
-    infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
+    infoPtr = (TOOLBAR_INFO *)Alloc (sizeof(TOOLBAR_INFO));
     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
 
     /* paranoid!! */
     infoPtr->dwStructSize = sizeof(TBBUTTON);
+    infoPtr->nRows = 1;
 
     /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
@@ -5339,4 +5650,135 @@
 
 
+/* handles requests from the tooltip control on what text to display */
+static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnmtdi)
+{
+    int index = TOOLBAR_GetButtonIndex(infoPtr, lpnmtdi->hdr.idFrom, FALSE);
+
+    TRACE("button index = %d\n", index);
+
+    if (infoPtr->pszTooltipText)
+    {
+        HeapFree(GetProcessHeap(), 0, infoPtr->pszTooltipText);
+        infoPtr->pszTooltipText = NULL;
+    }
+
+    if (index < 0)
+        return 0;
+
+    if (infoPtr->bNtfUnicode)
+    {
+        WCHAR wszBuffer[INFOTIPSIZE+1];
+        NMTBGETINFOTIPW tbgit;
+        int len; /* in chars */
+
+        wszBuffer[0] = '\0';
+        wszBuffer[INFOTIPSIZE] = '\0';
+
+        tbgit.pszText = wszBuffer;
+        tbgit.cchTextMax = INFOTIPSIZE;
+        tbgit.iItem = lpnmtdi->hdr.idFrom;
+        tbgit.lParam = infoPtr->buttons[index].dwData;
+
+        TOOLBAR_SendNotify(&tbgit.hdr, infoPtr, TBN_GETINFOTIPW);
+
+        TRACE("TBN_GETINFOTIPW - got string %s\n", debugstr_w(tbgit.pszText));
+
+        len = strlenW(tbgit.pszText);
+        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
+        {
+            /* need to allocate temporary buffer in infoPtr as there
+             * isn't enough space in buffer passed to us by the
+             * tooltip control */
+            infoPtr->pszTooltipText = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+            if (infoPtr->pszTooltipText)
+            {
+                memcpy(infoPtr->pszTooltipText, tbgit.pszText, (len+1)*sizeof(WCHAR));
+                lpnmtdi->lpszText = infoPtr->pszTooltipText;
+                return 0;
+            }
+        }
+        else if (len > 0)
+        {
+            memcpy(lpnmtdi->lpszText, tbgit.pszText, (len+1)*sizeof(WCHAR));
+            return 0;
+        }
+    }
+    else
+    {
+        CHAR szBuffer[INFOTIPSIZE+1];
+        NMTBGETINFOTIPA tbgit;
+        int len; /* in chars */
+
+        szBuffer[0] = '\0';
+        szBuffer[INFOTIPSIZE] = '\0';
+
+        tbgit.pszText = szBuffer;
+        tbgit.cchTextMax = INFOTIPSIZE;
+        tbgit.iItem = lpnmtdi->hdr.idFrom;
+        tbgit.lParam = infoPtr->buttons[index].dwData;
+
+        TOOLBAR_SendNotify(&tbgit.hdr, infoPtr, TBN_GETINFOTIPA);
+
+        TRACE("TBN_GETINFOTIPA - got string %s\n", debugstr_a(tbgit.pszText));
+
+        len = -1 + MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, NULL, 0);
+        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
+        {
+            /* need to allocate temporary buffer in infoPtr as there
+             * isn't enough space in buffer passed to us by the
+             * tooltip control */
+            infoPtr->pszTooltipText = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+            if (infoPtr->pszTooltipText)
+            {
+                MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, len+1, infoPtr->pszTooltipText, (len+1)*sizeof(WCHAR));
+                lpnmtdi->lpszText = infoPtr->pszTooltipText;
+                return 0;
+            }
+        }
+        else if (len > 0)
+        {
+            MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, len+1, lpnmtdi->lpszText, (len+1)*sizeof(WCHAR));
+            return 0;
+        }
+    }
+
+    /* if button has text, but it is not shown then automatically
+     * use that text as tooltip */
+    if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) &&
+        !(infoPtr->buttons[index].fsStyle & BTNS_SHOWTEXT))
+    {
+        LPWSTR pszText = TOOLBAR_GetText(infoPtr, &infoPtr->buttons[index]);
+        int len = pszText ? strlenW(pszText) : 0;
+
+        TRACE("using button hidden text %s\n", debugstr_w(pszText));
+
+        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
+        {
+            /* need to allocate temporary buffer in infoPtr as there
+             * isn't enough space in buffer passed to us by the
+             * tooltip control */
+            infoPtr->pszTooltipText = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
+            if (infoPtr->pszTooltipText)
+            {
+                memcpy(infoPtr->pszTooltipText, pszText, (len+1)*sizeof(WCHAR));
+                lpnmtdi->lpszText = infoPtr->pszTooltipText;
+                return 0;
+            }
+        }
+        else if (len > 0)
+        {
+            memcpy(lpnmtdi->lpszText, pszText, (len+1)*sizeof(WCHAR));
+            return 0;
+        }
+    }
+
+    TRACE("Sending tooltip notification to %p\n", infoPtr->hwndNotify);
+
+    /* last resort: send notification on to app */
+    /* FIXME: find out what is really used here */
+    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, 0, (LPARAM)lpnmtdi);
+}
+
+
 inline static LRESULT
 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -5345,58 +5787,44 @@
     LPNMHDR lpnmh = (LPNMHDR)lParam;
 
-    if (lpnmh->code == PGN_CALCSIZE) {
-	LPNMPGCALCSIZE lppgc = (LPNMPGCALCSIZE)lParam;
-
-	if (lppgc->dwFlag == PGF_CALCWIDTH) {
-	    lppgc->iWidth = infoPtr->rcBound.right - infoPtr->rcBound.left;
-	    TRACE("processed PGN_CALCSIZE, returning horz size = %d\n",
-		  lppgc->iWidth);
-	}
-	else {
-	    lppgc->iHeight = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
-	    TRACE("processed PGN_CALCSIZE, returning vert size = %d\n",
-		  lppgc->iHeight);
-	}
-	return 0;
-    }
-
-    if (lpnmh->code == PGN_SCROLL) {
-	LPNMPGSCROLL lppgs = (LPNMPGSCROLL)lParam;
-
-	lppgs->iScroll = (lppgs->iDir & (PGF_SCROLLLEFT | PGF_SCROLLRIGHT)) ?
-	                  infoPtr->nButtonWidth : infoPtr->nButtonHeight;
-	TRACE("processed PGN_SCROLL, returning scroll=%d, dir=%d\n",
-	      lppgs->iScroll, lppgs->iDir);
-	return 0;
-    }
-
-
-    TRACE("passing WM_NOTIFY!\n");
-
-    if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
-	if (infoPtr->bNtfUnicode)
-	    return SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
-				 wParam, lParam);
-	else
-	    return SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
-				 wParam, lParam);
-
-#if 0
-	if (lpnmh->code == TTN_GETDISPINFOA) {
-	    LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
-
-	    FIXME("retrieving ASCII string\n");
-
-	}
-	else if (lpnmh->code == TTN_GETDISPINFOW) {
-	    LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
-
-	    FIXME("retrieving UNICODE string\n");
-
-	}
-#endif
-    }
-
-    return 0;
+    switch (lpnmh->code)
+    {
+    case PGN_CALCSIZE:
+    {
+        LPNMPGCALCSIZE lppgc = (LPNMPGCALCSIZE)lParam;
+
+        if (lppgc->dwFlag == PGF_CALCWIDTH) {
+            lppgc->iWidth = infoPtr->rcBound.right - infoPtr->rcBound.left;
+            TRACE("processed PGN_CALCSIZE, returning horz size = %d\n",
+                  lppgc->iWidth);
+        }
+        else {
+            lppgc->iHeight = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
+            TRACE("processed PGN_CALCSIZE, returning vert size = %d\n",
+                  lppgc->iHeight);
+        }
+    	return 0;
+    }
+
+    case PGN_SCROLL:
+    {
+        LPNMPGSCROLL lppgs = (LPNMPGSCROLL)lParam;
+
+        lppgs->iScroll = (lppgs->iDir & (PGF_SCROLLLEFT | PGF_SCROLLRIGHT)) ?
+                          infoPtr->nButtonWidth : infoPtr->nButtonHeight;
+        TRACE("processed PGN_SCROLL, returning scroll=%d, dir=%d\n",
+              lppgs->iScroll, lppgs->iDir);
+        return 0;
+    }
+
+    case TTN_GETDISPINFOW:
+        return TOOLBAR_TTGetDispInfo(infoPtr, (LPNMTTDISPINFOW)lParam);
+
+    case TTN_GETDISPINFOA:
+        FIXME("TTN_GETDISPINFOA - stub\n");
+        return 0;
+
+    default:
+        return 0;
+    }
 }
 
@@ -5418,6 +5846,11 @@
     INT i;
 
+    TRACE("wParam = 0x%x, lParam = 0x%08lx\n", wParam, lParam);
+
+    if ((lParam == NF_QUERY) && ((HWND)wParam == infoPtr->hwndToolTip))
+        return NFR_UNICODE;
+
     if (lParam == NF_REQUERY) {
-	i = SendMessageA(GetParent(infoPtr->hwndSelf),
+	i = SendMessageA(infoPtr->hwndNotify,
 			 WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
 	if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
@@ -5467,5 +5900,5 @@
       *  *previous* status of the redraw flag (either 0 or 1)
       *  instead of the MSDN documented value of 0 if handled.
-      *  (For laughs see the "consistancy" with same function
+      *  (For laughs see the "consistency" with same function
       *   in rebar.)
       *
@@ -5542,9 +5975,14 @@
 	    cx = infoPtr->nWidth;
 
-	    if (dwStyle & CCS_NOMOVEY) {
+	    if ((dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) {
 		GetWindowRect(hwnd, &window_rect);
 		ScreenToClient(parent, (LPPOINT)&window_rect.left);
-		y = window_rect.top;
+                y = window_rect.top;
 	    }
+            if ((dwStyle & CCS_BOTTOM) == CCS_BOTTOM) {
+                GetWindowRect(hwnd, &window_rect);
+                y = parent_rect.bottom -
+                    ( window_rect.bottom - window_rect.top);
+            }
 	}
 
@@ -5565,7 +6003,48 @@
 	}
 
-	SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
-			cx, cy, uPosFlags | SWP_NOZORDER);
-    }
+        if(infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
+        {
+            RECT delta_width, delta_height, client, dummy;
+            DWORD min_x, max_x, min_y, max_y;
+            TBUTTON_INFO *btnPtr;
+            INT i;
+
+            GetClientRect(hwnd, &client);
+            if(client.right > infoPtr->client_rect.right)
+            {
+                min_x = infoPtr->client_rect.right;
+                max_x = client.right;
+            }
+            else
+            {
+                max_x = infoPtr->client_rect.right;
+                min_x = client.right;
+            }
+            if(client.bottom > infoPtr->client_rect.bottom)
+            {
+                min_y = infoPtr->client_rect.bottom;
+                max_y = client.bottom;
+            }
+            else
+            {
+                max_y = infoPtr->client_rect.bottom;
+                min_y = client.bottom;
+            }
+
+            SetRect(&delta_width, min_x, 0, max_x, min_y);
+            SetRect(&delta_height, 0, min_y, max_x, max_y);
+
+            TRACE("delta_width %s delta_height %s\n", wine_dbgstr_rect(&delta_width), wine_dbgstr_rect(&delta_height));
+            btnPtr = infoPtr->buttons;
+            for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
+                if(IntersectRect(&dummy, &delta_width, &btnPtr->rect) ||
+                   IntersectRect(&dummy, &delta_height, &btnPtr->rect))
+                    InvalidateRect(hwnd, &btnPtr->rect, TRUE);
+        }
+
+        if((uPosFlags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) 
+            SetWindowPos (hwnd, 0,  x,  y, cx, cy, uPosFlags | SWP_NOZORDER);
+    }
+    GetClientRect(hwnd, &infoPtr->client_rect);
     return 0;
 }
@@ -5588,9 +6067,13 @@
 				 (TBSTYLE_FLAT | TBSTYLE_LIST));
 	TOOLBAR_CheckStyle (hwnd, lpStyle->styleNew);
-    }
+
+        TRACE("new style 0x%08lx\n", lpStyle->styleNew);
+    }
+
+    TOOLBAR_CalcToolbar(hwnd);
 
     TOOLBAR_AutoSize (hwnd);
 
-    InvalidateRect(hwnd, NULL, FALSE);
+    InvalidateRect(hwnd, NULL, TRUE);
 
     return 0;
@@ -5611,4 +6094,6 @@
 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+
     TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n",
 	  hwnd, uMsg, /* SPY_GetMsgName(uMsg), */ wParam, lParam);
@@ -5726,4 +6211,10 @@
 	    return TOOLBAR_GetState (hwnd, wParam, lParam);
 
+	case TB_GETSTRINGA:
+        return TOOLBAR_GetStringA (hwnd, wParam, lParam);
+
+	case TB_GETSTRINGW:
+	    return TOOLBAR_GetStringW (hwnd, wParam, lParam);
+
 	case TB_GETSTYLE:
 	    return TOOLBAR_GetStyle (hwnd, wParam, lParam);
@@ -5773,11 +6264,14 @@
 	    return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
 
-	case TB_LOADIMAGES:			   /* 4.70 */
-	    FIXME("missing standard imagelists\n");
-	    return 0;
-
-/*	case TB_MAPACCELERATORA:		*/ /* 4.71 */
-/*	case TB_MAPACCELERATORW:		*/ /* 4.71 */
-/*	case TB_MARKBUTTON:			*/ /* 4.71 */
+	case TB_LOADIMAGES:
+	    return TOOLBAR_LoadImages (hwnd, wParam, lParam);
+
+	case TB_MAPACCELERATORA:
+	case TB_MAPACCELERATORW:
+	    return TOOLBAR_MapAccelerator (hwnd, wParam, lParam);
+
+	case TB_MARKBUTTON:
+	    return TOOLBAR_MarkButton (hwnd, wParam, lParam);
+
 /*	case TB_MOVEBUTTON:			*/ /* 4.71 */
 
@@ -5865,10 +6359,21 @@
 	    return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
 
+	case TB_UNKWN45D:
+	    return TOOLBAR_Unkwn45D(hwnd, wParam, lParam);
+
 	case TB_UNKWN45E:
 	    return TOOLBAR_Unkwn45E (hwnd, wParam, lParam);
 
+	case TB_UNKWN460:
+	    return TOOLBAR_Unkwn460(hwnd, wParam, lParam);
+
+	case TB_UNKWN462:
+	    return TOOLBAR_Unkwn462(hwnd, wParam, lParam);
+
 	case TB_UNKWN463:
 	    return TOOLBAR_Unkwn463 (hwnd, wParam, lParam);
 
+	case TB_UNKWN464:
+	    return TOOLBAR_Unkwn464(hwnd, wParam, lParam);
 
 /* Common Control Messages */
@@ -5940,5 +6445,5 @@
 
 	case WM_NOTIFYFORMAT:
-	    TOOLBAR_NotifyFormatFake (hwnd, wParam, lParam);
+	    return TOOLBAR_NotifyFormatFake (hwnd, wParam, lParam);
 
 	case WM_PAINT:
@@ -5964,11 +6469,5 @@
 	case WM_MEASUREITEM:
 	case WM_VKEYTOITEM:
-	    {
-                TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
-                if(infoPtr != NULL)
-                    return SendMessageA (infoPtr->hwndNotify, uMsg, wParam, lParam);
-                else
-                    return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
-            }
+            return SendMessageA (infoPtr->hwndNotify, uMsg, wParam, lParam);
 
 	/* We see this in Outlook Express 5.x and just does DefWindowProc */
@@ -5996,5 +6495,5 @@
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
-    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
+    wndClass.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROWA);
     wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
     wndClass.lpszClassName = TOOLBARCLASSNAMEA;
@@ -6023,13 +6522,13 @@
         PIMLENTRY *pnies;
 
-	c = (PIMLENTRY) COMCTL32_Alloc(sizeof(IMLENTRY));
+	c = (PIMLENTRY) Alloc(sizeof(IMLENTRY));
 	c->id = id;
 
-	pnies = COMCTL32_Alloc((*cies + 1) * sizeof(PIMLENTRY));
+	pnies = Alloc((*cies + 1) * sizeof(PIMLENTRY));
 	memcpy(pnies, *pies, ((*cies) * sizeof(PIMLENTRY)));
 	pnies[*cies] = c;
 	(*cies)++;
 
-	COMCTL32_Free(*pies);
+	Free(*pies);
 	*pies = pnies;
     }
@@ -6047,7 +6546,7 @@
 
     for (i = 0; i < *cies; i++)
-	COMCTL32_Free((*pies)[i]);
-
-    COMCTL32_Free(*pies);
+	Free((*pies)[i]);
+
+    Free(*pies);
 
     *cies = 0;
