Commit in reactos/lib/comctl32 on MAIN
toolbar.c+181-1031.7 -> 1.8
Sync with Wine-20040213:
Huw Davies <huw@codeweavers.com>
Only redraw button in PressButton and Indeterminate if its state has
changed.
Huw Davies <huw@codeweavers.com>
Honour TB_SETMAXTEXTROWS.
Ulrich Czekalla <ulrich@codeweavers.com>
Add support for BTNS_WHOLEDROPDOWN.
Populate button rect when sending TBN_DROPDOWN.
Dmitry Timoshkov <dmitry@codeweavers.com>
Add partial support for some undocumented toolbar messages.
Huw Davies <huw@codeweavers.com>
TB_ADDBUTTONS can pass a string ptr instead of an index.
TB_GETBUTTONINFO only returns a string if it's not in the internal
string list.
Huw Davies <huw@codeweavers.com>
Use the BTNS_* toolbar button style defines rather than the outdated
TBSTYLE_*.
Huw Davies <huw@codeweavers.com>
Add a missing return.
Jon Griffiths <jon_p_griffiths@yahoo.com>
Draw disabled toolbar buttons correctly.

reactos/lib/comctl32
toolbar.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- toolbar.c	14 Jan 2004 23:16:59 -0000	1.7
+++ toolbar.c	17 Feb 2004 22:39:49 -0000	1.8
@@ -497,7 +497,7 @@
 /***********************************************************************
 * 		TOOLBAR_DrawDDFlatSeparator
 *
-* This function draws the separator that was flaged as TBSTYLE_DROPDOWN.
+* This function draws the separator that was flaged 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
 * are horizontal as opposed to the vertical separators for not dropdown
@@ -614,39 +614,51 @@
 }
 
 
-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);
+    }
 }
 
 
@@ -672,8 +684,11 @@
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-    BOOL hasDropDownArrow = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
-	                    (btnPtr->fsStyle & TBSTYLE_DROPDOWN);
+    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, rcFill;
     LPWSTR lpText = NULL;
     NMTBCUSTOMDRAW tbcd;
@@ -693,11 +708,17 @@
 
     if (hasDropDownArrow)
     {
+        int right;
+
 	if (dwStyle & TBSTYLE_FLAT)
-            rc.right = max(rc.left, rc.right - DDARROW_WIDTH);
+            right = max(rc.left, rc.right - DDARROW_WIDTH);
 	else
-            rc.right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
-	rcArrow.left = rc.right;
+            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
@@ -733,7 +754,7 @@
 		 * 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->fsStyle & BTNS_AUTOSIZE) == 0) &&
 		 *       (btnPtr->iBitmap != I_IMAGENONE))
 		 */
 	        if (dwStyle & TBSTYLE_LIST) {
@@ -810,19 +831,19 @@
 	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    */
         /* so now we need to draw the vertical separator             */
         /* empirical tests show that iBitmap can/will be non-zero    */
         /* 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);
 	}
@@ -858,7 +879,7 @@
 	{
 	    DrawEdge (hdc, &rc, EDGE_RAISED,
 		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
-            if (hasDropDownArrow)
+            if (drawSepDropDownArrow)
             DrawEdge (hdc, &rcArrow, EDGE_RAISED,
 		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
 	}
@@ -879,7 +900,7 @@
 	goto FINALNOTIFY;
     }
 
-    /* pressed TBSTYLE_BUTTON */
+    /* pressed BTNS_BUTTON */
     if (tbcd.nmcd.uItemState & CDIS_SELECTED) {
 	offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
 	if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
@@ -887,13 +908,13 @@
 	    if (dwStyle & TBSTYLE_FLAT)
 	    {
 		DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
-		if (hasDropDownArrow)
+		if (drawSepDropDownArrow)
 		    DrawEdge (hdc, &rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
 	    }
 	    else
 	    {
 		DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
-		if (hasDropDownArrow)
+		if (drawSepDropDownArrow)
 		    DrawEdge (hdc, &rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
 	    }
 	}
@@ -910,9 +931,9 @@
 	goto FINALNOTIFY;
     }
 
-    /* checked TBSTYLE_CHECK */
+    /* checked BTNS_CHECK */
     if ((tbcd.nmcd.uItemState & CDIS_CHECKED) &&
-	(btnPtr->fsStyle & TBSTYLE_CHECK)) {
+	(btnPtr->fsStyle & BTNS_CHECK)) {
 	if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
 	{
 	    if (dwStyle & TBSTYLE_FLAT)
@@ -977,7 +998,7 @@
 
         if (hasDropDownArrow)
 	{
-	    if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
+	    if (drawSepDropDownArrow && !(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
 		DrawEdge (hdc, &rcArrow, EDGE_RAISED,
 			  BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
 	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, COLOR_WINDOWFRAME);
@@ -1084,7 +1105,7 @@
 * prefix characters as M$ likes to call them). The prefix character
 * 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
 TOOLBAR_MeasureString(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
@@ -1112,7 +1133,7 @@
 
 	    /* 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));
 
 	    /* feed back to caller  */
@@ -1143,6 +1164,9 @@
     lpSize->cx = 0;
     lpSize->cy = 0;
 
+    if(infoPtr->nMaxTextRows == 0)
+        return;
+
     hdc = GetDC (hwnd);
     hOldFont = SelectObject (hdc, infoPtr->hFont);
 
@@ -1221,10 +1245,10 @@
 	/* it is the actual width of the separator. This is used for */
 	/* 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;
 	else
@@ -1234,9 +1258,9 @@
 	/* The first separator in a group should be wrapped to the   */
 	/* next row if the previous wrapping is on a button.	     */
 	if( bButtonWrap &&
-		(btnPtr[i].fsStyle & 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);
 	    btnPtr[i].fsState |= TBSTATE_WRAP;
@@ -1258,8 +1282,8 @@
 	    /* 	If the current button is a separator and not hidden,  */
 	    /*	go to the next until it reaches a non separator.      */
 	    /*	Wrap the last separator if it is before a button.     */
-	    while( ( ((btnPtr[i].fsStyle & 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 )
 	    {
@@ -1284,7 +1308,7 @@
 	    /*	separator and wrap it.   				 */
 	    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))
 		{
 		    bFound = TRUE;
@@ -1327,7 +1351,7 @@
 		btnPtr[i].fsState |= TBSTATE_WRAP;
 		bFound = TRUE;
 		x = infoPtr->nIndent;
-		if (btnPtr[i].fsStyle & TBSTYLE_SEP )
+		if (btnPtr[i].fsStyle & BTNS_SEP )
 		    bButtonWrap = FALSE;
 		else
 		    bButtonWrap = TRUE;
@@ -1394,13 +1418,13 @@
             else
                 infoPtr->nButtonHeight = sizeString.cy + 6;
         }
-        else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
+        else
 	    infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
 
         if (sizeString.cx > infoPtr->nBitmapWidth)
 	    infoPtr->nButtonWidth = sizeString.cx + 6;
-        else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
-	    infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
+        else
+            infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
     }
 
     if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
@@ -1464,8 +1488,8 @@
 	/* UNDOCUMENTED: If a separator has a non zero bitmap index, */
 	/* 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;
 		cx = infoPtr->nButtonWidth;
@@ -1477,7 +1501,7 @@
 	else
 	{
             if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || 
-                (btnPtr->fsStyle & TBSTYLE_AUTOSIZE))
+                (btnPtr->fsStyle & BTNS_AUTOSIZE))
             {
               SIZE sz;
 	      HDC hdc;
@@ -1507,7 +1531,7 @@
             else
 	      cx = infoPtr->nButtonWidth;
 
-	    if (hasDropDownArrows && (btnPtr->fsStyle & TBSTYLE_DROPDOWN))
+	    if ((hasDropDownArrows && (btnPtr->fsStyle & BTNS_DROPDOWN)) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN))
 	      cx += DDARROW_WIDTH;
 	}
 	if (btnPtr->fsState & TBSTATE_WRAP )
@@ -1523,7 +1547,7 @@
 	    infoPtr->rcBound.bottom = y + cy;
 
 	/* 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;
 
@@ -1546,14 +1570,14 @@
 
 	if( bWrap )
 	{
-	    if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
+	    if ( !(btnPtr->fsStyle & BTNS_SEP) )
 	        y += cy;
 	    else
 	    {
 		/* UNDOCUMENTED: If a separator has a non zero bitmap index, */
 		/* 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;
 		else
@@ -1613,7 +1637,7 @@
 	if (btnPtr->fsState & TBSTATE_HIDDEN)
 	    continue;
 
-	if (btnPtr->fsStyle & TBSTYLE_SEP) {
+	if (btnPtr->fsStyle & BTNS_SEP) {
 	    if (PtInRect (&btnPtr->rect, *lpPt)) {
 		TRACE(" ON SEPARATOR %d!\n", i);
 		return -i;
@@ -1666,7 +1690,7 @@
 
     /* 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;
     }
@@ -1675,7 +1699,7 @@
     nRunIndex = nIndex - 1;
     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;
 	}
@@ -1688,7 +1712,7 @@
     nRunIndex = nIndex + 1;
     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;
 	}
@@ -1766,7 +1790,7 @@
                 {
 		    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);
 
@@ -1780,7 +1804,7 @@
 		/* insert separator button into 'available buttons' list */
 		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;
 		LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
@@ -1828,7 +1852,7 @@
                     }
 
                     memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
-                    if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
+                    if (!(nmtb.tbButton.fsStyle & BTNS_SEP))
                     {
                         if (lstrlenW(nmtb.pszText))
                             lstrcpyW(btnInfo->text, nmtb.pszText);
@@ -1847,7 +1871,7 @@
 		/* append 'virtual' separator button to the 'toolbar buttons' list */
 		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;
 		LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
@@ -2017,7 +2041,7 @@
 			    SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
 
 			    /* 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);
 				SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
@@ -2164,7 +2188,7 @@
 		DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
 
 		/* 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));
 		    ImageList_Draw (himl, GETIBITMAP(infoPtr, btnInfo->btn.iBitmap), 
@@ -2461,10 +2485,13 @@
 	btnPtr->fsState   = lpTbb[nCount].fsState;
 	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;
 
 	    ZeroMemory (&ti, sizeof(TTTOOLINFOA));
@@ -2525,10 +2552,13 @@
 	btnPtr->fsState   = lpTbb[nCount].fsState;
 	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;
 
 	    ZeroMemory (&ti, sizeof(TTTOOLINFOW));
@@ -2869,7 +2899,7 @@
 
     btnPtr = &infoPtr->buttons[nIndex];
 
-    if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
+    if (!(btnPtr->fsStyle & BTNS_CHECK))
 	return FALSE;
 
     bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
@@ -2877,7 +2907,7 @@
     if (LOWORD(lParam) == FALSE)
 	btnPtr->fsState &= ~TBSTATE_CHECKED;
     else {
-	if (btnPtr->fsStyle & TBSTYLE_GROUP) {
+	if (btnPtr->fsStyle & BTNS_GROUP) {
 	    nOldIndex =
 		TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
 	    if (nOldIndex == nIndex)
@@ -2962,7 +2992,7 @@
 	return FALSE;
 
     if ((infoPtr->hwndToolTip) &&
-	!(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
+	!(infoPtr->buttons[nIndex].fsStyle & BTNS_SEP)) {
 	TTTOOLINFOA ti;
 
 	ZeroMemory (&ti, sizeof(TTTOOLINFOA));
@@ -3135,10 +3165,16 @@
 	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);
-         }
+    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_GetPtrWtoA (lpText, lpTbInfo->pszText,lpTbInfo->cchText);
+        } else
+            lpTbInfo->pszText[0] = '\0';
+    }
     return nIndex;
 }
 
@@ -3181,8 +3217,14 @@
     if (lpTbInfo->dwMask & TBIF_STYLE)
 	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_GetPtrW (lpText,lpTbInfo->pszText,lpTbInfo->cchText);
+        } else
+            lpTbInfo->pszText[0] = '\0';
     }
 
     return nIndex;
@@ -3509,18 +3551,21 @@
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     TBUTTON_INFO *btnPtr;
     INT nIndex;
+    DWORD oldState;
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     if (nIndex == -1)
 	return FALSE;
 
     btnPtr = &infoPtr->buttons[nIndex];
+    oldState = btnPtr->fsState;
     if (LOWORD(lParam) == FALSE)
 	btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
     else
 	btnPtr->fsState |= TBSTATE_INDETERMINATE;
 
-    InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
+    if(oldState != btnPtr->fsState)
+        InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
 
     return TRUE;
 }
@@ -3596,7 +3641,7 @@
     else
         infoPtr->buttons[nIndex].iString   = lpTbb->iString;
 
-    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
+    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
 	TTTOOLINFOA ti;
 
 	ZeroMemory (&ti, sizeof(TTTOOLINFOA));
@@ -3696,7 +3741,7 @@
     else
         infoPtr->buttons[nIndex].iString   = lpTbb->iString;
 
-    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
+    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
 	TTTOOLINFOW ti;
 
 	ZeroMemory (&ti, sizeof(TTTOOLINFOW));
@@ -3825,18 +3870,21 @@
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     TBUTTON_INFO *btnPtr;
     INT nIndex;
+    DWORD oldState;
 
     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     if (nIndex == -1)
 	return FALSE;
 
     btnPtr = &infoPtr->buttons[nIndex];
+    oldState = btnPtr->fsState;
     if (LOWORD(lParam) == FALSE)
 	btnPtr->fsState &= ~TBSTATE_PRESSED;
     else
 	btnPtr->fsState |= TBSTATE_PRESSED;
 
-    InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
+    if(oldState != btnPtr->fsState)
+        InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
 
     return TRUE;
 }
@@ -4419,6 +4467,7 @@
 
     infoPtr->nMaxTextRows = (INT)wParam;
 
+    TOOLBAR_CalcToolbar(hwnd);
     return TRUE;
 }
 
@@ -4604,6 +4653,11 @@
     return iOldVersion;
 }
 
+static LRESULT TOOLBAR_Unkwn45D(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    FIXME("hwnd=%p wParam %08x lParam %08lx stub!\n", hwnd, wParam, lParam);
+    return 0;
+}
 
 /*********************************************************************/
 /*                                                                   */
@@ -4657,6 +4711,13 @@
     return (LRESULT)nOldHotItem;
 }
 
+static LRESULT TOOLBAR_Unkwn460(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+
+    InvalidateRect(hwnd, NULL, TRUE);
+    return 0;
+}
 
 static LRESULT
 TOOLBAR_Unkwn463 (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -4687,7 +4748,6 @@
 	    RECT rc;
 	    HWND hwndParent = GetParent(hwnd);
 
-	    InvalidateRect(hwnd, 0, 1);
 	    GetWindowRect(hwnd, &rc);
 	    MapWindowPoints(0, hwndParent, (LPPOINT)&rc, 2);
 	    TRACE("mapped to (%ld,%ld)-(%ld,%ld)\n",
@@ -4713,6 +4773,14 @@
     return 1;
 }
 
+static LRESULT TOOLBAR_Unkwn464(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+
+    InvalidateRect(hwnd, NULL, TRUE);
+    return 1;
+}
+
 
 static LRESULT
 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -4963,9 +5031,11 @@
 	arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH);
 
 	/* 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;
 	    /*
@@ -4979,7 +5049,7 @@
 	    memset(&nmtb.tbButton, 0, sizeof(TBBUTTON));
 	    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);
 	    if (res != TBDDRET_TREATPRESSED)
@@ -5046,8 +5116,8 @@
 	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);
 		    if (nOldIndex == nHit)
@@ -5936,12 +6006,20 @@
 	case TB_SETUNICODEFORMAT:
 	    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_UNKWN463:
 	    return TOOLBAR_Unkwn463 (hwnd, wParam, lParam);
 
+	case TB_UNKWN464:
+	    return TOOLBAR_Unkwn464(hwnd, wParam, lParam);
 
 /* Common Control Messages */
 
@@ -6011,7 +6089,7 @@
 	    return TOOLBAR_Notify (hwnd, wParam, lParam);
 
 	case WM_NOTIFYFORMAT:
-	    TOOLBAR_NotifyFormatFake (hwnd, wParam, lParam);
+	    return TOOLBAR_NotifyFormatFake (hwnd, wParam, lParam);
 
 	case WM_PAINT:
 	    return TOOLBAR_Paint (hwnd, wParam);
CVSspam 0.2.8