Ignore:
Timestamp:
Mar 17, 2004, 5:38:52 PM (22 years ago)
Author:
sandervl
Message:

Wine merge + status & rebar fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/comctl32/toolbar.c

    r10098 r10535  
    1919 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2020 *
     21 * NOTES
     22 *
    2123 *  Differences between MSDN and actual native control operation:
    2224 *   1. MSDN says: "TBSTYLE_LIST: Creates a flat toolbar with button text
     
    2830 *      *not* imply TBSTYLE_FLAT as documented.  (GA 8/2001)
    2931 *
    30  *
     32 * This code was audited for completeness against the documented features
     33 * of Comctl32.dll version 6.0 on Mar. 14, 2004, by Robert Shearman.
     34 *
     35 * Unless otherwise noted, we believe this code to be complete, as per
     36 * the specification mentioned above.
     37 * If you discover missing features or bugs please note them below.
     38 *
    3139 * TODO:
    3240 *   - Button wrapping (under construction).
    33  *   - Messages.
    34  *   - Notifications (under construction).
     41 *   - Messages:
     42 *     - TB_GETINSERTMARK
     43 *     - TB_GETINSERTMARKCOLOR
     44 *     - TB_GETMETRICS
     45 *     - TB_GETOBJECT
     46 *     - TB_INSERTMARKHITTEST
     47 *     - TB_MOVEBUTTON
     48 *     - TB_SETINSERTMARK
     49 *     - TB_SETMETRICS
     50 *   - Notifications:
     51 *     - NM_CHAR
     52 *     - NM_KEYDOWN
     53 *     - NM_LDOWN
     54 *     - NM_RCLICK
     55 *     - NM_RDBLCLICK
     56 *     - TBN_DELETINGBUTTON
     57 *     - TBN_DRAGOUT
     58 *     - TBN_GETOBJECT
     59 *     - TBN_RESTORE
     60 *     - TBN_SAVE
     61 *     - TBN_TOOLBARCHANGE
    3562 *   - Fix TB_SETROWS.
    36  *   - Tooltip support (almost complete).
    37  *   - Unicode suppport (under construction).
    3863 *   - Fix TOOLBAR_SetButtonInfo32A/W.
    39  *   - TBSTYLE_AUTOSIZE for toolbar and buttons.
    40  *   - I_IMAGECALLBACK support.
    41  *   - iString of -1 is undocumented
     64 *   - iListGap custom draw support.
    4265 *   - Customization dialog:
    43  *      - Add flat look.
    4466 *      - Minor buglet in 'available buttons' list:
    45  *        Buttons are not listed in M$-like order. M$ seems to use a single
     67 *        Buttons are not listed in MS-like order. MS seems to use a single
    4668 *        internal list to store the button information of both listboxes.
    4769 *      - Drag list support.
    48  *      - Help and Reset button support.
    4970 *
    5071 * Testing:
     
    5980 */
    6081
     82#include <stdarg.h>
    6183#include <string.h>
    6284
     85#include "windef.h"
    6386#include "winbase.h"
    64 #include "windef.h"
    6587#include "wingdi.h"
    6688#include "winuser.h"
    6789#include "wine/unicode.h"
     90#include "winnls.h"
    6891#include "commctrl.h"
    6992#include "imagelist.h"
     
    105128    INT      nHeight;        /* height of the toolbar */
    106129    INT      nWidth;         /* width of the toolbar */
     130    RECT     client_rect;
    107131    INT      nButtonHeight;
    108132    INT      nButtonWidth;
     
    127151    DWORD    dwItemCDFlag;    /* TBCDRF_ flags from last ITEMPREPAINT    */
    128152    SIZE     szPadding;       /* padding values around button */
     153    INT      iListGap;        /* default gap between text and image for toolbar with list style */
    129154    HFONT    hDefaultFont;
    130155    HFONT    hFont;           /* text font */
     
    153178    RECT     rcBound;         /* bounding rectangle */
    154179    INT      iVersion;
    155 
     180    LPWSTR   pszTooltipText;    /* temporary store for a string > 80 characters
     181                                 * for TTN_GETDISPINFOW notification */
    156182    TBUTTON_INFO *buttons;      /* pointer to button array */
    157183    LPWSTR       *strings;      /* pointer to string array */
     
    175201} CUSTOMBUTTON, *PCUSTOMBUTTON;
    176202
     203typedef enum
     204{
     205    IMAGE_LIST_DEFAULT,
     206    IMAGE_LIST_HOT,
     207    IMAGE_LIST_DISABLED
     208} IMAGE_LIST_TYPE;
    177209
    178210#define SEPARATOR_WIDTH    8
     
    180212#define BOTTOM_BORDER      2
    181213#define DDARROW_WIDTH      11
     214#define ARROW_HEIGHT       3
     215
     216/* gap between border of button and text/image */
     217#define OFFSET_X 1
     218#define OFFSET_Y 1
     219/* how wide to treat the bitmap if it isn't present */
     220#define LIST_IMAGE_ABSENT_WIDTH 2
    182221
    183222#define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
    184223#define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
    185224#define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
     225
     226#ifdef __WIN32OS2__
     227static inline const char *wine_dbgstr_rect( const RECT *rect )
     228{
     229    return "rect (null)";
     230}
     231#endif
     232
     233static inline int TOOLBAR_GetListTextOffset(TOOLBAR_INFO *infoPtr, INT iListGap)
     234{
     235    return GetSystemMetrics(SM_CXEDGE) + iListGap - infoPtr->szPadding.cx/2;
     236}
    186237
    187238/* Used to find undocumented extended styles */
     
    355406
    356407/***********************************************************************
    357 *               TOOLBAR_DrawImageList
     408*               TOOLBAR_GetImageListForDrawing
    358409*
    359410* This function validates the bitmap index (including I_IMAGECALLBACK
    360 * functionality). It then draws the image via the ImageList_Draw
    361 * function. It returns TRUE if the image was drawn, FALSE otherwise.
     411* functionality) and returns the corresponding image list.
     412*/
     413static HIMAGELIST
     414TOOLBAR_GetImageListForDrawing (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, IMAGE_LIST_TYPE imagelist, INT * index)
     415{
     416    HIMAGELIST himl;
     417
     418    if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
     419        if (btnPtr->iBitmap == I_IMAGENONE) return NULL;
     420        ERR("index %d,%d is not valid, max %d\n",
     421            HIWORD(btnPtr->iBitmap), LOWORD(btnPtr->iBitmap), infoPtr->nNumBitmaps);
     422        return NULL;
     423    }
     424
     425    if ((*index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
     426        if ((*index == I_IMAGECALLBACK) ||
     427            (*index == I_IMAGENONE)) return NULL;
     428        ERR("TBN_GETDISPINFO returned invalid index %d\n",
     429            *index);
     430        return NULL;
     431    }
     432
     433    switch(imagelist)
     434    {
     435    case IMAGE_LIST_DEFAULT:
     436        himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
     437        break;
     438    case IMAGE_LIST_HOT:
     439        himl = GETHOTIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
     440        break;
     441    case IMAGE_LIST_DISABLED:
     442        himl = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
     443        break;
     444    default:
     445        himl = NULL;
     446        FIXME("Shouldn't reach here\n");
     447    }
     448
     449    if (!himl)
     450       TRACE("no image list\n");
     451
     452    return himl;
     453}
     454
     455
     456/***********************************************************************
     457*               TOOLBAR_TestImageExist
     458*
     459* This function is similar to TOOLBAR_GetImageListForDrawing, except it does not
     460* return the image list. The I_IMAGECALLBACK functionality is implemented.
    362461*/
    363462static BOOL
    364 TOOLBAR_DrawImageList (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl,
    365                         HDC hdc, UINT left, UINT top, UINT draw_flags)
     463TOOLBAR_TestImageExist (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl)
    366464{
    367465    INT index;
     
    383481        return FALSE;
    384482    }
    385     TRACE("drawing index=%d, himl=%p, left=%d, top=%d, flags=%08x\n",
    386           index, himl, left, top, draw_flags);
    387 
    388     ImageList_Draw (himl, index, hdc, left, top, draw_flags);
    389     return TRUE;
    390 }
    391 
    392 
    393 /***********************************************************************
    394 *               TOOLBAR_TestImageExist
    395 *
    396 * This function is similar to TOOLBAR_DrawImageList, except it does not
    397 * draw the image. The I_IMAGECALLBACK functionality is implemented.
    398 */
    399 static BOOL
    400 TOOLBAR_TestImageExist (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl)
    401 {
    402     INT index;
    403 
    404     if (!himl) return FALSE;
    405 
    406     if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
    407         if (btnPtr->iBitmap == I_IMAGENONE) return FALSE;
    408         ERR("index %d is not valid, max %d\n",
    409             btnPtr->iBitmap, infoPtr->nNumBitmaps);
    410         return FALSE;
    411     }
    412 
    413     if ((index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
    414         if ((index == I_IMAGECALLBACK) ||
    415             (index == I_IMAGENONE)) return FALSE;
    416         ERR("TBN_GETDISPINFO returned invalid index %d\n",
    417             index);
    418         return FALSE;
    419     }
    420483    return TRUE;
    421484}
     
    453516*               TOOLBAR_DrawDDFlatSeparator
    454517*
    455 * This function draws the separator that was flaged as TBSTYLE_DROPDOWN.
     518* This function draws the separator that was flagged as BTNS_DROPDOWN.
    456519* In this case, the separator is a pixel high line of COLOR_BTNSHADOW,
    457520* followed by a pixel high line of COLOR_BTNHIGHLIGHT. These separators
     
    495558
    496559static void
    497 TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, INT colorRef)
     560TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, COLORREF clr)
    498561{
    499562    INT x, y;
    500563    HPEN hPen, hOldPen;
    501564
    502     if (!(hPen = CreatePen( PS_SOLID, 1, GetSysColor( colorRef )))) return;
     565    if (!(hPen = CreatePen( PS_SOLID, 1, clr))) return;
    503566    hOldPen = SelectObject ( hdc, hPen );
    504567    x = left + 2;
    505     y = top + 8;
     568    y = top;
    506569    MoveToEx (hdc, x, y, NULL);
    507570    LineTo (hdc, x+5, y++); x++;
     
    521584 */
    522585static void
    523 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
    524                     HDC hdc, INT nState, DWORD dwStyle,
    525                     RECT *rcText, LPWSTR lpText, NMTBCUSTOMDRAW *tbcd)
    526 {
     586TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, RECT *rcText, LPWSTR lpText,
     587                    NMTBCUSTOMDRAW *tbcd)
     588{
     589    HDC hdc = tbcd->nmcd.hdc;
    527590    HFONT  hOldFont = 0;
    528591    COLORREF clrOld = 0;
     592    COLORREF clrOldBk = 0;
     593    int oldBkMode = 0;
     594    UINT state = tbcd->nmcd.uItemState;
    529595
    530596    /* draw text */
    531597    if (lpText) {
    532         TRACE("string rect=(%ld,%ld)-(%ld,%ld)\n",
     598        TRACE("string=%s rect=(%ld,%ld)-(%ld,%ld)\n", debugstr_w(lpText),
    533599              rcText->left, rcText->top, rcText->right, rcText->bottom);
    534600
    535601        hOldFont = SelectObject (hdc, infoPtr->hFont);
    536         if (!(nState & TBSTATE_ENABLED)) {
     602        if ((state & CDIS_HOT) && (infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) {
     603            clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
     604        }
     605        else if (state & CDIS_DISABLED) {
    537606            clrOld = SetTextColor (hdc, tbcd->clrBtnHighlight);
    538607            OffsetRect (rcText, 1, 1);
     
    541610            OffsetRect (rcText, -1, -1);
    542611        }
    543         else if (nState & TBSTATE_INDETERMINATE) {
     612        else if (state & CDIS_INDETERMINATE) {
    544613            clrOld = SetTextColor (hdc, comctl32_color.clr3dShadow);
    545614        }
    546         else if (btnPtr->bHot && (infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) {
     615        else if ((state & CDIS_MARKED) && !(infoPtr->dwItemCDFlag & TBCDRF_NOMARK)) {
    547616            clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
     617            clrOldBk = SetBkColor (hdc, tbcd->clrMark);
     618            oldBkMode = SetBkMode (hdc, OPAQUE); /* FIXME: should this be in the NMTBCUSTOMDRAW structure? */
    548619        }
    549620        else {
     
    553624        DrawTextW (hdc, lpText, -1, rcText, infoPtr->dwDTFlags);
    554625        SetTextColor (hdc, clrOld);
     626        if ((state & CDIS_MARKED) && !(infoPtr->dwItemCDFlag & TBCDRF_NOMARK))
     627        {
     628            SetBkColor (hdc, clrOldBk);
     629            SetBkMode (hdc, oldBkMode);
     630        }
    555631        SelectObject (hdc, hOldFont);
    556632    }
     
    559635
    560636static void
    561 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
    562 {
    563     HBRUSH hbr = SelectObject (hdc, COMCTL32_hPattern55AABrush);
     637TOOLBAR_DrawPattern (LPRECT lpRect, NMTBCUSTOMDRAW *tbcd)
     638{
     639    HDC hdc = tbcd->nmcd.hdc;
     640    HBRUSH hbr = SelectObject (hdc, tbcd->hbrMonoDither);
     641    COLORREF clrTextOld;
     642    COLORREF clrBkOld;
    564643    INT cx = lpRect->right - lpRect->left;
    565644    INT cy = lpRect->bottom - lpRect->top;
    566     PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
     645    clrTextOld = SetTextColor(hdc, tbcd->clrBtnHighlight);
     646    clrBkOld = SetBkColor(hdc, tbcd->clrBtnFace);
     647    PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, PATCOPY);
     648    SetBkColor(hdc, clrBkOld);
     649    SetTextColor(hdc, clrTextOld);
    567650    SelectObject (hdc, hbr);
    568651}
    569652
    570653
    571 static void
    572 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
    573                     HDC hdc, INT x, INT y)
     654static void TOOLBAR_DrawMasked(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
     655                               HDC hdc, INT x, INT y)
    574656{
    575657    HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, 0);
    576     INT cx, cy;
    577     HBITMAP hbmMask;
    578     HDC hdcMask;
    579 
    580     if (!himl)
    581         return;
    582 
    583     ImageList_GetIconSize(himl, &cx, &cy);
    584 
    585     /* create new dc's */
    586     hdcMask = CreateCompatibleDC (0);
    587 
    588     /* create new bitmap */
    589     hbmMask = CreateBitmap (cx, cy, 1, 1, NULL);
    590     SelectObject (hdcMask, hbmMask);
    591 
    592     /* copy the mask bitmap */
    593     ImageList_DrawEx(himl, btnPtr->iBitmap, hdcMask, 0, 0, 0, 0, RGB(255, 255, 255), RGB(0, 0, 0), ILD_MASK);
    594 
    595     /* draw the new mask */
    596     SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
    597     BitBlt (hdc, x+1, y+1, cx, cy, hdcMask, 0, 0, 0xB8074A);
    598 
    599     SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
    600     BitBlt (hdc, x, y, cx, cy, hdcMask, 0, 0, 0xB8074A);
    601 
    602     DeleteObject (hbmMask);
    603     DeleteDC (hdcMask);
     658
     659    if (himl)
     660    {
     661        INT cx, cy;
     662        HBITMAP hbmMask, hbmImage;
     663        HDC hdcMask, hdcImage;
     664
     665        ImageList_GetIconSize(himl, &cx, &cy);
     666
     667        /* Create src image */
     668        hdcImage = CreateCompatibleDC(hdc);
     669        hbmImage = CreateBitmap(cx, cy, GetDeviceCaps(hdc,PLANES),
     670                                GetDeviceCaps(hdc,BITSPIXEL), NULL);
     671        SelectObject(hdcImage, hbmImage);
     672        ImageList_DrawEx(himl, btnPtr->iBitmap, hdcImage, 0, 0, cx, cy,
     673                         RGB(0xff, 0xff, 0xff), RGB(0,0,0), ILD_NORMAL);
     674
     675        /* Create Mask */
     676        hdcMask = CreateCompatibleDC(0);
     677        hbmMask = CreateBitmap(cx, cy, 1, 1, NULL);
     678        SelectObject(hdcMask, hbmMask);
     679
     680        /* Remove the background and all white pixels */
     681        SetBkColor(hdcImage, ImageList_GetBkColor(himl));
     682        BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, SRCCOPY);
     683        SetBkColor(hdcImage, RGB(0xff, 0xff, 0xff));
     684        BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, NOTSRCERASE);
     685
     686        /* draw the new mask 'etched' to hdc */
     687        SetBkColor(hdc, RGB(255, 255, 255));
     688        SelectObject(hdc, GetSysColorBrush(COLOR_3DHILIGHT));
     689        BitBlt(hdc, x + 1, y + 1, cx, cy, hdcMask, 0, 0, 0xE20746);
     690        SelectObject(hdc, GetSysColorBrush(COLOR_3DSHADOW));
     691        BitBlt(hdc, x, y, cx, cy, hdcMask, 0, 0, 0xE20746);
     692
     693        /* Cleanup */
     694        DeleteObject(hbmImage);
     695        DeleteDC(hdcImage);
     696        DeleteObject (hbmMask);
     697        DeleteDC(hdcMask);
     698    }
    604699}
    605700
     
    621716}
    622717
    623 
     718/* draws the image on a toolbar button */
     719static void
     720TOOLBAR_DrawImage(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, INT top, const NMTBCUSTOMDRAW *tbcd)
     721{
     722    HIMAGELIST himl = NULL;
     723    BOOL draw_masked = FALSE;
     724    INT index;
     725    INT offset = 0;
     726    UINT draw_flags = ILD_NORMAL;
     727
     728    if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
     729    {
     730        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DISABLED, &index);
     731        if (!himl)
     732           draw_masked = TRUE;
     733    }
     734    else if ((tbcd->nmcd.uItemState & CDIS_HOT) && (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & TBSTYLE_FLAT))
     735    {
     736        /* if hot, attempt to draw with hot image list, if fails,
     737           use default image list */
     738        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_HOT, &index);
     739        if (!himl)
     740            himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
     741        }
     742    else
     743        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
     744
     745    if (!(infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) &&
     746        (tbcd->nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED)))
     747        offset = 1;
     748
     749    if (!(infoPtr->dwItemCDFlag & TBCDRF_NOMARK) &&
     750        (tbcd->nmcd.uItemState & CDIS_MARKED))
     751        draw_flags |= ILD_BLEND50;
     752
     753    TRACE("drawing index=%d, himl=%p, left=%d, top=%d, offset=%d\n",
     754      index, himl, left, top, offset);
     755
     756    if (draw_masked)
     757        TOOLBAR_DrawMasked (infoPtr, btnPtr, tbcd->nmcd.hdc, left + offset, top + offset);
     758    else if (himl)
     759        ImageList_Draw (himl, index, tbcd->nmcd.hdc, left + offset, top + offset, draw_flags);
     760}
     761
     762/* draws a blank frame for a toolbar button */
     763static void
     764TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, BOOL flat, const NMTBCUSTOMDRAW *tbcd)
     765{
     766    HDC hdc = tbcd->nmcd.hdc;
     767    RECT rc = tbcd->nmcd.rc;
     768    /* if the state is disabled or indeterminate then the button
     769     * cannot have an interactive look like pressed or hot */
     770    BOOL non_interactive_state = (tbcd->nmcd.uItemState & CDIS_DISABLED) ||
     771                                 (tbcd->nmcd.uItemState & CDIS_INDETERMINATE);
     772    BOOL pressed_look = !non_interactive_state &&
     773                        ((tbcd->nmcd.uItemState & CDIS_SELECTED) ||
     774                         (tbcd->nmcd.uItemState & CDIS_CHECKED));
     775
     776    /* app don't want us to draw any edges */
     777    if (infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)
     778        return;
     779
     780    if (flat)
     781    {
     782        if (pressed_look)
     783            DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT);
     784        else if ((tbcd->nmcd.uItemState & CDIS_HOT) && !non_interactive_state)
     785            DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT);
     786    }
     787    else
     788    {
     789        if (pressed_look)
     790            DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE);
     791        else
     792            DrawEdge (hdc, &rc, EDGE_RAISED,
     793              BF_SOFT | BF_RECT | BF_MIDDLE);
     794    }
     795}
     796
     797static void
     798TOOLBAR_DrawSepDDArrow(const TOOLBAR_INFO *infoPtr, BOOL flat, const NMTBCUSTOMDRAW *tbcd, RECT *rcArrow)
     799{
     800    HDC hdc = tbcd->nmcd.hdc;
     801    int offset = 0;
     802
     803    if (flat)
     804    {
     805        if ((tbcd->nmcd.uItemState & CDIS_SELECTED) || (tbcd->nmcd.uItemState & CDIS_CHECKED))
     806            DrawEdge (hdc, rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
     807        else if ( (tbcd->nmcd.uItemState & CDIS_HOT) &&
     808                 !(tbcd->nmcd.uItemState & CDIS_DISABLED) &&
     809                 !(tbcd->nmcd.uItemState & CDIS_INDETERMINATE))
     810            DrawEdge (hdc, rcArrow, BDR_RAISEDINNER, BF_RECT);
     811    }
     812    else
     813    {
     814        if ((tbcd->nmcd.uItemState & CDIS_SELECTED) || (tbcd->nmcd.uItemState & CDIS_CHECKED))
     815            DrawEdge (hdc, rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
     816        else
     817            DrawEdge (hdc, rcArrow, EDGE_RAISED,
     818              BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
     819    }
     820
     821    if (tbcd->nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED))
     822        offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
     823
     824    if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
     825    {
     826        TOOLBAR_DrawArrow(hdc, rcArrow->left+1, rcArrow->top+1 + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight);
     827        TOOLBAR_DrawArrow(hdc, rcArrow->left, rcArrow->top + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow);
     828    }
     829    else
     830        TOOLBAR_DrawArrow(hdc, rcArrow->left + offset, rcArrow->top + offset + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
     831}
     832
     833/* draws a complete toolbar button */
    624834static void
    625835TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
     
    627837    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
    628838    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    629     BOOL hasDropDownArrow = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
    630                             (btnPtr->fsStyle & TBSTYLE_DROPDOWN);
    631     RECT rc, rcArrow, rcBitmap, rcText, rcFill;
     839    BOOL hasDropDownArrow = (TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
     840                            (btnPtr->fsStyle & BTNS_DROPDOWN)) ||
     841                            (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
     842    BOOL drawSepDropDownArrow = hasDropDownArrow &&
     843                                (~btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
     844    RECT rc, rcArrow, rcBitmap, rcText;
    632845    LPWSTR lpText = NULL;
    633846    NMTBCUSTOMDRAW tbcd;
    634847    DWORD ntfret;
    635848    INT offset;
    636     HIMAGELIST himlDef;
    637 
    638     if (btnPtr->fsState & TBSTATE_HIDDEN)
    639         return;
    640849
    641850    rc = btnPtr->rect;
    642     CopyRect (&rcFill, &rc);
    643851    CopyRect (&rcArrow, &rc);
    644852    CopyRect(&rcBitmap, &rc);
    645     CopyRect(&rcText, &rc);
    646853
    647854    /* get a pointer to the text */
     
    650857    if (hasDropDownArrow)
    651858    {
    652         if (dwStyle & TBSTYLE_FLAT)
    653             rc.right = max(rc.left, rc.right - DDARROW_WIDTH);
    654         else
    655             rc.right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
    656         rcArrow.left = rc.right;
    657     }
     859        int right;
     860
     861        if (dwStyle & TBSTYLE_FLAT)
     862            right = max(rc.left, rc.right - DDARROW_WIDTH);
     863        else
     864            right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
     865
     866        if (drawSepDropDownArrow)
     867           rc.right = right;
     868
     869        rcArrow.left = right;
     870    }
     871
     872    /* copy text rect after adjusting for drop-down arrow
     873     * so that text is centred in the rectangle not containing
     874     * the arrow */
     875    CopyRect(&rcText, &rc);
    658876
    659877    /* Center the bitmap horizontally and vertically */
    660878    if (dwStyle & TBSTYLE_LIST)
    661         rcBitmap.left += 3;
     879        rcBitmap.left += GetSystemMetrics(SM_CXEDGE) + OFFSET_X;
    662880    else
    663         rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
     881        rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
    664882
    665883    if(lpText)
    666         rcBitmap.top+=2; /* this looks to be the correct value from vmware comparison - cmm */
     884        rcBitmap.top+= GetSystemMetrics(SM_CYEDGE) + OFFSET_Y;
    667885    else
    668886        rcBitmap.top+=(infoPtr->nButtonHeight - infoPtr->nBitmapHeight) / 2;
    669887
    670888    TRACE("iBitmap: %d, start=(%ld,%ld) w=%d, h=%d\n",
    671           btnPtr->iBitmap, rcBitmap.left, rcBitmap.top,
    672           infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
     889      btnPtr->iBitmap, rcBitmap.left, rcBitmap.top,
     890      infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
    673891    TRACE ("iString: %x\n", btnPtr->iString);
    674892    TRACE ("Stringtext: %s\n", debugstr_w(lpText));
     
    676894    /* draw text */
    677895    if (lpText) {
    678 
    679         InflateRect (&rcText, -3, -3);
    680 
    681         if (GETDEFIMAGELIST(infoPtr, 0) &&
    682             TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
    683                 /* The following test looked like this before
    684                  * I changed it. IE4 "Links" toolbar would not
    685                  * draw correctly with the original code.  - GA 8/01
    686                  *   ((dwStyle & TBSTYLE_LIST) &&
    687                  *    ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
    688                  *       (btnPtr->iBitmap != I_IMAGENONE))
    689                  */
    690                 if (dwStyle & TBSTYLE_LIST) {
    691                     /* LIST style w/ ICON offset is by matching native. */
    692                     /* Matches IE4 "Links" bar.   - GA 8/01             */
    693                     rcText.left += (infoPtr->nBitmapWidth + 2);
    694                 }
    695                 else {
    696                     rcText.top += infoPtr->nBitmapHeight + 1;
    697                 }
    698         }
    699         else {
    700                 if (dwStyle & TBSTYLE_LIST) {
    701                     /* LIST style w/o ICON offset is by matching native. */
    702                     /* Matches IE4 "menu" bar.   - GA  8/01              */
    703                     rcText.left += 4;
    704                 }
    705         }
    706 
    707         if (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
    708             OffsetRect (&rcText, 1, 1);
    709     }
    710 
    711     /* Initialize fields in all cases, because we use these later */
     896        rcText.left += GetSystemMetrics(SM_CXEDGE) + OFFSET_X;
     897        rcText.right -= GetSystemMetrics(SM_CXEDGE) + OFFSET_X;
     898        if (GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr,btnPtr->iBitmap)) &&
     899                TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
     900        {
     901            if (dwStyle & TBSTYLE_LIST)
     902                rcText.left += infoPtr->nBitmapWidth + TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap);
     903            else
     904                rcText.top += GetSystemMetrics(SM_CYEDGE) + OFFSET_Y + infoPtr->nBitmapHeight + infoPtr->szPadding.cy/2;
     905        }
     906        else
     907            if (dwStyle & TBSTYLE_LIST)
     908                rcText.left += LIST_IMAGE_ABSENT_WIDTH + TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap);
     909
     910        if (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
     911            OffsetRect (&rcText, 1, 1);
     912    }
     913
     914    /* Initialize fields in all cases, because we use these later
     915     * NOTE: applications can and do alter these to customize their
     916     * toolbars */
    712917    ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
    713918    tbcd.clrText = comctl32_color.clrBtnText;
     
    719924    tbcd.nStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
    720925    tbcd.nHLStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
    721     /* MSDN says that this is the text rectangle.              */
    722     /* But (why always a but) tracing of v5.7 of native shows  */
    723     /* that this is really a *relative* rectangle based on the */
    724     /* the nmcd.rc. Also the left and top are always 0 ignoring*/
    725     /* any bitmap that might be present.                      */
     926    /* MSDN says that this is the text rectangle.
     927     * But (why always a but) tracing of v5.7 of native shows
     928     * that this is really a *relative* rectangle based on the
     929     * the nmcd.rc. Also the left and top are always 0 ignoring
     930     * any bitmap that might be present. */
    726931    tbcd.rcText.left = 0;
    727932    tbcd.rcText.top = 0;
    728933    tbcd.rcText.right = rcText.right - rc.left;
    729934    tbcd.rcText.bottom = rcText.bottom - rc.top;
    730 
    731     /* FIXME: what should these be set to ????? */
    732     tbcd.hbrMonoDither = 0;
     935    tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
     936    tbcd.nmcd.hdc = hdc;
     937    tbcd.nmcd.rc = rc;
     938    tbcd.hbrMonoDither = COMCTL32_hPattern55AABrush;
     939
     940    /* FIXME: what are these used for? */
    733941    tbcd.hbrLines = 0;
    734942    tbcd.hpenLines = 0;
     
    740948    {
    741949        tbcd.nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
    742         tbcd.nmcd.hdc = hdc;
    743         tbcd.nmcd.rc = rc;
    744950        tbcd.nmcd.dwItemSpec = btnPtr->idCommand;
    745         tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
    746951        tbcd.nmcd.lItemlParam = btnPtr->dwData;
    747952        ntfret = TOOLBAR_SendNotify ((NMHDR *)&tbcd, infoPtr, NM_CUSTOMDRAW);
     953        /* reset these fields so the user can't alter the behaviour like native */
     954        tbcd.nmcd.hdc = hdc;
     955        tbcd.nmcd.rc = rc;
     956
    748957        infoPtr->dwItemCustDraw = ntfret & 0xffff;
    749958        infoPtr->dwItemCDFlag = ntfret & 0xffff0000;
     
    755964    }
    756965
    757     if (!infoPtr->bBtnTranspnt)
    758         FillRect( hdc, &rcFill, GetSysColorBrush(COLOR_BTNFACE));
    759 
    760966    /* separator */
    761     if (btnPtr->fsStyle & TBSTYLE_SEP) {
     967    if (btnPtr->fsStyle & BTNS_SEP) {
    762968        /* with the FLAT style, iBitmap is the width and has already */
    763969        /* been taken into consideration in calculating the width    */
     
    766972        /* when drawing the vertical bar...      */
    767973        if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */) {
    768             if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
     974            if (btnPtr->fsStyle & BTNS_DROPDOWN)
    769975                TOOLBAR_DrawDDFlatSeparator (&rc, hdc, btnPtr, infoPtr);
    770976            else
    771977                TOOLBAR_DrawFlatSeparator (&rc, hdc, infoPtr);
    772978        }
    773         else if (btnPtr->fsStyle != TBSTYLE_SEP) {
     979        else if (btnPtr->fsStyle != BTNS_SEP) {
    774980            FIXME("Draw some kind of separator: fsStyle=%x\n",
    775981                  btnPtr->fsStyle);
     
    778984    }
    779985
    780     /* Determine index of image list */
    781     himlDef = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
    782 
    783     /* disabled */
    784     if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
    785         HIMAGELIST himlDis = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
    786         if (!(dwStyle & TBSTYLE_FLAT) && !(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    787         {
    788             DrawEdge (hdc, &rc, EDGE_RAISED,
    789                       BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
     986    if (!(tbcd.nmcd.uItemState & CDIS_HOT) &&
     987        ((tbcd.nmcd.uItemState & CDIS_CHECKED) || (tbcd.nmcd.uItemState & CDIS_INDETERMINATE)))
     988        TOOLBAR_DrawPattern (&rc, &tbcd);
     989
     990    if ((dwStyle & TBSTYLE_FLAT) && (tbcd.nmcd.uItemState & CDIS_HOT))
     991    {
     992        if ( infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )
     993        {
     994            COLORREF oldclr;
     995
     996            oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack);
     997            ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
    790998            if (hasDropDownArrow)
    791             DrawEdge (hdc, &rcArrow, EDGE_RAISED,
    792                       BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
    793         }
    794 
    795         if (hasDropDownArrow)
    796         {
    797             TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1, COLOR_3DHIGHLIGHT);
    798             TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_3DSHADOW);
    799         }
    800 
    801         if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDis,
    802                                    hdc, rcBitmap.left, rcBitmap.top,
    803                                    ILD_NORMAL))
    804             TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
    805 
    806         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
    807         goto FINALNOTIFY;
    808     }
    809 
    810     /* pressed TBSTYLE_BUTTON */
    811     if (btnPtr->fsState & TBSTATE_PRESSED) {
    812         offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
    813         if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    814         {
    815             if (dwStyle & TBSTYLE_FLAT)
    816             {
    817                 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
    818                 if (hasDropDownArrow)
    819                     DrawEdge (hdc, &rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
    820             }
    821             else
    822             {
    823                 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
    824                 if (hasDropDownArrow)
    825                     DrawEdge (hdc, &rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
    826             }
    827         }
    828 
    829         if (hasDropDownArrow)
    830             TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
    831 
    832         TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
    833                                hdc, rcBitmap.left+offset, rcBitmap.top+offset,
    834                                ILD_NORMAL);
    835 
    836         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
    837         goto FINALNOTIFY;
    838     }
    839 
    840     /* checked TBSTYLE_CHECK */
    841     if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
    842         (btnPtr->fsState & TBSTATE_CHECKED)) {
    843         if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    844         {
    845             if (dwStyle & TBSTYLE_FLAT)
    846                 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
    847                           BF_RECT | BF_ADJUST);
    848             else
    849                 DrawEdge (hdc, &rc, EDGE_SUNKEN,
    850                           BF_RECT | BF_MIDDLE | BF_ADJUST);
    851         }
    852 
    853         TOOLBAR_DrawPattern (hdc, &rc);
    854 
    855         TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
    856                                hdc, rcBitmap.left+1, rcBitmap.top+1,
    857                                ILD_NORMAL);
    858 
    859         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
    860         goto FINALNOTIFY;
    861     }
    862 
    863     /* indeterminate */
    864     if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
    865         if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    866             DrawEdge (hdc, &rc, EDGE_RAISED,
    867                       BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
    868 
    869         TOOLBAR_DrawPattern (hdc, &rc);
    870         TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
    871         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
    872         goto FINALNOTIFY;
    873     }
    874 
    875     /* normal state */
    876     if (dwStyle & TBSTYLE_FLAT)
     999                ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0);
     1000            SetBkColor(hdc, oldclr);
     1001        }
     1002    }
     1003
     1004    TOOLBAR_DrawFrame(infoPtr, dwStyle & TBSTYLE_FLAT, &tbcd);
     1005
     1006    if (drawSepDropDownArrow)
     1007        TOOLBAR_DrawSepDDArrow(infoPtr, dwStyle & TBSTYLE_FLAT, &tbcd, &rcArrow);
     1008
     1009    if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
     1010        TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
     1011
     1012    TOOLBAR_DrawImage(infoPtr, btnPtr, rcBitmap.left, rcBitmap.top, &tbcd);
     1013
     1014    if (hasDropDownArrow && !drawSepDropDownArrow)
    8771015    {
    878         if (btnPtr->bHot)
    879         {
    880             if ( infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )
    881             {
    882                 COLORREF oldclr;
    883 
    884                 oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack);
    885                 ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
    886                 if (hasDropDownArrow)
    887                     ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0);
    888                 SetBkColor(hdc, oldclr);
    889             }
    890             else
    891             {
    892                 if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    893                 {
    894                     DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT);
    895                     if (hasDropDownArrow)
    896                         DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT);
    897                 }
    898             }
    899         }
    900 #if 1
    901         else /* The following code needs to be removed after
    902               * "hot item" support has been implemented for the
    903               * case where it is being de-selected.
    904               */
    905         {
    906             FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
    907             if (hasDropDownArrow)
    908             FrameRect(hdc, &rcArrow, GetSysColorBrush(COLOR_BTNFACE));
    909         }
    910 #endif
    911 
    912         if (hasDropDownArrow)
    913             TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top, COLOR_WINDOWFRAME);
    914 
    915         if (btnPtr->bHot) {
    916             HIMAGELIST himlHot = GETHOTIMAGELIST(infoPtr,
    917                 GETHIMLID(infoPtr, btnPtr->iBitmap));
    918             /* if hot, attempt to draw with himlHot, if fails, use himlDef */
    919             if (!TOOLBAR_DrawImageList (infoPtr, btnPtr,
    920                                         himlHot,
    921                                         hdc, rcBitmap.left,
    922                                         rcBitmap.top, ILD_NORMAL))
    923                 TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
    924                                        hdc, rcBitmap.left, rcBitmap.top,
    925                                        ILD_NORMAL);
    926         }
    927         else
    928             TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
    929                                    hdc, rcBitmap.left, rcBitmap.top,
    930                                    ILD_NORMAL);
    931     }
    932     else
    933     {
    934         if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    935             DrawEdge (hdc, &rc, EDGE_RAISED,
    936                       BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
    937 
    938         if (hasDropDownArrow)
    939         {
    940             if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
    941                 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
    942                           BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
    943             TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
    944         }
    945 
    946         TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
    947                                hdc, rcBitmap.left, rcBitmap.top,
    948                                ILD_NORMAL);}
    949 
    950 
    951     TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd);
    952 
    953  FINALNOTIFY:
     1016        if (tbcd.nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
     1017        {
     1018            TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1 + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight);
     1019            TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow);
     1020        }
     1021        else if (tbcd.nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED))
     1022        {
     1023            offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
     1024            TOOLBAR_DrawArrow(hdc, rcArrow.left + offset, rcArrow.top + offset + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
     1025        }
     1026        else
     1027            TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
     1028    }
     1029
     1030FINALNOTIFY:
    9541031    if (infoPtr->dwItemCustDraw & CDRF_NOTIFYPOSTPAINT)
    9551032    {
     
    9751052    TBUTTON_INFO *btnPtr;
    9761053    INT i, oldBKmode = 0;
    977     RECT rcTemp;
     1054    RECT rcTemp, rcClient;
    9781055    NMTBCUSTOMDRAW tbcd;
    9791056    DWORD ntfret;
     1057
     1058    /* the app has told us not to redraw the toolbar */
     1059    if (!infoPtr->bDoRedraw)
     1060        return;
    9801061
    9811062    /* if imagelist belongs to the app, it can be changed
     
    10011082        oldBKmode = SetBkMode (hdc, TRANSPARENT);
    10021083
     1084    GetClientRect(hwnd, &rcClient);
     1085
    10031086    /* redraw necessary buttons */
    10041087    btnPtr = infoPtr->buttons;
    10051088    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
    10061089    {
    1007         if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
     1090        BOOL bDraw;
     1091        if (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
     1092        {
     1093            IntersectRect(&rcTemp, &rcClient, &btnPtr->rect);
     1094            bDraw = EqualRect(&rcTemp, &btnPtr->rect);
     1095        }
     1096        else
     1097            bDraw = TRUE;
     1098        bDraw &= IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect));
     1099        bDraw = (btnPtr->fsState & TBSTATE_HIDDEN) ? FALSE : bDraw;
     1100        if (bDraw)
    10081101            TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
    10091102    }
     
    10321125* indicates where the underline goes, except for the string "&&" which
    10331126* is reduced to a single "&". GetTextExtentPoint does not process these
    1034 * only DrawText does. Note that the TBSTYLE_NOPREFIX is handled here.
     1127* only DrawText does. Note that the BTNS_NOPREFIX is handled here.
    10351128*/
    10361129static void
     
    10431136    lpSize->cy = 0;
    10441137
    1045     if (!(btnPtr->fsState & TBSTATE_HIDDEN) )
     1138    if (infoPtr->nMaxTextRows > 0 &&
     1139        !(btnPtr->fsState & TBSTATE_HIDDEN) &&
     1140        (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
     1141        (btnPtr->fsStyle & BTNS_SHOWTEXT)) )
    10461142    {
    10471143        LPWSTR lpText = TOOLBAR_GetText(infoPtr, btnPtr);
     
    10581154            /* Use DrawText to get true size as drawn (less pesky "&") */
    10591155            DrawTextW (hdc, lpText, -1, &myrect, DT_VCENTER | DT_SINGLELINE |
    1060                    DT_CALCRECT | ((btnPtr->fsStyle & TBSTYLE_NOPREFIX) ?
     1156                   DT_CALCRECT | ((btnPtr->fsStyle & BTNS_NOPREFIX) ?
    10611157                                  DT_NOPREFIX : 0));
    10621158
     
    10881184    lpSize->cx = 0;
    10891185    lpSize->cy = 0;
     1186
     1187    if(infoPtr->nMaxTextRows == 0)
     1188        return;
    10901189
    10911190    hdc = GetDC (hwnd);
     
    11131212*               TOOLBAR_WrapToolbar
    11141213*
    1115 * This function walks through the buttons and seperators in the
     1214* This function walks through the buttons and separators in the
    11161215* toolbar, and sets the TBSTATE_WRAP flag only on those items where
    11171216* wrapping should occur based on the width of the toolbar window.
     
    11671266        /* custom controls in toolbars.                              */
    11681267        /*                                                           */
    1169         /* TBSTYLE_DROPDOWN separators are treated as buttons for    */
     1268        /* BTNS_DROPDOWN separators are treated as buttons for    */
    11701269        /* width.  - GA 8/01                                         */
    1171         if ((btnPtr[i].fsStyle & TBSTYLE_SEP) &&
    1172             !(btnPtr[i].fsStyle & TBSTYLE_DROPDOWN))
     1270        if ((btnPtr[i].fsStyle & BTNS_SEP) &&
     1271            !(btnPtr[i].fsStyle & BTNS_DROPDOWN))
    11731272            cx = (btnPtr[i].iBitmap > 0) ?
    11741273                        btnPtr[i].iBitmap : SEPARATOR_WIDTH;
     
    11801279        /* next row if the previous wrapping is on a button.         */
    11811280        if( bButtonWrap &&
    1182                 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
     1281                (btnPtr[i].fsStyle & BTNS_SEP) &&
    11831282                (i + 1 < infoPtr->nNumButtons ) &&
    1184                 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
     1283                (btnPtr[i + 1].fsStyle & BTNS_SEP) )
    11851284        {
    11861285            TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
     
    12041303            /*  go to the next until it reaches a non separator.      */
    12051304            /*  Wrap the last separator if it is before a button.     */
    1206             while( ( ((btnPtr[i].fsStyle & TBSTYLE_SEP) &&
    1207                       !(btnPtr[i].fsStyle & TBSTYLE_DROPDOWN)) ||
     1305            while( ( ((btnPtr[i].fsStyle & BTNS_SEP) &&
     1306                      !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
    12081307                     (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
    12091308                        i < infoPtr->nNumButtons )
     
    12301329            for ( j = i - 1; j >= 0  &&  !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
    12311330            {
    1232                 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
     1331                if ((btnPtr[j].fsStyle & BTNS_SEP) &&
    12331332                        !(btnPtr[j].fsState & TBSTATE_HIDDEN))
    12341333                {
     
    12731372                bFound = TRUE;
    12741373                x = infoPtr->nIndent;
    1275                 if (btnPtr[i].fsStyle & TBSTYLE_SEP )
     1374                if (btnPtr[i].fsStyle & BTNS_SEP )
    12761375                    bButtonWrap = FALSE;
    12771376                else
     
    13141413    TOOLBAR_CalcStrings (hwnd, &sizeString);
    13151414
     1415    TOOLBAR_DumpToolbar (infoPtr, __LINE__);
     1416
    13161417    for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
    13171418    {
     
    13241425                                     0, sizeString.cy) + infoPtr->szPadding.cy;
    13251426        infoPtr->nButtonWidth = ((usesBitmaps) ? infoPtr->nBitmapWidth :
    1326                                  0) + sizeString.cx + 6;
     1427                                 LIST_IMAGE_ABSENT_WIDTH) + sizeString.cx + infoPtr->szPadding.cx;
     1428        if (sizeString.cx > 0)
     1429            infoPtr->nButtonWidth += TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap) + infoPtr->szPadding.cx/2;
    13271430        TRACE("LIST style, But w=%d h=%d, useBitmaps=%d, Bit w=%d h=%d\n",
    13281431              infoPtr->nButtonWidth, infoPtr->nButtonHeight, usesBitmaps,
    13291432              infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
    1330         TOOLBAR_DumpToolbar (infoPtr, __LINE__);
    13311433    }
    13321434    else {
     
    13351437            if (usesBitmaps)
    13361438                infoPtr->nButtonHeight = sizeString.cy +
    1337                     2 + /* this is the space to separate text from bitmap */
    1338                   infoPtr->nBitmapHeight + 6;
     1439                    infoPtr->szPadding.cy/2 + /* this is the space to separate text from bitmap */
     1440                  infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
    13391441            else
    1340                 infoPtr->nButtonHeight = sizeString.cy + 6;
     1442                infoPtr->nButtonHeight = sizeString.cy + infoPtr->szPadding.cy;
    13411443        }
    1342         else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
    1343             infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
     1444        else
     1445            infoPtr->nButtonHeight = infoPtr->nBitmapHeight + infoPtr->szPadding.cy;
    13441446
    13451447        if (sizeString.cx > infoPtr->nBitmapWidth)
    1346             infoPtr->nButtonWidth = sizeString.cx + 6;
    1347         else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
    1348             infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
     1448            infoPtr->nButtonWidth = sizeString.cx + infoPtr->szPadding.cx;
     1449        else
     1450            infoPtr->nButtonWidth = infoPtr->nBitmapWidth + infoPtr->szPadding.cx;
    13491451    }
    13501452
     
    13591461    y  = 0;
    13601462
    1361    /*
    1362     * We will set the height below, and we set the width on entry
    1363     * so we do not reset them here..
    1364     */
    1365 #if 0
    1366     GetClientRect( hwnd, &rc );
    1367     /* get initial values for toolbar */
    1368     infoPtr->nWidth  = rc.right - rc.left;
    1369     infoPtr->nHeight = rc.bottom - rc.top;
    1370 #endif
    1371 
    13721463    /* from above, minimum is a button, and possible text */
    13731464    cx = infoPtr->nButtonWidth;
     
    13871478
    13881479    btnPtr = infoPtr->buttons;
    1389 
    1390     /* do not base height/width on parent, if the parent is a */
    1391     /* rebar control it could have multiple rows of toolbars  */
    1392 /*    GetClientRect( GetParent(hwnd), &rc ); */
    1393 /*    cx = rc.right - rc.left; */
    1394 /*    cy = rc.bottom - rc.top; */
    13951480
    13961481    TRACE("cy=%d\n", cy);
     
    14101495        /* it is the actual width of the separator. This is used for */
    14111496        /* custom controls in toolbars.                              */
    1412         if (btnPtr->fsStyle & TBSTYLE_SEP) {
    1413             if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
     1497        if (btnPtr->fsStyle & BTNS_SEP) {
     1498            if (btnPtr->fsStyle & BTNS_DROPDOWN) {
    14141499                cy = (btnPtr->iBitmap > 0) ?
    14151500                     btnPtr->iBitmap : SEPARATOR_WIDTH;
     
    14221507        else
    14231508        {
    1424             if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
     1509            if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
     1510                (btnPtr->fsStyle & BTNS_AUTOSIZE))
    14251511            {
    14261512              SIZE sz;
     
    14361522              ReleaseDC (hwnd, hdc);
    14371523
    1438               /* Fudge amount measured against IE4 "menu" and "Links" */
    1439               /* toolbars with native control (v4.71).  -  GA 8/01    */
    1440               cx = sz.cx + 6 + 5 + 5;
    1441               if ((dwStyle & TBSTYLE_LIST) &&
    1442                   (TOOLBAR_TestImageExist (infoPtr, btnPtr, GETDEFIMAGELIST(infoPtr,0))))
    1443                   cx += infoPtr->nBitmapWidth;
     1524              /* add space on for button frame, etc */
     1525              cx = sz.cx + infoPtr->szPadding.cx;
     1526             
     1527              /* add list padding */
     1528              if ((dwStyle & TBSTYLE_LIST) && sz.cx > 0)
     1529                  cx += TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap) + infoPtr->szPadding.cx/2;
     1530
     1531              if (TOOLBAR_TestImageExist (infoPtr, btnPtr, GETDEFIMAGELIST(infoPtr,0)))
     1532              {
     1533                if (dwStyle & TBSTYLE_LIST)
     1534                  cx += infoPtr->nBitmapWidth;
     1535                else if (cx < (infoPtr->nBitmapWidth+infoPtr->szPadding.cx))
     1536                  cx = infoPtr->nBitmapWidth+infoPtr->szPadding.cx;
     1537              }
     1538              else if (dwStyle & TBSTYLE_LIST)
     1539                  cx += LIST_IMAGE_ABSENT_WIDTH;
    14441540            }
    14451541            else
    14461542              cx = infoPtr->nButtonWidth;
    14471543
    1448             if (hasDropDownArrows && (btnPtr->fsStyle & TBSTYLE_DROPDOWN))
     1544            if ((hasDropDownArrows && (btnPtr->fsStyle & BTNS_DROPDOWN)) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN))
    14491545              cx += DDARROW_WIDTH;
    14501546        }
     
    14621558
    14631559        /* Set the toolTip only for non-hidden, non-separator button */
    1464         if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
     1560        if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & BTNS_SEP ))
    14651561        {
    14661562            TTTOOLINFOA ti;
     
    14851581        if( bWrap )
    14861582        {
    1487             if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
     1583            if ( !(btnPtr->fsStyle & BTNS_SEP) )
    14881584                y += cy;
    14891585            else
     
    14921588                /* it is the actual width of the separator. This is used for */
    14931589                /* custom controls in toolbars.                              */
    1494                 if ( !(btnPtr->fsStyle & TBSTYLE_DROPDOWN))
     1590                if ( !(btnPtr->fsStyle & BTNS_DROPDOWN))
    14951591                    y += cy + ( (btnPtr->iBitmap > 0 ) ?
    14961592                                btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
     
    15521648            continue;
    15531649
    1554         if (btnPtr->fsStyle & TBSTYLE_SEP) {
     1650        if (btnPtr->fsStyle & BTNS_SEP) {
    15551651            if (PtInRect (&btnPtr->rect, *lpPt)) {
    15561652                TRACE(" ON SEPARATOR %d!\n", i);
     
    16051701    /* check index button */
    16061702    btnPtr = &infoPtr->buttons[nIndex];
    1607     if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
     1703    if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
    16081704        if (btnPtr->fsState & TBSTATE_CHECKED)
    16091705            return nIndex;
     
    16141710    while (nRunIndex >= 0) {
    16151711        btnPtr = &infoPtr->buttons[nRunIndex];
    1616         if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
     1712        if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
    16171713            if (btnPtr->fsState & TBSTATE_CHECKED)
    16181714                return nRunIndex;
     
    16271723    while (nRunIndex < infoPtr->nNumButtons) {
    16281724        btnPtr = &infoPtr->buttons[nRunIndex];
    1629         if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
     1725        if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
    16301726            if (btnPtr->fsState & TBSTATE_CHECKED)
    16311727                return nRunIndex;
     
    16901786                    return FALSE;
    16911787
     1788                /* UNDOCUMENTED: dialog hwnd immediately follows NMHDR */
     1789                nmtb.iItem = (int)hwnd;
    16921790                /* Send TBN_INITCUSTOMIZE notification */
    16931791                if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_INITCUSTOMIZE) ==
    1694                     TBNRF_HIDEHELP)
     1792                    TBNRF_HIDEHELP)
    16951793                {
    1696                     FIXME("TBNRF_HIDEHELP not supported\n");
     1794                    TRACE("TBNRF_HIDEHELP requested\n");
     1795                    ShowWindow(GetDlgItem(hwnd, IDC_HELP_BTN), SW_HIDE);
    16971796                }
    16981797
     
    17001799                for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
    17011800                {
    1702                     btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
     1801                    btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
    17031802                    memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
    1704                     btnInfo->btn.fsStyle = TBSTYLE_SEP;
     1803                    btnInfo->btn.fsStyle = BTNS_SEP;
    17051804                    btnInfo->bVirtual = FALSE;
    17061805                    LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
     
    17141813
    17151814                /* insert separator button into 'available buttons' list */
    1716                 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
     1815                btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
    17171816                memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
    1718                 btnInfo->btn.fsStyle = TBSTYLE_SEP;
     1817                btnInfo->btn.fsStyle = BTNS_SEP;
    17191818                btnInfo->bVirtual = FALSE;
    17201819                btnInfo->bRemovable = TRUE;
     
    17491848                    if (index == -1)
    17501849                    {
    1751                         btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
     1850                        btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
    17521851                        btnInfo->bVirtual = FALSE;
    17531852                        btnInfo->bRemovable = TRUE;
     
    17641863
    17651864                    memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
    1766                     if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
     1865                    if (!(nmtb.tbButton.fsStyle & BTNS_SEP))
    17671866                    {
    17681867                        if (lstrlenW(nmtb.pszText))
     
    17811880
    17821881                /* append 'virtual' separator button to the 'toolbar buttons' list */
    1783                 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
     1882                btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
    17841883                memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
    1785                 btnInfo->btn.fsStyle = TBSTYLE_SEP;
     1884                btnInfo->btn.fsStyle = BTNS_SEP;
    17861885                btnInfo->bVirtual = TRUE;
    17871886                btnInfo->bRemovable = FALSE;
     
    19532052
    19542053                            /* insert into 'available button' list */
    1955                             if (!(btnInfo->btn.fsStyle & TBSTYLE_SEP))
     2054                            if (!(btnInfo->btn.fsStyle & BTNS_SEP))
    19562055                            {
    19572056                                index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
     
    19592058                            }
    19602059                            else
    1961                                 COMCTL32_Free (btnInfo);
     2060                                Free (btnInfo);
    19622061                        }
    19632062                    }
    19642063                    break;
     2064                case IDC_HELP_BTN:
     2065                        TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_CUSTHELP);
     2066                        break;
     2067                case IDC_RESET_BTN:
     2068                        TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_RESET);
     2069                        break;
    19652070
    19662071                case IDOK: /* Add button */
     
    19942099
    19952100                                /* duplicate 'separator' button */
    1996                                 btnNew = (PCUSTOMBUTTON)COMCTL32_Alloc (sizeof(CUSTOMBUTTON));
     2101                                btnNew = (PCUSTOMBUTTON)Alloc (sizeof(CUSTOMBUTTON));
    19972102                                memcpy (btnNew, btnInfo, sizeof(CUSTOMBUTTON));
    19982103                                btnInfo = btnNew;
     
    20252130                {
    20262131                    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
    2027                     COMCTL32_Free(btnInfo);
     2132                    Free(btnInfo);
    20282133                    SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
    20292134                }
     
    20362141                {
    20372142                    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
    2038                     COMCTL32_Free(btnInfo);
     2143                    Free(btnInfo);
    20392144                    SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
    20402145                }
     
    20942199
    20952200                /* draw image and text */
    2096                 if ((btnInfo->btn.fsStyle & TBSTYLE_SEP) == 0) {
     2201                if ((btnInfo->btn.fsStyle & BTNS_SEP) == 0) {
    20972202                        HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr,
    20982203                                btnInfo->btn.iBitmap));
     
    21992304        TRACE ("creating default image list!\n");
    22002305
    2201     himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
    2202                 ILC_COLOR | ILC_MASK, nButtons, 2);
     2306        himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
     2307                                    ILC_COLORDDB | ILC_MASK, nButtons, 2);
    22032308        TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0);
    2204     infoPtr->himlInt = himlDef;
     2309        infoPtr->himlInt = himlDef;
    22052310    }
    22062311    else {
     
    22442349       DeleteDC (hdcBitmap);
    22452350
    2246        nIndex = ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
     2351       nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace);
    22472352       DeleteObject (hbmLoad);
    22482353    }
     
    22562361                                       MAKEINTRESOURCEA(IDB_STD_SMALL));
    22572362                nIndex = ImageList_AddMasked (himlDef,
    2258                                               hbmLoad, CLR_DEFAULT);
     2363                                              hbmLoad, comctl32_color.clrBtnFace);
    22592364                DeleteObject (hbmLoad);
    22602365                break;
     
    22642369                                       MAKEINTRESOURCEA(IDB_STD_LARGE));
    22652370                nIndex = ImageList_AddMasked (himlDef,
    2266                                               hbmLoad, CLR_DEFAULT);
     2371                                              hbmLoad, comctl32_color.clrBtnFace);
    22672372                DeleteObject (hbmLoad);
    22682373                break;
     
    22722377                                       MAKEINTRESOURCEA(IDB_VIEW_SMALL));
    22732378                nIndex = ImageList_AddMasked (himlDef,
    2274                                               hbmLoad, CLR_DEFAULT);
     2379                                              hbmLoad, comctl32_color.clrBtnFace);
    22752380                DeleteObject (hbmLoad);
    22762381                break;
     
    22802385                                       MAKEINTRESOURCEA(IDB_VIEW_LARGE));
    22812386                nIndex = ImageList_AddMasked (himlDef,
    2282                                               hbmLoad, CLR_DEFAULT);
     2387                                              hbmLoad, comctl32_color.clrBtnFace);
    22832388                DeleteObject (hbmLoad);
    22842389                break;
     
    22882393                                       MAKEINTRESOURCEA(IDB_HIST_SMALL));
    22892394                nIndex = ImageList_AddMasked (himlDef,
    2290                                               hbmLoad, CLR_DEFAULT);
     2395                                              hbmLoad, comctl32_color.clrBtnFace);
    22912396                DeleteObject (hbmLoad);
    22922397                break;
     
    22962401                                       MAKEINTRESOURCEA(IDB_HIST_LARGE));
    22972402                nIndex = ImageList_AddMasked (himlDef,
    2298                                               hbmLoad, CLR_DEFAULT);
     2403                                              hbmLoad, comctl32_color.clrBtnFace);
    22992404                DeleteObject (hbmLoad);
    23002405                break;
     
    23092414    {
    23102415        hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
    2311         nIndex = ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
     2416        nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace);
    23122417        DeleteObject (hbmLoad);
    23132418    }
     
    23172422    if (infoPtr->nNumBitmapInfos == 0)
    23182423    {
    2319         infoPtr->bitmaps = COMCTL32_Alloc(sizeof(TBITMAP_INFO));
     2424        infoPtr->bitmaps = Alloc(sizeof(TBITMAP_INFO));
    23202425    }
    23212426    else
    23222427    {
    23232428        TBITMAP_INFO *oldBitmaps = infoPtr->bitmaps;
    2324         infoPtr->bitmaps = COMCTL32_Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
     2429        infoPtr->bitmaps = Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
    23252430        memcpy(&infoPtr->bitmaps[0], &oldBitmaps[0], infoPtr->nNumBitmapInfos);
    23262431    }
     
    23492454    }
    23502455
    2351     InvalidateRect(hwnd, NULL, FALSE);
     2456    InvalidateRect(hwnd, NULL, TRUE);
    23522457
    23532458    return nIndex;
     
    23702475    if (infoPtr->nNumButtons == 0) {
    23712476        infoPtr->buttons =
    2372             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     2477            Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
    23732478    }
    23742479    else {
    23752480        TBUTTON_INFO *oldButtons = infoPtr->buttons;
    23762481        infoPtr->buttons =
    2377             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     2482            Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
    23782483        memcpy (&infoPtr->buttons[0], &oldButtons[0],
    23792484                nOldButtons * sizeof(TBUTTON_INFO));
    2380         COMCTL32_Free (oldButtons);
     2485        Free (oldButtons);
    23812486    }
    23822487
     
    23912496        btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
    23922497        btnPtr->dwData    = lpTbb[nCount].dwData;
    2393         btnPtr->iString   = lpTbb[nCount].iString;
     2498        if(HIWORD(lpTbb[nCount].iString) && lpTbb[nCount].iString != -1)
     2499            Str_SetPtrAtoW ((LPWSTR*)&btnPtr->iString, (LPSTR)lpTbb[nCount].iString );
     2500        else
     2501            btnPtr->iString   = lpTbb[nCount].iString;
    23942502        btnPtr->bHot      = FALSE;
    23952503
    2396         if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
     2504        if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & BTNS_SEP)) {
    23972505            TTTOOLINFOA ti;
    23982506
     
    24132521    TOOLBAR_DumpToolbar (infoPtr, __LINE__);
    24142522
    2415     InvalidateRect(hwnd, NULL, FALSE);
     2523    InvalidateRect(hwnd, NULL, TRUE);
    24162524
    24172525    return TRUE;
     
    24342542    if (infoPtr->nNumButtons == 0) {
    24352543        infoPtr->buttons =
    2436             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     2544            Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
    24372545    }
    24382546    else {
    24392547        TBUTTON_INFO *oldButtons = infoPtr->buttons;
    24402548        infoPtr->buttons =
    2441             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
     2549            Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
    24422550        memcpy (&infoPtr->buttons[0], &oldButtons[0],
    24432551                nOldButtons * sizeof(TBUTTON_INFO));
    2444         COMCTL32_Free (oldButtons);
     2552        Free (oldButtons);
    24452553    }
    24462554
     
    24552563        btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
    24562564        btnPtr->dwData    = lpTbb[nCount].dwData;
    2457         btnPtr->iString   = lpTbb[nCount].iString;
     2565        if(HIWORD(lpTbb[nCount].iString) && lpTbb[nCount].iString != -1)
     2566            Str_SetPtrW ((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[nCount].iString );
     2567        else
     2568            btnPtr->iString   = lpTbb[nCount].iString;
    24582569        btnPtr->bHot      = FALSE;
    24592570
    2460         if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
     2571        if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & BTNS_SEP)) {
    24612572            TTTOOLINFOW ti;
    24622573
     
    24782589    TOOLBAR_DumpToolbar (infoPtr, __LINE__);
    24792590
    2480     InvalidateRect(hwnd, NULL, FALSE);
     2591    InvalidateRect(hwnd, NULL, TRUE);
    24812592
    24822593    return TRUE;
     
    25022613        if (infoPtr->nNumStrings == 0) {
    25032614            infoPtr->strings =
    2504                 COMCTL32_Alloc (sizeof(LPWSTR));
     2615                Alloc (sizeof(LPWSTR));
    25052616        }
    25062617        else {
    25072618            LPWSTR *oldStrings = infoPtr->strings;
    25082619            infoPtr->strings =
    2509                 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
     2620                Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
    25102621            memcpy (&infoPtr->strings[0], &oldStrings[0],
    25112622                    sizeof(LPWSTR) * infoPtr->nNumStrings);
    2512             COMCTL32_Free (oldStrings);
     2623            Free (oldStrings);
    25132624        }
    25142625
    2515         /*COMCTL32_Alloc zeros out the allocated memory*/
     2626        /*Alloc zeros out the allocated memory*/
    25162627        Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], szString );
    25172628        infoPtr->nNumStrings++;
     
    25322643            if (infoPtr->nNumStrings == 0) {
    25332644                infoPtr->strings =
    2534                     COMCTL32_Alloc (sizeof(LPWSTR));
     2645                    Alloc (sizeof(LPWSTR));
    25352646            }
    25362647            else {
    25372648                LPWSTR *oldStrings = infoPtr->strings;
    25382649                infoPtr->strings =
    2539                     COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
     2650                    Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
    25402651                memcpy (&infoPtr->strings[0], &oldStrings[0],
    25412652                        sizeof(LPWSTR) * infoPtr->nNumStrings);
    2542                 COMCTL32_Free (oldStrings);
     2653                Free (oldStrings);
    25432654            }
    25442655
     
    25802691
    25812692                if (infoPtr->nNumStrings == 0) {
    2582                     infoPtr->strings = COMCTL32_Alloc (sizeof(LPWSTR));
     2693                    infoPtr->strings = Alloc (sizeof(LPWSTR));
    25832694                }
    25842695                else
    25852696                {
    25862697                    LPWSTR *oldStrings = infoPtr->strings;
    2587                     infoPtr->strings = COMCTL32_Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
     2698                    infoPtr->strings = Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
    25882699                    memcpy(&infoPtr->strings[0], &oldStrings[0],
    25892700                           sizeof(LPWSTR) * infoPtr->nNumStrings);
    2590                     COMCTL32_Free(oldStrings);
     2701                    Free(oldStrings);
    25912702                }
    25922703
    2593                 np=COMCTL32_StrChrW (p, L'|');
     2704                np=strchrW (p, '|');
    25942705                if (np!=NULL) {
    25952706                    len = np - p;
     
    26012712                TRACE("len=%d %s\n", len, debugstr_w(p));
    26022713                infoPtr->strings[infoPtr->nNumStrings] =
    2603                     COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
     2714                    Alloc (sizeof(WCHAR)*(len+1));
    26042715                lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len+1);
    26052716                infoPtr->nNumStrings++;
     
    26132724            if (infoPtr->nNumStrings == 0) {
    26142725                infoPtr->strings =
    2615                     COMCTL32_Alloc (sizeof(LPWSTR));
     2726                    Alloc (sizeof(LPWSTR));
    26162727            }
    26172728            else {
    26182729                LPWSTR *oldStrings = infoPtr->strings;
    26192730                infoPtr->strings =
    2620                     COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
     2731                    Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
    26212732                memcpy (&infoPtr->strings[0], &oldStrings[0],
    26222733                        sizeof(LPWSTR) * infoPtr->nNumStrings);
    2623                 COMCTL32_Free (oldStrings);
     2734                Free (oldStrings);
    26242735            }
    26252736
     
    26422753            if (infoPtr->nNumStrings == 0) {
    26432754                infoPtr->strings =
    2644                     COMCTL32_Alloc (sizeof(LPWSTR));
     2755                    Alloc (sizeof(LPWSTR));
    26452756            }
    26462757            else {
    26472758                LPWSTR *oldStrings = infoPtr->strings;
    26482759                infoPtr->strings =
    2649                     COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
     2760                    Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
    26502761                memcpy (&infoPtr->strings[0], &oldStrings[0],
    26512762                        sizeof(LPWSTR) * infoPtr->nNumStrings);
    2652                 COMCTL32_Free (oldStrings);
     2763                Free (oldStrings);
    26532764            }
    26542765
     
    27002811        cx = infoPtr->nWidth;
    27012812
    2702         if (dwStyle & CCS_NOMOVEY) {
     2813        if ((dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) {
    27032814                GetWindowRect(hwnd, &window_rect);
    27042815                ScreenToClient(parent, (LPPOINT)&window_rect.left);
    27052816                y = window_rect.top;
    27062817        }
     2818        if ((dwStyle & CCS_BOTTOM) == CCS_BOTTOM) {
     2819            GetWindowRect(hwnd, &window_rect);
     2820            y = parent_rect.bottom - ( window_rect.bottom - window_rect.top);
     2821        }
    27072822    }
    27082823
     
    27212836
    27222837    infoPtr->bAutoSize = TRUE;
    2723     SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
    2724                         cx, cy, uPosFlags);
    2725     /* The following line makes sure that the infoPtr->bAutoSize is turned off after
    2726      * the setwindowpos calls */
     2838    SetWindowPos (hwnd, HWND_TOP,  x, y, cx, cy, uPosFlags);
     2839    /* The following line makes sure that the infoPtr->bAutoSize is turned off
     2840     * after the setwindowpos calls */
    27272841    infoPtr->bAutoSize = FALSE;
    27282842
     
    27642878    INT nIndex;
    27652879
     2880    TRACE("button %d, iBitmap now %d\n", wParam, LOWORD(lParam));
     2881
    27662882    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
    27672883    if (nIndex == -1)
     
    27892905
    27902906    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     2907
     2908    TRACE("hwnd=%p, btn index=%d, lParam=0x%08lx\n", hwnd, nIndex, lParam);
     2909
    27912910    if (nIndex == -1)
    27922911        return FALSE;
    27932912
    27942913    btnPtr = &infoPtr->buttons[nIndex];
    2795 
    2796     if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
    2797         return FALSE;
    27982914
    27992915    bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
     
    28022918        btnPtr->fsState &= ~TBSTATE_CHECKED;
    28032919    else {
    2804         if (btnPtr->fsStyle & TBSTYLE_GROUP) {
     2920        if (btnPtr->fsStyle & BTNS_GROUP) {
    28052921            nOldIndex =
    28062922                TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
     
    28152931    if( bChecked != LOWORD(lParam) )
    28162932    {
    2817         if (nOldIndex != -1)
    2818         {
    2819             InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
    2820                 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
    2821         }
     2933        if (nOldIndex != -1)
     2934            InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, TRUE);
    28222935        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    28232936    }
     
    28572970    if (!(hRes = FindResourceA (COMCTL32_hModule,
    28582971                                MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
    2859                                 RT_DIALOGA)))
     2972                                (LPSTR)RT_DIALOGA)))
    28602973        return FALSE;
    28612974
     
    28873000
    28883001    if ((infoPtr->hwndToolTip) &&
    2889         !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
     3002        !(infoPtr->buttons[nIndex].fsStyle & BTNS_SEP)) {
    28903003        TTTOOLINFOA ti;
    28913004
     
    29003013    if (infoPtr->nNumButtons == 1) {
    29013014        TRACE(" simple delete!\n");
    2902         COMCTL32_Free (infoPtr->buttons);
     3015        Free (infoPtr->buttons);
    29033016        infoPtr->buttons = NULL;
    29043017        infoPtr->nNumButtons = 0;
     
    29093022
    29103023        infoPtr->nNumButtons--;
    2911         infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
     3024        infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
    29123025        if (nIndex > 0) {
    29133026            memcpy (&infoPtr->buttons[0], &oldButtons[0],
     
    29203033        }
    29213034
    2922         COMCTL32_Free (oldButtons);
     3035        Free (oldButtons);
    29233036    }
    29243037
     
    29403053
    29413054    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     3055
     3056    TRACE("hwnd=%p, btn index=%d, lParam=0x%08lx\n", hwnd, wParam, lParam);
     3057
    29423058    if (nIndex == -1)
    29433059        return FALSE;
     
    29563072    /* redraw the button only if the state of the button changed */
    29573073    if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
    2958     {
    2959         InvalidateRect(hwnd, &btnPtr->rect,
    2960             TOOLBAR_HasText(infoPtr, btnPtr));
    2961     }
     3074        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    29623075
    29633076    return TRUE;
     
    30473160
    30483161    if (!(btnPtr = &infoPtr->buttons[nIndex])) return -1;
    3049 
    3050     if (lpTbInfo->dwMask & TBIF_COMMAND)
    3051         lpTbInfo->idCommand = btnPtr->idCommand;
    3052     if (lpTbInfo->dwMask & TBIF_IMAGE)
    3053         lpTbInfo->iImage = btnPtr->iBitmap;
    3054     if (lpTbInfo->dwMask & TBIF_LPARAM)
    3055         lpTbInfo->lParam = btnPtr->dwData;
    3056     if (lpTbInfo->dwMask & TBIF_SIZE)
    3057         lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
    3058     if (lpTbInfo->dwMask & TBIF_STATE)
    3059         lpTbInfo->fsState = btnPtr->fsState;
    3060     if (lpTbInfo->dwMask & TBIF_STYLE)
    3061         lpTbInfo->fsStyle = btnPtr->fsStyle;
    3062      if (lpTbInfo->dwMask & TBIF_TEXT) {
    3063          LPWSTR lpText = TOOLBAR_GetText(infoPtr,btnPtr);
    3064          Str_GetPtrWtoA (lpText, lpTbInfo->pszText,lpTbInfo->cchText);
    3065          }
    3066     return nIndex;
    3067 }
    3068 
    3069 
    3070 static LRESULT
    3071 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
    3072 {
    3073     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
    3074     LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
    3075     TBUTTON_INFO *btnPtr;
    3076     INT nIndex;
    3077 
    3078     if (infoPtr == NULL)
    3079         return -1;
    3080     if (lpTbInfo == NULL)
    3081         return -1;
    3082     if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
    3083         return -1;
    3084 
    3085     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam,
    3086                                      lpTbInfo->dwMask & 0x80000000);
    3087     if (nIndex == -1)
    3088         return -1;
    3089 
    3090     btnPtr = &infoPtr->buttons[nIndex];
    3091 
    3092     if(!btnPtr)
    3093         return -1;
    30943162
    30953163    if (lpTbInfo->dwMask & TBIF_COMMAND)
     
    31063174        lpTbInfo->fsStyle = btnPtr->fsStyle;
    31073175    if (lpTbInfo->dwMask & TBIF_TEXT) {
    3108         LPWSTR lpText = TOOLBAR_GetText(infoPtr,btnPtr);
    3109         Str_GetPtrW (lpText,lpTbInfo->pszText,lpTbInfo->cchText);
     3176        /* TB_GETBUTTONINFO doesn't retrieve text from the string list, so we
     3177           can't use TOOLBAR_GetText here */
     3178        LPWSTR lpText;
     3179        if (HIWORD(btnPtr->iString) && (btnPtr->iString != -1)) {
     3180            lpText = (LPWSTR)btnPtr->iString;
     3181            Str_GetPtrWtoA (lpText, lpTbInfo->pszText,lpTbInfo->cchText);
     3182        } else
     3183            lpTbInfo->pszText[0] = '\0';
     3184    }
     3185    return nIndex;
     3186}
     3187
     3188
     3189static LRESULT
     3190TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
     3191{
     3192    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     3193    LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
     3194    TBUTTON_INFO *btnPtr;
     3195    INT nIndex;
     3196
     3197    if (infoPtr == NULL)
     3198        return -1;
     3199    if (lpTbInfo == NULL)
     3200        return -1;
     3201    if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
     3202        return -1;
     3203
     3204    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam,
     3205                                     lpTbInfo->dwMask & 0x80000000);
     3206    if (nIndex == -1)
     3207        return -1;
     3208
     3209    btnPtr = &infoPtr->buttons[nIndex];
     3210
     3211    if(!btnPtr)
     3212        return -1;
     3213
     3214    if (lpTbInfo->dwMask & TBIF_COMMAND)
     3215        lpTbInfo->idCommand = btnPtr->idCommand;
     3216    if (lpTbInfo->dwMask & TBIF_IMAGE)
     3217        lpTbInfo->iImage = btnPtr->iBitmap;
     3218    if (lpTbInfo->dwMask & TBIF_LPARAM)
     3219        lpTbInfo->lParam = btnPtr->dwData;
     3220    if (lpTbInfo->dwMask & TBIF_SIZE)
     3221        lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
     3222    if (lpTbInfo->dwMask & TBIF_STATE)
     3223        lpTbInfo->fsState = btnPtr->fsState;
     3224    if (lpTbInfo->dwMask & TBIF_STYLE)
     3225        lpTbInfo->fsStyle = btnPtr->fsStyle;
     3226    if (lpTbInfo->dwMask & TBIF_TEXT) {
     3227        /* TB_GETBUTTONINFO doesn't retrieve text from the string list, so we
     3228           can't use TOOLBAR_GetText here */
     3229        LPWSTR lpText;
     3230        if (HIWORD(btnPtr->iString) && (btnPtr->iString != -1)) {
     3231            lpText = (LPWSTR)btnPtr->iString;
     3232            Str_GetPtrW (lpText,lpTbInfo->pszText,lpTbInfo->cchText);
     3233        } else
     3234            lpTbInfo->pszText[0] = '\0';
    31103235    }
    31113236
     
    31733298TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
    31743299{
    3175     return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
     3300    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
     3301    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
     3302    return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), wParam);
    31763303}
    31773304
     
    31823309    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
    31833310
     3311    TRACE("\n");
     3312
    31843313    return infoPtr->dwExStyle;
    31853314}
     
    31893318TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
    31903319{
    3191     return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
     3320    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
     3321    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
     3322    return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), wParam);
    31923323}
    31933324
     
    32113342TOOLBAR_GetDefImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
    32123343{
    3213     return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), 0);
     3344    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
     3345    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
     3346    return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), wParam);
    32143347}
    32153348
     
    34323565    TBUTTON_INFO *btnPtr;
    34333566    INT nIndex;
     3567    DWORD oldState;
    34343568
    34353569    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     
    34383572
    34393573    btnPtr = &infoPtr->buttons[nIndex];
     3574    oldState = btnPtr->fsState;
    34403575    if (LOWORD(lParam) == FALSE)
    34413576        btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
     
    34433578        btnPtr->fsState |= TBSTATE_INDETERMINATE;
    34443579
    3445     InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
     3580    if(oldState != btnPtr->fsState)
     3581        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    34463582
    34473583    return TRUE;
     
    34843620              debugstr_a((LPSTR)lpTbb->iString));
    34853621        len = strlen((LPSTR)lpTbb->iString) + 2;
    3486         ptr = COMCTL32_Alloc(len);
     3622        ptr = Alloc(len);
    34873623        strcpy(ptr, (LPSTR)lpTbb->iString);
    34883624        ptr[len - 1] = 0; /* ended by two '\0' */
    34893625        lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
    3490         COMCTL32_Free(ptr);
     3626        Free(ptr);
    34913627    }
    34923628
     
    34993635    oldButtons = infoPtr->buttons;
    35003636    infoPtr->nNumButtons++;
    3501     infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
     3637    infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
    35023638    /* pre insert copy */
    35033639    if (nIndex > 0) {
     
    35193655        infoPtr->buttons[nIndex].iString   = lpTbb->iString;
    35203656
    3521     if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
     3657    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
    35223658        TTTOOLINFOA ti;
    35233659
     
    35393675    }
    35403676
    3541     COMCTL32_Free (oldButtons);
     3677    Free (oldButtons);
    35423678
    35433679    TOOLBAR_CalcToolbar (hwnd);
     
    35843720              debugstr_w((LPWSTR)lpTbb->iString));
    35853721        len = strlenW((LPWSTR)lpTbb->iString) + 2;
    3586         ptr = COMCTL32_Alloc(len*sizeof(WCHAR));
     3722        ptr = Alloc(len*sizeof(WCHAR));
    35873723        strcpyW(ptr, (LPWSTR)lpTbb->iString);
    35883724        ptr[len - 1] = 0; /* ended by two '\0' */
    35893725        lpTbb->iString = TOOLBAR_AddStringW(hwnd, 0, (LPARAM)ptr);
    3590         COMCTL32_Free(ptr);
     3726        Free(ptr);
    35913727    }
    35923728
     
    35993735    oldButtons = infoPtr->buttons;
    36003736    infoPtr->nNumButtons++;
    3601     infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
     3737    infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
    36023738    /* pre insert copy */
    36033739    if (nIndex > 0) {
     
    36193755        infoPtr->buttons[nIndex].iString   = lpTbb->iString;
    36203756
    3621     if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
     3757    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
    36223758        TTTOOLINFOW ti;
    36233759
     
    36393775    }
    36403776
    3641     COMCTL32_Free (oldButtons);
     3777    Free (oldButtons);
    36423778
    36433779    TOOLBAR_CalcToolbar (hwnd);
     
    37363872
    37373873
    3738 /* << TOOLBAR_LoadImages >> */
    3739 /* << TOOLBAR_MapAccelerator >> */
    3740 /* << TOOLBAR_MarkButton >> */
     3874static LRESULT
     3875TOOLBAR_LoadImages (HWND hwnd, WPARAM wParam, LPARAM lParam)
     3876{
     3877    TBADDBITMAP tbab;
     3878    tbab.hInst = (HINSTANCE)lParam;
     3879    tbab.nID = (UINT_PTR)wParam;
     3880
     3881    TRACE("hwnd = %p, hInst = %p, nID = %u\n", hwnd, tbab.hInst, tbab.nID);
     3882
     3883    return TOOLBAR_AddBitmap(hwnd, 0, (LPARAM)&tbab);
     3884}
     3885
     3886
     3887static LRESULT
     3888TOOLBAR_MapAccelerator (HWND hwnd, WPARAM wParam, LPARAM lParam)
     3889{
     3890    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     3891    WCHAR wAccel = (WCHAR)wParam;
     3892    UINT* pIDButton = (UINT*)lParam;
     3893    WCHAR wszAccel[] = {'&',wAccel,0};
     3894    int i;
     3895   
     3896    TRACE("hwnd = %p, wAccel = %x(%s), pIDButton = %p\n",
     3897        hwnd, wAccel, debugstr_wn(&wAccel,1), pIDButton);
     3898   
     3899    for (i = 0; i < infoPtr->nNumButtons; i++)
     3900    {
     3901        TBUTTON_INFO *btnPtr = infoPtr->buttons+i;
     3902        if (!(btnPtr->fsStyle & BTNS_NOPREFIX) &&
     3903            !(btnPtr->fsState & TBSTATE_HIDDEN))
     3904        {
     3905            int iLen = strlenW(wszAccel);
     3906            LPCWSTR lpszStr = TOOLBAR_GetText(infoPtr, btnPtr);
     3907           
     3908            if (!lpszStr)
     3909                continue;
     3910
     3911            while (*lpszStr)
     3912            {
     3913                if ((lpszStr[0] == '&') && (lpszStr[1] == '&'))
     3914                {
     3915                    lpszStr += 2;
     3916                    continue;
     3917                }
     3918                if (!strncmpiW(lpszStr, wszAccel, iLen))
     3919                {
     3920                    *pIDButton = btnPtr->idCommand;
     3921                    return TRUE;
     3922                }
     3923                lpszStr++;
     3924            }
     3925        }
     3926    }
     3927    return FALSE;
     3928}
     3929
     3930
     3931static LRESULT
     3932TOOLBAR_MarkButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
     3933{
     3934    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     3935    INT nIndex;
     3936
     3937    TRACE("hwnd = %p, wParam = %d, lParam = 0x%08lx\n", hwnd, wParam, lParam);
     3938
     3939    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     3940    if (nIndex == -1)
     3941        return FALSE;
     3942
     3943    if (LOWORD(lParam))
     3944        infoPtr->buttons[nIndex].fsState |= TBSTATE_MARKED;
     3945    else
     3946        infoPtr->buttons[nIndex].fsState &= ~TBSTATE_MARKED;
     3947
     3948    return TRUE;
     3949}
     3950
    37413951/* << TOOLBAR_MoveButton >> */
    37423952
     
    37483958    TBUTTON_INFO *btnPtr;
    37493959    INT nIndex;
     3960    DWORD oldState;
    37503961
    37513962    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
     
    37543965
    37553966    btnPtr = &infoPtr->buttons[nIndex];
     3967    oldState = btnPtr->fsState;
    37563968    if (LOWORD(lParam) == FALSE)
    37573969        btnPtr->fsState &= ~TBSTATE_PRESSED;
     
    37593971        btnPtr->fsState |= TBSTATE_PRESSED;
    37603972
    3761     InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
     3973    if(oldState != btnPtr->fsState)
     3974        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    37623975
    37633976    return TRUE;
    37643977}
    37653978
    3766 
     3979/* FIXME: there might still be some confusion her between number of buttons
     3980 * and number of bitmaps */
    37673981static LRESULT
    37683982TOOLBAR_ReplaceBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
     
    37723986    HBITMAP hBitmap;
    37733987    int i = 0, nOldButtons = 0, pos = 0;
     3988    int nOldBitmaps, nNewBitmaps;
    37743989    HIMAGELIST himlDef = 0;
    37753990
     
    38154030        return FALSE;
    38164031    }
    3817 
    3818     infoPtr->nNumBitmaps = infoPtr->nNumBitmaps - nOldButtons + lpReplace->nButtons;
     4032   
     4033    himlDef = GETDEFIMAGELIST(infoPtr, 0); /* fixme: correct? */
     4034    nOldBitmaps = ImageList_GetImageCount(himlDef);
    38194035
    38204036    /* ImageList_Replace(GETDEFIMAGELIST(), pos, hBitmap, NULL); */
    38214037
    3822 
    3823     himlDef = GETDEFIMAGELIST(infoPtr, 0);
    3824     for (i = pos + nOldButtons - 1; i >= pos; i--) {
     4038    for (i = pos + nOldBitmaps - 1; i >= pos; i--)
    38254039        ImageList_Remove(himlDef, i);
    3826     }
    38274040
    38284041    {
     
    38534066       DeleteDC (hdcBitmap);
    38544067
    3855        ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
     4068       ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace);
     4069       nNewBitmaps = ImageList_GetImageCount(himlDef);
    38564070       DeleteObject (hbmLoad);
    38574071    }
    38584072
    3859     InvalidateRect(hwnd, NULL, FALSE);
     4073    infoPtr->nNumBitmaps = infoPtr->nNumBitmaps - nOldBitmaps + nNewBitmaps;
     4074
     4075    TRACE(" pos %d  %d old bitmaps replaced by %d new ones.\n",
     4076            pos, nOldBitmaps, nNewBitmaps);
     4077
     4078    InvalidateRect(hwnd, NULL, TRUE);
    38604079
    38614080    return TRUE;
     
    41744393}
    41754394
     4395/* This function differs a bit from what MSDN says it does:
     4396 * 1. lParam contains extended style flags to OR with current style
     4397 *  (MSDN isn't clear on the OR bit)
     4398 * 2. wParam appears to contain extended style flags to be reset
     4399 *  (MSDN says that this parameter is reserved)
     4400 */
    41764401static LRESULT
    41774402TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
     
    41814406
    41824407    dwTemp = infoPtr->dwExStyle;
    4183     infoPtr->dwExStyle = (DWORD)lParam;
    4184 
    4185     if (infoPtr->dwExStyle & (TBSTYLE_EX_MIXEDBUTTONS |
    4186                               TBSTYLE_EX_HIDECLIPPEDBUTTONS)) {
    4187         FIXME("Extended style not implemented %s %s\n",
    4188               (infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ?
    4189               "TBSTYLE_EX_MIXEDBUTTONS" : "",
    4190               (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS) ?
    4191               "TBSTYLE_EX_HIDECLIPPEDBUTTONS" : "");
    4192     }
     4408    infoPtr->dwExStyle &= ~wParam;
     4409    infoPtr->dwExStyle |= (DWORD)lParam;
     4410
     4411    TRACE("new style 0x%08lx\n", infoPtr->dwExStyle);
    41934412
    41944413    if (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL)
    41954414        FIXME("Unknown Toolbar Extended Style 0x%08lx. Please report.\n",
    41964415              (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL));
     4416
     4417    TOOLBAR_CalcToolbar (hwnd);
     4418
     4419    TOOLBAR_AutoSize(hwnd);
     4420
     4421    InvalidateRect(hwnd, NULL, TRUE);
    41974422
    41984423    return (LRESULT)dwTemp;
     
    42104435    if (infoPtr->iVersion >= 5)
    42114436        id = wParam;
     4437
     4438    TRACE("hwnd = %p, himl = %p, id = %d\n", hwnd, himl, id);
    42124439
    42134440    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlHot,
     
    42384465            btnPtr = &infoPtr->buttons[(INT)wParam];
    42394466            btnPtr->bHot = TRUE;
    4240                 InvalidateRect (hwnd, &btnPtr->rect,
    4241                     TOOLBAR_HasText(infoPtr, btnPtr));
     4467                InvalidateRect (hwnd, &btnPtr->rect, TRUE);
    42424468        }
    42434469        if (nOldHotItem>=0)
     
    42454471            btnPtr = &infoPtr->buttons[nOldHotItem];
    42464472            btnPtr->bHot = FALSE;
    4247                 InvalidateRect (hwnd, &btnPtr->rect,
    4248                     TOOLBAR_HasText(infoPtr, btnPtr));
     4473                InvalidateRect (hwnd, &btnPtr->rect, TRUE);
    42494474        }
    42504475    }
     
    42814506          infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
    42824507
    4283     /* FIXME: redraw ? */
    42844508    InvalidateRect(hwnd, NULL, TRUE);
    42854509
     
    43354559    infoPtr->nMaxTextRows = (INT)wParam;
    43364560
     4561    TOOLBAR_CalcToolbar(hwnd);
    43374562    return TRUE;
    43384563}
    43394564
    43404565
     4566/* MSDN gives slightly wrong info on padding.
     4567 * 1. It is not only used on buttons with the BTNS_AUTOSIZE style
     4568 * 2. It is not used to create a blank area between the edge of the button
     4569 *    and the text or image if TBSTYLE_LIST is set. It is used to control
     4570 *    the gap between the image and text.
     4571 * 3. It is not applied to both sides. If TBSTYLE_LIST is set it is used
     4572 *    to control the bottom and right borders [with the border being
     4573 *    szPadding.cx - (GetSystemMetrics(SM_CXEDGE)+1)], otherwise the padding
     4574 *    is shared evenly on both sides of the button.
     4575 */
    43414576static LRESULT
    43424577TOOLBAR_SetPadding (HWND hwnd, WPARAM wParam, LPARAM lParam)
     
    43484583    infoPtr->szPadding.cx = LOWORD((DWORD)lParam);
    43494584    infoPtr->szPadding.cy = HIWORD((DWORD)lParam);
    4350     FIXME("stub - nothing done with values, cx=%ld, cy=%ld\n",
     4585    TRACE("cx=%ld, cy=%ld\n",
    43514586          infoPtr->szPadding.cx, infoPtr->szPadding.cy);
    43524587    return (LRESULT) oldPad;
     
    43914626
    43924627        /* repaint toolbar */
    4393         InvalidateRect(hwnd, NULL, FALSE);
     4628        InvalidateRect(hwnd, NULL, TRUE);
    43944629    }
    43954630
     
    44234658        btnPtr->fsState = LOWORD(lParam);
    44244659        TOOLBAR_CalcToolbar (hwnd);
    4425         InvalidateRect(hwnd, 0, TOOLBAR_HasText(infoPtr, btnPtr));
     4660        InvalidateRect(hwnd, 0, TRUE);
    44264661        return TRUE;
    44274662    }
     
    44314666    {
    44324667        btnPtr->fsState = LOWORD(lParam);
    4433         InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
    4434             btnPtr));
     4668        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    44354669    }
    44364670
     
    44424676TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
    44434677{
    4444     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
    4445     TBUTTON_INFO *btnPtr;
    4446     INT nIndex;
    4447 
    4448     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE);
    4449     if (nIndex == -1)
    4450         return FALSE;
    4451 
    4452     btnPtr = &infoPtr->buttons[nIndex];
    4453 
    4454     /* process style change if current style doesn't match new style */
    4455     if(btnPtr->fsStyle != LOWORD(lParam))
    4456     {
    4457         btnPtr->fsStyle = LOWORD(lParam);
    4458         InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
    4459             btnPtr));
    4460 
    4461         if (infoPtr->hwndToolTip) {
    4462             FIXME("change tool tip!\n");
    4463         }
    4464     }
     4678    SetWindowLongW(hwnd, GWL_STYLE, lParam);
    44654679
    44664680    return TRUE;
     
    44724686{
    44734687    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     4688
     4689    TRACE("hwnd=%p, hwndTooltip=%p, lParam=0x%lx\n", hwnd, (HWND)wParam, lParam);
    44744690
    44754691    if (infoPtr == NULL)
     
    45214737    infoPtr->clrBtnHighlight = lParam->clrBtnHighlight;
    45224738    infoPtr->clrBtnShadow = lParam->clrBtnShadow;
    4523     InvalidateRect(hwnd, 0, 0);
     4739    InvalidateRect(hwnd, NULL, TRUE);
    45244740    return 0;
    45254741}
     
    45404756}
    45414757
     4758
     4759static LRESULT
     4760TOOLBAR_GetStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
     4761{
     4762    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
     4763    WORD iString = HIWORD(wParam);
     4764    WORD buffersize = LOWORD(wParam);
     4765    LPSTR str = (LPSTR)lParam;
     4766    LRESULT ret = -1;
     4767
     4768    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", hwnd, iString, buffersize, str);
     4769
     4770    if (iString < infoPtr->nNumStrings)
     4771    {
     4772        ret = WideCharToMultiByte(CP_ACP, 0, infoPtr->strings[iString], -1, str, buffersize, NULL, NULL);
     4773
     4774        TRACE("returning %s\n", debugstr_a(str));
     4775    }
     4776    else
     4777        ERR("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);
     4778
     4779    return ret;
     4780}
     4781
     4782
     4783static LRESULT
     4784TOOLBAR_GetStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
     4785{
     4786    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
     4787    WORD iString = HIWORD(wParam);
     4788    WORD len = LOWORD(wParam)/sizeof(WCHAR) - 1;
     4789    LPWSTR str = (LPWSTR)lParam;
     4790    LRESULT ret = -1;
     4791
     4792    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", hwnd, iString, LOWORD(wParam), str);
     4793
     4794    if (iString < infoPtr->nNumStrings)
     4795    {
     4796        len = min(len, strlenW(infoPtr->strings[iString]));
     4797        ret = (len+1)*sizeof(WCHAR);
     4798        memcpy(str, infoPtr->strings[iString], ret);
     4799        str[len] = '\0';
     4800
     4801        TRACE("returning %s\n", debugstr_w(str));
     4802    }
     4803    else
     4804        ERR("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);
     4805
     4806    return ret;
     4807}
     4808
     4809/* UNDOCUMENTED MESSAGE: This appears to set some kind of size. Perhaps it
     4810 * is the maximum size of the toolbar? */
     4811static LRESULT TOOLBAR_Unkwn45D(HWND hwnd, WPARAM wParam, LPARAM lParam)
     4812{
     4813    SIZE * pSize = (SIZE*)lParam;
     4814    FIXME("hwnd=%p, wParam=0x%08x, size.cx=%ld, size.cy=%ld stub!\n", hwnd, wParam, pSize->cx, pSize->cy);
     4815    return 0;
     4816}
    45424817
    45434818/*********************************************************************/
     
    45744849        btnPtr = &infoPtr->buttons[(INT)wParam];
    45754850        btnPtr->bHot = (no_hi) ? FALSE : TRUE;
    4576         InvalidateRect (hwnd, &btnPtr->rect,
    4577                         TOOLBAR_HasText(infoPtr, btnPtr));
     4851        InvalidateRect (hwnd, &btnPtr->rect, TRUE);
    45784852    }
    45794853    if (nOldHotItem>=0) {
    45804854        btnPtr = &infoPtr->buttons[nOldHotItem];
    45814855        btnPtr->bHot = FALSE;
    4582         InvalidateRect (hwnd, &btnPtr->rect,
    4583                         TOOLBAR_HasText(infoPtr, btnPtr));
     4856        InvalidateRect (hwnd, &btnPtr->rect, TRUE);
    45844857    }
    45854858    GetFocus();
     
    45934866}
    45944867
     4868/* UNDOCUMENTED MESSAGE: This sets the toolbar global iListGap parameter
     4869 * which controls the amount of spacing between the image and the text
     4870 * of buttons for TBSTYLE_LIST toolbars. */
     4871static LRESULT TOOLBAR_Unkwn460(HWND hwnd, WPARAM wParam, LPARAM lParam)
     4872{
     4873    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
     4874
     4875    TRACE("hwnd=%p iListGap=%d\n", hwnd, wParam);
     4876   
     4877    if (lParam != 0)
     4878        FIXME("lParam = 0x%08lx. Please report\n", lParam);
     4879   
     4880    infoPtr->iListGap = (INT)wParam;
     4881
     4882    TOOLBAR_CalcToolbar(hwnd);
     4883    InvalidateRect(hwnd, NULL, TRUE);
     4884
     4885    return 0;
     4886}
     4887
     4888/* UNDOCUMENTED MESSAGE: This returns the number of maximum number
     4889 * of image lists associated with the various states. */
     4890static LRESULT TOOLBAR_Unkwn462(HWND hwnd, WPARAM wParam, LPARAM lParam)
     4891{
     4892    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
     4893
     4894    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
     4895
     4896    return max(infoPtr->cimlDef, max(infoPtr->cimlHot, infoPtr->cimlDis));
     4897}
    45954898
    45964899static LRESULT
     
    46234926            HWND hwndParent = GetParent(hwnd);
    46244927
    4625             InvalidateRect(hwnd, 0, 1);
    46264928            GetWindowRect(hwnd, &rc);
    46274929            MapWindowPoints(0, hwndParent, (LPPOINT)&rc, 2);
     
    46494951}
    46504952
     4953static LRESULT TOOLBAR_Unkwn464(HWND hwnd, WPARAM wParam, LPARAM lParam)
     4954{
     4955    FIXME("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
     4956
     4957    InvalidateRect(hwnd, NULL, TRUE);
     4958    return 1;
     4959}
     4960
    46514961
    46524962static LRESULT
     
    46564966    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    46574967    LOGFONTA logFont;
     4968
     4969    TRACE("hwnd = %p\n", hwnd);
    46584970
    46594971    /* initialize info structure */
     
    46644976
    46654977    infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
    4666     infoPtr->nRows = 1;
    46674978    infoPtr->nMaxTextRows = 1;
    46684979    infoPtr->cxMin = -1;
     
    46764987    infoPtr->nOldHit = -1;
    46774988    infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
    4678     infoPtr->hwndNotify = GetParent (hwnd);
     4989    infoPtr->hwndNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
    46794990    infoPtr->bTransparent = (dwStyle & TBSTYLE_TRANSPARENT);
    46804991    infoPtr->bBtnTranspnt = (dwStyle & (TBSTYLE_FLAT | TBSTYLE_LIST));
     
    46864997    infoPtr->clrBtnHighlight = CLR_DEFAULT;
    46874998    infoPtr->clrBtnShadow = CLR_DEFAULT;
    4688     infoPtr->szPadding.cx = 7;
    4689     infoPtr->szPadding.cy = 6;
     4999    /* not sure where the +1 comes from, but this comes to the same value
     5000     * as native so this is probably correct */
     5001    infoPtr->szPadding.cx = 2*(GetSystemMetrics(SM_CXEDGE)+OFFSET_X) + 1;
     5002    infoPtr->szPadding.cy = 2*(GetSystemMetrics(SM_CYEDGE)+OFFSET_Y);
     5003    infoPtr->iListGap = infoPtr->szPadding.cx / 2;
     5004    GetClientRect(hwnd, &infoPtr->client_rect);
    46905005    TOOLBAR_NotifyFormat(infoPtr, (WPARAM)hwnd, (LPARAM)NF_REQUERY);
    46915006
     
    47295044        DestroyWindow (infoPtr->hwndToolTip);
    47305045
     5046    /* delete temporary buffer for tooltip text */
     5047    if (infoPtr->pszTooltipText)
     5048        HeapFree(GetProcessHeap(), 0, infoPtr->pszTooltipText);
     5049
    47315050    /* delete button data */
    47325051    if (infoPtr->buttons)
    4733         COMCTL32_Free (infoPtr->buttons);
     5052        Free (infoPtr->buttons);
    47345053
    47355054    /* delete strings */
     
    47385057        for (i = 0; i < infoPtr->nNumStrings; i++)
    47395058            if (infoPtr->strings[i])
    4740                 COMCTL32_Free (infoPtr->strings[i]);
    4741 
    4742         COMCTL32_Free (infoPtr->strings);
     5059                Free (infoPtr->strings[i]);
     5060
     5061        Free (infoPtr->strings);
    47435062    }
    47445063
     
    47565075
    47575076    /* free toolbar info data */
    4758     COMCTL32_Free (infoPtr);
     5077    Free (infoPtr);
    47595078    SetWindowLongA (hwnd, 0, 0);
    47605079
     
    48645183        btnPtr->fsState |= TBSTATE_PRESSED;
    48655184
    4866         InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
    4867             btnPtr));
     5185        InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    48685186    }
    48695187    else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
     
    49005218
    49015219        /* for EX_DRAWDDARROWS style,  click must be in the drop-down arrow rect */
    4902         if ((btnPtr->fsState & TBSTATE_ENABLED) && (btnPtr->fsStyle & TBSTYLE_DROPDOWN) &&
    4903              ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) ||
    4904               (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle))))
     5220        if ((btnPtr->fsState & TBSTATE_ENABLED) &&
     5221             ((btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) ||
     5222              ((btnPtr->fsStyle & BTNS_DROPDOWN) &&
     5223               ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) ||
     5224               (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle))))))
    49055225        {
    49065226            LRESULT res;
     
    49165236            nmtb.cchText = 0;
    49175237            nmtb.pszText = 0;
    4918             memset(&nmtb.rcButton, 0, sizeof(RECT));
     5238            CopyRect(&nmtb.rcButton, &btnPtr->rect);
    49195239            res = TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
    49205240                                  TBN_DROPDOWN);
     
    49325252
    49335253        if (btnPtr->fsState & TBSTATE_ENABLED)
    4934             InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
     5254            InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    49355255        UpdateWindow(hwnd);
    49365256        SetCapture (hwnd);
     
    49795299        infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
    49805300
     5301    if (0 <= infoPtr->nButtonDown) {
    49815302        btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
    49825303        btnPtr->fsState &= ~TBSTATE_PRESSED;
    49835304
    4984         if (btnPtr->fsStyle & TBSTYLE_CHECK) {
    4985                 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
     5305        if (btnPtr->fsStyle & BTNS_CHECK) {
     5306                if (btnPtr->fsStyle & BTNS_GROUP) {
    49865307                    nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
    49875308                        nHit);
     
    50015322        }
    50025323
    5003         if (nOldIndex != -1)
    5004         {
    5005             InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
    5006                 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
    5007         }
     5324        if (nOldIndex != -1)
     5325            InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, TRUE);
    50085326
    50095327        /*
     
    50485366            TOOLBAR_SendNotify ((NMHDR *) &nmmouse, infoPtr, NM_CLICK);
    50495367        }
     5368    }
    50505369    return 0;
    50515370}
     
    50675386
    50685387        if (btnPtr->fsState & TBSTATE_ENABLED)
    5069             InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
    5070               btnPtr));
     5388            InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    50715389    }
    50725390    return 0;
     
    50925410        rc1 = hotBtnPtr->rect;
    50935411        InflateRect (&rc1, 1, 1);
    5094         InvalidateRect (hwnd, &rc1, TOOLBAR_HasText(infoPtr,
    5095             hotBtnPtr));
     5412        InvalidateRect (hwnd, &rc1, TRUE);
    50965413    }
    50975414
     
    51545471    if (infoPtr->nOldHit != nHit)
    51555472    {
    5156         /* Remove the effect of an old hot button if the button was enabled and was
     5473        /* Remove the effect of an old hot button if the button was
    51575474           drawn with the hot button effect */
    5158         if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
    5159                 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
     5475        if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem)
    51605476        {
    51615477            oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
     
    51705486            infoPtr->nHotItem = nHit;
    51715487
    5172             /* only enabled buttons show hot effect */
    5173             if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
    5174             {
    5175                 btnPtr->bHot = TRUE;
    5176             }
     5488            btnPtr->bHot = TRUE;
    51775489        }
    51785490
     
    51905502        /* now invalidate the old and new buttons so they will be painted */
    51915503        if (oldBtnPtr)
    5192             InvalidateRect (hwnd, &oldBtnPtr->rect,
    5193                             TOOLBAR_HasText(infoPtr, oldBtnPtr));
    5194         if (btnPtr && (btnPtr->fsState & TBSTATE_ENABLED))
    5195             InvalidateRect(hwnd, &btnPtr->rect,
    5196                            TOOLBAR_HasText(infoPtr, btnPtr));
     5504            InvalidateRect (hwnd, &oldBtnPtr->rect, TRUE);
     5505        if (btnPtr)
     5506            InvalidateRect(hwnd, &btnPtr->rect, TRUE);
    51975507
    51985508        if (infoPtr->bCaptured) {
     
    52415551
    52425552    /* allocate memory for info structure */
    5243     infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
     5553    infoPtr = (TOOLBAR_INFO *)Alloc (sizeof(TOOLBAR_INFO));
    52445554    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
    52455555
    52465556    /* paranoid!! */
    52475557    infoPtr->dwStructSize = sizeof(TBBUTTON);
     5558    infoPtr->nRows = 1;
    52485559
    52495560    /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
     
    53395650
    53405651
     5652/* handles requests from the tooltip control on what text to display */
     5653static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnmtdi)
     5654{
     5655    int index = TOOLBAR_GetButtonIndex(infoPtr, lpnmtdi->hdr.idFrom, FALSE);
     5656
     5657    TRACE("button index = %d\n", index);
     5658
     5659    if (infoPtr->pszTooltipText)
     5660    {
     5661        HeapFree(GetProcessHeap(), 0, infoPtr->pszTooltipText);
     5662        infoPtr->pszTooltipText = NULL;
     5663    }
     5664
     5665    if (index < 0)
     5666        return 0;
     5667
     5668    if (infoPtr->bNtfUnicode)
     5669    {
     5670        WCHAR wszBuffer[INFOTIPSIZE+1];
     5671        NMTBGETINFOTIPW tbgit;
     5672        int len; /* in chars */
     5673
     5674        wszBuffer[0] = '\0';
     5675        wszBuffer[INFOTIPSIZE] = '\0';
     5676
     5677        tbgit.pszText = wszBuffer;
     5678        tbgit.cchTextMax = INFOTIPSIZE;
     5679        tbgit.iItem = lpnmtdi->hdr.idFrom;
     5680        tbgit.lParam = infoPtr->buttons[index].dwData;
     5681
     5682        TOOLBAR_SendNotify(&tbgit.hdr, infoPtr, TBN_GETINFOTIPW);
     5683
     5684        TRACE("TBN_GETINFOTIPW - got string %s\n", debugstr_w(tbgit.pszText));
     5685
     5686        len = strlenW(tbgit.pszText);
     5687        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
     5688        {
     5689            /* need to allocate temporary buffer in infoPtr as there
     5690             * isn't enough space in buffer passed to us by the
     5691             * tooltip control */
     5692            infoPtr->pszTooltipText = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
     5693            if (infoPtr->pszTooltipText)
     5694            {
     5695                memcpy(infoPtr->pszTooltipText, tbgit.pszText, (len+1)*sizeof(WCHAR));
     5696                lpnmtdi->lpszText = infoPtr->pszTooltipText;
     5697                return 0;
     5698            }
     5699        }
     5700        else if (len > 0)
     5701        {
     5702            memcpy(lpnmtdi->lpszText, tbgit.pszText, (len+1)*sizeof(WCHAR));
     5703            return 0;
     5704        }
     5705    }
     5706    else
     5707    {
     5708        CHAR szBuffer[INFOTIPSIZE+1];
     5709        NMTBGETINFOTIPA tbgit;
     5710        int len; /* in chars */
     5711
     5712        szBuffer[0] = '\0';
     5713        szBuffer[INFOTIPSIZE] = '\0';
     5714
     5715        tbgit.pszText = szBuffer;
     5716        tbgit.cchTextMax = INFOTIPSIZE;
     5717        tbgit.iItem = lpnmtdi->hdr.idFrom;
     5718        tbgit.lParam = infoPtr->buttons[index].dwData;
     5719
     5720        TOOLBAR_SendNotify(&tbgit.hdr, infoPtr, TBN_GETINFOTIPA);
     5721
     5722        TRACE("TBN_GETINFOTIPA - got string %s\n", debugstr_a(tbgit.pszText));
     5723
     5724        len = -1 + MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, NULL, 0);
     5725        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
     5726        {
     5727            /* need to allocate temporary buffer in infoPtr as there
     5728             * isn't enough space in buffer passed to us by the
     5729             * tooltip control */
     5730            infoPtr->pszTooltipText = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
     5731            if (infoPtr->pszTooltipText)
     5732            {
     5733                MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, len+1, infoPtr->pszTooltipText, (len+1)*sizeof(WCHAR));
     5734                lpnmtdi->lpszText = infoPtr->pszTooltipText;
     5735                return 0;
     5736            }
     5737        }
     5738        else if (len > 0)
     5739        {
     5740            MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, len+1, lpnmtdi->lpszText, (len+1)*sizeof(WCHAR));
     5741            return 0;
     5742        }
     5743    }
     5744
     5745    /* if button has text, but it is not shown then automatically
     5746     * use that text as tooltip */
     5747    if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) &&
     5748        !(infoPtr->buttons[index].fsStyle & BTNS_SHOWTEXT))
     5749    {
     5750        LPWSTR pszText = TOOLBAR_GetText(infoPtr, &infoPtr->buttons[index]);
     5751        int len = pszText ? strlenW(pszText) : 0;
     5752
     5753        TRACE("using button hidden text %s\n", debugstr_w(pszText));
     5754
     5755        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
     5756        {
     5757            /* need to allocate temporary buffer in infoPtr as there
     5758             * isn't enough space in buffer passed to us by the
     5759             * tooltip control */
     5760            infoPtr->pszTooltipText = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
     5761            if (infoPtr->pszTooltipText)
     5762            {
     5763                memcpy(infoPtr->pszTooltipText, pszText, (len+1)*sizeof(WCHAR));
     5764                lpnmtdi->lpszText = infoPtr->pszTooltipText;
     5765                return 0;
     5766            }
     5767        }
     5768        else if (len > 0)
     5769        {
     5770            memcpy(lpnmtdi->lpszText, pszText, (len+1)*sizeof(WCHAR));
     5771            return 0;
     5772        }
     5773    }
     5774
     5775    TRACE("Sending tooltip notification to %p\n", infoPtr->hwndNotify);
     5776
     5777    /* last resort: send notification on to app */
     5778    /* FIXME: find out what is really used here */
     5779    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, 0, (LPARAM)lpnmtdi);
     5780}
     5781
     5782
    53415783inline static LRESULT
    53425784TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
     
    53455787    LPNMHDR lpnmh = (LPNMHDR)lParam;
    53465788
    5347     if (lpnmh->code == PGN_CALCSIZE) {
    5348         LPNMPGCALCSIZE lppgc = (LPNMPGCALCSIZE)lParam;
    5349 
    5350         if (lppgc->dwFlag == PGF_CALCWIDTH) {
    5351             lppgc->iWidth = infoPtr->rcBound.right - infoPtr->rcBound.left;
    5352             TRACE("processed PGN_CALCSIZE, returning horz size = %d\n",
    5353                   lppgc->iWidth);
    5354         }
    5355         else {
    5356             lppgc->iHeight = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
    5357             TRACE("processed PGN_CALCSIZE, returning vert size = %d\n",
    5358                   lppgc->iHeight);
    5359         }
    5360         return 0;
    5361     }
    5362 
    5363     if (lpnmh->code == PGN_SCROLL) {
    5364         LPNMPGSCROLL lppgs = (LPNMPGSCROLL)lParam;
    5365 
    5366         lppgs->iScroll = (lppgs->iDir & (PGF_SCROLLLEFT | PGF_SCROLLRIGHT)) ?
    5367                           infoPtr->nButtonWidth : infoPtr->nButtonHeight;
    5368         TRACE("processed PGN_SCROLL, returning scroll=%d, dir=%d\n",
    5369               lppgs->iScroll, lppgs->iDir);
    5370         return 0;
    5371     }
    5372 
    5373 
    5374     TRACE("passing WM_NOTIFY!\n");
    5375 
    5376     if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
    5377         if (infoPtr->bNtfUnicode)
    5378             return SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
    5379                                  wParam, lParam);
    5380         else
    5381             return SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
    5382                                  wParam, lParam);
    5383 
    5384 #if 0
    5385         if (lpnmh->code == TTN_GETDISPINFOA) {
    5386             LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
    5387 
    5388             FIXME("retrieving ASCII string\n");
    5389 
    5390         }
    5391         else if (lpnmh->code == TTN_GETDISPINFOW) {
    5392             LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
    5393 
    5394             FIXME("retrieving UNICODE string\n");
    5395 
    5396         }
    5397 #endif
    5398     }
    5399 
    5400     return 0;
     5789    switch (lpnmh->code)
     5790    {
     5791    case PGN_CALCSIZE:
     5792    {
     5793        LPNMPGCALCSIZE lppgc = (LPNMPGCALCSIZE)lParam;
     5794
     5795        if (lppgc->dwFlag == PGF_CALCWIDTH) {
     5796            lppgc->iWidth = infoPtr->rcBound.right - infoPtr->rcBound.left;
     5797            TRACE("processed PGN_CALCSIZE, returning horz size = %d\n",
     5798                  lppgc->iWidth);
     5799        }
     5800        else {
     5801            lppgc->iHeight = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
     5802            TRACE("processed PGN_CALCSIZE, returning vert size = %d\n",
     5803                  lppgc->iHeight);
     5804        }
     5805        return 0;
     5806    }
     5807
     5808    case PGN_SCROLL:
     5809    {
     5810        LPNMPGSCROLL lppgs = (LPNMPGSCROLL)lParam;
     5811
     5812        lppgs->iScroll = (lppgs->iDir & (PGF_SCROLLLEFT | PGF_SCROLLRIGHT)) ?
     5813                          infoPtr->nButtonWidth : infoPtr->nButtonHeight;
     5814        TRACE("processed PGN_SCROLL, returning scroll=%d, dir=%d\n",
     5815              lppgs->iScroll, lppgs->iDir);
     5816        return 0;
     5817    }
     5818
     5819    case TTN_GETDISPINFOW:
     5820        return TOOLBAR_TTGetDispInfo(infoPtr, (LPNMTTDISPINFOW)lParam);
     5821
     5822    case TTN_GETDISPINFOA:
     5823        FIXME("TTN_GETDISPINFOA - stub\n");
     5824        return 0;
     5825
     5826    default:
     5827        return 0;
     5828    }
    54015829}
    54025830
     
    54185846    INT i;
    54195847
     5848    TRACE("wParam = 0x%x, lParam = 0x%08lx\n", wParam, lParam);
     5849
     5850    if ((lParam == NF_QUERY) && ((HWND)wParam == infoPtr->hwndToolTip))
     5851        return NFR_UNICODE;
     5852
    54205853    if (lParam == NF_REQUERY) {
    5421         i = SendMessageA(GetParent(infoPtr->hwndSelf),
     5854        i = SendMessageA(infoPtr->hwndNotify,
    54225855                         WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
    54235856        if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
     
    54675900      *  *previous* status of the redraw flag (either 0 or 1)
    54685901      *  instead of the MSDN documented value of 0 if handled.
    5469       *  (For laughs see the "consistancy" with same function
     5902      *  (For laughs see the "consistency" with same function
    54705903      *   in rebar.)
    54715904      *
     
    55425975            cx = infoPtr->nWidth;
    55435976
    5544             if (dwStyle & CCS_NOMOVEY) {
     5977            if ((dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) {
    55455978                GetWindowRect(hwnd, &window_rect);
    55465979                ScreenToClient(parent, (LPPOINT)&window_rect.left);
    5547                 y = window_rect.top;
     5980                y = window_rect.top;
    55485981            }
     5982            if ((dwStyle & CCS_BOTTOM) == CCS_BOTTOM) {
     5983                GetWindowRect(hwnd, &window_rect);
     5984                y = parent_rect.bottom -
     5985                    ( window_rect.bottom - window_rect.top);
     5986            }
    55495987        }
    55505988
     
    55656003        }
    55666004
    5567         SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
    5568                         cx, cy, uPosFlags | SWP_NOZORDER);
    5569     }
     6005        if(infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
     6006        {
     6007            RECT delta_width, delta_height, client, dummy;
     6008            DWORD min_x, max_x, min_y, max_y;
     6009            TBUTTON_INFO *btnPtr;
     6010            INT i;
     6011
     6012            GetClientRect(hwnd, &client);
     6013            if(client.right > infoPtr->client_rect.right)
     6014            {
     6015                min_x = infoPtr->client_rect.right;
     6016                max_x = client.right;
     6017            }
     6018            else
     6019            {
     6020                max_x = infoPtr->client_rect.right;
     6021                min_x = client.right;
     6022            }
     6023            if(client.bottom > infoPtr->client_rect.bottom)
     6024            {
     6025                min_y = infoPtr->client_rect.bottom;
     6026                max_y = client.bottom;
     6027            }
     6028            else
     6029            {
     6030                max_y = infoPtr->client_rect.bottom;
     6031                min_y = client.bottom;
     6032            }
     6033
     6034            SetRect(&delta_width, min_x, 0, max_x, min_y);
     6035            SetRect(&delta_height, 0, min_y, max_x, max_y);
     6036
     6037            TRACE("delta_width %s delta_height %s\n", wine_dbgstr_rect(&delta_width), wine_dbgstr_rect(&delta_height));
     6038            btnPtr = infoPtr->buttons;
     6039            for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
     6040                if(IntersectRect(&dummy, &delta_width, &btnPtr->rect) ||
     6041                   IntersectRect(&dummy, &delta_height, &btnPtr->rect))
     6042                    InvalidateRect(hwnd, &btnPtr->rect, TRUE);
     6043        }
     6044
     6045        if((uPosFlags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
     6046            SetWindowPos (hwnd, 0,  x,  y, cx, cy, uPosFlags | SWP_NOZORDER);
     6047    }
     6048    GetClientRect(hwnd, &infoPtr->client_rect);
    55706049    return 0;
    55716050}
     
    55886067                                 (TBSTYLE_FLAT | TBSTYLE_LIST));
    55896068        TOOLBAR_CheckStyle (hwnd, lpStyle->styleNew);
    5590     }
     6069
     6070        TRACE("new style 0x%08lx\n", lpStyle->styleNew);
     6071    }
     6072
     6073    TOOLBAR_CalcToolbar(hwnd);
    55916074
    55926075    TOOLBAR_AutoSize (hwnd);
    55936076
    5594     InvalidateRect(hwnd, NULL, FALSE);
     6077    InvalidateRect(hwnd, NULL, TRUE);
    55956078
    55966079    return 0;
     
    56116094ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    56126095{
     6096    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     6097
    56136098    TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n",
    56146099          hwnd, uMsg, /* SPY_GetMsgName(uMsg), */ wParam, lParam);
     
    57266211            return TOOLBAR_GetState (hwnd, wParam, lParam);
    57276212
     6213        case TB_GETSTRINGA:
     6214        return TOOLBAR_GetStringA (hwnd, wParam, lParam);
     6215
     6216        case TB_GETSTRINGW:
     6217            return TOOLBAR_GetStringW (hwnd, wParam, lParam);
     6218
    57286219        case TB_GETSTYLE:
    57296220            return TOOLBAR_GetStyle (hwnd, wParam, lParam);
     
    57736264            return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
    57746265
    5775         case TB_LOADIMAGES:                        /* 4.70 */
    5776             FIXME("missing standard imagelists\n");
    5777             return 0;
    5778 
    5779 /*      case TB_MAPACCELERATORA:                */ /* 4.71 */
    5780 /*      case TB_MAPACCELERATORW:                */ /* 4.71 */
    5781 /*      case TB_MARKBUTTON:                     */ /* 4.71 */
     6266        case TB_LOADIMAGES:
     6267            return TOOLBAR_LoadImages (hwnd, wParam, lParam);
     6268
     6269        case TB_MAPACCELERATORA:
     6270        case TB_MAPACCELERATORW:
     6271            return TOOLBAR_MapAccelerator (hwnd, wParam, lParam);
     6272
     6273        case TB_MARKBUTTON:
     6274            return TOOLBAR_MarkButton (hwnd, wParam, lParam);
     6275
    57826276/*      case TB_MOVEBUTTON:                     */ /* 4.71 */
    57836277
     
    58656359            return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
    58666360
     6361        case TB_UNKWN45D:
     6362            return TOOLBAR_Unkwn45D(hwnd, wParam, lParam);
     6363
    58676364        case TB_UNKWN45E:
    58686365            return TOOLBAR_Unkwn45E (hwnd, wParam, lParam);
    58696366
     6367        case TB_UNKWN460:
     6368            return TOOLBAR_Unkwn460(hwnd, wParam, lParam);
     6369
     6370        case TB_UNKWN462:
     6371            return TOOLBAR_Unkwn462(hwnd, wParam, lParam);
     6372
    58706373        case TB_UNKWN463:
    58716374            return TOOLBAR_Unkwn463 (hwnd, wParam, lParam);
    58726375
     6376        case TB_UNKWN464:
     6377            return TOOLBAR_Unkwn464(hwnd, wParam, lParam);
    58736378
    58746379/* Common Control Messages */
     
    59406445
    59416446        case WM_NOTIFYFORMAT:
    5942             TOOLBAR_NotifyFormatFake (hwnd, wParam, lParam);
     6447            return TOOLBAR_NotifyFormatFake (hwnd, wParam, lParam);
    59436448
    59446449        case WM_PAINT:
     
    59646469        case WM_MEASUREITEM:
    59656470        case WM_VKEYTOITEM:
    5966             {
    5967                 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
    5968                 if(infoPtr != NULL)
    5969                     return SendMessageA (infoPtr->hwndNotify, uMsg, wParam, lParam);
    5970                 else
    5971                     return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
    5972             }
     6471            return SendMessageA (infoPtr->hwndNotify, uMsg, wParam, lParam);
    59736472
    59746473        /* We see this in Outlook Express 5.x and just does DefWindowProc */
     
    59966495    wndClass.cbClsExtra    = 0;
    59976496    wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
    5998     wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
     6497    wndClass.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROWA);
    59996498    wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
    60006499    wndClass.lpszClassName = TOOLBARCLASSNAMEA;
     
    60236522        PIMLENTRY *pnies;
    60246523
    6025         c = (PIMLENTRY) COMCTL32_Alloc(sizeof(IMLENTRY));
     6524        c = (PIMLENTRY) Alloc(sizeof(IMLENTRY));
    60266525        c->id = id;
    60276526
    6028         pnies = COMCTL32_Alloc((*cies + 1) * sizeof(PIMLENTRY));
     6527        pnies = Alloc((*cies + 1) * sizeof(PIMLENTRY));
    60296528        memcpy(pnies, *pies, ((*cies) * sizeof(PIMLENTRY)));
    60306529        pnies[*cies] = c;
    60316530        (*cies)++;
    60326531
    6033         COMCTL32_Free(*pies);
     6532        Free(*pies);
    60346533        *pies = pnies;
    60356534    }
     
    60476546
    60486547    for (i = 0; i < *cies; i++)
    6049         COMCTL32_Free((*pies)[i]);
    6050 
    6051     COMCTL32_Free(*pies);
     6548        Free((*pies)[i]);
     6549
     6550    Free(*pies);
    60526551
    60536552    *cies = 0;
Note: See TracChangeset for help on using the changeset viewer.