/*
 * Toolbar control
 *
 * Copyright 1998,1999 Eric Kohl
 * Copyright 2000 Eric Kohl for CodeWeavers
 * Copyright 2004 Robert Shearman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES
 *
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on Mar. 14, 2004, by Robert Shearman.
 * 
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features or bugs please note them below.
 * 
 * TODO:
 *   - Styles:
 *     - TBSTYLE_REGISTERDROP
 *     - TBSTYLE_EX_DOUBLEBUFFER
 *   - Messages:
 *     - TB_GETMETRICS
 *     - TB_GETOBJECT
 *     - TB_INSERTMARKHITTEST
 *     - TB_SAVERESTORE
 *     - TB_SETMETRICS
 *     - WM_WININICHANGE
 *   - Notifications:
 *     - NM_CHAR
 *     - TBN_GETOBJECT
 *     - TBN_SAVE
 *   - Button wrapping (under construction).
 *   - Fix TB_SETROWS and Separators.
 *   - iListGap custom draw support.
 *
 * Testing:
 *   - Run tests using Waite Group Windows95 API Bible Volume 2.
 *     The second cdrom contains executables addstr.exe, btncount.exe,
 *     btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
 *     enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
 *     indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
 *     setparnt.exe, setrows.exe, toolwnd.exe.
 *   - Microsoft's controlspy examples.
 *   - Charles Petzold's 'Programming Windows': gadgets.exe
 *
 *  Differences between MSDN and actual native control operation:
 *   1. MSDN says: "TBSTYLE_LIST: Creates a flat toolbar with button text
 *                  to the right of the bitmap. Otherwise, this style is
 *                  identical to TBSTYLE_FLAT."
 *      As implemented by both v4.71 and v5.80 of the native COMCTL32.DLL
 *      you can create a TBSTYLE_LIST without TBSTYLE_FLAT and the result
 *      is non-flat non-transparent buttons. Therefore TBSTYLE_LIST does
 *      *not* imply TBSTYLE_FLAT as documented.  (GA 8/2001)
 *
 */

#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "uxtheme.h"
#include "vssym32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(toolbar);

static HCURSOR hCursorDrag = NULL;

typedef struct
{
    INT iBitmap;
    INT idCommand;
    BYTE  fsState;
    BYTE  fsStyle;
    BOOL  bHot;
    BOOL  bDropDownPressed;
    DWORD_PTR dwData;
    INT_PTR iString;
    INT nRow;
    RECT rect;
    INT cx; /* manually set size */
} TBUTTON_INFO;

typedef struct
{
    UINT nButtons;
    HINSTANCE hInst;
    UINT nID;
} TBITMAP_INFO;

typedef struct
{
    HIMAGELIST himl;
    INT id;
} IMLENTRY, *PIMLENTRY;

typedef struct
{
    DWORD    dwStructSize;    /* size of TBBUTTON struct */
    RECT     client_rect;
    RECT     rcBound;         /* bounding rectangle */
    INT      nButtonHeight;
    INT      nButtonWidth;
    INT      nBitmapHeight;
    INT      nBitmapWidth;
    INT      nIndent;
    INT      nRows;           /* number of button rows */
    INT      nMaxTextRows;    /* maximum number of text rows */
    INT      cxMin;           /* minimum button width */
    INT      cxMax;           /* maximum button width */
    INT      nNumButtons;     /* number of buttons */
    INT      nNumBitmaps;     /* number of bitmaps */
    INT      nNumStrings;     /* number of strings */
    INT      nNumBitmapInfos;
    INT      nButtonDown;     /* toolbar button being pressed or -1 if none */
    INT      nButtonDrag;     /* toolbar button being dragged or -1 if none */
    INT      nOldHit;
    INT      nHotItem;        /* index of the "hot" item */
    SIZE     szPadding;       /* padding values around button */
    INT      iTopMargin;      /* the top margin */
    INT      iListGap;        /* default gap between text and image for toolbar with list style */
    HFONT    hDefaultFont;
    HFONT    hFont;           /* text font */
    HIMAGELIST himlInt;       /* image list created internally */
    PIMLENTRY *himlDef;       /* default image list array */
    INT       cimlDef;        /* default image list array count */
    PIMLENTRY *himlHot;       /* hot image list array */
    INT       cimlHot;        /* hot image list array count */
    PIMLENTRY *himlDis;       /* disabled image list array */
    INT       cimlDis;        /* disabled image list array count */
    HWND     hwndToolTip;     /* handle to tool tip control */
    HWND     hwndNotify;      /* handle to the window that gets notifications */
    HWND     hwndSelf;        /* my own handle */
    BOOL     bAnchor;         /* anchor highlight enabled */
    BOOL     bDoRedraw;       /* Redraw status */
    BOOL     bDragOutSent;    /* has TBN_DRAGOUT notification been sent for this drag? */
    BOOL     bUnicode;        /* Notifications are ASCII (FALSE) or Unicode (TRUE)? */
    BOOL     bCaptured;       /* mouse captured? */
    DWORD      dwStyle;       /* regular toolbar style */
    DWORD      dwExStyle;     /* extended toolbar style */
    DWORD      dwDTFlags;     /* DrawText flags */

    COLORREF   clrInsertMark;   /* insert mark color */
    COLORREF   clrBtnHighlight; /* color for Flat Separator */
    COLORREF   clrBtnShadow;    /* color for Flag Separator */
    INT      iVersion;
    LPWSTR   pszTooltipText;    /* temporary store for a string > 80 characters
                                 * for TTN_GETDISPINFOW notification */
    TBINSERTMARK  tbim;         /* info on insertion mark */
    TBUTTON_INFO *buttons;      /* pointer to button array */
    LPWSTR       *strings;      /* pointer to string array */
    TBITMAP_INFO *bitmaps;
} TOOLBAR_INFO, *PTOOLBAR_INFO;


/* used by customization dialog */
typedef struct
{
    PTOOLBAR_INFO tbInfo;
    HWND          tbHwnd;
} CUSTDLG_INFO, *PCUSTDLG_INFO;

typedef struct
{
    TBBUTTON btn;
    BOOL     bVirtual;
    BOOL     bRemovable;
    WCHAR    text[64];
} CUSTOMBUTTON, *PCUSTOMBUTTON;

typedef enum
{
    IMAGE_LIST_DEFAULT,
    IMAGE_LIST_HOT,
    IMAGE_LIST_DISABLED
} IMAGE_LIST_TYPE;

#define SEPARATOR_WIDTH    8
#define TOP_BORDER         2
#define BOTTOM_BORDER      2
#define DDARROW_WIDTH      11
#define ARROW_HEIGHT       3
#define INSERTMARK_WIDTH   2

#define DEFPAD_CX 7
#define DEFPAD_CY 6
#define DEFLISTGAP 4

/* vertical padding used in list mode when image is present */
#define LISTPAD_CY 9

/* how wide to treat the bitmap if it isn't present */
#define NONLIST_NOTEXT_OFFSET 2

#define TOOLBAR_NOWHERE (-1)

/* Used to find undocumented extended styles */
#define TBSTYLE_EX_ALL (TBSTYLE_EX_DRAWDDARROWS | \
                        TBSTYLE_EX_VERTICAL | \
                        TBSTYLE_EX_MIXEDBUTTONS | \
                        TBSTYLE_EX_DOUBLEBUFFER | \
                        TBSTYLE_EX_HIDECLIPPEDBUTTONS)

/* all of the CCS_ styles */
#define COMMON_STYLES (CCS_TOP|CCS_NOMOVEY|CCS_BOTTOM|CCS_NORESIZE| \
                       CCS_NOPARENTALIGN|CCS_ADJUSTABLE|CCS_NODIVIDER|CCS_VERT)

#define GETIBITMAP(infoPtr, i) (infoPtr->iVersion >= 5 ? LOWORD(i) : i)
#define GETHIMLID(infoPtr, i) (infoPtr->iVersion >= 5 ? HIWORD(i) : 0)
#define GETDEFIMAGELIST(infoPtr, id) TOOLBAR_GetImageList(infoPtr->himlDef, infoPtr->cimlDef, id)
#define GETHOTIMAGELIST(infoPtr, id) TOOLBAR_GetImageList(infoPtr->himlHot, infoPtr->cimlHot, id)
#define GETDISIMAGELIST(infoPtr, id) TOOLBAR_GetImageList(infoPtr->himlDis, infoPtr->cimlDis, id)

static const WCHAR themeClass[] = { 'T','o','o','l','b','a','r',0 };

static BOOL TOOLBAR_GetButtonInfo(const TOOLBAR_INFO *infoPtr, NMTOOLBARW *nmtb);
static BOOL TOOLBAR_IsButtonRemovable(const TOOLBAR_INFO *infoPtr, int iItem, const CUSTOMBUTTON *btnInfo);
static HIMAGELIST TOOLBAR_GetImageList(const PIMLENTRY *pies, INT cies, INT id);
static PIMLENTRY TOOLBAR_GetImageListEntry(const PIMLENTRY *pies, INT cies, INT id);
static VOID TOOLBAR_DeleteImageList(PIMLENTRY **pies, INT *cies);
static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIST himl, INT id);
static LRESULT TOOLBAR_LButtonDown(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam);
static void TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr);
static LRESULT TOOLBAR_AutoSize(TOOLBAR_INFO *infoPtr);
static void TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr);
static void TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button);
static void TOOLBAR_TooltipSetRect(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button);
static LRESULT TOOLBAR_SetButtonInfo(TOOLBAR_INFO *infoPtr, INT Id,
                                     const TBBUTTONINFOW *lptbbi, BOOL isW);


static inline int default_top_margin(const TOOLBAR_INFO *infoPtr)
{
    return (infoPtr->dwStyle & TBSTYLE_FLAT ? 0 : TOP_BORDER);
}

static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle)
{
    return (exStyle & TBSTYLE_EX_DRAWDDARROWS) != 0;
}

static inline BOOL button_has_ddarrow(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
{
    return (TOOLBAR_HasDropDownArrows( infoPtr->dwExStyle ) && (btnPtr->fsStyle & BTNS_DROPDOWN)) ||
        (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
}

static LPWSTR
TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
{
    LPWSTR lpText = NULL;

    /* NOTE: iString == -1 is undocumented */
    if (!IS_INTRESOURCE(btnPtr->iString) && (btnPtr->iString != -1))
        lpText = (LPWSTR)btnPtr->iString;
    else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
        lpText = infoPtr->strings[btnPtr->iString];

    return lpText;
}

static void
TOOLBAR_DumpTBButton(const TBBUTTON *tbb, BOOL fUnicode)
{
    TRACE("TBBUTTON: id %d, bitmap=%d, state=%02x, style=%02x, data=%08lx, stringid=0x%08lx (%s)\n",
          tbb->idCommand,tbb->iBitmap, tbb->fsState, tbb->fsStyle, tbb->dwData, tbb->iString,
          (fUnicode ? wine_dbgstr_w((LPWSTR)tbb->iString) : wine_dbgstr_a((LPSTR)tbb->iString)));
}

static void
TOOLBAR_DumpButton(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *bP, INT btn_num)
{
    if (TRACE_ON(toolbar)){
        TRACE("button %d id %d, bitmap=%d, state=%02x, style=%02x, data=%08lx, stringid=0x%08lx\n",
              btn_num, bP->idCommand, GETIBITMAP(infoPtr, bP->iBitmap), 
              bP->fsState, bP->fsStyle, bP->dwData, bP->iString);
	TRACE("string %s\n", debugstr_w(TOOLBAR_GetText(infoPtr,bP)));
        TRACE("button %d id %d, hot=%s, row=%d, rect=(%s)\n",
              btn_num, bP->idCommand, (bP->bHot) ? "TRUE":"FALSE", bP->nRow,
              wine_dbgstr_rect(&bP->rect));
    }
}


static void
TOOLBAR_DumpToolbar(const TOOLBAR_INFO *iP, INT line)
{
    if (TRACE_ON(toolbar)) {
	INT i;

	TRACE("toolbar %p at line %d, exStyle=%08x, buttons=%d, bitmaps=%d, strings=%d, style=%08x\n",
	      iP->hwndSelf, line,
	      iP->dwExStyle, iP->nNumButtons, iP->nNumBitmaps,
	      iP->nNumStrings, iP->dwStyle);
	TRACE("toolbar %p at line %d, himlInt=%p, himlDef=%p, himlHot=%p, himlDis=%p, redrawable=%s\n",
	      iP->hwndSelf, line,
	      iP->himlInt, iP->himlDef, iP->himlHot, iP->himlDis,
	      (iP->bDoRedraw) ? "TRUE" : "FALSE");
 	for(i=0; i<iP->nNumButtons; i++) {
            TOOLBAR_DumpButton(iP, &iP->buttons[i], i);
	}
    }
}

static inline BOOL
TOOLBAR_ButtonHasString(const TBUTTON_INFO *btnPtr)
{
    return HIWORD(btnPtr->iString) && btnPtr->iString != -1;
}

static void set_string_index( TBUTTON_INFO *btn, INT_PTR str, BOOL unicode )
{
    if (!IS_INTRESOURCE( str ) && str != -1)
    {
        if (!TOOLBAR_ButtonHasString( btn )) btn->iString = 0;

        if (unicode)
            Str_SetPtrW( (WCHAR **)&btn->iString, (WCHAR *)str );
        else
            Str_SetPtrAtoW( (WCHAR **)&btn->iString, (char *)str );
    }
    else
    {
        if (TOOLBAR_ButtonHasString( btn )) Free( (WCHAR *)btn->iString );

        btn->iString  = str;
    }
}

static void set_stringT( TBUTTON_INFO *btn, const WCHAR *str, BOOL unicode )
{
    if (IS_INTRESOURCE( (DWORD_PTR)str ) || (DWORD_PTR)str == -1) return;
    set_string_index( btn, (DWORD_PTR)str, unicode );
}

static void free_string( TBUTTON_INFO *btn )
{
    set_string_index( btn, 0, TRUE );

}

/***********************************************************************
* 		TOOLBAR_CheckStyle
*
* This function validates that the styles set are implemented and
* issues FIXMEs warning of possible problems. In a perfect world this
* function should be null.
*/
static void
TOOLBAR_CheckStyle (const TOOLBAR_INFO *infoPtr)
{
    if (infoPtr->dwStyle & TBSTYLE_REGISTERDROP)
	FIXME("[%p] TBSTYLE_REGISTERDROP not implemented\n", infoPtr->hwndSelf);
}


static INT
TOOLBAR_SendNotify (NMHDR *nmhdr, const TOOLBAR_INFO *infoPtr, UINT code)
{
	if(!IsWindow(infoPtr->hwndSelf))
	    return 0;   /* we have just been destroyed */

    nmhdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
    nmhdr->hwndFrom = infoPtr->hwndSelf;
    nmhdr->code = code;

    TRACE("to window %p, code=%08x, %s\n", infoPtr->hwndNotify, code,
	  (infoPtr->bUnicode) ? "via Unicode" : "via ANSI");

    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmhdr->idFrom, (LPARAM)nmhdr);
}

/***********************************************************************
* 		TOOLBAR_GetBitmapIndex
*
* This function returns the bitmap index associated with a button.
* If the button specifies I_IMAGECALLBACK, then the TBN_GETDISPINFO
* is issued to retrieve the index.
*/
static INT
TOOLBAR_GetBitmapIndex(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
{
    INT ret = btnPtr->iBitmap;

    if (ret == I_IMAGECALLBACK)
    {
        /* issue TBN_GETDISPINFO */
        NMTBDISPINFOW nmgd;

        memset(&nmgd, 0, sizeof(nmgd));
        nmgd.idCommand = btnPtr->idCommand;
        nmgd.lParam = btnPtr->dwData;
        nmgd.dwMask = TBNF_IMAGE;
        nmgd.iImage = -1;
        /* Windows also send TBN_GETDISPINFOW even if the control is ANSI */
        TOOLBAR_SendNotify(&nmgd.hdr, infoPtr, TBN_GETDISPINFOW);
        if (nmgd.dwMask & TBNF_DI_SETITEM)
            btnPtr->iBitmap = nmgd.iImage;
        ret = nmgd.iImage;
        TRACE("TBN_GETDISPINFO returned bitmap id %d, mask=%08x, nNumBitmaps=%d\n",
            ret, nmgd.dwMask, infoPtr->nNumBitmaps);
    }

    if (ret != I_IMAGENONE)
        ret = GETIBITMAP(infoPtr, ret);

    return ret;
}


static BOOL
TOOLBAR_IsValidBitmapIndex(const TOOLBAR_INFO *infoPtr, INT index)
{
    HIMAGELIST himl;
    INT id = GETHIMLID(infoPtr, index);
    INT iBitmap = GETIBITMAP(infoPtr, index);

    if (((himl = GETDEFIMAGELIST(infoPtr, id)) &&
        iBitmap >= 0 && iBitmap < ImageList_GetImageCount(himl)) ||
        (index == I_IMAGECALLBACK))
      return TRUE;
    else
      return FALSE;
}


static inline BOOL
TOOLBAR_IsValidImageList(const TOOLBAR_INFO *infoPtr, INT index)
{
    HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, index));
    return (himl != NULL) && (ImageList_GetImageCount(himl) > 0);
}


/***********************************************************************
* 		TOOLBAR_GetImageListForDrawing
*
* This function validates the bitmap index (including I_IMAGECALLBACK
* functionality) and returns the corresponding image list.
*/
static HIMAGELIST
TOOLBAR_GetImageListForDrawing (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
                                IMAGE_LIST_TYPE imagelist, INT * index)
{
    HIMAGELIST himl;

    if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
	if (btnPtr->iBitmap == I_IMAGENONE) return NULL;
	WARN("bitmap for ID %d, index %d is not valid, number of bitmaps in imagelist: %d\n",
	    HIWORD(btnPtr->iBitmap), LOWORD(btnPtr->iBitmap), infoPtr->nNumBitmaps);
	return NULL;
    }

    if ((*index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
	if ((*index == I_IMAGECALLBACK) ||
	    (*index == I_IMAGENONE)) return NULL;
	ERR("TBN_GETDISPINFO returned invalid index %d\n",
	    *index);
	return NULL;
    }

    switch(imagelist)
    {
    case IMAGE_LIST_DEFAULT:
        himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
        break;
    case IMAGE_LIST_HOT:
        himl = GETHOTIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
        break;
    case IMAGE_LIST_DISABLED:
        himl = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
        break;
    default:
        himl = NULL;
        FIXME("Shouldn't reach here\n");
    }

    if (!himl)
       TRACE("no image list\n");

    return himl;
}


static void
TOOLBAR_DrawFlatSeparator (const RECT *lpRect, HDC hdc, const TOOLBAR_INFO *infoPtr)
{
    RECT myrect;
    COLORREF oldcolor, newcolor;

    myrect.left = (lpRect->left + lpRect->right) / 2 - 1;
    myrect.right = myrect.left + 1;
    myrect.top = lpRect->top + 2;
    myrect.bottom = lpRect->bottom - 2;

    newcolor = (infoPtr->clrBtnShadow == CLR_DEFAULT) ?
	        comctl32_color.clrBtnShadow : infoPtr->clrBtnShadow;
    oldcolor = SetBkColor (hdc, newcolor);
    ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &myrect, 0, 0, 0);

    myrect.left = myrect.right;
    myrect.right = myrect.left + 1;

    newcolor = (infoPtr->clrBtnHighlight == CLR_DEFAULT) ?
	        comctl32_color.clrBtnHighlight : infoPtr->clrBtnHighlight;
    SetBkColor (hdc, newcolor);
    ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &myrect, 0, 0, 0);

    SetBkColor (hdc, oldcolor);
}


/***********************************************************************
* 		TOOLBAR_DrawFlatHorizontalSeparator
*
* This function draws horizontal separator for toolbars having CCS_VERT style.
* In this case, the separator is a pixel high line of COLOR_BTNSHADOW,
* followed by a pixel high line of COLOR_BTNHIGHLIGHT. These separators
* are horizontal as opposed to the vertical separators for not dropdown
* type.
*
* FIXME: It is possible that the height of each line is really SM_CYBORDER.
*/
static void
TOOLBAR_DrawFlatHorizontalSeparator (const RECT *lpRect, HDC hdc,
                             const TOOLBAR_INFO *infoPtr)
{
    RECT myrect;
    COLORREF oldcolor, newcolor;

    myrect.left = lpRect->left;
    myrect.right = lpRect->right;
    myrect.top = lpRect->top + (lpRect->bottom - lpRect->top - 2)/2;
    myrect.bottom = myrect.top + 1;

    InflateRect (&myrect, -2, 0);

    TRACE("rect=(%s)\n", wine_dbgstr_rect(&myrect));

    newcolor = (infoPtr->clrBtnShadow == CLR_DEFAULT) ?
	        comctl32_color.clrBtnShadow : infoPtr->clrBtnShadow;
    oldcolor = SetBkColor (hdc, newcolor);
    ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &myrect, 0, 0, 0);

    myrect.top = myrect.bottom;
    myrect.bottom = myrect.top + 1;

    newcolor = (infoPtr->clrBtnHighlight == CLR_DEFAULT) ?
	        comctl32_color.clrBtnHighlight : infoPtr->clrBtnHighlight;
    SetBkColor (hdc, newcolor);
    ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &myrect, 0, 0, 0);

    SetBkColor (hdc, oldcolor);
}


static void
TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, COLORREF clr)
{
    INT x, y;
    HPEN hPen, hOldPen;

    if (!(hPen = CreatePen( PS_SOLID, 1, clr))) return;
    hOldPen = SelectObject ( hdc, hPen );
    x = left + 2;
    y = top;
    MoveToEx (hdc, x, y, NULL);
    LineTo (hdc, x+5, y++); x++;
    MoveToEx (hdc, x, y, NULL);
    LineTo (hdc, x+3, y++); x++;
    MoveToEx (hdc, x, y, NULL);
    LineTo (hdc, x+1, y);
    SelectObject( hdc, hOldPen );
    DeleteObject( hPen );
}

/*
 * Draw the text string for this button.
 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
 * 	is non-zero, so we can simply check himlDef to see if we have
 *      an image list
 */
static void
TOOLBAR_DrawString (const TOOLBAR_INFO *infoPtr, RECT *rcText, LPCWSTR lpText,
                    const NMTBCUSTOMDRAW *tbcd, DWORD dwItemCDFlag)
{
    HDC hdc = tbcd->nmcd.hdc;
    HFONT  hOldFont = 0;
    COLORREF clrOld = 0;
    COLORREF clrOldBk = 0;
    int oldBkMode = 0;
    UINT state = tbcd->nmcd.uItemState;

    /* draw text */
    if (lpText && infoPtr->nMaxTextRows > 0) {
        TRACE("string=%s rect=(%s)\n", debugstr_w(lpText),
              wine_dbgstr_rect(rcText));

	hOldFont = SelectObject (hdc, infoPtr->hFont);
	if ((state & CDIS_HOT) && (dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) {
	    clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
	}
	else if (state & CDIS_DISABLED) {
	    clrOld = SetTextColor (hdc, tbcd->clrBtnHighlight);
	    OffsetRect (rcText, 1, 1);
	    DrawTextW (hdc, lpText, -1, rcText, infoPtr->dwDTFlags);
	    SetTextColor (hdc, comctl32_color.clr3dShadow);
	    OffsetRect (rcText, -1, -1);
	}
	else if (state & CDIS_INDETERMINATE) {
	    clrOld = SetTextColor (hdc, comctl32_color.clr3dShadow);
	}
	else if ((state & CDIS_MARKED) && !(dwItemCDFlag & TBCDRF_NOMARK)) {
	    clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
	    clrOldBk = SetBkColor (hdc, tbcd->clrMark);
	    oldBkMode = SetBkMode (hdc, tbcd->nHLStringBkMode);
	}
	else {
	    clrOld = SetTextColor (hdc, tbcd->clrText);
	}

	DrawTextW (hdc, lpText, -1, rcText, infoPtr->dwDTFlags);
	SetTextColor (hdc, clrOld);
	if ((state & CDIS_MARKED) && !(dwItemCDFlag & TBCDRF_NOMARK))
	{
	    SetBkColor (hdc, clrOldBk);
	    SetBkMode (hdc, oldBkMode);
	}
	SelectObject (hdc, hOldFont);
    }
}


static void
TOOLBAR_DrawPattern (const RECT *lpRect, const NMTBCUSTOMDRAW *tbcd)
{
    HDC hdc = tbcd->nmcd.hdc;
    HBRUSH hbr = SelectObject (hdc, tbcd->hbrMonoDither);
    COLORREF clrTextOld;
    COLORREF clrBkOld;
    INT cx = lpRect->right - lpRect->left;
    INT cy = lpRect->bottom - lpRect->top;
    INT cxEdge = GetSystemMetrics(SM_CXEDGE);
    INT cyEdge = GetSystemMetrics(SM_CYEDGE);
    clrTextOld = SetTextColor(hdc, tbcd->clrBtnHighlight);
    clrBkOld = SetBkColor(hdc, tbcd->clrBtnFace);
    PatBlt (hdc, lpRect->left + cxEdge, lpRect->top + cyEdge,
            cx - (2 * cxEdge), cy - (2 * cyEdge), PATCOPY);
    SetBkColor(hdc, clrBkOld);
    SetTextColor(hdc, clrTextOld);
    SelectObject (hdc, hbr);
}


static void TOOLBAR_DrawMasked(HIMAGELIST himl, int index, HDC hdc, INT x, INT y, UINT draw_flags)
{
    INT cx, cy;
    HBITMAP hbmMask, hbmImage;
    HDC hdcMask, hdcImage;

    ImageList_GetIconSize(himl, &cx, &cy);

    /* Create src image */
    hdcImage = CreateCompatibleDC(hdc);
    hbmImage = CreateCompatibleBitmap(hdc, cx, cy);
    SelectObject(hdcImage, hbmImage);
    ImageList_DrawEx(himl, index, hdcImage, 0, 0, cx, cy,
                     RGB(0xff, 0xff, 0xff), RGB(0,0,0), draw_flags);

    /* Create Mask */
    hdcMask = CreateCompatibleDC(0);
    hbmMask = CreateBitmap(cx, cy, 1, 1, NULL);
    SelectObject(hdcMask, hbmMask);

    /* Remove the background and all white pixels */
    ImageList_DrawEx(himl, index, hdcMask, 0, 0, cx, cy,
                     RGB(0xff, 0xff, 0xff), RGB(0,0,0), ILD_MASK);
    SetBkColor(hdcImage, RGB(0xff, 0xff, 0xff));
    BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, NOTSRCERASE);

    /* draw the new mask 'etched' to hdc */
    SetBkColor(hdc, RGB(255, 255, 255));
    SelectObject(hdc, GetSysColorBrush(COLOR_3DHILIGHT));
    /* E20746 op code is (Dst ^ (Src & (Pat ^ Dst))) */
    BitBlt(hdc, x + 1, y + 1, cx, cy, hdcMask, 0, 0, 0xE20746);
    SelectObject(hdc, GetSysColorBrush(COLOR_3DSHADOW));
    BitBlt(hdc, x, y, cx, cy, hdcMask, 0, 0, 0xE20746);

    /* Cleanup */
    DeleteObject(hbmImage);
    DeleteDC(hdcImage);
    DeleteObject (hbmMask);
    DeleteDC(hdcMask);
}


static UINT
TOOLBAR_TranslateState(const TBUTTON_INFO *btnPtr)
{
    UINT retstate = 0;

    retstate |= (btnPtr->fsState & TBSTATE_CHECKED) ? CDIS_CHECKED  : 0;
    retstate |= (btnPtr->fsState & TBSTATE_PRESSED) ? CDIS_SELECTED : 0;
    retstate |= (btnPtr->fsState & TBSTATE_ENABLED) ? 0 : CDIS_DISABLED;
    retstate |= (btnPtr->fsState & TBSTATE_MARKED ) ? CDIS_MARKED   : 0;
    retstate |= (btnPtr->bHot                     ) ? CDIS_HOT      : 0;
    retstate |= ((btnPtr->fsState & (TBSTATE_ENABLED|TBSTATE_INDETERMINATE)) == (TBSTATE_ENABLED|TBSTATE_INDETERMINATE)) ? CDIS_INDETERMINATE : 0;
    /* NOTE: we don't set CDIS_GRAYED, CDIS_FOCUS, CDIS_DEFAULT */
    return retstate;
}

/* draws the image on a toolbar button */
static void
TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, INT top,
                  const NMTBCUSTOMDRAW *tbcd, DWORD dwItemCDFlag)
{
    HIMAGELIST himl = NULL;
    BOOL draw_masked = FALSE;
    INT index;
    INT offset = 0;
    UINT draw_flags = ILD_TRANSPARENT;

    if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
    {
        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DISABLED, &index);
        if (!himl)
        {
            himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
            draw_masked = TRUE;
        }
    }
    else if (tbcd->nmcd.uItemState & CDIS_CHECKED ||
      ((tbcd->nmcd.uItemState & CDIS_HOT) 
      && ((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf))))
    {
        /* if hot, attempt to draw with hot image list, if fails, 
           use default image list */
        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_HOT, &index);
        if (!himl)
            himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);
	}
    else
        himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index);

    if (!himl)
        return;

    if (!(dwItemCDFlag & TBCDRF_NOOFFSET) && 
        (tbcd->nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED)))
        offset = 1;

    if (!(dwItemCDFlag & TBCDRF_NOMARK) &&
        (tbcd->nmcd.uItemState & CDIS_MARKED))
        draw_flags |= ILD_BLEND50;

    TRACE("drawing index=%d, himl=%p, left=%d, top=%d, offset=%d\n",
      index, himl, left, top, offset);

    if (draw_masked)
        TOOLBAR_DrawMasked (himl, index, tbcd->nmcd.hdc, left + offset, top + offset, draw_flags);
    else
        ImageList_Draw (himl, index, tbcd->nmcd.hdc, left + offset, top + offset, draw_flags);
}

/* draws a blank frame for a toolbar button */
static void
TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, const NMTBCUSTOMDRAW *tbcd, const RECT *rect, DWORD dwItemCDFlag)
{
    HDC hdc = tbcd->nmcd.hdc;
    RECT rc = *rect;
    /* if the state is disabled or indeterminate then the button
     * cannot have an interactive look like pressed or hot */
    BOOL non_interactive_state = (tbcd->nmcd.uItemState & CDIS_DISABLED) ||
                                 (tbcd->nmcd.uItemState & CDIS_INDETERMINATE);
    BOOL pressed_look = !non_interactive_state &&
                        ((tbcd->nmcd.uItemState & CDIS_SELECTED) || 
                         (tbcd->nmcd.uItemState & CDIS_CHECKED));

    /* app don't want us to draw any edges */
    if (dwItemCDFlag & TBCDRF_NOEDGES)
        return;

    if (infoPtr->dwStyle & TBSTYLE_FLAT)
    {
        if (pressed_look)
            DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT);
        else if ((tbcd->nmcd.uItemState & CDIS_HOT) && !non_interactive_state)
            DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT);
    }
    else
    {
        if (pressed_look)
            DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE);
        else
            DrawEdge (hdc, &rc, EDGE_RAISED,
              BF_SOFT | BF_RECT | BF_MIDDLE);
    }
}

static void
TOOLBAR_DrawSepDDArrow(const TOOLBAR_INFO *infoPtr, const NMTBCUSTOMDRAW *tbcd, RECT *rcArrow, BOOL bDropDownPressed, DWORD dwItemCDFlag)
{
    HDC hdc = tbcd->nmcd.hdc;
    int offset = 0;
    BOOL pressed = bDropDownPressed ||
        (tbcd->nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED));

    if (infoPtr->dwStyle & TBSTYLE_FLAT)
    {
        if (pressed)
            DrawEdge (hdc, rcArrow, BDR_SUNKENOUTER, BF_RECT);
        else if ( (tbcd->nmcd.uItemState & CDIS_HOT) &&
                 !(tbcd->nmcd.uItemState & CDIS_DISABLED) &&
                 !(tbcd->nmcd.uItemState & CDIS_INDETERMINATE))
            DrawEdge (hdc, rcArrow, BDR_RAISEDINNER, BF_RECT);
    }
    else
    {
        if (pressed)
            DrawEdge (hdc, rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE);
        else
            DrawEdge (hdc, rcArrow, EDGE_RAISED,
              BF_SOFT | BF_RECT | BF_MIDDLE);
    }

    if (pressed)
        offset = (dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;

    if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
    {
        TOOLBAR_DrawArrow(hdc, rcArrow->left+1, rcArrow->top+1 + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight);
        TOOLBAR_DrawArrow(hdc, rcArrow->left, rcArrow->top + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow);
    }
    else
        TOOLBAR_DrawArrow(hdc, rcArrow->left + offset, rcArrow->top + offset + (rcArrow->bottom - rcArrow->top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
}

/* draws a complete toolbar button */
static void
TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, DWORD dwBaseCustDraw)
{
    DWORD dwStyle = infoPtr->dwStyle;
    BOOL hasDropDownArrow = button_has_ddarrow( infoPtr, btnPtr );
    BOOL drawSepDropDownArrow = hasDropDownArrow && 
                                (~btnPtr->fsStyle & BTNS_WHOLEDROPDOWN);
    RECT rc, rcArrow, rcBitmap, rcText;
    LPWSTR lpText = NULL;
    NMTBCUSTOMDRAW tbcd;
    DWORD ntfret;
    INT offset;
    INT oldBkMode;
    DWORD dwItemCustDraw;
    DWORD dwItemCDFlag;
    HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);

    rc = btnPtr->rect;
    CopyRect (&rcArrow, &rc);

    /* separator - doesn't send NM_CUSTOMDRAW */
    if (btnPtr->fsStyle & BTNS_SEP) {
        if (theme)
        {
            DrawThemeBackground (theme, hdc, 
                (dwStyle & CCS_VERT) ? TP_SEPARATORVERT : TP_SEPARATOR, 0, 
                &rc, NULL);
        }
        else
        /* with the FLAT style, iBitmap is the width and has already */
        /* been taken into consideration in calculating the width    */
        /* so now we need to draw the vertical separator             */
        /* empirical tests show that iBitmap can/will be non-zero    */
        /* when drawing the vertical bar...      */
        if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */) {
            if (dwStyle & CCS_VERT) {
                RECT rcsep = rc;
                InflateRect(&rcsep, -infoPtr->szPadding.cx, -infoPtr->szPadding.cy);
                TOOLBAR_DrawFlatHorizontalSeparator (&rcsep, hdc, infoPtr);
            }
	    else
		TOOLBAR_DrawFlatSeparator (&rc, hdc, infoPtr);
	}
	else if (btnPtr->fsStyle != BTNS_SEP) {
	    FIXME("Draw some kind of separator: fsStyle=%x\n",
		  btnPtr->fsStyle);
	}
	return;
    }

    /* get a pointer to the text */
    lpText = TOOLBAR_GetText(infoPtr, btnPtr);

    if (hasDropDownArrow)
    {
        int right;

        if (dwStyle & TBSTYLE_FLAT)
            right = max(rc.left, rc.right - DDARROW_WIDTH);
        else
            right = max(rc.left, rc.right - DDARROW_WIDTH - 2);

        if (drawSepDropDownArrow)
           rc.right = right;

        rcArrow.left = right;
    }

    /* copy text & bitmap rects after adjusting for drop-down arrow
     * so that text & bitmap is centered in the rectangle not containing
     * the arrow */
    CopyRect(&rcText, &rc);
    CopyRect(&rcBitmap, &rc);

    /* Center the bitmap horizontally and vertically */
    if (dwStyle & TBSTYLE_LIST)
    {
        if (lpText &&
            infoPtr->nMaxTextRows > 0 &&
            (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
            (btnPtr->fsStyle & BTNS_SHOWTEXT)) )
            rcBitmap.left += GetSystemMetrics(SM_CXEDGE) + infoPtr->szPadding.cx / 2;
        else
            rcBitmap.left += GetSystemMetrics(SM_CXEDGE) + infoPtr->iListGap / 2;
    }
    else
        rcBitmap.left += ((rc.right - rc.left) - infoPtr->nBitmapWidth) / 2;

    rcBitmap.top += infoPtr->szPadding.cy / 2;

    TRACE("iBitmap=%d, start=(%d,%d) w=%d, h=%d\n",
      btnPtr->iBitmap, rcBitmap.left, rcBitmap.top,
      infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
    TRACE("Text=%s\n", debugstr_w(lpText));
    TRACE("iListGap=%d, padding = { %d, %d }\n", infoPtr->iListGap, infoPtr->szPadding.cx, infoPtr->szPadding.cy);

    /* calculate text position */
    if (lpText)
    {
        rcText.left += GetSystemMetrics(SM_CXEDGE);
        rcText.right -= GetSystemMetrics(SM_CXEDGE);
        if (dwStyle & TBSTYLE_LIST)
        {
            rcText.left += infoPtr->nBitmapWidth + infoPtr->iListGap + 2;
        }
        else
        {
            if (ImageList_GetImageCount(GETDEFIMAGELIST(infoPtr, 0)) > 0)
                rcText.top += infoPtr->szPadding.cy/2 + infoPtr->nBitmapHeight + 1;
            else
                rcText.top += infoPtr->szPadding.cy/2 + 2;
        }
    }

    /* Initialize fields in all cases, because we use these later
     * NOTE: applications can and do alter these to customize their
     * toolbars */
    ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
    tbcd.clrText = comctl32_color.clrBtnText;
    tbcd.clrTextHighlight = comctl32_color.clrHighlightText;
    tbcd.clrBtnFace = comctl32_color.clrBtnFace;
    tbcd.clrBtnHighlight = comctl32_color.clrBtnHighlight;
    tbcd.clrMark = comctl32_color.clrHighlight;
    tbcd.clrHighlightHotTrack = 0;
    tbcd.nStringBkMode = TRANSPARENT;
    tbcd.nHLStringBkMode = OPAQUE;
    tbcd.rcText.left = 0;
    tbcd.rcText.top = 0;
    tbcd.rcText.right = rcText.right - rc.left;
    tbcd.rcText.bottom = rcText.bottom - rc.top;
    tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
    tbcd.nmcd.hdc = hdc;
    tbcd.nmcd.rc = btnPtr->rect;
    tbcd.hbrMonoDither = COMCTL32_hPattern55AABrush;

    /* FIXME: what are these used for? */
    tbcd.hbrLines = 0;
    tbcd.hpenLines = 0;

    /* Issue Item Prepaint notify */
    dwItemCustDraw = 0;
    dwItemCDFlag = 0;
    if (dwBaseCustDraw & CDRF_NOTIFYITEMDRAW)
    {
	tbcd.nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
	tbcd.nmcd.dwItemSpec = btnPtr->idCommand;
	tbcd.nmcd.lItemlParam = btnPtr->dwData;
	ntfret = TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
        /* reset these fields so the user can't alter the behaviour like native */
        tbcd.nmcd.hdc = hdc;
        tbcd.nmcd.rc = btnPtr->rect;

	dwItemCustDraw = ntfret & 0xffff;
	dwItemCDFlag = ntfret & 0xffff0000;
	if (dwItemCustDraw & CDRF_SKIPDEFAULT)
	    return;
	/* save the only part of the rect that the user can change */
	rcText.right = tbcd.rcText.right + rc.left;
	rcText.bottom = tbcd.rcText.bottom + rc.top;
    }

    if (!(dwItemCDFlag & TBCDRF_NOOFFSET) &&
        (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED)))
        OffsetRect(&rcText, 1, 1);

    if (!(tbcd.nmcd.uItemState & CDIS_HOT) && 
        ((tbcd.nmcd.uItemState & CDIS_CHECKED) || (tbcd.nmcd.uItemState & CDIS_INDETERMINATE)))
        TOOLBAR_DrawPattern (&rc, &tbcd);

    if (((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf)) 
        && (tbcd.nmcd.uItemState & CDIS_HOT))
    {
        if ( dwItemCDFlag & TBCDRF_HILITEHOTTRACK )
        {
            COLORREF oldclr;

            oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack);
            ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0);
            if (hasDropDownArrow)
                ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0);
            SetBkColor(hdc, oldclr);
        }
    }

    if (theme)
    {
        int partId = drawSepDropDownArrow ? TP_SPLITBUTTON : TP_BUTTON;
        int stateId = TS_NORMAL;
        
        if (tbcd.nmcd.uItemState & CDIS_DISABLED)
            stateId = TS_DISABLED;
        else if (tbcd.nmcd.uItemState & CDIS_SELECTED)
            stateId = TS_PRESSED;
        else if (tbcd.nmcd.uItemState & CDIS_CHECKED)
            stateId = (tbcd.nmcd.uItemState & CDIS_HOT) ? TS_HOTCHECKED : TS_HOT;
        else if ((tbcd.nmcd.uItemState & CDIS_HOT)
            || (drawSepDropDownArrow && btnPtr->bDropDownPressed))
            stateId = TS_HOT;
            
        DrawThemeBackground (theme, hdc, partId, stateId, &rc, NULL);
    }
    else
        TOOLBAR_DrawFrame(infoPtr, &tbcd, &rc, dwItemCDFlag);

    if (drawSepDropDownArrow)
    {
        if (theme)
        {
            int stateId = TS_NORMAL;
            
            if (tbcd.nmcd.uItemState & CDIS_DISABLED)
                stateId = TS_DISABLED;
            else if (btnPtr->bDropDownPressed || (tbcd.nmcd.uItemState & CDIS_SELECTED))
                stateId = TS_PRESSED;
            else if (tbcd.nmcd.uItemState & CDIS_CHECKED)
                stateId = (tbcd.nmcd.uItemState & CDIS_HOT) ? TS_HOTCHECKED : TS_HOT;
            else if (tbcd.nmcd.uItemState & CDIS_HOT)
                stateId = TS_HOT;
                
            DrawThemeBackground (theme, hdc, TP_DROPDOWNBUTTON, stateId, &rcArrow, NULL);
            DrawThemeBackground (theme, hdc, TP_SPLITBUTTONDROPDOWN, stateId, &rcArrow, NULL);
        }
        else
            TOOLBAR_DrawSepDDArrow(infoPtr, &tbcd, &rcArrow, btnPtr->bDropDownPressed, dwItemCDFlag);
    }

    oldBkMode = SetBkMode (hdc, tbcd.nStringBkMode);
    if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
        TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd, dwItemCDFlag);
    SetBkMode (hdc, oldBkMode);

    TOOLBAR_DrawImage(infoPtr, btnPtr, rcBitmap.left, rcBitmap.top, &tbcd, dwItemCDFlag);

    if (hasDropDownArrow && !drawSepDropDownArrow)
    {
        if (tbcd.nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE))
        {
            TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1 + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight);
            TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow);
        }
        else if (tbcd.nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED))
        {
            offset = (dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1;
            TOOLBAR_DrawArrow(hdc, rcArrow.left + offset, rcArrow.top + offset + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
        }
        else
            TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText);
    }

    if (dwItemCustDraw & CDRF_NOTIFYPOSTPAINT)
    {
        tbcd.nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
        TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
    }

}


static void
TOOLBAR_Refresh (TOOLBAR_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
{
    TBUTTON_INFO *btnPtr;
    INT i;
    RECT rcTemp, rcClient;
    NMTBCUSTOMDRAW tbcd;
    DWORD ntfret;
    DWORD dwBaseCustDraw;

    /* the app has told us not to redraw the toolbar */
    if (!infoPtr->bDoRedraw)
        return;

    /* if imagelist belongs to the app, it can be changed
       by the app after setting it */
    if (GETDEFIMAGELIST(infoPtr, 0) != infoPtr->himlInt)
    {
        infoPtr->nNumBitmaps = 0;
        for (i = 0; i < infoPtr->cimlDef; i++)
            infoPtr->nNumBitmaps += ImageList_GetImageCount(infoPtr->himlDef[i]->himl);
    }

    TOOLBAR_DumpToolbar (infoPtr, __LINE__);

    /* change the imagelist icon size if we manage the list and it is necessary */
    TOOLBAR_CheckImageListIconSize(infoPtr);

    /* Send initial notify */
    ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
    tbcd.nmcd.dwDrawStage = CDDS_PREPAINT;
    tbcd.nmcd.hdc = hdc;
    tbcd.nmcd.rc = ps->rcPaint;
    ntfret = TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
    dwBaseCustDraw = ntfret & 0xffff;

    GetClientRect(infoPtr->hwndSelf, &rcClient);

    /* redraw necessary buttons */
    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
    {
        BOOL bDraw;
        if (!RectVisible(hdc, &btnPtr->rect))
            continue;
        if (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
        {
            IntersectRect(&rcTemp, &rcClient, &btnPtr->rect);
            bDraw = EqualRect(&rcTemp, &btnPtr->rect);
        }
        else
            bDraw = TRUE;
        bDraw &= IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect));
        bDraw = (btnPtr->fsState & TBSTATE_HIDDEN) ? FALSE : bDraw;
        if (bDraw)
            TOOLBAR_DrawButton(infoPtr, btnPtr, hdc, dwBaseCustDraw);
    }

    /* draw insert mark if required */
    if (infoPtr->tbim.iButton != -1)
    {
        RECT rcButton = infoPtr->buttons[infoPtr->tbim.iButton].rect;
        RECT rcInsertMark;
        rcInsertMark.top = rcButton.top;
        rcInsertMark.bottom = rcButton.bottom;
        if (infoPtr->tbim.dwFlags & TBIMHT_AFTER)
            rcInsertMark.left = rcInsertMark.right = rcButton.right;
        else
            rcInsertMark.left = rcInsertMark.right = rcButton.left - INSERTMARK_WIDTH;
        COMCTL32_DrawInsertMark(hdc, &rcInsertMark, infoPtr->clrInsertMark, FALSE);
    }

    if (dwBaseCustDraw & CDRF_NOTIFYPOSTPAINT)
    {
	ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
	tbcd.nmcd.dwDrawStage = CDDS_POSTPAINT;
	tbcd.nmcd.hdc = hdc;
	tbcd.nmcd.rc = ps->rcPaint;
	TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
    }
}

/***********************************************************************
* 		TOOLBAR_MeasureString
*
* This function gets the width and height of a string in pixels. This
* is done first by using GetTextExtentPoint to get the basic width
* and height. The DrawText is called with DT_CALCRECT to get the exact
* width. The reason is because the text may have more than one "&" (or
* prefix characters as M$ likes to call them). The prefix character
* indicates where the underline goes, except for the string "&&" which
* is reduced to a single "&". GetTextExtentPoint does not process these
* only DrawText does. Note that the BTNS_NOPREFIX is handled here.
*/
static void
TOOLBAR_MeasureString(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr,
		      HDC hdc, LPSIZE lpSize)
{
    RECT myrect;

    lpSize->cx = 0;
    lpSize->cy = 0;

    if (infoPtr->nMaxTextRows > 0 &&
        !(btnPtr->fsState & TBSTATE_HIDDEN) &&
        (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
        (btnPtr->fsStyle & BTNS_SHOWTEXT)) )
    {
        LPWSTR lpText = TOOLBAR_GetText(infoPtr, btnPtr);

	if(lpText != NULL) {
	    /* first get size of all the text */
	    GetTextExtentPoint32W (hdc, lpText, strlenW (lpText), lpSize);

	    /* feed above size into the rectangle for DrawText */
            SetRect(&myrect, 0, 0, lpSize->cx, lpSize->cy);

	    /* Use DrawText to get true size as drawn (less pesky "&") */
	    DrawTextW (hdc, lpText, -1, &myrect, DT_VCENTER | DT_SINGLELINE |
	    	   DT_CALCRECT | ((btnPtr->fsStyle & BTNS_NOPREFIX) ?
				  DT_NOPREFIX : 0));

	    /* feed back to caller  */
	    lpSize->cx = myrect.right;
	    lpSize->cy = myrect.bottom;
	}
    }

    TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
}

/***********************************************************************
* 		TOOLBAR_CalcStrings
*
* This function walks through each string and measures it and returns
* the largest height and width to caller.
*/
static void
TOOLBAR_CalcStrings (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize)
{
    TBUTTON_INFO *btnPtr;
    INT i;
    SIZE sz;
    HDC hdc;
    HFONT hOldFont;

    lpSize->cx = 0;
    lpSize->cy = 0;

    if (infoPtr->nMaxTextRows == 0)
        return;

    hdc = GetDC (infoPtr->hwndSelf);
    hOldFont = SelectObject (hdc, infoPtr->hFont);

    if (infoPtr->nNumButtons == 0 && infoPtr->nNumStrings > 0)
    {
        TEXTMETRICW tm;

        GetTextMetricsW(hdc, &tm);
        lpSize->cy = tm.tmHeight;
    }

    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
        if(TOOLBAR_GetText(infoPtr, btnPtr))
        {
            TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
            if (sz.cx > lpSize->cx)
                lpSize->cx = sz.cx;
            if (sz.cy > lpSize->cy)
                lpSize->cy = sz.cy;
        }
    }

    SelectObject (hdc, hOldFont);
    ReleaseDC (infoPtr->hwndSelf, hdc);

    TRACE("max string size %d x %d!\n", lpSize->cx, lpSize->cy);
}

/***********************************************************************
* 		TOOLBAR_WrapToolbar
*
* This function walks through the buttons and separators in the
* toolbar, and sets the TBSTATE_WRAP flag only on those items where
* wrapping should occur based on the width of the toolbar window.
* It does *not* calculate button placement itself.  That task
* takes place in TOOLBAR_CalcToolbar. If the program wants to manage
* the toolbar wrapping on its own, it can use the TBSTYLE_WRAPABLE
* flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
*
* Note: TBSTYLE_WRAPABLE or TBSTYLE_EX_VERTICAL can be used also to allow
* vertical toolbar lists.
*/

static void
TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr)
{
    TBUTTON_INFO *btnPtr;
    INT x, cx, i, j, width;
    BOOL bButtonWrap;

    /* 	When the toolbar window style is not TBSTYLE_WRAPABLE,	*/
    /*	no layout is necessary. Applications may use this style */
    /*	to perform their own layout on the toolbar. 		*/
    if( !(infoPtr->dwStyle & TBSTYLE_WRAPABLE) &&
	!(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL) )  return;

    btnPtr = infoPtr->buttons;
    x  = infoPtr->nIndent;
    width = infoPtr->client_rect.right - infoPtr->client_rect.left;

    bButtonWrap = FALSE;

    TRACE("start ButtonWidth=%d, BitmapWidth=%d, width=%d, nIndent=%d\n",
	  infoPtr->nButtonWidth, infoPtr->nBitmapWidth, width,
	  infoPtr->nIndent);

    for (i = 0; i < infoPtr->nNumButtons; i++ )
    {
	btnPtr[i].fsState &= ~TBSTATE_WRAP;

	if (btnPtr[i].fsState & TBSTATE_HIDDEN)
	    continue;

        if (btnPtr[i].cx > 0)
            cx = btnPtr[i].cx;
        /* horizontal separators are treated as buttons for width    */
	else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
            !(infoPtr->dwStyle & CCS_VERT))
            cx = (btnPtr[i].iBitmap > 0) ? btnPtr[i].iBitmap : SEPARATOR_WIDTH;
	else
	    cx = infoPtr->nButtonWidth;

        if (!btnPtr[i].cx && button_has_ddarrow( infoPtr, btnPtr + i ))
            cx += DDARROW_WIDTH;

	/* Two or more adjacent separators form a separator group.   */
	/* The first separator in a group should be wrapped to the   */
	/* next row if the previous wrapping is on a button.	     */
	if( bButtonWrap &&
		(btnPtr[i].fsStyle & BTNS_SEP) &&
		(i + 1 < infoPtr->nNumButtons ) &&
		(btnPtr[i + 1].fsStyle & BTNS_SEP) )
	{
	    TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
	    btnPtr[i].fsState |= TBSTATE_WRAP;
	    x = infoPtr->nIndent;
	    i++;
	    bButtonWrap = FALSE;
	    continue;
	}

	/* The layout makes sure the bitmap is visible, but not the button. */
	/* Test added to also wrap after a button that starts a row but     */
	/* is bigger than the area.  - GA  8/01                             */
        if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2 > width) ||
            ((x == infoPtr->nIndent) && (cx > width)))
	{
	    BOOL bFound = FALSE;

	    /* 	If the current button is a separator and not hidden,  */
	    /*	go to the next until it reaches a non separator.      */
	    /*	Wrap the last separator if it is before a button.     */
	    while( ( ((btnPtr[i].fsStyle & BTNS_SEP) &&
		      !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) ||
		     (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
			i < infoPtr->nNumButtons )
	    {
		i++;
		bFound = TRUE;
	    }

	    if( bFound && i < infoPtr->nNumButtons )
	    {
		i--;
		TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
		      i, btnPtr[i].fsStyle, x, cx);
		btnPtr[i].fsState |= TBSTATE_WRAP;
		x = infoPtr->nIndent;
		bButtonWrap = FALSE;
		continue;
	    }
	    else if ( i >= infoPtr->nNumButtons)
		break;

	    /* 	If the current button is not a separator, find the last  */
	    /*	separator and wrap it.   				 */
	    for ( j = i - 1; j >= 0  &&  !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
	    {
		if ((btnPtr[j].fsStyle & BTNS_SEP) &&
			!(btnPtr[j].fsState & TBSTATE_HIDDEN))
		{
		    bFound = TRUE;
		    i = j;
		    TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
			  i, btnPtr[i].fsStyle, x, cx);
		    x = infoPtr->nIndent;
		    btnPtr[j].fsState |= TBSTATE_WRAP;
		    bButtonWrap = FALSE;
		    break;
		}
	    }

	    /* 	If no separator available for wrapping, wrap one of 	*/
	    /*  non-hidden previous button.  			     	*/
	    if (!bFound)
	    {
		for ( j = i - 1;
			j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
		{
		    if (btnPtr[j].fsState & TBSTATE_HIDDEN)
			continue;

		    bFound = TRUE;
		    i = j;
		    TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
			  i, btnPtr[i].fsStyle, x, cx);
		    x = infoPtr->nIndent;
		    btnPtr[j].fsState |= TBSTATE_WRAP;
		    bButtonWrap = TRUE;
		    break;
		}
	    }

	    /* If all above failed, wrap the current button. */
	    if (!bFound)
	    {
		TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
		      i, btnPtr[i].fsStyle, x, cx);
		btnPtr[i].fsState |= TBSTATE_WRAP;
		x = infoPtr->nIndent;
		if (btnPtr[i].fsStyle & BTNS_SEP )
		    bButtonWrap = FALSE;
		else
		    bButtonWrap = TRUE;
	    }
	}
	else {
	    TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
		  i, btnPtr[i].fsStyle, x, cx);
	    x += cx;
	}
    }
}


/***********************************************************************
* 		TOOLBAR_MeasureButton
*
* Calculates the width and height required for a button. Used in
* TOOLBAR_CalcToolbar to set the all-button width and height and also for
* the width of buttons that are autosized.
*
* Note that it would have been rather elegant to use one piece of code for
* both the laying out of the toolbar and for controlling where button parts
* are drawn, but the native control has inconsistencies between the two that
* prevent this from being effectively. These inconsistencies can be seen as
* artefacts where parts of the button appear outside of the bounding button
* rectangle.
*
* There are several cases for the calculation of the button dimensions and
* button part positioning:
*
* List
* ====
*
* With Bitmap:
*
* +--------------------------------------------------------+ ^
* |                    ^                     ^             | |
* |                    | pad.cy / 2          | centered    | |
* | pad.cx/2 + cxedge +--------------+     +------------+  | | DEFPAD_CY +
* |<----------------->| nBitmapWidth |     | Text       |  | | max(nBitmapHeight, szText.cy)
* |                   |<------------>|     |            |  | |
* |                   +--------------+     +------------+  | |
* |<-------------------------------------->|               | |
* |  cxedge + iListGap + nBitmapWidth + 2  |<----------->  | |
* |                                           szText.cx    | |
* +--------------------------------------------------------+ -
* <-------------------------------------------------------->
*  2*cxedge + nBitmapWidth + iListGap + szText.cx + pad.cx
*
* Without Bitmap (I_IMAGENONE):
*
* +-----------------------------------+ ^
* |                     ^             | |
* |                     | centered    | | LISTPAD_CY +
* |                   +------------+  | | szText.cy
* |                   | Text       |  | |
* |                   |            |  | |
* |                   +------------+  | |
* |<----------------->|               | |
* |      cxedge       |<----------->  | |
* |                      szText.cx    | |
* +-----------------------------------+ -
* <----------------------------------->
*          szText.cx + pad.cx
*
* Without text:
*
* +--------------------------------------+ ^
* |                       ^              | |
* |                       | padding.cy/2 | | DEFPAD_CY +
* |                     +------------+   | | nBitmapHeight
* |                     | Bitmap     |   | |
* |                     |            |   | |
* |                     +------------+   | |
* |<------------------->|                | |
* | cxedge + iListGap/2 |<----------->   | |
* |                       nBitmapWidth   | |
* +--------------------------------------+ -
* <-------------------------------------->
*     2*cxedge + nBitmapWidth + iListGap
*
* Non-List
* ========
*
* With bitmap:
*
* +-----------------------------------+ ^
* |                     ^             | |
* |                     | pad.cy / 2  | | nBitmapHeight +
* |                     -             | | szText.cy +
* |                   +------------+  | | DEFPAD_CY + 1
* |    centered       |   Bitmap   |  | |
* |<----------------->|            |  | |
* |                   +------------+  | |
* |                         ^         | |
* |                       1 |         | |
* |                         -         | |
* |     centered    +---------------+ | |
* |<--------------->|      Text     | | |
* |                 +---------------+ | |
* +-----------------------------------+ -
* <----------------------------------->
* pad.cx + max(nBitmapWidth, szText.cx)
*
* Without bitmaps (NULL imagelist or ImageList_GetImageCount() = 0):
*
* +---------------------------------------+ ^
* |                     ^                 | |
* |                     | 2 + pad.cy / 2  | |
* |                     -                 | | szText.cy +
* |    centered     +-----------------+   | | pad.cy + 2
* |<--------------->|   Text          |   | |
* |                 +-----------------+   | |
* |                                       | |
* +---------------------------------------+ -
* <--------------------------------------->
*          2*cxedge + pad.cx + szText.cx
*
* Without text:
*   As for with bitmaps, but with szText.cx zero.
*/
static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeString,
                                         BOOL bHasBitmap, BOOL bValidImageList)
{
    SIZE sizeButton;
    if (infoPtr->dwStyle & TBSTYLE_LIST)
    {
        /* set button height from bitmap / text height... */
        sizeButton.cy = max((bHasBitmap ? infoPtr->nBitmapHeight : 0),
            sizeString.cy);

        /* ... add on the necessary padding */
        if (bValidImageList)
        {
            if (bHasBitmap)
                sizeButton.cy += DEFPAD_CY;
            else
                sizeButton.cy += LISTPAD_CY;
        }
        else
            sizeButton.cy += infoPtr->szPadding.cy;

        /* calculate button width */
        sizeButton.cx = 2*GetSystemMetrics(SM_CXEDGE) +
            infoPtr->nBitmapWidth + infoPtr->iListGap;
        if (sizeString.cx > 0)
            sizeButton.cx += sizeString.cx + infoPtr->szPadding.cx;

    }
    else
    {
        if (bHasBitmap)
        {
            sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY;
            if (sizeString.cy > 0)
                sizeButton.cy += 1 + sizeString.cy;
            sizeButton.cx = infoPtr->szPadding.cx +
                max(sizeString.cx, infoPtr->nBitmapWidth);
        }
        else
        {
            sizeButton.cy = sizeString.cy + infoPtr->szPadding.cy +
                NONLIST_NOTEXT_OFFSET;
            sizeButton.cx = infoPtr->szPadding.cx +
                max(2*GetSystemMetrics(SM_CXEDGE) + sizeString.cx, infoPtr->nBitmapWidth);
        }
    }
    return sizeButton;
}


/***********************************************************************
* 		TOOLBAR_CalcToolbar
*
* This function calculates button and separator placement. It first
* calculates the button sizes, gets the toolbar window width and then
* calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
* on. It assigns a new location to each item and sends this location to
* the tooltip window if appropriate. Finally, it updates the rcBound
* rect and calculates the new required toolbar window height.
*/
static void
TOOLBAR_CalcToolbar (TOOLBAR_INFO *infoPtr)
{
    SIZE  sizeString, sizeButton;
    BOOL validImageList = FALSE;

    TOOLBAR_CalcStrings (infoPtr, &sizeString);

    TOOLBAR_DumpToolbar (infoPtr, __LINE__);

    if (TOOLBAR_IsValidImageList(infoPtr, 0))
        validImageList = TRUE;
    sizeButton = TOOLBAR_MeasureButton(infoPtr, sizeString, TRUE, validImageList);
    infoPtr->nButtonWidth = sizeButton.cx;
    infoPtr->nButtonHeight = sizeButton.cy;
    infoPtr->iTopMargin = default_top_margin(infoPtr);

    if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
        infoPtr->nButtonWidth = infoPtr->cxMin;
    if ( infoPtr->cxMax > 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
        infoPtr->nButtonWidth = infoPtr->cxMax;

    TOOLBAR_LayoutToolbar(infoPtr);
}

static void
TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
{
    TBUTTON_INFO *btnPtr;
    SIZE sizeButton;
    INT i, nRows, nSepRows;
    INT x, y, cx, cy;
    BOOL bWrap;
    BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0);

    TOOLBAR_WrapToolbar(infoPtr);

    x  = infoPtr->nIndent;
    y  = infoPtr->iTopMargin;
    cx = infoPtr->nButtonWidth;
    cy = infoPtr->nButtonHeight;

    nRows = nSepRows = 0;

    infoPtr->rcBound.top = y;
    infoPtr->rcBound.left = x;
    infoPtr->rcBound.bottom = y + cy;
    infoPtr->rcBound.right = x;

    btnPtr = infoPtr->buttons;

    TRACE("cy=%d\n", cy);

    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
    {
	bWrap = FALSE;
	if (btnPtr->fsState & TBSTATE_HIDDEN)
	{
	    SetRectEmpty (&btnPtr->rect);
	    continue;
	}

	cy = infoPtr->nButtonHeight;

	if (btnPtr->fsStyle & BTNS_SEP) {
	    if (infoPtr->dwStyle & CCS_VERT) {
                cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
                cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth;
	    }
	    else
                cx = (btnPtr->cx > 0) ? btnPtr->cx :
                    (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH;
	}
	else
	{
            if (btnPtr->cx)
              cx = btnPtr->cx;
            else if (btnPtr->fsStyle & BTNS_AUTOSIZE)
            {
              SIZE sz;
	      HDC hdc;
	      HFONT hOldFont;

	      hdc = GetDC (infoPtr->hwndSelf);
	      hOldFont = SelectObject (hdc, infoPtr->hFont);

              TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);

	      SelectObject (hdc, hOldFont);
	      ReleaseDC (infoPtr->hwndSelf, hdc);

              sizeButton = TOOLBAR_MeasureButton(infoPtr, sz,
                  TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap),
                  validImageList);
              cx = sizeButton.cx;
            }
            else
	      cx = infoPtr->nButtonWidth;

            /* if size has been set manually then don't add on extra space
             * for the drop down arrow */
            if (!btnPtr->cx && button_has_ddarrow( infoPtr, btnPtr ))
              cx += DDARROW_WIDTH;
	}
	if (btnPtr->fsState & TBSTATE_WRAP)
		    bWrap = TRUE;

	SetRect (&btnPtr->rect, x, y, x + cx, y + cy);

	if (infoPtr->rcBound.left > x)
	    infoPtr->rcBound.left = x;
	if (infoPtr->rcBound.right < x + cx)
	    infoPtr->rcBound.right = x + cx;
	if (infoPtr->rcBound.bottom < y + cy)
	    infoPtr->rcBound.bottom = y + cy;

        TOOLBAR_TooltipSetRect(infoPtr, btnPtr);

	/* btnPtr->nRow is zero based. The space between the rows is 	*/
	/* also considered as a row. 					*/
	btnPtr->nRow = nRows + nSepRows;

	TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n",
	      i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow,
	      x, y, x+cx, y+cy);

	if( bWrap )
	{
	    if ( !(btnPtr->fsStyle & BTNS_SEP) )
	        y += cy;
	    else
	    {
               if ( !(infoPtr->dwStyle & CCS_VERT))
                    y += cy + ( (btnPtr->cx > 0 ) ?
                                btnPtr->cx : SEPARATOR_WIDTH) * 2 /3;
		else
		    y += cy;

		/* nSepRows is used to calculate the extra height following  */
		/* the last row.					     */
		nSepRows++;
	    }
	    x = infoPtr->nIndent;

	    /* Increment row number unless this is the last button    */
	    /* and it has Wrap set.                                   */
	    if (i != infoPtr->nNumButtons-1)
		nRows++;
	}
	else
	    x += cx;
    }

    /* infoPtr->nRows is the number of rows on the toolbar */
    infoPtr->nRows = nRows + nSepRows + 1;

    TRACE("toolbar button width %d\n", infoPtr->nButtonWidth);
}


static INT
TOOLBAR_InternalHitTest (const TOOLBAR_INFO *infoPtr, const POINT *lpPt, BOOL *button)
{
    TBUTTON_INFO *btnPtr;
    INT i;

    if (button)
        *button = FALSE;

    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
	if (btnPtr->fsState & TBSTATE_HIDDEN)
	    continue;

	if (btnPtr->fsStyle & BTNS_SEP) {
	    if (PtInRect (&btnPtr->rect, *lpPt)) {
		TRACE(" ON SEPARATOR %d!\n", i);
		return -i;
	    }
	}
	else {
	    if (PtInRect (&btnPtr->rect, *lpPt)) {
		TRACE(" ON BUTTON %d!\n", i);
                if (button)
                    *button = TRUE;
		return i;
	    }
	}
    }

    TRACE(" NOWHERE!\n");
    return TOOLBAR_NOWHERE;
}


/* worker for TB_ADDBUTTONS and TB_INSERTBUTTON */
static BOOL
TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButtons, const TBBUTTON *lpTbb, BOOL fUnicode)
{
    INT nOldButtons, nNewButtons, iButton;
    BOOL fHasString = FALSE;

    if (iIndex < 0)  /* iIndex can be negative, what means adding at the end */
        iIndex = infoPtr->nNumButtons;

    nOldButtons = infoPtr->nNumButtons;
    nNewButtons = nOldButtons + nAddButtons;

    infoPtr->buttons = ReAlloc(infoPtr->buttons, sizeof(TBUTTON_INFO)*nNewButtons);
    memmove(&infoPtr->buttons[iIndex + nAddButtons], &infoPtr->buttons[iIndex],
            (nOldButtons - iIndex) * sizeof(TBUTTON_INFO));
    infoPtr->nNumButtons += nAddButtons;

    /* insert new buttons data */
    for (iButton = 0; iButton < nAddButtons; iButton++) {
        TBUTTON_INFO *btnPtr = &infoPtr->buttons[iIndex + iButton];
        INT_PTR str;

        TOOLBAR_DumpTBButton(lpTbb + iButton, fUnicode);

        ZeroMemory(btnPtr, sizeof(*btnPtr));

        btnPtr->iBitmap   = lpTbb[iButton].iBitmap;
        btnPtr->idCommand = lpTbb[iButton].idCommand;
        btnPtr->fsState   = lpTbb[iButton].fsState;
        btnPtr->fsStyle   = lpTbb[iButton].fsStyle;
        btnPtr->dwData    = lpTbb[iButton].dwData;

        if (btnPtr->fsStyle & BTNS_SEP)
            str = -1;
        else
            str = lpTbb[iButton].iString;
        set_string_index( btnPtr, str, fUnicode );
        fHasString |= TOOLBAR_ButtonHasString( btnPtr );

        TOOLBAR_TooltipAddTool(infoPtr, btnPtr);
    }

    if (infoPtr->nNumStrings > 0 || fHasString)
        TOOLBAR_CalcToolbar(infoPtr);
    else
        TOOLBAR_LayoutToolbar(infoPtr);
    TOOLBAR_AutoSize(infoPtr);

    TOOLBAR_DumpToolbar(infoPtr, __LINE__);
    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return TRUE;
}


static INT
TOOLBAR_GetButtonIndex (const TOOLBAR_INFO *infoPtr, INT idCommand, BOOL CommandIsIndex)
{
    TBUTTON_INFO *btnPtr;
    INT i;

    if (CommandIsIndex) {
	TRACE("command is really index command=%d\n", idCommand);
	if (idCommand >= infoPtr->nNumButtons) return -1;
	return idCommand;
    }
    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
	if (btnPtr->idCommand == idCommand) {
	    TRACE("command=%d index=%d\n", idCommand, i);
	    return i;
	}
    }
    TRACE("no index found for command=%d\n", idCommand);
    return -1;
}


static INT
TOOLBAR_GetCheckedGroupButtonIndex (const TOOLBAR_INFO *infoPtr, INT nIndex)
{
    TBUTTON_INFO *btnPtr;
    INT nRunIndex;

    if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
	return -1;

    /* check index button */
    btnPtr = &infoPtr->buttons[nIndex];
    if ((btnPtr->fsStyle & BTNS_CHECKGROUP) == BTNS_CHECKGROUP) {
	if (btnPtr->fsState & TBSTATE_CHECKED)
	    return nIndex;
    }

    /* check previous buttons */
    nRunIndex = nIndex - 1;
    while (nRunIndex >= 0) {
	btnPtr = &infoPtr->buttons[nRunIndex];
	if ((btnPtr->fsStyle & BTNS_GROUP) == BTNS_GROUP) {
	    if (btnPtr->fsState & TBSTATE_CHECKED)
		return nRunIndex;
	}
	else
	    break;
	nRunIndex--;
    }

    /* check next buttons */
    nRunIndex = nIndex + 1;
    while (nRunIndex < infoPtr->nNumButtons) {
	btnPtr = &infoPtr->buttons[nRunIndex];
	if ((btnPtr->fsStyle & BTNS_GROUP) == BTNS_GROUP) {
	    if (btnPtr->fsState & TBSTATE_CHECKED)
		return nRunIndex;
	}
	else
	    break;
	nRunIndex++;
    }

    return -1;
}


static VOID
TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
		    WPARAM wParam, LPARAM lParam)
{
    MSG msg;

    msg.hwnd = hwndMsg;
    msg.message = uMsg;
    msg.wParam = wParam;
    msg.lParam = lParam;
    msg.time = GetMessageTime ();
    msg.pt.x = (short)LOWORD(GetMessagePos ());
    msg.pt.y = (short)HIWORD(GetMessagePos ());

    SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}

static void
TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
{
    if (infoPtr->hwndToolTip && !(button->fsStyle & BTNS_SEP)) {
        TTTOOLINFOW ti;

        ZeroMemory(&ti, sizeof(TTTOOLINFOW));
        ti.cbSize   = sizeof (TTTOOLINFOW);
        ti.hwnd     = infoPtr->hwndSelf;
        ti.uId      = button->idCommand;
        ti.hinst    = 0;
        ti.lpszText = LPSTR_TEXTCALLBACKW;
        /* ti.lParam = random value from the stack? */

        SendMessageW(infoPtr->hwndToolTip, TTM_ADDTOOLW,
            0, (LPARAM)&ti);
    }
}

static void
TOOLBAR_TooltipDelTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
{
    if ((infoPtr->hwndToolTip) && !(button->fsStyle & BTNS_SEP)) {
        TTTOOLINFOW ti;

        ZeroMemory(&ti, sizeof(ti));
        ti.cbSize   = sizeof(ti);
        ti.hwnd     = infoPtr->hwndSelf;
        ti.uId      = button->idCommand;

        SendMessageW(infoPtr->hwndToolTip, TTM_DELTOOLW, 0, (LPARAM)&ti);
    }
}

static void TOOLBAR_TooltipSetRect(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
{
    /* Set the toolTip only for non-hidden, non-separator button */
    if (infoPtr->hwndToolTip && !(button->fsStyle & BTNS_SEP))
    {
        TTTOOLINFOW ti;

        ZeroMemory(&ti, sizeof(ti));
        ti.cbSize = sizeof(ti);
        ti.hwnd = infoPtr->hwndSelf;
        ti.uId = button->idCommand;
        ti.rect = button->rect;
        SendMessageW(infoPtr->hwndToolTip, TTM_NEWTOOLRECTW, 0, (LPARAM)&ti);
    }
}

/* Creates the tooltip control */
static void
TOOLBAR_TooltipCreateControl(TOOLBAR_INFO *infoPtr)
{
    int i;
    NMTOOLTIPSCREATED nmttc;

    infoPtr->hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            infoPtr->hwndSelf, 0, 0, 0);

    if (!infoPtr->hwndToolTip)
        return;

    /* Send NM_TOOLTIPSCREATED notification */
    nmttc.hwndToolTips = infoPtr->hwndToolTip;
    TOOLBAR_SendNotify(&nmttc.hdr, infoPtr, NM_TOOLTIPSCREATED);

    for (i = 0; i < infoPtr->nNumButtons; i++)
    {
        TOOLBAR_TooltipAddTool(infoPtr, &infoPtr->buttons[i]);
        TOOLBAR_TooltipSetRect(infoPtr, &infoPtr->buttons[i]);
    }
}

/* keeps available button list box sorted by button id */
static void TOOLBAR_Cust_InsertAvailButton(HWND hwnd, PCUSTOMBUTTON btnInfoNew)
{
    int i;
    int count;
    PCUSTOMBUTTON btnInfo;
    HWND hwndAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);

    TRACE("button %s, idCommand %d\n", debugstr_w(btnInfoNew->text), btnInfoNew->btn.idCommand);

    count = SendMessageW(hwndAvail, LB_GETCOUNT, 0, 0);

    /* position 0 is always separator */
    for (i = 1; i < count; i++)
    {
        btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndAvail, LB_GETITEMDATA, i, 0);
        if (btnInfoNew->btn.idCommand < btnInfo->btn.idCommand)
        {
            i = SendMessageW(hwndAvail, LB_INSERTSTRING, i, 0);
            SendMessageW(hwndAvail, LB_SETITEMDATA, i, (LPARAM)btnInfoNew);
            return;
        }
    }
    /* id higher than all others add to end */
    i = SendMessageW(hwndAvail, LB_ADDSTRING, 0, 0);
    SendMessageW(hwndAvail, LB_SETITEMDATA, i, (LPARAM)btnInfoNew);
}

static void TOOLBAR_Cust_MoveButton(const CUSTDLG_INFO *custInfo, HWND hwnd, INT nIndexFrom, INT nIndexTo)
{
    NMTOOLBARW nmtb;

	TRACE("index from %d, index to %d\n", nIndexFrom, nIndexTo);

    if (nIndexFrom == nIndexTo)
        return;

    /* MSDN states that iItem is the index of the button, rather than the
     * command ID as used by every other NMTOOLBAR notification */
    nmtb.iItem = nIndexFrom;
    if (TOOLBAR_SendNotify(&nmtb.hdr, custInfo->tbInfo, TBN_QUERYINSERT))
    {
        PCUSTOMBUTTON btnInfo;
        NMHDR hdr;
        HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);
        int count = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);

        btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndList, LB_GETITEMDATA, nIndexFrom, 0);

        SendMessageW(hwndList, LB_DELETESTRING, nIndexFrom, 0);
        SendMessageW(hwndList, LB_INSERTSTRING, nIndexTo, 0);
        SendMessageW(hwndList, LB_SETITEMDATA, nIndexTo, (LPARAM)btnInfo);
        SendMessageW(hwndList, LB_SETCURSEL, nIndexTo, 0);

        if (nIndexTo <= 0)
            EnableWindow(GetDlgItem(hwnd,IDC_MOVEUP_BTN), FALSE);
        else
            EnableWindow(GetDlgItem(hwnd,IDC_MOVEUP_BTN), TRUE);

        /* last item is always separator, so -2 instead of -1 */
        if (nIndexTo >= (count - 2))
            EnableWindow(GetDlgItem(hwnd,IDC_MOVEDN_BTN), FALSE);
        else
            EnableWindow(GetDlgItem(hwnd,IDC_MOVEDN_BTN), TRUE);

        SendMessageW(custInfo->tbHwnd, TB_DELETEBUTTON, nIndexFrom, 0);
        SendMessageW(custInfo->tbHwnd, TB_INSERTBUTTONW, nIndexTo, (LPARAM)&(btnInfo->btn));

        TOOLBAR_SendNotify(&hdr, custInfo->tbInfo, TBN_TOOLBARCHANGE);
    }
}

static void TOOLBAR_Cust_AddButton(const CUSTDLG_INFO *custInfo, HWND hwnd, INT nIndexAvail, INT nIndexTo)
{
    NMTOOLBARW nmtb;

    TRACE("Add: nIndexAvail %d, nIndexTo %d\n", nIndexAvail, nIndexTo);

    /* MSDN states that iItem is the index of the button, rather than the
     * command ID as used by every other NMTOOLBAR notification */
    nmtb.iItem = nIndexAvail;
    if (TOOLBAR_SendNotify(&nmtb.hdr, custInfo->tbInfo, TBN_QUERYINSERT))
    {
        PCUSTOMBUTTON btnInfo;
        NMHDR hdr;
        HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);
        HWND hwndAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);
        int count = SendMessageW(hwndAvail, LB_GETCOUNT, 0, 0);

        btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndAvail, LB_GETITEMDATA, nIndexAvail, 0);

        if (nIndexAvail != 0) /* index == 0 indicates separator */
        {
            /* remove from 'available buttons' list */
            SendMessageW(hwndAvail, LB_DELETESTRING, nIndexAvail, 0);
            if (nIndexAvail == count-1)
                SendMessageW(hwndAvail, LB_SETCURSEL, nIndexAvail-1 , 0);
            else
                SendMessageW(hwndAvail, LB_SETCURSEL, nIndexAvail , 0);
        }
        else
        {
            PCUSTOMBUTTON btnNew;

            /* duplicate 'separator' button */
            btnNew = Alloc(sizeof(CUSTOMBUTTON));
            *btnNew = *btnInfo;
            btnInfo = btnNew;
        }

        /* insert into 'toolbar button' list */
        SendMessageW(hwndList, LB_INSERTSTRING, nIndexTo, 0);
        SendMessageW(hwndList, LB_SETITEMDATA, nIndexTo, (LPARAM)btnInfo);

        SendMessageW(custInfo->tbHwnd, TB_INSERTBUTTONW, nIndexTo, (LPARAM)&(btnInfo->btn));

        TOOLBAR_SendNotify(&hdr, custInfo->tbInfo, TBN_TOOLBARCHANGE);
    }
}

static void TOOLBAR_Cust_RemoveButton(const CUSTDLG_INFO *custInfo, HWND hwnd, INT index)
{
    PCUSTOMBUTTON btnInfo;
    HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);

    TRACE("Remove: index %d\n", index);

    btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndList, LB_GETITEMDATA, index, 0);

    /* send TBN_QUERYDELETE notification */
    if (TOOLBAR_IsButtonRemovable(custInfo->tbInfo, index, btnInfo))
    {
        NMHDR hdr;

        SendMessageW(hwndList, LB_DELETESTRING, index, 0);
        SendMessageW(hwndList, LB_SETCURSEL, index , 0);

        SendMessageW(custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);

        /* insert into 'available button' list */
        if (!(btnInfo->btn.fsStyle & BTNS_SEP))
            TOOLBAR_Cust_InsertAvailButton(hwnd, btnInfo);
        else
            Free(btnInfo);

        TOOLBAR_SendNotify(&hdr, custInfo->tbInfo, TBN_TOOLBARCHANGE);
    }
}

/* drag list notification function for toolbar buttons list box */
static LRESULT TOOLBAR_Cust_ToolbarDragListNotification(const CUSTDLG_INFO *custInfo, HWND hwnd,
                                                        const DRAGLISTINFO *pDLI)
{
    HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);
    switch (pDLI->uNotification)
    {
    case DL_BEGINDRAG:
    {
        INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
        INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
        /* no dragging for last item (separator) */
        if (nCurrentItem >= (nCount - 1)) return FALSE;
        return TRUE;
    }
    case DL_DRAGGING:
    {
        INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
        INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
        /* no dragging past last item (separator) */
        if ((nCurrentItem >= 0) && (nCurrentItem < (nCount - 1)))
        {
            DrawInsert(hwnd, hwndList, nCurrentItem);
            /* FIXME: native uses "move button" cursor */
            return DL_COPYCURSOR;
        }

        /* not over toolbar buttons list */
        if (nCurrentItem < 0)
        {
            POINT ptWindow = pDLI->ptCursor;
            HWND hwndListAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);
            MapWindowPoints(NULL, hwnd, &ptWindow, 1);
            /* over available buttons list? */
            if (ChildWindowFromPoint(hwnd, ptWindow) == hwndListAvail)
                /* FIXME: native uses "move button" cursor */
                return DL_COPYCURSOR;
        }
        /* clear drag arrow */
        DrawInsert(hwnd, hwndList, -1);
        return DL_STOPCURSOR;
    }
    case DL_DROPPED:
    {
        INT nIndexTo = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
        INT nIndexFrom = SendMessageW(hwndList, LB_GETCURSEL, 0, 0);
        INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
        if ((nIndexTo >= 0) && (nIndexTo < (nCount - 1)))
        {
            /* clear drag arrow */
            DrawInsert(hwnd, hwndList, -1);
            /* move item */
            TOOLBAR_Cust_MoveButton(custInfo, hwnd, nIndexFrom, nIndexTo);
        }
        /* not over toolbar buttons list */
        if (nIndexTo < 0)
        {
            POINT ptWindow = pDLI->ptCursor;
            HWND hwndListAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);
            MapWindowPoints(NULL, hwnd, &ptWindow, 1);
            /* over available buttons list? */
            if (ChildWindowFromPoint(hwnd, ptWindow) == hwndListAvail)
                TOOLBAR_Cust_RemoveButton(custInfo, hwnd, nIndexFrom);
        }
        break;
    }
    case DL_CANCELDRAG:
        /* Clear drag arrow */
        DrawInsert(hwnd, hwndList, -1);
        break;
    }

    return 0;
}

/* drag list notification function for available buttons list box */
static LRESULT TOOLBAR_Cust_AvailDragListNotification(const CUSTDLG_INFO *custInfo, HWND hwnd,
                                                      const DRAGLISTINFO *pDLI)
{
    HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);
    switch (pDLI->uNotification)
    {
    case DL_BEGINDRAG:
        return TRUE;
    case DL_DRAGGING:
    {
        INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
        INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
        /* no dragging past last item (separator) */
        if ((nCurrentItem >= 0) && (nCurrentItem < nCount))
        {
            DrawInsert(hwnd, hwndList, nCurrentItem);
            /* FIXME: native uses "move button" cursor */
            return DL_COPYCURSOR;
        }

        /* not over toolbar buttons list */
        if (nCurrentItem < 0)
        {
            POINT ptWindow = pDLI->ptCursor;
            HWND hwndListAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);
            MapWindowPoints(NULL, hwnd, &ptWindow, 1);
            /* over available buttons list? */
            if (ChildWindowFromPoint(hwnd, ptWindow) == hwndListAvail)
                /* FIXME: native uses "move button" cursor */
                return DL_COPYCURSOR;
        }
        /* clear drag arrow */
        DrawInsert(hwnd, hwndList, -1);
        return DL_STOPCURSOR;
    }
    case DL_DROPPED:
    {
        INT nIndexTo = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
        INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
        INT nIndexFrom = SendDlgItemMessageW(hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
        if ((nIndexTo >= 0) && (nIndexTo < nCount))
        {
            /* clear drag arrow */
            DrawInsert(hwnd, hwndList, -1);
            /* add item */
            TOOLBAR_Cust_AddButton(custInfo, hwnd, nIndexFrom, nIndexTo);
        }
    }
    case DL_CANCELDRAG:
        /* Clear drag arrow */
        DrawInsert(hwnd, hwndList, -1);
        break;
    }
    return 0;
}

extern UINT uDragListMessage DECLSPEC_HIDDEN;

/***********************************************************************
 * TOOLBAR_CustomizeDialogProc
 * This function implements the toolbar customization dialog.
 */
static INT_PTR CALLBACK
TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    PCUSTDLG_INFO custInfo = (PCUSTDLG_INFO)GetWindowLongPtrW (hwnd, DWLP_USER);
    PCUSTOMBUTTON btnInfo;
    NMTOOLBARA nmtb;
    TOOLBAR_INFO *infoPtr = custInfo ? custInfo->tbInfo : NULL;

    switch (uMsg)
    {
	case WM_INITDIALOG:
	    custInfo = (PCUSTDLG_INFO)lParam;
	    SetWindowLongPtrW (hwnd, DWLP_USER, (LONG_PTR)custInfo);

	    if (custInfo)
	    {
		WCHAR Buffer[256];
		int i = 0;
		int index;
		NMTBINITCUSTOMIZE nmtbic;

		infoPtr = custInfo->tbInfo;

		/* send TBN_QUERYINSERT notification */
		nmtb.iItem = custInfo->tbInfo->nNumButtons;

		if (!TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_QUERYINSERT))
		    return FALSE;

		nmtbic.hwndDialog = hwnd;
		/* Send TBN_INITCUSTOMIZE notification */
		if (TOOLBAR_SendNotify (&nmtbic.hdr, infoPtr, TBN_INITCUSTOMIZE) ==
		    TBNRF_HIDEHELP)
                {
                    TRACE("TBNRF_HIDEHELP requested\n");
                    ShowWindow(GetDlgItem(hwnd, IDC_HELP_BTN), SW_HIDE);
                }

		/* add items to 'toolbar buttons' list and check if removable */
		for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
                {
                    btnInfo = Alloc(sizeof(CUSTOMBUTTON));
                    memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
                    btnInfo->btn.fsStyle = BTNS_SEP;
                    btnInfo->bVirtual = FALSE;
		    LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);

		    /* send TBN_QUERYDELETE notification */
                    btnInfo->bRemovable = TOOLBAR_IsButtonRemovable(infoPtr, i, btnInfo);

		    index = (int)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
		    SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
		}

		SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMHEIGHT, 0, infoPtr->nBitmapHeight + 8);

		/* insert separator button into 'available buttons' list */
                btnInfo = Alloc(sizeof(CUSTOMBUTTON));
		memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
		btnInfo->btn.fsStyle = BTNS_SEP;
		btnInfo->bVirtual = FALSE;
		btnInfo->bRemovable = TRUE;
		LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
		index = (int)SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
		SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);

		/* insert all buttons into dsa */
		for (i = 0;; i++)
		{
		    /* send TBN_GETBUTTONINFO notification */
                    NMTOOLBARW nmtb;
		    nmtb.iItem = i;
		    nmtb.pszText = Buffer;
		    nmtb.cchText = 256;

                    /* Clear previous button's text */
                    ZeroMemory(nmtb.pszText, nmtb.cchText * sizeof(WCHAR));

                    if (!TOOLBAR_GetButtonInfo(infoPtr, &nmtb))
			break;

		    TRACE("WM_INITDIALOG style: %x iItem(%d) idCommand(%d) iString(%ld) %s\n",
                        nmtb.tbButton.fsStyle, i, 
                        nmtb.tbButton.idCommand,
                        nmtb.tbButton.iString,
                        nmtb.tbButton.iString >= 0 ? debugstr_w(infoPtr->strings[nmtb.tbButton.iString])
                        : "");

		    /* insert button into the appropriate list */
		    index = TOOLBAR_GetButtonIndex (custInfo->tbInfo, nmtb.tbButton.idCommand, FALSE);
		    if (index == -1)
		    {
                        btnInfo = Alloc(sizeof(CUSTOMBUTTON));
			btnInfo->bVirtual = FALSE;
			btnInfo->bRemovable = TRUE;
		    }
		    else
		    {
                        btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, 
                            IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
                    }

                    btnInfo->btn = nmtb.tbButton;
                    if (!(nmtb.tbButton.fsStyle & BTNS_SEP))
                    {
                        if (lstrlenW(nmtb.pszText))
                            lstrcpyW(btnInfo->text, nmtb.pszText);
                        else if (nmtb.tbButton.iString >= 0 && 
                            nmtb.tbButton.iString < infoPtr->nNumStrings)
                        {
                            lstrcpyW(btnInfo->text, 
                                infoPtr->strings[nmtb.tbButton.iString]);
                        }
		    }

		    if (index == -1)
			TOOLBAR_Cust_InsertAvailButton(hwnd, btnInfo);
		}

		SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMHEIGHT, 0, infoPtr->nBitmapHeight + 8);

		/* select first item in the 'available' list */
		SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, 0, 0);

		/* append 'virtual' separator button to the 'toolbar buttons' list */
                btnInfo = Alloc(sizeof(CUSTOMBUTTON));
		memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
		btnInfo->btn.fsStyle = BTNS_SEP;
		btnInfo->bVirtual = TRUE;
		btnInfo->bRemovable = FALSE;
		LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
		index = (int)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
		SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);

		/* select last item in the 'toolbar' list */
		SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index, 0);
		SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETTOPINDEX, index, 0);

		MakeDragList(GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX));
		MakeDragList(GetDlgItem(hwnd, IDC_AVAILBTN_LBOX));

		/* set focus and disable buttons */
		PostMessageW (hwnd, WM_USER, 0, 0);
	    }
	    return TRUE;

	case WM_USER:
	    EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
	    EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
	    EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), FALSE);
	    SetFocus (GetDlgItem (hwnd, IDC_TOOLBARBTN_LBOX));
	    return TRUE;

	case WM_CLOSE:
	    EndDialog(hwnd, FALSE);
	    return TRUE;

	case WM_COMMAND:
	    switch (LOWORD(wParam))
	    {
		case IDC_TOOLBARBTN_LBOX:
		    if (HIWORD(wParam) == LBN_SELCHANGE)
		    {
			PCUSTOMBUTTON btnInfo;
			NMTOOLBARA nmtb;
			int count;
			int index;

			count = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
			index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);

			/* send TBN_QUERYINSERT notification */
			nmtb.iItem = index;
		        TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_QUERYINSERT);

			/* get list box item */
			btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);

			if (index == (count - 1))
			{
			    /* last item (virtual separator) */
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
			}
			else if (index == (count - 2))
			{
			    /* second last item (last non-virtual item) */
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
			}
			else if (index == 0)
			{
			    /* first item */
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
			}
			else
			{
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
			    EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
			}

			EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), btnInfo->bRemovable);
		    }
		    break;

		case IDC_MOVEUP_BTN:
		    {
			int index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
			TOOLBAR_Cust_MoveButton(custInfo, hwnd, index, index-1);
		    }
		    break;

		case IDC_MOVEDN_BTN: /* move down */
		    {
			int index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
			TOOLBAR_Cust_MoveButton(custInfo, hwnd, index, index+1);
		    }
		    break;

		case IDC_REMOVE_BTN: /* remove button */
		    {
			int index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);

			if (LB_ERR == index)
				break;

			TOOLBAR_Cust_RemoveButton(custInfo, hwnd, index);
		    }
		    break;
		case IDC_HELP_BTN:
			TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_CUSTHELP);
			break;
		case IDC_RESET_BTN:
			TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_RESET);
			break;

		case IDOK: /* Add button */
		    {
			int index;
			int indexto;

			index = SendDlgItemMessageW(hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
			indexto = SendDlgItemMessageW(hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);

			TOOLBAR_Cust_AddButton(custInfo, hwnd, index, indexto);
		    }
		    break;

		case IDCANCEL:
		    EndDialog(hwnd, FALSE);
		    break;
	    }
	    return TRUE;

	case WM_DESTROY:
	    {
		int count;
		int i;

		/* delete items from 'toolbar buttons' listbox*/
		count = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
		for (i = 0; i < count; i++)
		{
		    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
		    Free(btnInfo);
		    SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
		}
		SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_RESETCONTENT, 0, 0);


		/* delete items from 'available buttons' listbox*/
		count = SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
		for (i = 0; i < count; i++)
		{
		    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
		    Free(btnInfo);
		    SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
		}
		SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_RESETCONTENT, 0, 0);
            }
	    return TRUE;

	case WM_DRAWITEM:
	    if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
	    {
		LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
		RECT rcButton;
		RECT rcText;
		HPEN hPen, hOldPen;
		HBRUSH hOldBrush;
		COLORREF oldText = 0;
		COLORREF oldBk = 0;

		/* get item data */
               btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, wParam, LB_GETITEMDATA, lpdis->itemID, 0);
		if (btnInfo == NULL)
		{
		    FIXME("btnInfo invalid!\n");
		    return TRUE;
		}

		/* set colors and select objects */
		oldBk = SetBkColor (lpdis->hDC, (lpdis->itemState & ODS_FOCUS)?comctl32_color.clrHighlight:comctl32_color.clrWindow);
		if (btnInfo->bVirtual)
		   oldText = SetTextColor (lpdis->hDC, comctl32_color.clrGrayText);
		else
		   oldText = SetTextColor (lpdis->hDC, (lpdis->itemState & ODS_FOCUS)?comctl32_color.clrHighlightText:comctl32_color.clrWindowText);
                hPen = CreatePen( PS_SOLID, 1,
                                 (lpdis->itemState & ODS_SELECTED)?comctl32_color.clrHighlight:comctl32_color.clrWindow);
		hOldPen = SelectObject (lpdis->hDC, hPen );
		hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));

		/* fill background rectangle */
		Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
			   lpdis->rcItem.right, lpdis->rcItem.bottom);

		/* calculate button and text rectangles */
		CopyRect (&rcButton, &lpdis->rcItem);
		InflateRect (&rcButton, -1, -1);
		CopyRect (&rcText, &rcButton);
		rcButton.right = rcButton.left + custInfo->tbInfo->nBitmapWidth + 6;
		rcText.left = rcButton.right + 2;

		/* draw focus rectangle */
		if (lpdis->itemState & ODS_FOCUS)
		    DrawFocusRect (lpdis->hDC, &lpdis->rcItem);

		/* draw button */
		if (!(infoPtr->dwStyle & TBSTYLE_FLAT))
		    DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);

		/* draw image and text */
		if ((btnInfo->btn.fsStyle & BTNS_SEP) == 0) {
			HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, 
				btnInfo->btn.iBitmap));
		    ImageList_Draw (himl, GETIBITMAP(infoPtr, btnInfo->btn.iBitmap), 
				lpdis->hDC, rcButton.left+3, rcButton.top+3, ILD_NORMAL);
		}
		DrawTextW (lpdis->hDC,  btnInfo->text, -1, &rcText,
			       DT_LEFT | DT_VCENTER | DT_SINGLELINE);

		/* delete objects and reset colors */
		SelectObject (lpdis->hDC, hOldBrush);
		SelectObject (lpdis->hDC, hOldPen);
		SetBkColor (lpdis->hDC, oldBk);
		SetTextColor (lpdis->hDC, oldText);
                DeleteObject( hPen );
		return TRUE;
	    }
	    return FALSE;

	case WM_MEASUREITEM:
	    if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
	    {
		MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;

		lpmis->itemHeight = 15 + 8; /* default height */

		return TRUE;
	    }
	    return FALSE;

	default:
            if (uDragListMessage && (uMsg == uDragListMessage))
            {
                if (wParam == IDC_TOOLBARBTN_LBOX)
                {
                    LRESULT res = TOOLBAR_Cust_ToolbarDragListNotification(
                        custInfo, hwnd, (DRAGLISTINFO *)lParam);
                    SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, res);
                    return TRUE;
                }
                else if (wParam == IDC_AVAILBTN_LBOX)
                {
                    LRESULT res = TOOLBAR_Cust_AvailDragListNotification(
                        custInfo, hwnd, (DRAGLISTINFO *)lParam);
                    SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, res);
                    return TRUE;
                }
            }
            return FALSE;
    }
}

static BOOL
TOOLBAR_AddBitmapToImageList(TOOLBAR_INFO *infoPtr, HIMAGELIST himlDef, const TBITMAP_INFO *bitmap)
{
    HBITMAP hbmLoad;
    INT nCountBefore = ImageList_GetImageCount(himlDef);
    INT nCountAfter;
    INT cxIcon, cyIcon;
    INT nAdded;
    INT nIndex;

    TRACE("adding hInst=%p nID=%d nButtons=%d\n", bitmap->hInst, bitmap->nID, bitmap->nButtons);
    /* Add bitmaps to the default image list */
    if (bitmap->hInst == NULL)         /* a handle was passed */
        hbmLoad = CopyImage(ULongToHandle(bitmap->nID), IMAGE_BITMAP, 0, 0, 0);
    else if (bitmap->hInst == COMCTL32_hModule)
        hbmLoad = LoadImageW( bitmap->hInst, MAKEINTRESOURCEW(bitmap->nID),
                              IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
    else
        hbmLoad = CreateMappedBitmap(bitmap->hInst, bitmap->nID, 0, NULL, 0);

    /* enlarge the bitmap if needed */
    ImageList_GetIconSize(himlDef, &cxIcon, &cyIcon);
    if (bitmap->hInst != COMCTL32_hModule)
        COMCTL32_EnsureBitmapSize(&hbmLoad, cxIcon*(INT)bitmap->nButtons, cyIcon, comctl32_color.clrBtnFace);
    
    nIndex = ImageList_AddMasked(himlDef, hbmLoad, comctl32_color.clrBtnFace);
    DeleteObject(hbmLoad);
    if (nIndex == -1)
        return FALSE;
    
    nCountAfter = ImageList_GetImageCount(himlDef);
    nAdded =  nCountAfter - nCountBefore;
    if (bitmap->nButtons == 0) /* wParam == 0 is special and means add only one image */
    {
        ImageList_SetImageCount(himlDef, nCountBefore + 1);
    } else if (nAdded > (INT)bitmap->nButtons) {
        TRACE("Added more images than wParam: Previous image number %i added %i while wParam %i. Images in list %i\n",
            nCountBefore, nAdded, bitmap->nButtons, nCountAfter);
    }

    infoPtr->nNumBitmaps += nAdded;
    return TRUE;
}

static void
TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr)
{
    HIMAGELIST himlDef;
    HIMAGELIST himlNew;
    INT cx, cy;
    INT i;
    
    himlDef = GETDEFIMAGELIST(infoPtr, 0);
    if (himlDef == NULL || himlDef != infoPtr->himlInt)
        return;
    if (!ImageList_GetIconSize(himlDef, &cx, &cy))
        return;
    if (cx == infoPtr->nBitmapWidth && cy == infoPtr->nBitmapHeight)
        return;

    TRACE("Update icon size: %dx%d -> %dx%d\n",
        cx, cy, infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);

    himlNew = ImageList_Create(infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
                                ILC_COLOR32|ILC_MASK, 8, 2);
    for (i = 0; i < infoPtr->nNumBitmapInfos; i++)
        TOOLBAR_AddBitmapToImageList(infoPtr, himlNew, &infoPtr->bitmaps[i]);
    TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlNew, 0);
    infoPtr->himlInt = himlNew;

    infoPtr->nNumBitmaps -= ImageList_GetImageCount(himlDef);
    ImageList_Destroy(himlDef);
}

/***********************************************************************
 * TOOLBAR_AddBitmap:  Add the bitmaps to the default image list.
 *
 */
static LRESULT
TOOLBAR_AddBitmap (TOOLBAR_INFO *infoPtr, INT count, const TBADDBITMAP *lpAddBmp)
{
    TBITMAP_INFO info;
    INT iSumButtons, i;
    HIMAGELIST himlDef;

    TRACE("hwnd=%p count=%d lpAddBmp=%p\n", infoPtr->hwndSelf, count, lpAddBmp);
    if (!lpAddBmp)
	return -1;

    if (lpAddBmp->hInst == HINST_COMMCTRL)
    {
        info.hInst = COMCTL32_hModule;
        switch (lpAddBmp->nID)
        {
            case IDB_STD_SMALL_COLOR:
	        info.nButtons = 15;
	        info.nID = IDB_STD_SMALL;
	        break;
            case IDB_STD_LARGE_COLOR:
	        info.nButtons = 15;
	        info.nID = IDB_STD_LARGE;
	        break;
            case IDB_VIEW_SMALL_COLOR:
	        info.nButtons = 12;
	        info.nID = IDB_VIEW_SMALL;
	        break;
            case IDB_VIEW_LARGE_COLOR:
	        info.nButtons = 12;
	        info.nID = IDB_VIEW_LARGE;
	        break;
            case IDB_HIST_SMALL_COLOR:
	        info.nButtons = 5;
	        info.nID = IDB_HIST_SMALL;
	        break;
            case IDB_HIST_LARGE_COLOR:
	        info.nButtons = 5;
	        info.nID = IDB_HIST_LARGE;
	        break;
	    default:
	        return -1;
	}

	TRACE ("adding %d internal bitmaps!\n", info.nButtons);

	/* Windows resize all the buttons to the size of a newly added standard image */
	if (lpAddBmp->nID & 1)
	{
	    /* large icons: 24x24. Will make the button 31x30 */
	    SendMessageW (infoPtr->hwndSelf, TB_SETBITMAPSIZE, 0, MAKELPARAM(24, 24));
	}
	else
	{
	    /* small icons: 16x16. Will make the buttons 23x22 */
	    SendMessageW (infoPtr->hwndSelf, TB_SETBITMAPSIZE, 0, MAKELPARAM(16, 16));
	}

	TOOLBAR_CalcToolbar (infoPtr);
    }
    else
    {
	info.nButtons = count;
	info.hInst = lpAddBmp->hInst;
	info.nID = lpAddBmp->nID;
	TRACE("adding %d bitmaps!\n", info.nButtons);
    }
    
    /* check if the bitmap is already loaded and compute iSumButtons */
    iSumButtons = 0;
    for (i = 0; i < infoPtr->nNumBitmapInfos; i++)
    {
        if (infoPtr->bitmaps[i].hInst == info.hInst &&
            infoPtr->bitmaps[i].nID == info.nID)
            return iSumButtons;
        iSumButtons += infoPtr->bitmaps[i].nButtons;
    }

    if (!infoPtr->cimlDef) {
	/* create new default image list */
	TRACE ("creating default image list!\n");

        himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
                                    ILC_COLOR32 | ILC_MASK, info.nButtons, 2);
	TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0);
        infoPtr->himlInt = himlDef;
    }
    else {
        himlDef = GETDEFIMAGELIST(infoPtr, 0);
    }

    if (!himlDef) {
        WARN("No default image list available\n");
        return -1;
    }

    if (!TOOLBAR_AddBitmapToImageList(infoPtr, himlDef, &info))
        return -1;

    TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos);
    infoPtr->bitmaps = ReAlloc(infoPtr->bitmaps, (infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
    infoPtr->bitmaps[infoPtr->nNumBitmapInfos] = info;
    infoPtr->nNumBitmapInfos++;
    TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos);

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return iSumButtons;
}


static LRESULT
TOOLBAR_AddButtonsT(TOOLBAR_INFO *infoPtr, INT nAddButtons, const TBBUTTON* lpTbb, BOOL fUnicode)
{
    TRACE("adding %d buttons (unicode=%d)!\n", nAddButtons, fUnicode);

    return TOOLBAR_InternalInsertButtonsT(infoPtr, -1, nAddButtons, lpTbb, fUnicode);
}


static LRESULT
TOOLBAR_AddStringW (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam)
{
#define MAX_RESOURCE_STRING_LENGTH 512
    BOOL fFirstString = (infoPtr->nNumStrings == 0);
    INT nIndex = infoPtr->nNumStrings;

    TRACE("%p, %lx\n", hInstance, lParam);

    if (IS_INTRESOURCE(lParam)) {
	WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
	WCHAR delimiter;
	WCHAR *next_delim;
        HRSRC hrsrc;
	WCHAR *p;
	INT len;

	TRACE("adding string from resource\n");

        if (!hInstance) return -1;

        hrsrc = FindResourceW( hInstance, MAKEINTRESOURCEW((LOWORD(lParam) >> 4) + 1),
                               (LPWSTR)RT_STRING );
        if (!hrsrc)
        {
            TRACE("string not found in resources\n");
            return -1;
        }

        len = LoadStringW (hInstance, (UINT)lParam,
                             szString, MAX_RESOURCE_STRING_LENGTH);

        TRACE("len=%d %s\n", len, debugstr_w(szString));
        if (len == 0 || len == 1)
            return nIndex;

        TRACE("delimiter: 0x%x\n", *szString);
        delimiter = *szString;
        p = szString + 1;

        while ((next_delim = strchrW(p, delimiter)) != NULL) {
            *next_delim = 0;
            if (next_delim + 1 >= szString + len)
            {
                /* this may happen if delimiter == '\0' or if the last char is a
                 * delimiter (then it is ignored like the native does) */
                break;
            }

            infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1));
            Str_SetPtrW(&infoPtr->strings[infoPtr->nNumStrings], p);
            infoPtr->nNumStrings++;

            p = next_delim + 1;
        }
    }
    else {
	LPWSTR p = (LPWSTR)lParam;
	INT len;

	if (p == NULL)
	    return -1;
	TRACE("adding string(s) from array\n");
	while (*p) {
            len = strlenW (p);

            TRACE("len=%d %s\n", len, debugstr_w(p));
            infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1));
            Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p);
	    infoPtr->nNumStrings++;

	    p += (len+1);
	}
    }

    if (fFirstString)
        TOOLBAR_CalcToolbar(infoPtr);
    return nIndex;
}


static LRESULT
TOOLBAR_AddStringA (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam)
{
    BOOL fFirstString = (infoPtr->nNumStrings == 0);
    LPSTR p;
    INT nIndex;
    INT len;

    TRACE("%p, %lx\n", hInstance, lParam);

    if (IS_INTRESOURCE(lParam))  /* load from resources */
        return TOOLBAR_AddStringW(infoPtr, hInstance, lParam);

    p = (LPSTR)lParam;
    if (p == NULL)
        return -1;

    TRACE("adding string(s) from array\n");
    nIndex = infoPtr->nNumStrings;
    while (*p) {
        len = strlen (p);
        TRACE("len=%d \"%s\"\n", len, p);

        infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1));
        Str_SetPtrAtoW(&infoPtr->strings[infoPtr->nNumStrings], p);
        infoPtr->nNumStrings++;

        p += (len+1);
    }

    if (fFirstString)
        TOOLBAR_CalcToolbar(infoPtr);
    return nIndex;
}


static LRESULT
TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr)
{
    TRACE("auto sizing, style=%x!\n", infoPtr->dwStyle);
    TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight);

    if (!(infoPtr->dwStyle & CCS_NORESIZE))
    {
        RECT window_rect, parent_rect;
        UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE;
        HWND parent;
        INT  x, y, cx, cy;

        parent = GetParent (infoPtr->hwndSelf);

        if (!parent || !infoPtr->bDoRedraw)
            return 0;

        GetClientRect(parent, &parent_rect);

        x = parent_rect.left;
        y = parent_rect.top;

        cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER;
        cx = parent_rect.right - parent_rect.left;

        if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_NOMOVEY)
        {
            GetWindowRect(infoPtr->hwndSelf, &window_rect);
            MapWindowPoints( 0, parent, (POINT *)&window_rect, 2 );
            y = window_rect.top;
        }
        if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_BOTTOM)
        {
            GetWindowRect(infoPtr->hwndSelf, &window_rect);
            y = parent_rect.bottom - ( window_rect.bottom - window_rect.top);
        }

        if (infoPtr->dwStyle & CCS_NOPARENTALIGN)
            uPosFlags |= SWP_NOMOVE;
    
        if (!(infoPtr->dwStyle & CCS_NODIVIDER))
            cy += GetSystemMetrics(SM_CYEDGE);

        if (infoPtr->dwStyle & WS_BORDER)
        {
            cx += 2 * GetSystemMetrics(SM_CXBORDER);
            cy += 2 * GetSystemMetrics(SM_CYBORDER);
        }

        SetWindowPos(infoPtr->hwndSelf, NULL, x, y, cx, cy, uPosFlags);
    }

    if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL))
    {
        TOOLBAR_LayoutToolbar(infoPtr);
        InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
    }

    return 0;
}


static inline LRESULT
TOOLBAR_ButtonCount (const TOOLBAR_INFO *infoPtr)
{
    return infoPtr->nNumButtons;
}


static inline LRESULT
TOOLBAR_ButtonStructSize (TOOLBAR_INFO *infoPtr, DWORD Size)
{
    infoPtr->dwStructSize = Size;

    return 0;
}


static LRESULT
TOOLBAR_ChangeBitmap (TOOLBAR_INFO *infoPtr, INT Id, INT Index)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;

    TRACE("button %d, iBitmap now %d\n", Id, Index);

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    btnPtr->iBitmap = Index;

    /* we HAVE to erase the background, the new bitmap could be */
    /* transparent */
    InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

    return TRUE;
}


static LRESULT
TOOLBAR_CheckButton (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;
    INT nOldIndex = -1;
    BOOL bChecked = FALSE;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);

    TRACE("hwnd=%p, btn index=%d, lParam=0x%08lx\n", infoPtr->hwndSelf, nIndex, lParam);

    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];

    bChecked = (btnPtr->fsState & TBSTATE_CHECKED) != 0;

    if (!LOWORD(lParam))
	btnPtr->fsState &= ~TBSTATE_CHECKED;
    else {
	if (btnPtr->fsStyle & BTNS_GROUP) {
	    nOldIndex =
		TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
	    if (nOldIndex == nIndex)
		return 0;
	    if (nOldIndex != -1)
		infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
	}
	btnPtr->fsState |= TBSTATE_CHECKED;
    }

    if( bChecked != LOWORD(lParam) )
    {
        if (nOldIndex != -1)
            InvalidateRect(infoPtr->hwndSelf, &infoPtr->buttons[nOldIndex].rect, TRUE);
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
    }

    /* FIXME: Send a WM_NOTIFY?? */

    return TRUE;
}


static LRESULT
TOOLBAR_CommandToIndex (const TOOLBAR_INFO *infoPtr, INT Id)
{
    return TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
}


static LRESULT
TOOLBAR_Customize (TOOLBAR_INFO *infoPtr)
{
    CUSTDLG_INFO custInfo;
    LRESULT ret;
    NMHDR nmhdr;

    custInfo.tbInfo = infoPtr;
    custInfo.tbHwnd = infoPtr->hwndSelf;

    /* send TBN_BEGINADJUST notification */
    TOOLBAR_SendNotify (&nmhdr, infoPtr, TBN_BEGINADJUST);

    ret = DialogBoxParamW (COMCTL32_hModule, MAKEINTRESOURCEW(IDD_TBCUSTOMIZE),
                           infoPtr->hwndSelf, TOOLBAR_CustomizeDialogProc, (LPARAM)&custInfo);

    /* send TBN_ENDADJUST notification */
    TOOLBAR_SendNotify (&nmhdr, infoPtr, TBN_ENDADJUST);

    return ret;
}


static LRESULT
TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
{
    NMTOOLBARW nmtb;
    TBUTTON_INFO *btnPtr = &infoPtr->buttons[nIndex];

    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
        return FALSE;

    memset(&nmtb, 0, sizeof(nmtb));
    nmtb.iItem = btnPtr->idCommand;
    nmtb.tbButton.iBitmap = btnPtr->iBitmap;
    nmtb.tbButton.idCommand = btnPtr->idCommand;
    nmtb.tbButton.fsState = btnPtr->fsState;
    nmtb.tbButton.fsStyle = btnPtr->fsStyle;
    nmtb.tbButton.dwData = btnPtr->dwData;
    nmtb.tbButton.iString = btnPtr->iString;
    TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_DELETINGBUTTON);

    TOOLBAR_TooltipDelTool(infoPtr, &infoPtr->buttons[nIndex]);

    if (infoPtr->nNumButtons == 1) {
	TRACE(" simple delete!\n");
        free_string( infoPtr->buttons );
	Free (infoPtr->buttons);
	infoPtr->buttons = NULL;
	infoPtr->nNumButtons = 0;
    }
    else {
	TBUTTON_INFO *oldButtons = infoPtr->buttons;
        TRACE("complex delete! [nIndex=%d]\n", nIndex);

	infoPtr->nNumButtons--;
	infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
        if (nIndex > 0) {
            memcpy (&infoPtr->buttons[0], &oldButtons[0],
                    nIndex * sizeof(TBUTTON_INFO));
        }

        if (nIndex < infoPtr->nNumButtons) {
            memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
                    (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
        }

        free_string( oldButtons + nIndex );
	Free (oldButtons);
    }

    TOOLBAR_LayoutToolbar(infoPtr);

    InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);

    return TRUE;
}


static LRESULT
TOOLBAR_EnableButton (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;
    DWORD bState;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);

    TRACE("hwnd=%p, btn id=%d, lParam=0x%08lx\n", infoPtr->hwndSelf, Id, lParam);

    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];

    bState = btnPtr->fsState & TBSTATE_ENABLED;

    /* update the toolbar button state */
    if(!LOWORD(lParam)) {
 	btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
    } else {
	btnPtr->fsState |= TBSTATE_ENABLED;
    }

    /* redraw the button only if the state of the button changed */
    if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

    return TRUE;
}


static inline LRESULT
TOOLBAR_GetAnchorHighlight (const TOOLBAR_INFO *infoPtr)
{
    return infoPtr->bAnchor;
}


static LRESULT
TOOLBAR_GetBitmap (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return infoPtr->buttons[nIndex].iBitmap;
}


static inline LRESULT
TOOLBAR_GetBitmapFlags (void)
{
    return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
}


static LRESULT
TOOLBAR_GetButton (const TOOLBAR_INFO *infoPtr, INT nIndex, TBBUTTON *lpTbb)
{
    TBUTTON_INFO *btnPtr;

    if (lpTbb == NULL)
	return FALSE;

    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    lpTbb->iBitmap   = btnPtr->iBitmap;
    lpTbb->idCommand = btnPtr->idCommand;
    lpTbb->fsState   = btnPtr->fsState;
    lpTbb->fsStyle   = btnPtr->fsStyle;
    lpTbb->bReserved[0] = 0;
    lpTbb->bReserved[1] = 0;
    lpTbb->dwData    = btnPtr->dwData;
    lpTbb->iString   = btnPtr->iString;

    return TRUE;
}


static LRESULT
TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTbInfo, BOOL bUnicode)
{
    /* TBBUTTONINFOW and TBBUTTONINFOA have the same layout*/
    TBUTTON_INFO *btnPtr;
    INT nIndex;

    if (lpTbInfo == NULL)
	return -1;

    /* MSDN documents an iImageLabel field added in Vista but it is not present in
     * the headers and tests shows that even with comctl 6 Vista accepts only the
     * original TBBUTTONINFO size
     */
    if (lpTbInfo->cbSize != sizeof(TBBUTTONINFOW))
    {
        WARN("Invalid button size\n");
	return -1;
    }

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, lpTbInfo->dwMask & TBIF_BYINDEX);
    if (nIndex == -1)
	return -1;

    btnPtr = &infoPtr->buttons[nIndex];
    if (lpTbInfo->dwMask & TBIF_COMMAND)
	lpTbInfo->idCommand = btnPtr->idCommand;
    if (lpTbInfo->dwMask & TBIF_IMAGE)
	lpTbInfo->iImage = btnPtr->iBitmap;
    if (lpTbInfo->dwMask & TBIF_LPARAM)
	lpTbInfo->lParam = btnPtr->dwData;
    if (lpTbInfo->dwMask & TBIF_SIZE)
        /* tests show that for separators TBIF_SIZE returns not calculated width,
           but cx property, that differs from 0 only if application have
           specifically set it */
        lpTbInfo->cx = (btnPtr->fsStyle & BTNS_SEP)
            ? btnPtr->cx : (WORD)(btnPtr->rect.right - btnPtr->rect.left);
    if (lpTbInfo->dwMask & TBIF_STATE)
	lpTbInfo->fsState = btnPtr->fsState;
    if (lpTbInfo->dwMask & TBIF_STYLE)
	lpTbInfo->fsStyle = btnPtr->fsStyle;
    if (lpTbInfo->dwMask & TBIF_TEXT) {
        /* TB_GETBUTTONINFO doesn't retrieve text from the string list, so we
           can't use TOOLBAR_GetText here */
        if (!IS_INTRESOURCE(btnPtr->iString) && (btnPtr->iString != -1)) {
            LPWSTR lpText = (LPWSTR)btnPtr->iString;
            if (bUnicode)
                Str_GetPtrW(lpText, lpTbInfo->pszText, lpTbInfo->cchText);
            else
                Str_GetPtrWtoA(lpText, (LPSTR)lpTbInfo->pszText, lpTbInfo->cchText);
        } else
            lpTbInfo->pszText[0] = '\0';
    }
    return nIndex;
}


static inline LRESULT
TOOLBAR_GetButtonSize (const TOOLBAR_INFO *infoPtr)
{
    return MAKELONG((WORD)infoPtr->nButtonWidth,
                    (WORD)infoPtr->nButtonHeight);
}


static LRESULT
TOOLBAR_GetButtonText (const TOOLBAR_INFO *infoPtr, INT Id, LPWSTR lpStr, BOOL isW)
{
    INT nIndex;
    LPWSTR lpText;
    LRESULT ret = 0;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    lpText = TOOLBAR_GetText(infoPtr,&infoPtr->buttons[nIndex]);

    if (isW)
    {
        if (lpText)
        {
            ret = strlenW (lpText);
            if (lpStr) strcpyW (lpStr, lpText);
        }
    }
    else
        ret = WideCharToMultiByte( CP_ACP, 0, lpText, -1,
                                  (LPSTR)lpStr, lpStr ? 0x7fffffff : 0, NULL, NULL ) - 1;
    return ret;
}


static LRESULT
TOOLBAR_GetDisabledImageList (const TOOLBAR_INFO *infoPtr, WPARAM wParam)
{
    TRACE("hwnd=%p, wParam=%ld\n", infoPtr->hwndSelf, wParam);
    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
    return (LRESULT)GETDISIMAGELIST(infoPtr, wParam);
}


static inline LRESULT
TOOLBAR_GetExtendedStyle (const TOOLBAR_INFO *infoPtr)
{
    TRACE("\n");

    return infoPtr->dwExStyle;
}


static LRESULT
TOOLBAR_GetHotImageList (const TOOLBAR_INFO *infoPtr, WPARAM wParam)
{
    TRACE("hwnd=%p, wParam=%ld\n", infoPtr->hwndSelf, wParam);
    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
    return (LRESULT)GETHOTIMAGELIST(infoPtr, wParam);
}


static LRESULT
TOOLBAR_GetHotItem (const TOOLBAR_INFO *infoPtr)
{
    if (!((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf)))
	return -1;

    if (infoPtr->nHotItem < 0)
	return -1;

    return (LRESULT)infoPtr->nHotItem;
}


static LRESULT
TOOLBAR_GetDefImageList (const TOOLBAR_INFO *infoPtr, WPARAM wParam)
{
    TRACE("hwnd=%p, wParam=%ld\n", infoPtr->hwndSelf, wParam);
    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
    return (LRESULT) GETDEFIMAGELIST(infoPtr, wParam);
}


static LRESULT
TOOLBAR_GetInsertMark (const TOOLBAR_INFO *infoPtr, TBINSERTMARK *lptbim)
{
    TRACE("hwnd = %p, lptbim = %p\n", infoPtr->hwndSelf, lptbim);

    *lptbim = infoPtr->tbim;

    return 0;
}


static inline LRESULT
TOOLBAR_GetInsertMarkColor (const TOOLBAR_INFO *infoPtr)
{
    TRACE("hwnd = %p\n", infoPtr->hwndSelf);

    return (LRESULT)infoPtr->clrInsertMark;
}


static LRESULT
TOOLBAR_GetItemRect (const TOOLBAR_INFO *infoPtr, INT nIndex, LPRECT lpRect)
{
    TBUTTON_INFO *btnPtr;

    btnPtr = &infoPtr->buttons[nIndex];
    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
	return FALSE;

    if (lpRect == NULL)
	return FALSE;
    if (btnPtr->fsState & TBSTATE_HIDDEN)
	return FALSE;

    lpRect->left   = btnPtr->rect.left;
    lpRect->right  = btnPtr->rect.right;
    lpRect->bottom = btnPtr->rect.bottom;
    lpRect->top    = btnPtr->rect.top;

    return TRUE;
}


static LRESULT
TOOLBAR_GetMaxSize (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize)
{
    if (lpSize == NULL)
	return FALSE;

    lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
    lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;

    TRACE("maximum size %d x %d\n",
	   infoPtr->rcBound.right - infoPtr->rcBound.left,
	   infoPtr->rcBound.bottom - infoPtr->rcBound.top);

    return TRUE;
}


/* << TOOLBAR_GetObject >> */


static inline LRESULT
TOOLBAR_GetPadding (const TOOLBAR_INFO *infoPtr)
{
    return MAKELONG(infoPtr->szPadding.cx, infoPtr->szPadding.cy);
}


static LRESULT
TOOLBAR_GetRect (const TOOLBAR_INFO *infoPtr, INT Id, LPRECT lpRect)
{
    TBUTTON_INFO *btnPtr;
    INT        nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    btnPtr = &infoPtr->buttons[nIndex];
    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
	return FALSE;

    if (lpRect == NULL)
	return FALSE;

    lpRect->left   = btnPtr->rect.left;
    lpRect->right  = btnPtr->rect.right;
    lpRect->bottom = btnPtr->rect.bottom;
    lpRect->top    = btnPtr->rect.top;

    return TRUE;
}


static inline LRESULT
TOOLBAR_GetRows (const TOOLBAR_INFO *infoPtr)
{
    return infoPtr->nRows;
}


static LRESULT
TOOLBAR_GetState (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return infoPtr->buttons[nIndex].fsState;
}


static inline LRESULT
TOOLBAR_GetStyle (const TOOLBAR_INFO *infoPtr)
{
    return infoPtr->dwStyle;
}


static inline LRESULT
TOOLBAR_GetTextRows (const TOOLBAR_INFO *infoPtr)
{
    return infoPtr->nMaxTextRows;
}


static LRESULT
TOOLBAR_GetToolTips (TOOLBAR_INFO *infoPtr)
{
    if ((infoPtr->dwStyle & TBSTYLE_TOOLTIPS) && (infoPtr->hwndToolTip == NULL))
        TOOLBAR_TooltipCreateControl(infoPtr);
    return (LRESULT)infoPtr->hwndToolTip;
}


static LRESULT
TOOLBAR_GetUnicodeFormat (const TOOLBAR_INFO *infoPtr)
{
    TRACE("%s hwnd=%p\n",
	   infoPtr->bUnicode ? "TRUE" : "FALSE", infoPtr->hwndSelf);

    return infoPtr->bUnicode;
}


static inline LRESULT
TOOLBAR_GetVersion (const TOOLBAR_INFO *infoPtr)
{
    return infoPtr->iVersion;
}


static LRESULT
TOOLBAR_HideButton (TOOLBAR_INFO *infoPtr, INT Id, BOOL fHide)
{
    TBUTTON_INFO *btnPtr;
    BYTE oldState;
    INT nIndex;

    TRACE("\n");

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    oldState = btnPtr->fsState;

    if (fHide)
	btnPtr->fsState |= TBSTATE_HIDDEN;
    else
	btnPtr->fsState &= ~TBSTATE_HIDDEN;

    if (oldState != btnPtr->fsState) {
        TOOLBAR_LayoutToolbar (infoPtr);
        InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
    }

    return TRUE;
}


static inline LRESULT
TOOLBAR_HitTest (const TOOLBAR_INFO *infoPtr, const POINT* lpPt)
{
    return TOOLBAR_InternalHitTest (infoPtr, lpPt, NULL);
}


static LRESULT
TOOLBAR_Indeterminate (const TOOLBAR_INFO *infoPtr, INT Id, BOOL fIndeterminate)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;
    DWORD oldState;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    oldState = btnPtr->fsState;

    if (fIndeterminate)
	btnPtr->fsState |= TBSTATE_INDETERMINATE;
    else
	btnPtr->fsState &= ~TBSTATE_INDETERMINATE;

    if(oldState != btnPtr->fsState)
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

    return TRUE;
}


static LRESULT
TOOLBAR_InsertButtonT(TOOLBAR_INFO *infoPtr, INT nIndex, const TBBUTTON *lpTbb, BOOL fUnicode)
{
    if (lpTbb == NULL)
	return FALSE;

    if (nIndex == -1) {
       /* EPP: this seems to be an undocumented call (from my IE4)
	* I assume in that case that:
	* - index of insertion is at the end of existing buttons
	* I only see this happen with nIndex == -1, but it could have a special
	* meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
	*/
	nIndex = infoPtr->nNumButtons;

    } else if (nIndex < 0)
       return FALSE;

    TRACE("inserting button index=%d\n", nIndex);
    if (nIndex > infoPtr->nNumButtons) {
	nIndex = infoPtr->nNumButtons;
	TRACE("adjust index=%d\n", nIndex);
    }

    return TOOLBAR_InternalInsertButtonsT(infoPtr, nIndex, 1, lpTbb, fUnicode);
}

/* << TOOLBAR_InsertMarkHitTest >> */


static LRESULT
TOOLBAR_IsButtonChecked (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
}


static LRESULT
TOOLBAR_IsButtonEnabled (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
}


static LRESULT
TOOLBAR_IsButtonHidden (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
}


static LRESULT
TOOLBAR_IsButtonHighlighted (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
}


static LRESULT
TOOLBAR_IsButtonIndeterminate (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
}


static LRESULT
TOOLBAR_IsButtonPressed (const TOOLBAR_INFO *infoPtr, INT Id)
{
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return -1;

    return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
}


static LRESULT
TOOLBAR_LoadImages (TOOLBAR_INFO *infoPtr, WPARAM wParam, HINSTANCE hInstance)
{
    TBADDBITMAP tbab;
    tbab.hInst = hInstance;
    tbab.nID = wParam;

    TRACE("hwnd = %p, hInst = %p, nID = %lu\n", infoPtr->hwndSelf, tbab.hInst, tbab.nID);

    return TOOLBAR_AddBitmap(infoPtr, 0, &tbab);
}


static LRESULT
TOOLBAR_MapAccelerator (const TOOLBAR_INFO *infoPtr, WCHAR wAccel, UINT *pIDButton)
{
    WCHAR wszAccel[] = {'&',wAccel,0};
    int i;
    
    TRACE("hwnd = %p, wAccel = %x(%s), pIDButton = %p\n",
        infoPtr->hwndSelf, wAccel, debugstr_wn(&wAccel,1), pIDButton);
    
    for (i = 0; i < infoPtr->nNumButtons; i++)
    {
        TBUTTON_INFO *btnPtr = infoPtr->buttons+i;
        if (!(btnPtr->fsStyle & BTNS_NOPREFIX) &&
            !(btnPtr->fsState & TBSTATE_HIDDEN))
        {
            int iLen = strlenW(wszAccel);
            LPCWSTR lpszStr = TOOLBAR_GetText(infoPtr, btnPtr);
            
            if (!lpszStr)
                continue;

            while (*lpszStr)
            {
                if ((lpszStr[0] == '&') && (lpszStr[1] == '&'))
                {
                    lpszStr += 2;
                    continue;
                }
                if (!strncmpiW(lpszStr, wszAccel, iLen))
                {
                    *pIDButton = btnPtr->idCommand;
                    return TRUE;
                }
                lpszStr++;
            }
        }
    }
    return FALSE;
}


static LRESULT
TOOLBAR_MarkButton (const TOOLBAR_INFO *infoPtr, INT Id, BOOL fMark)
{
    INT nIndex;
    DWORD oldState;
    TBUTTON_INFO *btnPtr;

    TRACE("hwnd = %p, Id = %d, fMark = 0%d\n", infoPtr->hwndSelf, Id, fMark);

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
        return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    oldState = btnPtr->fsState;

    if (fMark)
        btnPtr->fsState |= TBSTATE_MARKED;
    else
        btnPtr->fsState &= ~TBSTATE_MARKED;

    if(oldState != btnPtr->fsState)
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

    return TRUE;
}


/* fixes up an index of a button affected by a move */
static inline void TOOLBAR_MoveFixupIndex(INT* pIndex, INT nIndex, INT nMoveIndex, BOOL bMoveUp)
{
    if (bMoveUp)
    {
        if (*pIndex > nIndex && *pIndex <= nMoveIndex)
            (*pIndex)--;
        else if (*pIndex == nIndex)
            *pIndex = nMoveIndex;
    }
    else
    {
        if (*pIndex >= nMoveIndex && *pIndex < nIndex)
            (*pIndex)++;
        else if (*pIndex == nIndex)
            *pIndex = nMoveIndex;
    }
}


static LRESULT
TOOLBAR_MoveButton (TOOLBAR_INFO *infoPtr, INT Id, INT nMoveIndex)
{
    INT nIndex;
    INT nCount;
    TBUTTON_INFO button;

    TRACE("hwnd=%p, Id=%d, nMoveIndex=%d\n", infoPtr->hwndSelf, Id, nMoveIndex);

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, TRUE);
    if ((nIndex == -1) || (nMoveIndex < 0))
        return FALSE;

    if (nMoveIndex > infoPtr->nNumButtons - 1)
        nMoveIndex = infoPtr->nNumButtons - 1;

    button = infoPtr->buttons[nIndex];

    /* move button right */
    if (nIndex < nMoveIndex)
    {
        nCount = nMoveIndex - nIndex;
        memmove(&infoPtr->buttons[nIndex], &infoPtr->buttons[nIndex+1], nCount*sizeof(TBUTTON_INFO));
        infoPtr->buttons[nMoveIndex] = button;

        TOOLBAR_MoveFixupIndex(&infoPtr->nButtonDown, nIndex, nMoveIndex, TRUE);
        TOOLBAR_MoveFixupIndex(&infoPtr->nButtonDrag, nIndex, nMoveIndex, TRUE);
        TOOLBAR_MoveFixupIndex(&infoPtr->nOldHit, nIndex, nMoveIndex, TRUE);
        TOOLBAR_MoveFixupIndex(&infoPtr->nHotItem, nIndex, nMoveIndex, TRUE);
    }
    else if (nIndex > nMoveIndex) /* move button left */
    {
        nCount = nIndex - nMoveIndex;
        memmove(&infoPtr->buttons[nMoveIndex+1], &infoPtr->buttons[nMoveIndex], nCount*sizeof(TBUTTON_INFO));
        infoPtr->buttons[nMoveIndex] = button;

        TOOLBAR_MoveFixupIndex(&infoPtr->nButtonDown, nIndex, nMoveIndex, FALSE);
        TOOLBAR_MoveFixupIndex(&infoPtr->nButtonDrag, nIndex, nMoveIndex, FALSE);
        TOOLBAR_MoveFixupIndex(&infoPtr->nOldHit, nIndex, nMoveIndex, FALSE);
        TOOLBAR_MoveFixupIndex(&infoPtr->nHotItem, nIndex, nMoveIndex, FALSE);
    }

    TOOLBAR_LayoutToolbar(infoPtr);
    TOOLBAR_AutoSize(infoPtr);
    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return TRUE;
}


static LRESULT
TOOLBAR_PressButton (const TOOLBAR_INFO *infoPtr, INT Id, BOOL fPress)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;
    DWORD oldState;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    oldState = btnPtr->fsState;

    if (fPress)
	btnPtr->fsState |= TBSTATE_PRESSED;
    else
	btnPtr->fsState &= ~TBSTATE_PRESSED;

    if(oldState != btnPtr->fsState)
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

    return TRUE;
}

/* FIXME: there might still be some confusion her between number of buttons
 * and number of bitmaps */
static LRESULT
TOOLBAR_ReplaceBitmap (TOOLBAR_INFO *infoPtr, const TBREPLACEBITMAP *lpReplace)
{
    HBITMAP hBitmap;
    int i = 0, nOldButtons = 0, pos = 0;
    int nOldBitmaps, nNewBitmaps = 0;
    HIMAGELIST himlDef = 0;

    TRACE("hInstOld %p nIDOld %lx hInstNew %p nIDNew %lx nButtons %x\n",
          lpReplace->hInstOld, lpReplace->nIDOld, lpReplace->hInstNew, lpReplace->nIDNew,
          lpReplace->nButtons);

    if (lpReplace->hInstOld == HINST_COMMCTRL)
    {
        FIXME("changing standard bitmaps not implemented\n");
        return FALSE;
    }
    else if (lpReplace->hInstOld != 0 && lpReplace->hInstOld != lpReplace->hInstNew)
        FIXME("resources not in the current module not implemented\n");

    TRACE("To be replaced hInstOld %p nIDOld %lx\n", lpReplace->hInstOld, lpReplace->nIDOld);
    for (i = 0; i < infoPtr->nNumBitmapInfos; i++) {
        TBITMAP_INFO *tbi = &infoPtr->bitmaps[i];
        TRACE("tbimapinfo %d hInstOld %p nIDOld %x\n", i, tbi->hInst, tbi->nID);
        if (tbi->hInst == lpReplace->hInstOld && tbi->nID == lpReplace->nIDOld)
        {
            TRACE("Found: nButtons %d hInst %p nID %x\n", tbi->nButtons, tbi->hInst, tbi->nID);
            nOldButtons = tbi->nButtons;
            tbi->nButtons = lpReplace->nButtons;
            tbi->hInst = lpReplace->hInstNew;
            tbi->nID = lpReplace->nIDNew;
            TRACE("tbimapinfo changed %d hInstOld %p nIDOld %x\n", i, tbi->hInst, tbi->nID);
            break;
        }
        pos += tbi->nButtons;
    }

    if (nOldButtons == 0)
    {
        WARN("No hinst/bitmap found! hInst %p nID %lx\n", lpReplace->hInstOld, lpReplace->nIDOld);
        return FALSE;
    }
    
    /* copy the bitmap before adding it as ImageList_AddMasked modifies the
    * bitmap
    */
    if (lpReplace->hInstNew)
        hBitmap = LoadBitmapW(lpReplace->hInstNew,(LPWSTR)lpReplace->nIDNew);
    else
        hBitmap = CopyImage((HBITMAP)lpReplace->nIDNew, IMAGE_BITMAP, 0, 0, 0);

    himlDef = GETDEFIMAGELIST(infoPtr, 0); /* fixme: correct? */
    nOldBitmaps = ImageList_GetImageCount(himlDef);

    /* ImageList_Replace(GETDEFIMAGELIST(), pos, hBitmap, NULL); */

    for (i = pos + nOldBitmaps - 1; i >= pos; i--)
        ImageList_Remove(himlDef, i);

    if (hBitmap)
    {
       ImageList_AddMasked (himlDef, hBitmap, comctl32_color.clrBtnFace);
       nNewBitmaps = ImageList_GetImageCount(himlDef);
       DeleteObject(hBitmap);
    }

    infoPtr->nNumBitmaps = infoPtr->nNumBitmaps - nOldBitmaps + nNewBitmaps;

    TRACE(" pos %d  %d old bitmaps replaced by %d new ones.\n",
            pos, nOldBitmaps, nNewBitmaps);

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return TRUE;
}


/* helper for TOOLBAR_SaveRestoreW */
static BOOL
TOOLBAR_Save(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *params)
{
    NMTBSAVE save;
    INT ret, i;
    BOOL alloced = FALSE;
    HKEY key;

    TRACE( "save to %s %s\n", debugstr_w(params->pszSubKey), debugstr_w(params->pszValueName) );

    memset( &save, 0, sizeof(save) );
    save.cbData = infoPtr->nNumButtons * sizeof(DWORD);
    save.iItem = -1;
    save.cButtons = infoPtr->nNumButtons;
    save.tbButton.idCommand = -1;
    TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE );

    if (!save.pData)
    {
        save.pData = Alloc( save.cbData );
        if (!save.pData) return FALSE;
        alloced = TRUE;
    }
    if (!save.pCurrent) save.pCurrent = save.pData;

    for (i = 0; i < infoPtr->nNumButtons; i++)
    {
        save.iItem = i;
        save.tbButton.iBitmap = infoPtr->buttons[i].iBitmap;
        save.tbButton.idCommand = infoPtr->buttons[i].idCommand;
        save.tbButton.fsState = infoPtr->buttons[i].fsState;
        save.tbButton.fsStyle = infoPtr->buttons[i].fsStyle;
        memset( save.tbButton.bReserved, 0, sizeof(save.tbButton.bReserved) );
        save.tbButton.dwData = infoPtr->buttons[i].dwData;
        save.tbButton.iString = infoPtr->buttons[i].iString;

        *save.pCurrent++ = save.tbButton.idCommand;

        TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE );
    }

    ret = RegCreateKeyW( params->hkr, params->pszSubKey, &key );
    if (ret == ERROR_SUCCESS)
    {
        ret = RegSetValueExW( key, params->pszValueName, 0, REG_BINARY, (BYTE *)save.pData, save.cbData );
        RegCloseKey( key );
    }

    if (alloced) Free( save.pData );
    return !ret;
}


/* helper for TOOLBAR_Restore */
static void
TOOLBAR_DeleteAllButtons(TOOLBAR_INFO *infoPtr)
{
    INT i;

    for (i = 0; i < infoPtr->nNumButtons; i++)
    {
        free_string( infoPtr->buttons + i );
        TOOLBAR_TooltipDelTool(infoPtr, &infoPtr->buttons[i]);
    }

    Free(infoPtr->buttons);
    infoPtr->buttons = NULL;
    infoPtr->nNumButtons = 0;
}


/* helper for TOOLBAR_SaveRestoreW */
static BOOL
TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
{
    LONG res;
    HKEY hkey = NULL;
    BOOL ret = FALSE;
    DWORD dwType;
    DWORD dwSize = 0;
    NMTBRESTORE nmtbr;
    NMHDR hdr;

    /* restore toolbar information */
    TRACE("restore from %s %s\n", debugstr_w(lpSave->pszSubKey),
        debugstr_w(lpSave->pszValueName));

    memset(&nmtbr, 0, sizeof(nmtbr));

    res = RegOpenKeyExW(lpSave->hkr, lpSave->pszSubKey, 0,
        KEY_QUERY_VALUE, &hkey);
    if (!res)
        res = RegQueryValueExW(hkey, lpSave->pszValueName, NULL, &dwType,
            NULL, &dwSize);
    if (!res && dwType != REG_BINARY)
        res = ERROR_FILE_NOT_FOUND;
    if (!res)
    {
        nmtbr.pData = Alloc(dwSize);
        nmtbr.cbData = dwSize;
        if (!nmtbr.pData) res = ERROR_OUTOFMEMORY;
    }
    if (!res)
        res = RegQueryValueExW(hkey, lpSave->pszValueName, NULL, &dwType,
            (LPBYTE)nmtbr.pData, &dwSize);
    if (!res)
    {
        nmtbr.pCurrent = nmtbr.pData;
        nmtbr.iItem = -1;
        nmtbr.cbBytesPerRecord = sizeof(DWORD);
        nmtbr.cButtons = nmtbr.cbData / nmtbr.cbBytesPerRecord;

        if (!TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE))
        {
            INT i, count = nmtbr.cButtons;

            /* remove all existing buttons as this function is designed to
             * restore the toolbar to a previously saved state */
            TOOLBAR_DeleteAllButtons(infoPtr);

            for (i = 0; i < count; i++)
            {
                nmtbr.iItem = i;
                nmtbr.tbButton.iBitmap = -1;
                nmtbr.tbButton.fsState = 0;
                nmtbr.tbButton.fsStyle = 0;
                nmtbr.tbButton.dwData = 0;
                nmtbr.tbButton.iString = 0;

                if (*nmtbr.pCurrent & 0x80000000)
                {
                    /* separator */
                    nmtbr.tbButton.iBitmap = SEPARATOR_WIDTH;
                    nmtbr.tbButton.idCommand = 0;
                    nmtbr.tbButton.fsStyle = BTNS_SEP;
                    if (*nmtbr.pCurrent != (DWORD)-1)
                        nmtbr.tbButton.fsState = TBSTATE_HIDDEN;
                }
                else
                    nmtbr.tbButton.idCommand = (int)*nmtbr.pCurrent;

                nmtbr.pCurrent++;
                
                TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE);

                /* All returned ptrs and -1 are ignored */
                if (!IS_INTRESOURCE(nmtbr.tbButton.iString))
                    nmtbr.tbButton.iString = 0;

                TOOLBAR_InsertButtonT(infoPtr, -1, &nmtbr.tbButton, TRUE);
            }

            TOOLBAR_SendNotify( &hdr, infoPtr, TBN_BEGINADJUST );
            for (i = 0; ; i++)
            {
                NMTOOLBARW tb;
                TBBUTTONINFOW bi;
                WCHAR buf[128];
                UINT code = infoPtr->bUnicode ? TBN_GETBUTTONINFOW : TBN_GETBUTTONINFOA;
                INT idx;

                memset( &tb, 0, sizeof(tb) );
                tb.iItem = i;
                tb.cchText = sizeof(buf) / sizeof(buf[0]);
                tb.pszText = buf;

                /* Use the same struct for both A and W versions since the layout is the same. */
                if (!TOOLBAR_SendNotify( &tb.hdr, infoPtr, code ))
                    break;

                idx = TOOLBAR_GetButtonIndex( infoPtr, tb.tbButton.idCommand, FALSE );
                if (idx == -1) continue;

                /* tb.pszText is ignored - the string comes from tb.tbButton.iString, which may
                   be an index or a ptr.  Either way it is simply copied.  There is no api to change
                   the string index, so we set it manually.  The other properties can be set with SetButtonInfo. */
                free_string( infoPtr->buttons + idx );
                infoPtr->buttons[idx].iString = tb.tbButton.iString;

                memset( &bi, 0, sizeof(bi) );
                bi.cbSize = sizeof(bi);
                bi.dwMask = TBIF_IMAGE | TBIF_STATE | TBIF_STYLE | TBIF_LPARAM;
                bi.iImage = tb.tbButton.iBitmap;
                bi.fsState = tb.tbButton.fsState;
                bi.fsStyle = tb.tbButton.fsStyle;
                bi.lParam = tb.tbButton.dwData;

                TOOLBAR_SetButtonInfo( infoPtr, tb.tbButton.idCommand, &bi, TRUE );
            }
            TOOLBAR_SendNotify( &hdr, infoPtr, TBN_ENDADJUST );

            /* remove all uninitialised buttons
             * note: loop backwards to avoid having to fixup i on a
             * delete */
            for (i = infoPtr->nNumButtons - 1; i >= 0; i--)
                if (infoPtr->buttons[i].iBitmap == -1)
                    TOOLBAR_DeleteButton(infoPtr, i);

            /* only indicate success if at least one button survived */
            if (infoPtr->nNumButtons > 0) ret = TRUE;
        }
    }
    Free (nmtbr.pData);
    RegCloseKey(hkey);

    return ret;
}


static LRESULT
TOOLBAR_SaveRestoreW (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSW *lpSave)
{
    if (lpSave == NULL) return 0;

    if (wParam)
        return TOOLBAR_Save(infoPtr, lpSave);
    else
        return TOOLBAR_Restore(infoPtr, lpSave);
}


static LRESULT
TOOLBAR_SaveRestoreA (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSA *lpSave)
{
    LPWSTR pszValueName = 0, pszSubKey = 0;
    TBSAVEPARAMSW SaveW;
    LRESULT result = 0;
    int len;

    if (lpSave == NULL) return 0;

    len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, NULL, 0);
    pszSubKey = Alloc(len * sizeof(WCHAR));
    if (!pszSubKey) goto exit;
    MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, pszSubKey, len);

    len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszValueName, -1, NULL, 0);
    pszValueName = Alloc(len * sizeof(WCHAR));
    if (!pszValueName) goto exit;
    MultiByteToWideChar(CP_ACP, 0, lpSave->pszValueName, -1, pszValueName, len);

    SaveW.pszValueName = pszValueName;
    SaveW.pszSubKey = pszSubKey;
    SaveW.hkr = lpSave->hkr;
    result = TOOLBAR_SaveRestoreW(infoPtr, wParam, &SaveW);

exit:
    Free (pszValueName);
    Free (pszSubKey);

    return result;
}


static LRESULT
TOOLBAR_SetAnchorHighlight (TOOLBAR_INFO *infoPtr, BOOL bAnchor)
{
    BOOL bOldAnchor = infoPtr->bAnchor;

    TRACE("hwnd=%p, bAnchor = %s\n", infoPtr->hwndSelf, bAnchor ? "TRUE" : "FALSE");

    infoPtr->bAnchor = bAnchor;

    /* Native does not remove the hot effect from an already hot button */

    return (LRESULT)bOldAnchor;
}


static LRESULT
TOOLBAR_SetBitmapSize (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    HIMAGELIST himlDef = GETDEFIMAGELIST(infoPtr, 0);
    short width = (short)LOWORD(lParam);
    short height = (short)HIWORD(lParam);

    TRACE("hwnd=%p, wParam=%ld, lParam=%ld\n", infoPtr->hwndSelf, wParam, lParam);

    if (wParam != 0)
        FIXME("wParam is %ld. Perhaps image list index?\n", wParam);

    /* 0 width or height is changed to 1 */
    if (width == 0)
        width = 1;
    if (height == 0)
        height = 1;

    if (infoPtr->nNumButtons > 0)
        TRACE("%d buttons, undoc change to bitmap size : %d-%d -> %d-%d\n",
              infoPtr->nNumButtons,
              infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, width, height);

    if (width < -1 || height < -1)
    {
        /* Windows destroys the imagelist and seems to actually use negative
         * values to compute button sizes */
        FIXME("Negative bitmap sizes not supported (%d, %d)\n", width, height);
        return FALSE;
    }

    /* width or height of -1 means no change */
    if (width != -1)
        infoPtr->nBitmapWidth = width;
    if (height != -1)
        infoPtr->nBitmapHeight = height;

    if ((himlDef == infoPtr->himlInt) &&
        (ImageList_GetImageCount(infoPtr->himlInt) == 0))
    {
        ImageList_SetIconSize(infoPtr->himlInt, infoPtr->nBitmapWidth,
            infoPtr->nBitmapHeight);
    }

    TOOLBAR_CalcToolbar(infoPtr);
    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
    return TRUE;
}


static LRESULT
TOOLBAR_SetButtonInfo (TOOLBAR_INFO *infoPtr, INT Id,
                       const TBBUTTONINFOW *lptbbi, BOOL isW)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;
    RECT oldBtnRect;

    if (lptbbi == NULL)
	return FALSE;
    if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
	return FALSE;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, lptbbi->dwMask & TBIF_BYINDEX);
    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];
    if (lptbbi->dwMask & TBIF_COMMAND)
	btnPtr->idCommand = lptbbi->idCommand;
    if (lptbbi->dwMask & TBIF_IMAGE)
	btnPtr->iBitmap = lptbbi->iImage;
    if (lptbbi->dwMask & TBIF_LPARAM)
	btnPtr->dwData = lptbbi->lParam;
    if (lptbbi->dwMask & TBIF_SIZE)
	btnPtr->cx = lptbbi->cx;
    if (lptbbi->dwMask & TBIF_STATE)
	btnPtr->fsState = lptbbi->fsState;
    if (lptbbi->dwMask & TBIF_STYLE)
	btnPtr->fsStyle = lptbbi->fsStyle;

    if (lptbbi->dwMask & TBIF_TEXT)
        set_stringT( btnPtr, lptbbi->pszText, isW );

    /* save the button rect to see if we need to redraw the whole toolbar */
    oldBtnRect = btnPtr->rect;
    TOOLBAR_LayoutToolbar(infoPtr);

    if (!EqualRect(&oldBtnRect, &btnPtr->rect))
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    else
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

    return TRUE;
}


static LRESULT
TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam)
{
    INT cx = (short)LOWORD(lParam), cy = (short)HIWORD(lParam);
    int top = default_top_margin(infoPtr);

    if ((cx < 0) || (cy < 0))
    {
        ERR("invalid parameter 0x%08x\n", (DWORD)lParam);
        return FALSE;
    }

    TRACE("%p, cx = %d, cy = %d\n", infoPtr->hwndSelf, cx, cy);

    /* The documentation claims you can only change the button size before
     * any button has been added. But this is wrong.
     * WINZIP32.EXE (ver 8) calls this on one of its buttons after adding
     * it to the toolbar, and it checks that the return value is nonzero - mjm
     * Further testing shows that we must actually perform the change too.
     */
    /*
     * The documentation also does not mention that if 0 is supplied for
     * either size, the system changes it to the default of 24 wide and
     * 22 high. Demonstrated in ControlSpy Toolbar. GLA 3/02
     */
    if (cx == 0) cx = 24;
    if (cy == 0) cy = 22;

    cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth);
    cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight);

    if (cx != infoPtr->nButtonWidth || cy != infoPtr->nButtonHeight ||
        top != infoPtr->iTopMargin)
    {
        infoPtr->nButtonWidth = cx;
        infoPtr->nButtonHeight = cy;
        infoPtr->iTopMargin = top;

        TOOLBAR_LayoutToolbar( infoPtr );
        InvalidateRect( infoPtr->hwndSelf, NULL, TRUE );
    }
    return TRUE;
}


static LRESULT
TOOLBAR_SetButtonWidth (TOOLBAR_INFO *infoPtr, LPARAM lParam)
{
    /* if setting to current values, ignore */
    if ((infoPtr->cxMin == (short)LOWORD(lParam)) &&
	(infoPtr->cxMax == (short)HIWORD(lParam))) {
	TRACE("matches current width, min=%d, max=%d, no recalc\n",
	      infoPtr->cxMin, infoPtr->cxMax);
	return TRUE;
    }

    /* save new values */
    infoPtr->cxMin = (short)LOWORD(lParam);
    infoPtr->cxMax = (short)HIWORD(lParam);

    /* otherwise we need to recalc the toolbar and in some cases
       recalc the bounding rectangle (does DrawText w/ DT_CALCRECT
       which doesn't actually draw - GA). */
    TRACE("number of buttons %d, cx=%d, cy=%d, recalcing\n",
	infoPtr->nNumButtons, infoPtr->cxMin, infoPtr->cxMax);

    TOOLBAR_CalcToolbar (infoPtr);

    InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);

    return TRUE;
}


static LRESULT
TOOLBAR_SetCmdId (TOOLBAR_INFO *infoPtr, INT nIndex, INT nId)
{
    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
	return FALSE;

    infoPtr->buttons[nIndex].idCommand = nId;

    if (infoPtr->hwndToolTip) {

	FIXME("change tool tip!\n");

    }

    return TRUE;
}


static LRESULT
TOOLBAR_SetDisabledImageList (TOOLBAR_INFO *infoPtr, WPARAM wParam, HIMAGELIST himl)
{
    HIMAGELIST himlTemp;
    INT id = 0;

    if (infoPtr->iVersion >= 5)
        id = wParam;

    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlDis, 
        &infoPtr->cimlDis, himl, id);

    /* FIXME: redraw ? */

    return (LRESULT)himlTemp;
}


static LRESULT
TOOLBAR_SetDrawTextFlags (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    DWORD dwTemp;

    TRACE("hwnd = %p, dwMask = 0x%08x, dwDTFlags = 0x%08x\n", infoPtr->hwndSelf, (DWORD)wParam, (DWORD)lParam);

    dwTemp = infoPtr->dwDTFlags;
    infoPtr->dwDTFlags =
	(infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;

    return (LRESULT)dwTemp;
}

/* This function differs a bit from what MSDN says it does:
 * 1. lParam contains extended style flags to OR with current style
 *  (MSDN isn't clear on the OR bit)
 * 2. wParam appears to contain extended style flags to be reset
 *  (MSDN says that this parameter is reserved)
 */
static LRESULT
TOOLBAR_SetExtendedStyle (TOOLBAR_INFO *infoPtr, DWORD mask, DWORD style)
{
    DWORD old_style = infoPtr->dwExStyle;

    TRACE("mask=0x%08x, style=0x%08x\n", mask, style);

    if (mask)
	infoPtr->dwExStyle = (old_style & ~mask) | (style & mask);
    else
	infoPtr->dwExStyle = style;

    if (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL)
	FIXME("Unknown Toolbar Extended Style 0x%08x. Please report.\n",
	      (infoPtr->dwExStyle & ~TBSTYLE_EX_ALL));

    if ((old_style ^ infoPtr->dwExStyle) & TBSTYLE_EX_MIXEDBUTTONS)
        TOOLBAR_CalcToolbar(infoPtr);
    else
        TOOLBAR_LayoutToolbar(infoPtr);

    TOOLBAR_AutoSize(infoPtr);
    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return old_style;
}


static LRESULT
TOOLBAR_SetHotImageList (TOOLBAR_INFO *infoPtr, WPARAM wParam, HIMAGELIST himl)
{
    HIMAGELIST himlTemp;
    INT id = 0;

    if (infoPtr->iVersion >= 5)
        id = wParam;

    TRACE("hwnd = %p, himl = %p, id = %d\n", infoPtr->hwndSelf, himl, id);

    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlHot, 
        &infoPtr->cimlHot, himl, id);

    /* FIXME: redraw ? */

    return (LRESULT)himlTemp;
}


/* Makes previous hot button no longer hot, makes the specified
 * button hot and sends appropriate notifications. dwReason is one or
 * more HICF_ flags. Specify nHit < 0 to make no buttons hot.
 * NOTE 1: this function does not validate nHit
 * NOTE 2: the name of this function is completely made up and
 * not based on any documentation from Microsoft. */
static void
TOOLBAR_SetHotItemEx (TOOLBAR_INFO *infoPtr, INT nHit, DWORD dwReason)
{
    if (infoPtr->nHotItem != nHit)
    {
        NMTBHOTITEM nmhotitem;
        TBUTTON_INFO *btnPtr = NULL, *oldBtnPtr = NULL;

        nmhotitem.dwFlags = dwReason;
        if(infoPtr->nHotItem >= 0)
        {
            oldBtnPtr = &infoPtr->buttons[infoPtr->nHotItem];
            nmhotitem.idOld = oldBtnPtr->idCommand;
        }
        else
        {
            nmhotitem.dwFlags |= HICF_ENTERING;
            nmhotitem.idOld = 0;
        }

        if (nHit >= 0)
        {
            btnPtr = &infoPtr->buttons[nHit];
            nmhotitem.idNew = btnPtr->idCommand;
        }
	else
	{
	    nmhotitem.dwFlags |= HICF_LEAVING;
	    nmhotitem.idNew = 0;
	}

	/* now change the hot and invalidate the old and new buttons - if the
	 * parent agrees */
	if (!TOOLBAR_SendNotify(&nmhotitem.hdr, infoPtr, TBN_HOTITEMCHANGE))
	{
            if (oldBtnPtr) {
                oldBtnPtr->bHot = FALSE;
                InvalidateRect(infoPtr->hwndSelf, &oldBtnPtr->rect, TRUE);
            }
            /* setting disabled buttons as hot fails even if the notify contains the button id */
            if (btnPtr && (btnPtr->fsState & TBSTATE_ENABLED)) {
                btnPtr->bHot = TRUE;
                InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
                infoPtr->nHotItem = nHit;
            }
            else
                infoPtr->nHotItem = -1;            
        }
    }
}

static LRESULT
TOOLBAR_SetHotItem (TOOLBAR_INFO *infoPtr, INT nHotItem)
{
    INT nOldHotItem = infoPtr->nHotItem;

    TRACE("hwnd = %p, nHotItem = %d\n", infoPtr->hwndSelf, nHotItem);

    if (nHotItem >= infoPtr->nNumButtons)
        return infoPtr->nHotItem;
    
    if (nHotItem < 0)
        nHotItem = -1;

    /* NOTE: an application can still remove the hot item even if anchor
     * highlighting is enabled */

    TOOLBAR_SetHotItemEx(infoPtr, nHotItem, HICF_OTHER);

    if (nOldHotItem < 0)
        return -1;

    return (LRESULT)nOldHotItem;
}


static LRESULT
TOOLBAR_SetImageList (TOOLBAR_INFO *infoPtr, WPARAM wParam, HIMAGELIST himl)
{
    HIMAGELIST himlTemp;
    INT oldButtonWidth = infoPtr->nButtonWidth;
    INT oldBitmapWidth = infoPtr->nBitmapWidth;
    INT oldBitmapHeight = infoPtr->nBitmapHeight;
    INT i, id = 0;

    if (infoPtr->iVersion >= 5)
        id = wParam;

    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlDef, 
        &infoPtr->cimlDef, himl, id);

    infoPtr->nNumBitmaps = 0;
    for (i = 0; i < infoPtr->cimlDef; i++)
        infoPtr->nNumBitmaps += ImageList_GetImageCount(infoPtr->himlDef[i]->himl);

    if (!ImageList_GetIconSize(himl, &infoPtr->nBitmapWidth,
            &infoPtr->nBitmapHeight))
    {
        infoPtr->nBitmapWidth = 1;
        infoPtr->nBitmapHeight = 1;
    }
    if ((oldBitmapWidth != infoPtr->nBitmapWidth) || (oldBitmapHeight != infoPtr->nBitmapHeight))
    {
        TOOLBAR_CalcToolbar(infoPtr);
        if (infoPtr->nButtonWidth < oldButtonWidth)
            TOOLBAR_SetButtonSize(infoPtr, MAKELONG(oldButtonWidth, infoPtr->nButtonHeight));
    }

    TRACE("hwnd %p, new himl=%p, id = %d, count=%d, bitmap w=%d, h=%d\n",
	  infoPtr->hwndSelf, infoPtr->himlDef, id, infoPtr->nNumBitmaps,
	  infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return (LRESULT)himlTemp;
}


static LRESULT
TOOLBAR_SetIndent (TOOLBAR_INFO *infoPtr, INT nIndent)
{
    infoPtr->nIndent = nIndent;

    TRACE("\n");

    /* process only on indent changing */
    if(infoPtr->nIndent != nIndent)
    {
        infoPtr->nIndent = nIndent;
        TOOLBAR_CalcToolbar (infoPtr);
        InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
    }

    return TRUE;
}


static LRESULT
TOOLBAR_SetInsertMark (TOOLBAR_INFO *infoPtr, const TBINSERTMARK *lptbim)
{
    TRACE("hwnd = %p, lptbim = { %d, 0x%08x}\n", infoPtr->hwndSelf, lptbim->iButton, lptbim->dwFlags);

    if ((lptbim->dwFlags & ~TBIMHT_AFTER) != 0)
    {
        FIXME("Unrecognized flag(s): 0x%08x\n", (lptbim->dwFlags & ~TBIMHT_AFTER));
        return 0;
    }

    if ((lptbim->iButton == -1) || 
        ((lptbim->iButton < infoPtr->nNumButtons) &&
         (lptbim->iButton >= 0)))
    {
        infoPtr->tbim = *lptbim;
        /* FIXME: don't need to update entire toolbar */
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    }
    else
        ERR("Invalid button index %d\n", lptbim->iButton);

    return 0;
}


static LRESULT
TOOLBAR_SetInsertMarkColor (TOOLBAR_INFO *infoPtr, COLORREF clr)
{
    infoPtr->clrInsertMark = clr;

    /* FIXME: don't need to update entire toolbar */
    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}


static LRESULT
TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *infoPtr, INT nMaxRows)
{
    infoPtr->nMaxTextRows = nMaxRows;

    TOOLBAR_CalcToolbar(infoPtr);
    return TRUE;
}


/* MSDN gives slightly wrong info on padding.
 * 1. It is not only used on buttons with the BTNS_AUTOSIZE style
 * 2. It is not used to create a blank area between the edge of the button
 *    and the text or image if TBSTYLE_LIST is set. It is used to control
 *    the gap between the image and text. 
 * 3. It is not applied to both sides. If TBSTYLE_LIST is set it is used 
 *    to control the bottom and right borders [with the border being
 *    szPadding.cx - (GetSystemMetrics(SM_CXEDGE)+1)], otherwise the padding
 *    is shared evenly on both sides of the button.
 * See blueprints in comments above TOOLBAR_MeasureButton for more info.
 */
static LRESULT
TOOLBAR_SetPadding (TOOLBAR_INFO *infoPtr, LPARAM lParam)
{
    DWORD  oldPad;

    oldPad = MAKELONG(infoPtr->szPadding.cx, infoPtr->szPadding.cy);
    infoPtr->szPadding.cx = min(LOWORD((DWORD)lParam), GetSystemMetrics(SM_CXEDGE));
    infoPtr->szPadding.cy = min(HIWORD((DWORD)lParam), GetSystemMetrics(SM_CYEDGE));
    TRACE("cx=%d, cy=%d\n",
	  infoPtr->szPadding.cx, infoPtr->szPadding.cy);
    return (LRESULT) oldPad;
}


static LRESULT
TOOLBAR_SetParent (TOOLBAR_INFO *infoPtr, HWND hParent)
{
    HWND hwndOldNotify;

    TRACE("\n");

    hwndOldNotify = infoPtr->hwndNotify;
    infoPtr->hwndNotify = hParent;

    return (LRESULT)hwndOldNotify;
}


static LRESULT
TOOLBAR_SetRows (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPRECT lprc)
{
    int rows = LOWORD(wParam);
    BOOL bLarger = HIWORD(wParam);

    TRACE("\n");

    TRACE("Setting rows to %d (%d)\n", rows, bLarger);

    if(infoPtr->nRows != rows)
    {
        TBUTTON_INFO *btnPtr = infoPtr->buttons;
        int curColumn = 0; /* Current column                      */
        int curRow    = 0; /* Current row                         */
        int hidden    = 0; /* Number of hidden buttons */
        int seps      = 0; /* Number of separators     */
        int idealWrap = 0; /* Ideal wrap point         */
        int i;
        BOOL wrap;

        /*
           Calculate new size and wrap points - Under windows, setrows will
           change the dimensions if needed to show the number of requested
           rows (if CCS_NORESIZE is set), or will take up the whole window
           (if no CCS_NORESIZE).

           Basic algorithm - If N buttons, and y rows requested, each row
           contains N/y buttons.

           FIXME: Handling of separators not obvious from testing results
           FIXME: Take width of window into account?
         */

        /* Loop through the buttons one by one counting key items  */
        for (i = 0; i < infoPtr->nNumButtons; i++ )
        {
            btnPtr[i].fsState &= ~TBSTATE_WRAP;
            if (btnPtr[i].fsState & TBSTATE_HIDDEN)
                hidden++;
            else if (btnPtr[i].fsStyle & BTNS_SEP)
                seps++;
        }

        /* FIXME: Separators make this quite complex */
        if (seps) FIXME("Separators unhandled\n");

        /* Round up so more per line, i.e., less rows */
        idealWrap = (infoPtr->nNumButtons - hidden + (rows-1)) / (rows ? rows : 1);

        /* Calculate ideal wrap point if we are allowed to grow, but cannot
           achieve the requested number of rows. */
        if (bLarger && idealWrap > 1)
        {
            int resRows = (infoPtr->nNumButtons + (idealWrap-1)) / idealWrap;
            int moreRows = (infoPtr->nNumButtons + (idealWrap-2)) / (idealWrap-1);

            if (resRows < rows && moreRows > rows)
            {
                idealWrap--;
                TRACE("Changing idealWrap due to bLarger (now %d)\n", idealWrap);
            }
        }

        curColumn = curRow = 0;
        wrap = FALSE;
        TRACE("Trying to wrap at %d (%d,%d,%d)\n", idealWrap,
              infoPtr->nNumButtons, hidden, rows);

        for (i = 0; i < infoPtr->nNumButtons; i++ )
        {
            if (btnPtr[i].fsState & TBSTATE_HIDDEN)
                continue;

            /* Step on, wrap if necessary or flag next to wrap */
            if (!wrap) {
                curColumn++;
            } else {
                wrap = FALSE;
                curColumn = 1;
                curRow++;
            }

            if (curColumn > (idealWrap-1)) {
                wrap = TRUE;
                btnPtr[i].fsState |= TBSTATE_WRAP;
            }
        }

        TRACE("Result - %d rows\n", curRow + 1);

        /* recalculate toolbar */
        TOOLBAR_CalcToolbar (infoPtr);

        /* Resize if necessary (Only if NORESIZE is set - odd, but basically
           if NORESIZE is NOT set, then the toolbar will always be resized to
           take up the whole window. With it set, sizing needs to be manual. */
        if (infoPtr->dwStyle & CCS_NORESIZE) {
            SetWindowPos(infoPtr->hwndSelf, NULL, 0, 0,
                         infoPtr->rcBound.right - infoPtr->rcBound.left,
                         infoPtr->rcBound.bottom - infoPtr->rcBound.top,
                         SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
        }

        /* repaint toolbar */
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    }

    /* return bounding rectangle */
    if (lprc) {
	lprc->left   = infoPtr->rcBound.left;
	lprc->right  = infoPtr->rcBound.right;
	lprc->top    = infoPtr->rcBound.top;
	lprc->bottom = infoPtr->rcBound.bottom;
    }

    return 0;
}


static LRESULT
TOOLBAR_SetState (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam)
{
    TBUTTON_INFO *btnPtr;
    INT nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
    if (nIndex == -1)
	return FALSE;

    btnPtr = &infoPtr->buttons[nIndex];

    /* if hidden state has changed the invalidate entire window and recalc */
    if ((btnPtr->fsState & TBSTATE_HIDDEN) != (LOWORD(lParam) & TBSTATE_HIDDEN)) {
	btnPtr->fsState = LOWORD(lParam);
	TOOLBAR_CalcToolbar (infoPtr);
	InvalidateRect(infoPtr->hwndSelf, 0, TRUE);
	return TRUE;
    }

    /* process state changing if current state doesn't match new state */
    if(btnPtr->fsState != LOWORD(lParam))
    {
        btnPtr->fsState = LOWORD(lParam);
        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
    }

    return TRUE;
}

static inline void unwrap(TOOLBAR_INFO *info)
{
    int i;

    for (i = 0; i < info->nNumButtons; i++)
	info->buttons[i].fsState &= ~TBSTATE_WRAP;
}

static LRESULT
TOOLBAR_SetStyle (TOOLBAR_INFO *infoPtr, DWORD style)
{
    DWORD dwOldStyle = infoPtr->dwStyle;

    TRACE("new style 0x%08x\n", style);

    if (style & TBSTYLE_LIST)
        infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS;
    else
        infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS;

    infoPtr->dwStyle = style;
    TOOLBAR_CheckStyle(infoPtr);

    if ((dwOldStyle ^ style) & TBSTYLE_WRAPABLE)
    {
        if (dwOldStyle & TBSTYLE_WRAPABLE)
            unwrap(infoPtr);
        TOOLBAR_CalcToolbar(infoPtr);
    }
    else if ((dwOldStyle ^ style) & CCS_VERT)
        TOOLBAR_LayoutToolbar(infoPtr);

    /* only resize if one of the CCS_* styles was changed */
    if ((dwOldStyle ^ style) & COMMON_STYLES)
    {
        TOOLBAR_AutoSize(infoPtr);
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    }

    return 0;
}


static inline LRESULT
TOOLBAR_SetToolTips (TOOLBAR_INFO *infoPtr, HWND hwndTooltip)
{
    TRACE("hwnd=%p, hwndTooltip=%p\n", infoPtr->hwndSelf, hwndTooltip);

    infoPtr->hwndToolTip = hwndTooltip;
    return 0;
}


static LRESULT
TOOLBAR_SetUnicodeFormat (TOOLBAR_INFO *infoPtr, WPARAM wParam)
{
    BOOL bTemp;

    TRACE("%s hwnd=%p\n",
	   ((BOOL)wParam) ? "TRUE" : "FALSE", infoPtr->hwndSelf);

    bTemp = infoPtr->bUnicode;
    infoPtr->bUnicode = (BOOL)wParam;

    return bTemp;
}


static LRESULT
TOOLBAR_GetColorScheme (const TOOLBAR_INFO *infoPtr, LPCOLORSCHEME lParam)
{
    lParam->clrBtnHighlight = (infoPtr->clrBtnHighlight == CLR_DEFAULT) ?
	                       comctl32_color.clrBtnHighlight :
                               infoPtr->clrBtnHighlight;
    lParam->clrBtnShadow = (infoPtr->clrBtnShadow == CLR_DEFAULT) ?
	                   comctl32_color.clrBtnShadow : infoPtr->clrBtnShadow;
    return 1;
}


static LRESULT
TOOLBAR_SetColorScheme (TOOLBAR_INFO *infoPtr, const COLORSCHEME *lParam)
{
    TRACE("new colors Hl=%x Shd=%x, old colors Hl=%x Shd=%x\n",
	  lParam->clrBtnHighlight, lParam->clrBtnShadow,
	  infoPtr->clrBtnHighlight, infoPtr->clrBtnShadow);

    infoPtr->clrBtnHighlight = lParam->clrBtnHighlight;
    infoPtr->clrBtnShadow = lParam->clrBtnShadow;
    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return 0;
}


static LRESULT
TOOLBAR_SetVersion (TOOLBAR_INFO *infoPtr, INT iVersion)
{
    INT iOldVersion = infoPtr->iVersion;

    infoPtr->iVersion = iVersion;

    if (infoPtr->iVersion >= 5)
        TOOLBAR_SetUnicodeFormat(infoPtr, TRUE);

    return iOldVersion;
}


static LRESULT
TOOLBAR_GetStringA (const TOOLBAR_INFO *infoPtr, WPARAM wParam, LPSTR str)
{
    WORD iString = HIWORD(wParam);
    WORD buffersize = LOWORD(wParam);
    LRESULT ret = -1;

    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", infoPtr->hwndSelf, iString, buffersize, str);

    if (iString < infoPtr->nNumStrings)
    {
        ret = WideCharToMultiByte(CP_ACP, 0, infoPtr->strings[iString], -1, str, buffersize, NULL, NULL);
        ret--;

        TRACE("returning %s\n", debugstr_a(str));
    }
    else
        WARN("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);

    return ret;
}


static LRESULT
TOOLBAR_GetStringW (const TOOLBAR_INFO *infoPtr, WPARAM wParam, LPWSTR str)
{
    WORD iString = HIWORD(wParam);
    WORD len = LOWORD(wParam)/sizeof(WCHAR) - 1;
    LRESULT ret = -1;

    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", infoPtr->hwndSelf, iString, LOWORD(wParam), str);

    if (iString < infoPtr->nNumStrings)
    {
        len = min(len, strlenW(infoPtr->strings[iString]));
        ret = (len+1)*sizeof(WCHAR);
        if (str)
        {
            memcpy(str, infoPtr->strings[iString], ret);
            str[len] = '\0';
        }
        ret = len;

        TRACE("returning %s\n", debugstr_w(str));
    }
    else
        WARN("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);

    return ret;
}

static LRESULT TOOLBAR_SetBoundingSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    SIZE * pSize = (SIZE*)lParam;
    FIXME("hwnd=%p, wParam=0x%08lx, size.cx=%d, size.cy=%d stub!\n", hwnd, wParam, pSize->cx, pSize->cy);
    return 0;
}

/* This is an extended version of the TB_SETHOTITEM message. It allows the
 * caller to specify a reason why the hot item changed (rather than just the
 * HICF_OTHER that TB_SETHOTITEM sends). */
static LRESULT
TOOLBAR_SetHotItem2 (TOOLBAR_INFO *infoPtr, INT nHotItem, LPARAM lParam)
{
    INT nOldHotItem = infoPtr->nHotItem;

    TRACE("old item=%d, new item=%d, flags=%08x\n",
	  nOldHotItem, nHotItem, (DWORD)lParam);

    if (nHotItem < 0 || nHotItem > infoPtr->nNumButtons)
        nHotItem = -1;

    /* NOTE: an application can still remove the hot item even if anchor
     * highlighting is enabled */

    TOOLBAR_SetHotItemEx(infoPtr, nHotItem, lParam);

    return (nOldHotItem < 0) ? -1 : (LRESULT)nOldHotItem;
}

/* Sets the toolbar global iListGap parameter which controls the amount of
 * spacing between the image and the text of buttons for TBSTYLE_LIST
 * toolbars. */
static LRESULT TOOLBAR_SetListGap(TOOLBAR_INFO *infoPtr, INT iListGap)
{
    TRACE("hwnd=%p iListGap=%d\n", infoPtr->hwndSelf, iListGap);
    
    infoPtr->iListGap = iListGap;

    InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);

    return 0;
}

/* Returns the number of maximum number of image lists associated with the
 * various states. */
static LRESULT TOOLBAR_GetImageListCount(const TOOLBAR_INFO *infoPtr)
{
    TRACE("hwnd=%p\n", infoPtr->hwndSelf);

    return max(infoPtr->cimlDef, max(infoPtr->cimlHot, infoPtr->cimlDis));
}

static LRESULT
TOOLBAR_GetIdealSize (const TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    LPSIZE lpsize = (LPSIZE)lParam;

    if (lpsize == NULL)
	return FALSE;

    /*
     * Testing shows the following:
     *   wParam    = 0 adjust cx value
     *             = 1 set cy value to max size.
     *   lParam    pointer to SIZE structure
     *
     */
    TRACE("wParam %ld, lParam 0x%08lx -> 0x%08x 0x%08x\n",
	  wParam, lParam, lpsize->cx, lpsize->cy);

    switch(wParam) {
    case 0:
	if (lpsize->cx == -1) {
	    lpsize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
	}
	else if(HIWORD(lpsize->cx)) {
	    RECT rc;
	    HWND hwndParent = GetParent(infoPtr->hwndSelf);

	    GetWindowRect(infoPtr->hwndSelf, &rc);
	    MapWindowPoints(0, hwndParent, (LPPOINT)&rc, 2);
            TRACE("mapped to (%s)\n", wine_dbgstr_rect(&rc));
	    lpsize->cx = max(rc.right-rc.left,
			     infoPtr->rcBound.right - infoPtr->rcBound.left);
	}
	else {
	    lpsize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
	}
	break;
    case 1:
	lpsize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
	break;
    default:
	FIXME("Unknown wParam %ld\n", wParam);
	return 0;
    }
    TRACE("set to -> 0x%08x 0x%08x\n",
	  lpsize->cx, lpsize->cy);
    return 1;
}

static LRESULT TOOLBAR_Unkwn464(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    FIXME("hwnd=%p wParam %08lx lParam %08lx\n", hwnd, wParam, lParam);

    InvalidateRect(hwnd, NULL, TRUE);
    return 1;
}


static LRESULT
TOOLBAR_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
{
    TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongPtrW(hwnd, 0);
    LOGFONTW logFont;

    TRACE("hwnd = %p, style=0x%08x\n", hwnd, lpcs->style);

    infoPtr->dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
    GetClientRect(hwnd, &infoPtr->client_rect);
    infoPtr->bUnicode = infoPtr->hwndNotify && 
        (NFR_UNICODE == SendMessageW(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_REQUERY));
    infoPtr->hwndToolTip = NULL; /* if needed the tooltip control will be created after a WM_MOUSEMOVE */

    SystemParametersInfoW (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
    infoPtr->hFont = infoPtr->hDefaultFont = CreateFontIndirectW (&logFont);
    
    OpenThemeData (hwnd, themeClass);

    TOOLBAR_CheckStyle (infoPtr);

    return 0;
}


static LRESULT
TOOLBAR_Destroy (TOOLBAR_INFO *infoPtr)
{
    INT i;

    /* delete tooltip control */
    if (infoPtr->hwndToolTip)
	DestroyWindow (infoPtr->hwndToolTip);

    /* delete temporary buffer for tooltip text */
    Free (infoPtr->pszTooltipText);
    Free (infoPtr->bitmaps);            /* bitmaps list */

    /* delete button data */
    for (i = 0; i < infoPtr->nNumButtons; i++)
        free_string( infoPtr->buttons + i );
    Free (infoPtr->buttons);

    /* delete strings */
    if (infoPtr->strings) {
	for (i = 0; i < infoPtr->nNumStrings; i++)
	    Free (infoPtr->strings[i]);

	Free (infoPtr->strings);
    }

    /* destroy internal image list */
    if (infoPtr->himlInt)
	ImageList_Destroy (infoPtr->himlInt);

    TOOLBAR_DeleteImageList(&infoPtr->himlDef, &infoPtr->cimlDef);
    TOOLBAR_DeleteImageList(&infoPtr->himlDis, &infoPtr->cimlDis);
    TOOLBAR_DeleteImageList(&infoPtr->himlHot, &infoPtr->cimlHot);

    /* delete default font */
    DeleteObject (infoPtr->hDefaultFont);
        
    CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));

    /* free toolbar info data */
    SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
    Free (infoPtr);

    return 0;
}


static LRESULT
TOOLBAR_EraseBackground (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    NMTBCUSTOMDRAW tbcd;
    INT ret = FALSE;
    DWORD ntfret;
    HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
    DWORD dwEraseCustDraw = 0;

    /* the app has told us not to redraw the toolbar */
    if (!infoPtr->bDoRedraw)
        return FALSE;

    if (infoPtr->dwStyle & TBSTYLE_CUSTOMERASE) {
	ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
	tbcd.nmcd.dwDrawStage = CDDS_PREERASE;
	tbcd.nmcd.hdc = (HDC)wParam;
	ntfret = TOOLBAR_SendNotify (&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
	dwEraseCustDraw = ntfret & 0xffff;

	/* FIXME: in general the return flags *can* be or'ed together */
	switch (dwEraseCustDraw)
	    {
	    case CDRF_DODEFAULT:
		break;
	    case CDRF_SKIPDEFAULT:
		return TRUE;
	    default:
		FIXME("[%p] response %d not handled to NM_CUSTOMDRAW (CDDS_PREERASE)\n",
		      infoPtr->hwndSelf, ntfret);
	    }
    }

    /* If the toolbar is "transparent" then pass the WM_ERASEBKGND up
     * to my parent for processing.
     */
    if (theme || (infoPtr->dwStyle & TBSTYLE_TRANSPARENT)) {
	POINT pt, ptorig;
	HDC hdc = (HDC)wParam;
	HWND parent;

	pt.x = 0;
	pt.y = 0;
	parent = GetParent(infoPtr->hwndSelf);
	MapWindowPoints(infoPtr->hwndSelf, parent, &pt, 1);
	OffsetWindowOrgEx (hdc, pt.x, pt.y, &ptorig);
	ret = SendMessageW (parent, WM_ERASEBKGND, wParam, lParam);
	SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
    }
    if (!ret)
	ret = DefWindowProcW (infoPtr->hwndSelf, WM_ERASEBKGND, wParam, lParam);

    if (dwEraseCustDraw & CDRF_NOTIFYPOSTERASE) {
	ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
	tbcd.nmcd.dwDrawStage = CDDS_POSTERASE;
	tbcd.nmcd.hdc = (HDC)wParam;
	ntfret = TOOLBAR_SendNotify (&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
	dwEraseCustDraw = ntfret & 0xffff;
	switch (dwEraseCustDraw)
	    {
	    case CDRF_DODEFAULT:
		break;
	    case CDRF_SKIPDEFAULT:
		return TRUE;
	    default:
		FIXME("[%p] response %d not handled to NM_CUSTOMDRAW (CDDS_POSTERASE)\n",
		      infoPtr->hwndSelf, ntfret);
	    }
    }
    return ret;
}


static inline LRESULT
TOOLBAR_GetFont (const TOOLBAR_INFO *infoPtr)
{
    return (LRESULT)infoPtr->hFont;
}


static void
TOOLBAR_SetRelativeHotItem(TOOLBAR_INFO *infoPtr, INT iDirection, DWORD dwReason)
{
    INT i;
    INT nNewHotItem = infoPtr->nHotItem;

    for (i = 0; i < infoPtr->nNumButtons; i++)
    {
        /* did we wrap? */
        if ((nNewHotItem + iDirection < 0) ||
            (nNewHotItem + iDirection >= infoPtr->nNumButtons))
        {
            NMTBWRAPHOTITEM nmtbwhi;
            nmtbwhi.idNew = infoPtr->buttons[nNewHotItem].idCommand;
            nmtbwhi.iDirection = iDirection;
            nmtbwhi.dwReason = dwReason;
    
            if (TOOLBAR_SendNotify(&nmtbwhi.hdr, infoPtr, TBN_WRAPHOTITEM))
                return;
        }

        nNewHotItem += iDirection;
        nNewHotItem = (nNewHotItem + infoPtr->nNumButtons) % infoPtr->nNumButtons;

        if ((infoPtr->buttons[nNewHotItem].fsState & TBSTATE_ENABLED) &&
            !(infoPtr->buttons[nNewHotItem].fsStyle & BTNS_SEP))
        {
            TOOLBAR_SetHotItemEx(infoPtr, nNewHotItem, dwReason);
            break;
        }
    }
}

static LRESULT
TOOLBAR_KeyDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    NMKEY nmkey;

    nmkey.nVKey = (UINT)wParam;
    nmkey.uFlags = HIWORD(lParam);

    if (TOOLBAR_SendNotify(&nmkey.hdr, infoPtr, NM_KEYDOWN))
        return DefWindowProcW(infoPtr->hwndSelf, WM_KEYDOWN, wParam, lParam);

    switch ((UINT)wParam)
    {
    case VK_LEFT:
    case VK_UP:
        TOOLBAR_SetRelativeHotItem(infoPtr, -1, HICF_ARROWKEYS);
        break;
    case VK_RIGHT:
    case VK_DOWN:
        TOOLBAR_SetRelativeHotItem(infoPtr, 1, HICF_ARROWKEYS);
        break;
    case VK_SPACE:
    case VK_RETURN:
        if ((infoPtr->nHotItem >= 0) &&
            (infoPtr->buttons[infoPtr->nHotItem].fsState & TBSTATE_ENABLED))
        {
            SendMessageW (infoPtr->hwndNotify, WM_COMMAND,
                MAKEWPARAM(infoPtr->buttons[infoPtr->nHotItem].idCommand, BN_CLICKED),
                (LPARAM)infoPtr->hwndSelf);
        }
        break;
    }

    return 0;
}


static LRESULT
TOOLBAR_LButtonDblClk (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    POINT pt;
    BOOL button;

    pt.x = (short)LOWORD(lParam);
    pt.y = (short)HIWORD(lParam);
    TOOLBAR_InternalHitTest (infoPtr, &pt, &button);

    if (button)
        TOOLBAR_LButtonDown (infoPtr, wParam, lParam);
    else if (infoPtr->dwStyle & CCS_ADJUSTABLE)
	TOOLBAR_Customize (infoPtr);

    return 0;
}


static LRESULT
TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    TBUTTON_INFO *btnPtr;
    POINT pt;
    INT   nHit;
    NMTOOLBARA nmtb;
    NMMOUSE nmmouse;
    BOOL bDragKeyPressed;
    BOOL button;

    TRACE("\n");

    if (infoPtr->dwStyle & TBSTYLE_ALTDRAG)
        bDragKeyPressed = (GetKeyState(VK_MENU) < 0);
    else
        bDragKeyPressed = (wParam & MK_SHIFT);

    if (infoPtr->hwndToolTip)
	TOOLBAR_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwndSelf,
			    WM_LBUTTONDOWN, wParam, lParam);

    pt.x = (short)LOWORD(lParam);
    pt.y = (short)HIWORD(lParam);
    nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button);

    if (button)
    {
        btnPtr = &infoPtr->buttons[nHit];

        if (bDragKeyPressed && (infoPtr->dwStyle & CCS_ADJUSTABLE))
        {
            infoPtr->nButtonDrag = nHit;
            SetCapture (infoPtr->hwndSelf);

            /* If drag cursor has not been loaded, load it.
             * Note: it doesn't need to be freed */
            if (!hCursorDrag)
                hCursorDrag = LoadCursorW(COMCTL32_hModule, (LPCWSTR)IDC_MOVEBUTTON);
            SetCursor(hCursorDrag);
        }
        else
        {
            RECT arrowRect;
            infoPtr->nOldHit = nHit;

            CopyRect(&arrowRect, &btnPtr->rect);
            arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH);

            /* for EX_DRAWDDARROWS style,  click must be in the drop-down arrow rect */
            if ((btnPtr->fsState & TBSTATE_ENABLED) &&
                 ((btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) ||
                  ((btnPtr->fsStyle & BTNS_DROPDOWN) &&
                   ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) ||
                   (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle))))))
            {
                LRESULT res;

                /* draw in pressed state */
                if (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN)
                    btnPtr->fsState |= TBSTATE_PRESSED;
                else
                    btnPtr->bDropDownPressed = TRUE;
                RedrawWindow(infoPtr->hwndSelf, &btnPtr->rect, 0, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);

                memset(&nmtb, 0, sizeof(nmtb));
                nmtb.iItem = btnPtr->idCommand;
                nmtb.rcButton = btnPtr->rect;
                res = TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_DROPDOWN);
                TRACE("TBN_DROPDOWN responded with %ld\n", res);

                if (res != TBDDRET_TREATPRESSED)
                {
                    MSG msg;

                    /* redraw button in unpressed state */
                    if (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN)
                        btnPtr->fsState &= ~TBSTATE_PRESSED;
                    else
                        btnPtr->bDropDownPressed = FALSE;
                    InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);

                    /* find and set hot item */
                    GetCursorPos(&pt);
                    ScreenToClient(infoPtr->hwndSelf, &pt);
                    nHit = TOOLBAR_InternalHitTest(infoPtr, &pt, &button);
                    if (!infoPtr->bAnchor || button)
                        TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE);

                    /* remove any left mouse button down or double-click messages
                     * so that we can get a toggle effect on the button */
                    while (PeekMessageW(&msg, infoPtr->hwndSelf, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE) ||
                           PeekMessageW(&msg, infoPtr->hwndSelf, WM_LBUTTONDBLCLK, WM_LBUTTONDBLCLK, PM_REMOVE))
                        ;

                    return 0;
                }
                /* otherwise drop through and process as pushed */
            }
            infoPtr->bCaptured = TRUE;
            infoPtr->nButtonDown = nHit;
            infoPtr->bDragOutSent = FALSE;

            btnPtr->fsState |= TBSTATE_PRESSED;

            TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE);

            if (btnPtr->fsState & TBSTATE_ENABLED)
                InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
            UpdateWindow(infoPtr->hwndSelf);
            SetCapture (infoPtr->hwndSelf);
        }

        memset(&nmtb, 0, sizeof(nmtb));
        nmtb.iItem = btnPtr->idCommand;
        TOOLBAR_SendNotify((NMHDR *)&nmtb, infoPtr, TBN_BEGINDRAG);
    }

    nmmouse.dwHitInfo = nHit;

    /* !!! Undocumented - sends NM_LDOWN with the NMMOUSE structure. */
    if (!button)
        nmmouse.dwItemSpec = -1;
    else
    {
        nmmouse.dwItemSpec = infoPtr->buttons[nmmouse.dwHitInfo].idCommand;
        nmmouse.dwItemData = infoPtr->buttons[nmmouse.dwHitInfo].dwData;
    }

    ClientToScreen(infoPtr->hwndSelf, &pt);
    nmmouse.pt = pt;

    if (!TOOLBAR_SendNotify(&nmmouse.hdr, infoPtr, NM_LDOWN))
        return DefWindowProcW(infoPtr->hwndSelf, WM_LBUTTONDOWN, wParam, lParam);

    return 0;
}

static LRESULT
TOOLBAR_LButtonUp (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    TBUTTON_INFO *btnPtr;
    POINT pt;
    INT   nHit;
    INT   nOldIndex = -1;
    NMHDR hdr;
    NMMOUSE nmmouse;
    NMTOOLBARA nmtb;
    BOOL button;

    if (infoPtr->hwndToolTip)
	TOOLBAR_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwndSelf,
			    WM_LBUTTONUP, wParam, lParam);

    pt.x = (short)LOWORD(lParam);
    pt.y = (short)HIWORD(lParam);
    nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button);

    if (!infoPtr->bAnchor || button)
        TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE);

    if (infoPtr->nButtonDrag >= 0) {
        RECT rcClient;
        NMHDR hdr;

        btnPtr = &infoPtr->buttons[infoPtr->nButtonDrag];
        ReleaseCapture();
        /* reset cursor */
        SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_ARROW));

        GetClientRect(infoPtr->hwndSelf, &rcClient);
        if (PtInRect(&rcClient, pt))
        {
            INT nButton = -1;
            if (nHit >= 0)
                nButton = nHit;
            else if (nHit < -1)
                nButton = -nHit;
            else if ((nHit == -1) && PtInRect(&infoPtr->buttons[-nHit].rect, pt))
                nButton = -nHit;

            if (nButton == infoPtr->nButtonDrag)
            {
                /* if the button is moved sightly left and we have a
                 * separator there then remove it */
                if (pt.x < (btnPtr->rect.left + (btnPtr->rect.right - btnPtr->rect.left)/2))
                {
                    if ((nButton > 0) && (infoPtr->buttons[nButton-1].fsStyle & BTNS_SEP))
                        TOOLBAR_DeleteButton(infoPtr, nButton - 1);
                }
                else /* else insert a separator before the dragged button */
                {
                    TBBUTTON tbb;
                    memset(&tbb, 0, sizeof(tbb));
                    tbb.fsStyle = BTNS_SEP;
                    tbb.iString = -1;
                    TOOLBAR_InsertButtonT(infoPtr, nButton, &tbb, TRUE);
                }
            }
            else
            {
                if (nButton == -1)
                {
                    if ((infoPtr->nNumButtons > 0) && (pt.x < infoPtr->buttons[0].rect.left))
                        TOOLBAR_MoveButton(infoPtr, infoPtr->nButtonDrag, 0);
                    else
                        TOOLBAR_MoveButton(infoPtr, infoPtr->nButtonDrag, infoPtr->nNumButtons);
                }
                else
                    TOOLBAR_MoveButton(infoPtr, infoPtr->nButtonDrag, nButton);
            }
        }
        else
        {
            TRACE("button %d dragged out of toolbar\n", infoPtr->nButtonDrag);
            TOOLBAR_DeleteButton(infoPtr, infoPtr->nButtonDrag);
        }

        /* button under cursor changed so need to re-set hot item */
        TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE);
        infoPtr->nButtonDrag = -1;

        TOOLBAR_SendNotify(&hdr, infoPtr, TBN_TOOLBARCHANGE);
    }
    else if (infoPtr->nButtonDown >= 0) {
	btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
	btnPtr->fsState &= ~TBSTATE_PRESSED;

	if (btnPtr->fsStyle & BTNS_CHECK) {
		if (btnPtr->fsStyle & BTNS_GROUP) {
		    nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
			nHit);
		    if ((nOldIndex != nHit) &&
			(nOldIndex != -1))
			infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
		    btnPtr->fsState |= TBSTATE_CHECKED;
		}
		else {
		    if (btnPtr->fsState & TBSTATE_CHECKED)
			btnPtr->fsState &= ~TBSTATE_CHECKED;
		    else
			btnPtr->fsState |= TBSTATE_CHECKED;
		}
	}

        if (nOldIndex != -1)
            InvalidateRect(infoPtr->hwndSelf, &infoPtr->buttons[nOldIndex].rect, TRUE);

	/*
	 * now we can ReleaseCapture, which triggers CAPTURECHANGED msg,
	 * that resets bCaptured and btn TBSTATE_PRESSED flags,
	 * and obliterates nButtonDown and nOldHit (see TOOLBAR_CaptureChanged)
	 */
	if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0))
	    ReleaseCapture ();
	infoPtr->nButtonDown = -1;

	/* Issue NM_RELEASEDCAPTURE to parent to let him know it is released */
	TOOLBAR_SendNotify (&hdr, infoPtr,
			NM_RELEASEDCAPTURE);

	memset(&nmtb, 0, sizeof(nmtb));
	nmtb.iItem = btnPtr->idCommand;
	TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
			TBN_ENDDRAG);

	if (btnPtr->fsState & TBSTATE_ENABLED)
	{
	    SendMessageW (infoPtr->hwndNotify, WM_COMMAND,
	      MAKEWPARAM(infoPtr->buttons[nHit].idCommand, BN_CLICKED), (LPARAM)infoPtr->hwndSelf);

            /* In case we have just been destroyed... */
            if(!IsWindow(infoPtr->hwndSelf))
                return 0;
        }
    }

    /* !!! Undocumented - toolbar at 4.71 level and above sends
    * NM_CLICK with the NMMOUSE structure. */
    nmmouse.dwHitInfo = nHit;

    if (!button)
        nmmouse.dwItemSpec = -1;
    else
    {
        nmmouse.dwItemSpec = infoPtr->buttons[nmmouse.dwHitInfo].idCommand;
        nmmouse.dwItemData = infoPtr->buttons[nmmouse.dwHitInfo].dwData;
    }

    ClientToScreen(infoPtr->hwndSelf, &pt);
    nmmouse.pt = pt;

    if (!TOOLBAR_SendNotify((LPNMHDR)&nmmouse, infoPtr, NM_CLICK))
        return DefWindowProcW(infoPtr->hwndSelf, WM_LBUTTONUP, wParam, lParam);

    return 0;
}

static LRESULT
TOOLBAR_RButtonUp(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    INT nHit;
    NMMOUSE nmmouse;
    POINT pt;
    BOOL button;

    pt.x = (short)LOWORD(lParam);
    pt.y = (short)HIWORD(lParam);

    nHit = TOOLBAR_InternalHitTest(infoPtr, &pt, &button);
    nmmouse.dwHitInfo = nHit;

    if (!button) {
	nmmouse.dwItemSpec = -1;
    } else {
	nmmouse.dwItemSpec = infoPtr->buttons[nmmouse.dwHitInfo].idCommand;
	nmmouse.dwItemData = infoPtr->buttons[nmmouse.dwHitInfo].dwData;
    }

    ClientToScreen(infoPtr->hwndSelf, &pt);
    nmmouse.pt = pt;

    if (!TOOLBAR_SendNotify((LPNMHDR)&nmmouse, infoPtr, NM_RCLICK))
        return DefWindowProcW(infoPtr->hwndSelf, WM_RBUTTONUP, wParam, lParam);

    return 0;
}

static LRESULT
TOOLBAR_RButtonDblClk( TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    NMHDR nmhdr;

    if (!TOOLBAR_SendNotify(&nmhdr, infoPtr, NM_RDBLCLK))
        return DefWindowProcW(infoPtr->hwndSelf, WM_RBUTTONDBLCLK, wParam, lParam);

    return 0;
}

static LRESULT
TOOLBAR_CaptureChanged(TOOLBAR_INFO *infoPtr)
{
    TBUTTON_INFO *btnPtr;

    infoPtr->bCaptured = FALSE;

    if (infoPtr->nButtonDown >= 0)
    {
        btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
       	btnPtr->fsState &= ~TBSTATE_PRESSED;

        infoPtr->nOldHit = -1;

        if (btnPtr->fsState & TBSTATE_ENABLED)
            InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
    }
    return 0;
}

static LRESULT
TOOLBAR_MouseLeave (TOOLBAR_INFO *infoPtr)
{
    /* don't remove hot effects when in anchor highlighting mode or when a
     * drop-down button is pressed */
    if (infoPtr->nHotItem >= 0 && !infoPtr->bAnchor)
    {
        TBUTTON_INFO *hotBtnPtr = &infoPtr->buttons[infoPtr->nHotItem];
        if (!hotBtnPtr->bDropDownPressed)
            TOOLBAR_SetHotItemEx(infoPtr, TOOLBAR_NOWHERE, HICF_MOUSE);
    }

    if (infoPtr->nOldHit < 0)
      return TRUE;

    /* If the last button we were over is depressed then make it not */
    /* depressed and redraw it */
    if(infoPtr->nOldHit == infoPtr->nButtonDown)
    {
      TBUTTON_INFO *btnPtr;
      RECT rc1;

      btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];

      btnPtr->fsState &= ~TBSTATE_PRESSED;

      rc1 = btnPtr->rect;
      InflateRect (&rc1, 1, 1);
      InvalidateRect (infoPtr->hwndSelf, &rc1, TRUE);
    }

    if (infoPtr->bCaptured && !infoPtr->bDragOutSent)
    {
        NMTOOLBARW nmt;
        ZeroMemory(&nmt, sizeof(nmt));
        nmt.iItem = infoPtr->buttons[infoPtr->nButtonDown].idCommand;
        TOOLBAR_SendNotify(&nmt.hdr, infoPtr, TBN_DRAGOUT);
        infoPtr->bDragOutSent = TRUE;
    }

    infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */

    return TRUE;
}

static LRESULT
TOOLBAR_MouseMove (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    POINT pt;
    TRACKMOUSEEVENT trackinfo;
    INT   nHit;
    TBUTTON_INFO *btnPtr;
    BOOL button;
    
    if ((infoPtr->dwStyle & TBSTYLE_TOOLTIPS) && (infoPtr->hwndToolTip == NULL))
        TOOLBAR_TooltipCreateControl(infoPtr);
    
    if ((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf)) {
        /* fill in the TRACKMOUSEEVENT struct */
        trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
        trackinfo.dwFlags = TME_QUERY;

        /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
        _TrackMouseEvent(&trackinfo);

        /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
        if(trackinfo.hwndTrack != infoPtr->hwndSelf || !(trackinfo.dwFlags & TME_LEAVE)) {
            trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
            trackinfo.hwndTrack = infoPtr->hwndSelf;

            /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
            /* and can properly deactivate the hot toolbar button */
            _TrackMouseEvent(&trackinfo);
        }
    }

    if (infoPtr->hwndToolTip)
	TOOLBAR_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwndSelf,
			    WM_MOUSEMOVE, wParam, lParam);

    pt.x = (short)LOWORD(lParam);
    pt.y = (short)HIWORD(lParam);

    nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button);

    if (((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf)) 
        && (!infoPtr->bAnchor || button))
        TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE);

    if (infoPtr->nOldHit != nHit)
    {
        if (infoPtr->bCaptured)
        {
            if (!infoPtr->bDragOutSent)
            {
                NMTOOLBARW nmt;
                ZeroMemory(&nmt, sizeof(nmt));
                nmt.iItem = infoPtr->buttons[infoPtr->nButtonDown].idCommand;
                TOOLBAR_SendNotify(&nmt.hdr, infoPtr, TBN_DRAGOUT);
                infoPtr->bDragOutSent = TRUE;
            }

            btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
            if (infoPtr->nOldHit == infoPtr->nButtonDown) {
                btnPtr->fsState &= ~TBSTATE_PRESSED;
                InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
            }
            else if (nHit == infoPtr->nButtonDown) {
                btnPtr->fsState |= TBSTATE_PRESSED;
                InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
            }
            infoPtr->nOldHit = nHit;
        }
    }

    return 0;
}


static inline LRESULT
TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/*    if (wndPtr->dwStyle & CCS_NODIVIDER) */
	return DefWindowProcW (hwnd, WM_NCACTIVATE, wParam, lParam);
/*    else */
/*	return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
}


static inline LRESULT
TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    if (!(GetWindowLongW(hwnd, GWL_STYLE) & CCS_NODIVIDER))
	((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);

    return DefWindowProcW (hwnd, WM_NCCALCSIZE, wParam, lParam);
}


static LRESULT
TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
{
    TOOLBAR_INFO *infoPtr;
    DWORD styleadd = 0;

    /* allocate memory for info structure */
    infoPtr = Alloc (sizeof(TOOLBAR_INFO));
    SetWindowLongPtrW (hwnd, 0, (LONG_PTR)infoPtr);

    /* paranoid!! */
    infoPtr->dwStructSize = sizeof(TBBUTTON);
    infoPtr->nRows = 1;

    /* initialize info structure */
    infoPtr->nButtonWidth = 23;
    infoPtr->nButtonHeight = 22;
    infoPtr->nBitmapHeight = 16;
    infoPtr->nBitmapWidth = 16;

    infoPtr->nMaxTextRows = 1;
    infoPtr->cxMin = -1;
    infoPtr->cxMax = -1;
    infoPtr->nNumBitmaps = 0;
    infoPtr->nNumStrings = 0;

    infoPtr->bCaptured = FALSE;
    infoPtr->nButtonDown = -1;
    infoPtr->nButtonDrag = -1;
    infoPtr->nOldHit = -1;
    infoPtr->nHotItem = -1;
    infoPtr->hwndNotify = lpcs->hwndParent;
    infoPtr->dwDTFlags = (lpcs->style & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS: DT_CENTER | DT_END_ELLIPSIS;
    infoPtr->bAnchor = FALSE; /* no anchor highlighting */
    infoPtr->bDragOutSent = FALSE;
    infoPtr->iVersion = 0;
    infoPtr->hwndSelf = hwnd;
    infoPtr->bDoRedraw = TRUE;
    infoPtr->clrBtnHighlight = CLR_DEFAULT;
    infoPtr->clrBtnShadow = CLR_DEFAULT;
    infoPtr->szPadding.cx = DEFPAD_CX;
    infoPtr->szPadding.cy = DEFPAD_CY;
    infoPtr->iListGap = DEFLISTGAP;
    infoPtr->iTopMargin = default_top_margin(infoPtr);
    infoPtr->dwStyle = lpcs->style;
    infoPtr->tbim.iButton = -1;

    /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
    if (!GetWindowLongPtrW (hwnd, GWLP_HINSTANCE)) {
        HINSTANCE hInst = (HINSTANCE)GetWindowLongPtrW (GetParent (hwnd), GWLP_HINSTANCE);
	SetWindowLongPtrW (hwnd, GWLP_HINSTANCE, (LONG_PTR)hInst);
    }

    /* I think the code below is a bug, but it is the way that the native
     * controls seem to work. The effect is that if the user of TBSTYLE_FLAT
     * forgets to specify TBSTYLE_TRANSPARENT but does specify either
     * CCS_TOP or CCS_BOTTOM (_NOMOVEY and _TOP), then the control
     * does *not* set TBSTYLE_TRANSPARENT even though it should!!!!
     * Somehow, the only cases of this seem to be MFC programs.
     *
     * Note also that the addition of _TRANSPARENT occurs *only* here. It
     * does not occur in the WM_STYLECHANGING routine.
     *    (Guy Albertelli   9/2001)
     *
     */
    if (((infoPtr->dwStyle & TBSTYLE_FLAT) || GetWindowTheme (infoPtr->hwndSelf)) 
        && !(lpcs->style & TBSTYLE_TRANSPARENT))
	styleadd |= TBSTYLE_TRANSPARENT;
    if (!(lpcs->style & (CCS_TOP | CCS_NOMOVEY))) {
	styleadd |= CCS_TOP;   /* default to top */
	SetWindowLongW (hwnd, GWL_STYLE, lpcs->style | styleadd);
    }

    return DefWindowProcW (hwnd, WM_NCCREATE, wParam, (LPARAM)lpcs);
}


static LRESULT
TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
    RECT rcWindow;
    HDC hdc;

    if (dwStyle & WS_MINIMIZE)
	return 0; /* Nothing to do */

    DefWindowProcW (hwnd, WM_NCPAINT, wParam, lParam);

    if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
	return 0;

    if (!(dwStyle & CCS_NODIVIDER))
    {
	GetWindowRect (hwnd, &rcWindow);
	OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
	if( dwStyle & WS_BORDER )
	    InflateRect (&rcWindow, -1, -1);
	DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
    }

    ReleaseDC( hwnd, hdc );

    return 0;
}


/* handles requests from the tooltip control on what text to display */
static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnmtdi)
{
    int index = TOOLBAR_GetButtonIndex(infoPtr, lpnmtdi->hdr.idFrom, FALSE);

    TRACE("button index = %d\n", index);

    Free (infoPtr->pszTooltipText);
    infoPtr->pszTooltipText = NULL;

    if (index < 0)
        return 0;

    if (infoPtr->bUnicode)
    {
        WCHAR wszBuffer[INFOTIPSIZE+1];
        NMTBGETINFOTIPW tbgit;
        unsigned int len; /* in chars */

        wszBuffer[0] = '\0';
        wszBuffer[INFOTIPSIZE] = '\0';

        tbgit.pszText = wszBuffer;
        tbgit.cchTextMax = INFOTIPSIZE;
        tbgit.iItem = lpnmtdi->hdr.idFrom;
        tbgit.lParam = infoPtr->buttons[index].dwData;

        TOOLBAR_SendNotify(&tbgit.hdr, infoPtr, TBN_GETINFOTIPW);

        TRACE("TBN_GETINFOTIPW - got string %s\n", debugstr_w(tbgit.pszText));

        len = strlenW(tbgit.pszText);
        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
        {
            /* need to allocate temporary buffer in infoPtr as there
             * isn't enough space in buffer passed to us by the
             * tooltip control */
            infoPtr->pszTooltipText = Alloc((len+1)*sizeof(WCHAR));
            if (infoPtr->pszTooltipText)
            {
                memcpy(infoPtr->pszTooltipText, tbgit.pszText, (len+1)*sizeof(WCHAR));
                lpnmtdi->lpszText = infoPtr->pszTooltipText;
                return 0;
            }
        }
        else if (len > 0)
        {
            memcpy(lpnmtdi->lpszText, tbgit.pszText, (len+1)*sizeof(WCHAR));
            return 0;
        }
    }
    else
    {
        CHAR szBuffer[INFOTIPSIZE+1];
        NMTBGETINFOTIPA tbgit;
        unsigned int len; /* in chars */

        szBuffer[0] = '\0';
        szBuffer[INFOTIPSIZE] = '\0';

        tbgit.pszText = szBuffer;
        tbgit.cchTextMax = INFOTIPSIZE;
        tbgit.iItem = lpnmtdi->hdr.idFrom;
        tbgit.lParam = infoPtr->buttons[index].dwData;

        TOOLBAR_SendNotify(&tbgit.hdr, infoPtr, TBN_GETINFOTIPA);

        TRACE("TBN_GETINFOTIPA - got string %s\n", debugstr_a(tbgit.pszText));

        len = MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, NULL, 0);
        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0]))
        {
            /* need to allocate temporary buffer in infoPtr as there
             * isn't enough space in buffer passed to us by the
             * tooltip control */
            infoPtr->pszTooltipText = Alloc(len*sizeof(WCHAR));
            if (infoPtr->pszTooltipText)
            {
                MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, infoPtr->pszTooltipText, len);
                lpnmtdi->lpszText = infoPtr->pszTooltipText;
                return 0;
            }
        }
        else if (tbgit.pszText && tbgit.pszText[0])
        {
            MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1,
                                lpnmtdi->lpszText, sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0]));
            return 0;
        }
    }

    /* if button has text, but it is not shown then automatically
     * use that text as tooltip */
    if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) &&
        !(infoPtr->buttons[index].fsStyle & BTNS_SHOWTEXT))
    {
        LPWSTR pszText = TOOLBAR_GetText(infoPtr, &infoPtr->buttons[index]);
        unsigned int len = pszText ? strlenW(pszText) : 0;

        TRACE("using button hidden text %s\n", debugstr_w(pszText));

        if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1)
        {
            /* need to allocate temporary buffer in infoPtr as there
             * isn't enough space in buffer passed to us by the
             * tooltip control */
            infoPtr->pszTooltipText = Alloc((len+1)*sizeof(WCHAR));
            if (infoPtr->pszTooltipText)
            {
                memcpy(infoPtr->pszTooltipText, pszText, (len+1)*sizeof(WCHAR));
                lpnmtdi->lpszText = infoPtr->pszTooltipText;
                return 0;
            }
        }
        else if (len > 0)
        {
            memcpy(lpnmtdi->lpszText, pszText, (len+1)*sizeof(WCHAR));
            return 0;
        }
    }

    TRACE("Sending tooltip notification to %p\n", infoPtr->hwndNotify);

    /* last resort: send notification on to app */
    /* FIXME: find out what is really used here */
    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, lpnmtdi->hdr.idFrom, (LPARAM)lpnmtdi);
}


static inline LRESULT
TOOLBAR_Notify (TOOLBAR_INFO *infoPtr, LPNMHDR lpnmh)
{
    switch (lpnmh->code)
    {
    case PGN_CALCSIZE:
    {
        LPNMPGCALCSIZE lppgc = (LPNMPGCALCSIZE)lpnmh;

        if (lppgc->dwFlag == PGF_CALCWIDTH) {
            lppgc->iWidth = infoPtr->rcBound.right - infoPtr->rcBound.left;
            TRACE("processed PGN_CALCSIZE, returning horz size = %d\n",
                  lppgc->iWidth);
        }
        else {
            lppgc->iHeight = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
            TRACE("processed PGN_CALCSIZE, returning vert size = %d\n",
                  lppgc->iHeight);
        }
    	return 0;
    }

    case PGN_SCROLL:
    {
        LPNMPGSCROLL lppgs = (LPNMPGSCROLL)lpnmh;

        lppgs->iScroll = (lppgs->iDir & (PGF_SCROLLLEFT | PGF_SCROLLRIGHT)) ?
                          infoPtr->nButtonWidth : infoPtr->nButtonHeight;
        TRACE("processed PGN_SCROLL, returning scroll=%d, dir=%d\n",
              lppgs->iScroll, lppgs->iDir);
        return 0;
    }

    case TTN_GETDISPINFOW:
        return TOOLBAR_TTGetDispInfo(infoPtr, (LPNMTTDISPINFOW)lpnmh);

    case TTN_GETDISPINFOA:
        FIXME("TTN_GETDISPINFOA - should not be received; please report\n");
        return 0;

    default:
        return 0;
    }
}


static LRESULT
TOOLBAR_NotifyFormat(const TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
    LRESULT format;

    TRACE("wParam = 0x%lx, lParam = 0x%08lx\n", wParam, lParam);

    if (lParam == NF_QUERY)
        return NFR_UNICODE;

    if (lParam == NF_REQUERY) {
	format = SendMessageW(infoPtr->hwndNotify,
			 WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
	if ((format != NFR_ANSI) && (format != NFR_UNICODE)) {
	    ERR("wrong response to WM_NOTIFYFORMAT (%ld), assuming ANSI\n",
		format);
	    format = NFR_ANSI;
	}
	return format;
    }
    return 0;
}


static LRESULT
TOOLBAR_Paint (TOOLBAR_INFO *infoPtr, WPARAM wParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    /* fill ps.rcPaint with a default rect */
    ps.rcPaint = infoPtr->rcBound;

    hdc = wParam==0 ? BeginPaint(infoPtr->hwndSelf, &ps) : (HDC)wParam;

    TRACE("psrect=(%s)\n", wine_dbgstr_rect(&ps.rcPaint));

    TOOLBAR_Refresh (infoPtr, hdc, &ps);
    if (!wParam) EndPaint (infoPtr->hwndSelf, &ps);

    return 0;
}


static LRESULT
TOOLBAR_SetFocus (TOOLBAR_INFO *infoPtr)
{
    TRACE("nHotItem = %d\n", infoPtr->nHotItem);

    /* make first item hot */
    if (infoPtr->nNumButtons > 0)
        TOOLBAR_SetHotItemEx(infoPtr, 0, HICF_OTHER);

    return 0;
}

static LRESULT
TOOLBAR_SetFont(TOOLBAR_INFO *infoPtr, HFONT hFont, WORD Redraw)
{
    TRACE("font=%p redraw=%d\n", hFont, Redraw);
    
    if (hFont == 0)
        infoPtr->hFont = infoPtr->hDefaultFont;
    else
        infoPtr->hFont = hFont;

    TOOLBAR_CalcToolbar(infoPtr);

    if (Redraw)
        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
    return 1;
}

static LRESULT
TOOLBAR_SetRedraw (TOOLBAR_INFO *infoPtr, WPARAM wParam)
     /*****************************************************
      *
      * Function;
      *  Handles the WM_SETREDRAW message.
      *
      * Documentation:
      *  According to testing V4.71 of COMCTL32 returns the
      *  *previous* status of the redraw flag (either 0 or 1)
      *  instead of the MSDN documented value of 0 if handled.
      *  (For laughs see the "consistency" with same function
      *   in rebar.)
      *
      *****************************************************/
{
    BOOL oldredraw = infoPtr->bDoRedraw;

    TRACE("set to %s\n",
	  (wParam) ? "TRUE" : "FALSE");
    infoPtr->bDoRedraw = (BOOL) wParam;
    if (wParam) {
	InvalidateRect (infoPtr->hwndSelf, 0, TRUE);
    }
    return (oldredraw) ? 1 : 0;
}


static LRESULT
TOOLBAR_Size (TOOLBAR_INFO *infoPtr)
{
    TRACE("sizing toolbar!\n");

    if (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
    {
        RECT delta_width, delta_height, client, dummy;
        DWORD min_x, max_x, min_y, max_y;
        TBUTTON_INFO *btnPtr;
        INT i;

        GetClientRect(infoPtr->hwndSelf, &client);
        if(client.right > infoPtr->client_rect.right)
        {
            min_x = infoPtr->client_rect.right;
            max_x = client.right;
        }
        else
        {
            max_x = infoPtr->client_rect.right;
            min_x = client.right;
        }
        if(client.bottom > infoPtr->client_rect.bottom)
        {
            min_y = infoPtr->client_rect.bottom;
            max_y = client.bottom;
        }
        else
        {
            max_y = infoPtr->client_rect.bottom;
            min_y = client.bottom;
        }

        SetRect(&delta_width, min_x, 0, max_x, min_y);
        SetRect(&delta_height, 0, min_y, max_x, max_y);

        TRACE("delta_width %s delta_height %s\n", wine_dbgstr_rect(&delta_width), wine_dbgstr_rect(&delta_height));
        btnPtr = infoPtr->buttons;
        for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
            if(IntersectRect(&dummy, &delta_width, &btnPtr->rect) ||
                IntersectRect(&dummy, &delta_height, &btnPtr->rect))
                InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
    }
    GetClientRect(infoPtr->hwndSelf, &infoPtr->client_rect);
    TOOLBAR_AutoSize(infoPtr);
    return 0;
}


static LRESULT
TOOLBAR_StyleChanged (TOOLBAR_INFO *infoPtr, INT nType, const STYLESTRUCT *lpStyle)
{
    if (nType == GWL_STYLE)
        return TOOLBAR_SetStyle(infoPtr, lpStyle->styleNew);

    return 0;
}


static LRESULT
TOOLBAR_SysColorChange (void)
{
    COMCTL32_RefreshSysColors();

    return 0;
}


/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed (HWND hwnd)
{
    HTHEME theme = GetWindowTheme (hwnd);
    CloseThemeData (theme);
    OpenThemeData (hwnd, themeClass);
    return 0;
}


static LRESULT WINAPI
ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongPtrW(hwnd, 0);

    TRACE("hwnd=%p msg=%x wparam=%lx lparam=%lx\n",
	  hwnd, uMsg, /* SPY_GetMsgName(uMsg), */ wParam, lParam);

    if (!infoPtr && (uMsg != WM_NCCREATE))
	return DefWindowProcW( hwnd, uMsg, wParam, lParam );

    switch (uMsg)
    {
	case TB_ADDBITMAP:
	    return TOOLBAR_AddBitmap (infoPtr, (INT)wParam, (TBADDBITMAP*)lParam);

	case TB_ADDBUTTONSA:
	case TB_ADDBUTTONSW:
	    return TOOLBAR_AddButtonsT (infoPtr, wParam, (LPTBBUTTON)lParam,
	                                uMsg == TB_ADDBUTTONSW);
	case TB_ADDSTRINGA:
	    return TOOLBAR_AddStringA (infoPtr, (HINSTANCE)wParam, lParam);

	case TB_ADDSTRINGW:
	    return TOOLBAR_AddStringW (infoPtr, (HINSTANCE)wParam, lParam);

	case TB_AUTOSIZE:
	    return TOOLBAR_AutoSize (infoPtr);

	case TB_BUTTONCOUNT:
	    return TOOLBAR_ButtonCount (infoPtr);

	case TB_BUTTONSTRUCTSIZE:
	    return TOOLBAR_ButtonStructSize (infoPtr, wParam);

	case TB_CHANGEBITMAP:
	    return TOOLBAR_ChangeBitmap (infoPtr, wParam, LOWORD(lParam));

	case TB_CHECKBUTTON:
	    return TOOLBAR_CheckButton (infoPtr, wParam, lParam);

	case TB_COMMANDTOINDEX:
	    return TOOLBAR_CommandToIndex (infoPtr, wParam);

	case TB_CUSTOMIZE:
	    return TOOLBAR_Customize (infoPtr);

	case TB_DELETEBUTTON:
	    return TOOLBAR_DeleteButton (infoPtr, wParam);

	case TB_ENABLEBUTTON:
	    return TOOLBAR_EnableButton (infoPtr, wParam, lParam);

	case TB_GETANCHORHIGHLIGHT:
	    return TOOLBAR_GetAnchorHighlight (infoPtr);

	case TB_GETBITMAP:
	    return TOOLBAR_GetBitmap (infoPtr, wParam);

	case TB_GETBITMAPFLAGS:
	    return TOOLBAR_GetBitmapFlags ();

	case TB_GETBUTTON:
	    return TOOLBAR_GetButton (infoPtr, wParam, (TBBUTTON*)lParam);

	case TB_GETBUTTONINFOA:
	case TB_GETBUTTONINFOW:
	    return TOOLBAR_GetButtonInfoT (infoPtr, wParam, (LPTBBUTTONINFOW)lParam,
	                                   uMsg == TB_GETBUTTONINFOW);
	case TB_GETBUTTONSIZE:
	    return TOOLBAR_GetButtonSize (infoPtr);

	case TB_GETBUTTONTEXTA:
	case TB_GETBUTTONTEXTW:
	    return TOOLBAR_GetButtonText (infoPtr, wParam, (LPWSTR)lParam,
	                                  uMsg == TB_GETBUTTONTEXTW);

	case TB_GETDISABLEDIMAGELIST:
	    return TOOLBAR_GetDisabledImageList (infoPtr, wParam);

	case TB_GETEXTENDEDSTYLE:
	    return TOOLBAR_GetExtendedStyle (infoPtr);

	case TB_GETHOTIMAGELIST:
	    return TOOLBAR_GetHotImageList (infoPtr, wParam);

	case TB_GETHOTITEM:
	    return TOOLBAR_GetHotItem (infoPtr);

	case TB_GETIMAGELIST:
	    return TOOLBAR_GetDefImageList (infoPtr, wParam);

	case TB_GETINSERTMARK:
	    return TOOLBAR_GetInsertMark (infoPtr, (TBINSERTMARK*)lParam);

	case TB_GETINSERTMARKCOLOR:
	    return TOOLBAR_GetInsertMarkColor (infoPtr);

	case TB_GETITEMRECT:
	    return TOOLBAR_GetItemRect (infoPtr, wParam, (LPRECT)lParam);

	case TB_GETMAXSIZE:
	    return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam);

/*	case TB_GETOBJECT:			*/ /* 4.71 */

	case TB_GETPADDING:
	    return TOOLBAR_GetPadding (infoPtr);

	case TB_GETRECT:
	    return TOOLBAR_GetRect (infoPtr, wParam, (LPRECT)lParam);

	case TB_GETROWS:
	    return TOOLBAR_GetRows (infoPtr);

	case TB_GETSTATE:
	    return TOOLBAR_GetState (infoPtr, wParam);

	case TB_GETSTRINGA:
            return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam);

	case TB_GETSTRINGW:
	    return TOOLBAR_GetStringW (infoPtr, wParam, (LPWSTR)lParam);

	case TB_GETSTYLE:
	    return TOOLBAR_GetStyle (infoPtr);

	case TB_GETTEXTROWS:
	    return TOOLBAR_GetTextRows (infoPtr);

	case TB_GETTOOLTIPS:
	    return TOOLBAR_GetToolTips (infoPtr);

	case TB_GETUNICODEFORMAT:
	    return TOOLBAR_GetUnicodeFormat (infoPtr);

	case TB_HIDEBUTTON:
	    return TOOLBAR_HideButton (infoPtr, wParam, LOWORD(lParam));

	case TB_HITTEST:
	    return TOOLBAR_HitTest (infoPtr, (LPPOINT)lParam);

	case TB_INDETERMINATE:
	    return TOOLBAR_Indeterminate (infoPtr, wParam, LOWORD(lParam));

	case TB_INSERTBUTTONA:
	case TB_INSERTBUTTONW:
	    return TOOLBAR_InsertButtonT(infoPtr, wParam, (TBBUTTON*)lParam,
	                                 uMsg == TB_INSERTBUTTONW);

/*	case TB_INSERTMARKHITTEST:		*/ /* 4.71 */

	case TB_ISBUTTONCHECKED:
	    return TOOLBAR_IsButtonChecked (infoPtr, wParam);

	case TB_ISBUTTONENABLED:
	    return TOOLBAR_IsButtonEnabled (infoPtr, wParam);

	case TB_ISBUTTONHIDDEN:
	    return TOOLBAR_IsButtonHidden (infoPtr, wParam);

	case TB_ISBUTTONHIGHLIGHTED:
	    return TOOLBAR_IsButtonHighlighted (infoPtr, wParam);

	case TB_ISBUTTONINDETERMINATE:
	    return TOOLBAR_IsButtonIndeterminate (infoPtr, wParam);

	case TB_ISBUTTONPRESSED:
	    return TOOLBAR_IsButtonPressed (infoPtr, wParam);

	case TB_LOADIMAGES:
	    return TOOLBAR_LoadImages (infoPtr, wParam, (HINSTANCE)lParam);

	case TB_MAPACCELERATORA:
	case TB_MAPACCELERATORW:
	    return TOOLBAR_MapAccelerator (infoPtr, wParam, (UINT*)lParam);

	case TB_MARKBUTTON:
	    return TOOLBAR_MarkButton (infoPtr, wParam, LOWORD(lParam));

	case TB_MOVEBUTTON:
	    return TOOLBAR_MoveButton (infoPtr, wParam, lParam);

	case TB_PRESSBUTTON:
	    return TOOLBAR_PressButton (infoPtr, wParam, LOWORD(lParam));

	case TB_REPLACEBITMAP:
            return TOOLBAR_ReplaceBitmap (infoPtr, (LPTBREPLACEBITMAP)lParam);

	case TB_SAVERESTOREA:
	    return TOOLBAR_SaveRestoreA (infoPtr, wParam, (LPTBSAVEPARAMSA)lParam);

	case TB_SAVERESTOREW:
	    return TOOLBAR_SaveRestoreW (infoPtr, wParam, (LPTBSAVEPARAMSW)lParam);

	case TB_SETANCHORHIGHLIGHT:
	    return TOOLBAR_SetAnchorHighlight (infoPtr, (BOOL)wParam);

	case TB_SETBITMAPSIZE:
	    return TOOLBAR_SetBitmapSize (infoPtr, wParam, lParam);

	case TB_SETBUTTONINFOA:
	case TB_SETBUTTONINFOW:
	    return TOOLBAR_SetButtonInfo (infoPtr, wParam, (LPTBBUTTONINFOW)lParam,
                                          uMsg == TB_SETBUTTONINFOW);
	case TB_SETBUTTONSIZE:
	    return TOOLBAR_SetButtonSize (infoPtr, lParam);

	case TB_SETBUTTONWIDTH:
	    return TOOLBAR_SetButtonWidth (infoPtr, lParam);

	case TB_SETCMDID:
	    return TOOLBAR_SetCmdId (infoPtr, wParam, lParam);

	case TB_SETDISABLEDIMAGELIST:
	    return TOOLBAR_SetDisabledImageList (infoPtr, wParam, (HIMAGELIST)lParam);

	case TB_SETDRAWTEXTFLAGS:
	    return TOOLBAR_SetDrawTextFlags (infoPtr, wParam, lParam);

	case TB_SETEXTENDEDSTYLE:
	    return TOOLBAR_SetExtendedStyle (infoPtr, wParam, lParam);

	case TB_SETHOTIMAGELIST:
	    return TOOLBAR_SetHotImageList (infoPtr, wParam, (HIMAGELIST)lParam);

	case TB_SETHOTITEM:
	    return TOOLBAR_SetHotItem (infoPtr, wParam);

	case TB_SETIMAGELIST:
	    return TOOLBAR_SetImageList (infoPtr, wParam, (HIMAGELIST)lParam);

	case TB_SETINDENT:
	    return TOOLBAR_SetIndent (infoPtr, wParam);

	case TB_SETINSERTMARK:
	    return TOOLBAR_SetInsertMark (infoPtr, (TBINSERTMARK*)lParam);

	case TB_SETINSERTMARKCOLOR:
	    return TOOLBAR_SetInsertMarkColor (infoPtr, lParam);

	case TB_SETMAXTEXTROWS:
	    return TOOLBAR_SetMaxTextRows (infoPtr, wParam);

	case TB_SETPADDING:
	    return TOOLBAR_SetPadding (infoPtr, lParam);

	case TB_SETPARENT:
	    return TOOLBAR_SetParent (infoPtr, (HWND)wParam);

	case TB_SETROWS:
	    return TOOLBAR_SetRows (infoPtr, wParam, (LPRECT)lParam);

	case TB_SETSTATE:
	    return TOOLBAR_SetState (infoPtr, wParam, lParam);

	case TB_SETSTYLE:
	    return TOOLBAR_SetStyle (infoPtr, lParam);

	case TB_SETTOOLTIPS:
	    return TOOLBAR_SetToolTips (infoPtr, (HWND)wParam);

	case TB_SETUNICODEFORMAT:
	    return TOOLBAR_SetUnicodeFormat (infoPtr, wParam);

	case TB_SETBOUNDINGSIZE:
	    return TOOLBAR_SetBoundingSize(hwnd, wParam, lParam);

	case TB_SETHOTITEM2:
	    return TOOLBAR_SetHotItem2 (infoPtr, wParam, lParam);

	case TB_SETLISTGAP:
	    return TOOLBAR_SetListGap(infoPtr, wParam);

	case TB_GETIMAGELISTCOUNT:
	    return TOOLBAR_GetImageListCount(infoPtr);

	case TB_GETIDEALSIZE:
	    return TOOLBAR_GetIdealSize (infoPtr, wParam, lParam);

	case TB_UNKWN464:
	    return TOOLBAR_Unkwn464(hwnd, wParam, lParam);

/* Common Control Messages */

/*	case TB_GETCOLORSCHEME:			*/ /* identical to CCM_ */
	case CCM_GETCOLORSCHEME:
	    return TOOLBAR_GetColorScheme (infoPtr, (LPCOLORSCHEME)lParam);

/*	case TB_SETCOLORSCHEME:			*/ /* identical to CCM_ */
	case CCM_SETCOLORSCHEME:
	    return TOOLBAR_SetColorScheme (infoPtr, (LPCOLORSCHEME)lParam);

	case CCM_GETVERSION:
	    return TOOLBAR_GetVersion (infoPtr);

	case CCM_SETVERSION:
	    return TOOLBAR_SetVersion (infoPtr, (INT)wParam);


/*	case WM_CHAR: */

	case WM_CREATE:
	    return TOOLBAR_Create (hwnd, (CREATESTRUCTW*)lParam);

	case WM_DESTROY:
	  return TOOLBAR_Destroy (infoPtr);

	case WM_ERASEBKGND:
	    return TOOLBAR_EraseBackground (infoPtr, wParam, lParam);

	case WM_GETFONT:
		return TOOLBAR_GetFont (infoPtr);

	case WM_KEYDOWN:
	    return TOOLBAR_KeyDown (infoPtr, wParam, lParam);

/*	case WM_KILLFOCUS: */

	case WM_LBUTTONDBLCLK:
	    return TOOLBAR_LButtonDblClk (infoPtr, wParam, lParam);

	case WM_LBUTTONDOWN:
	    return TOOLBAR_LButtonDown (infoPtr, wParam, lParam);

	case WM_LBUTTONUP:
	    return TOOLBAR_LButtonUp (infoPtr, wParam, lParam);

	case WM_RBUTTONUP:
	    return TOOLBAR_RButtonUp (infoPtr, wParam, lParam);

	case WM_RBUTTONDBLCLK:
	    return TOOLBAR_RButtonDblClk (infoPtr, wParam, lParam);

	case WM_MOUSEMOVE:
	    return TOOLBAR_MouseMove (infoPtr, wParam, lParam);

	case WM_MOUSELEAVE:
	    return TOOLBAR_MouseLeave (infoPtr);

	case WM_CAPTURECHANGED:
	    if (hwnd == (HWND)lParam) return 0;
	    return TOOLBAR_CaptureChanged(infoPtr);

	case WM_NCACTIVATE:
	    return TOOLBAR_NCActivate (hwnd, wParam, lParam);

	case WM_NCCALCSIZE:
	    return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);

	case WM_NCCREATE:
	    return TOOLBAR_NCCreate (hwnd, wParam, (CREATESTRUCTW*)lParam);

	case WM_NCPAINT:
	    return TOOLBAR_NCPaint (hwnd, wParam, lParam);

	case WM_NOTIFY:
	    return TOOLBAR_Notify (infoPtr, (LPNMHDR)lParam);

	case WM_NOTIFYFORMAT:
	    return TOOLBAR_NotifyFormat (infoPtr, wParam, lParam);

	case WM_PRINTCLIENT:
	case WM_PAINT:
	    return TOOLBAR_Paint (infoPtr, wParam);

	case WM_SETFOCUS:
	    return TOOLBAR_SetFocus (infoPtr);

	case WM_SETFONT:
            return TOOLBAR_SetFont(infoPtr, (HFONT)wParam, (WORD)lParam);

	case WM_SETREDRAW:
	    return TOOLBAR_SetRedraw (infoPtr, wParam);

	case WM_SIZE:
	    return TOOLBAR_Size (infoPtr);

	case WM_STYLECHANGED:
	    return TOOLBAR_StyleChanged (infoPtr, (INT)wParam, (LPSTYLESTRUCT)lParam);

	case WM_SYSCOLORCHANGE:
	    return TOOLBAR_SysColorChange ();
            
        case WM_THEMECHANGED:
            return theme_changed (hwnd);

/*	case WM_WININICHANGE: */

	case WM_CHARTOITEM:
	case WM_COMMAND:
	case WM_DRAWITEM:
	case WM_MEASUREITEM:
	case WM_VKEYTOITEM:
            return SendMessageW (infoPtr->hwndNotify, uMsg, wParam, lParam);

	/* We see this in Outlook Express 5.x and just does DefWindowProc */
        case PGM_FORWARDMOUSE:
	    return DefWindowProcW (hwnd, uMsg, wParam, lParam);

	default:
	    if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
		ERR("unknown msg %04x wp=%08lx lp=%08lx\n",
		     uMsg, wParam, lParam);
	    return DefWindowProcW (hwnd, uMsg, wParam, lParam);
    }
}


VOID
TOOLBAR_Register (void)
{
    WNDCLASSW wndClass;

    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc   = ToolbarWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wndClass.lpszClassName = TOOLBARCLASSNAMEW;

    RegisterClassW (&wndClass);
}


VOID
TOOLBAR_Unregister (void)
{
    UnregisterClassW (TOOLBARCLASSNAMEW, NULL);
}

static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIST himl, INT id)
{
    HIMAGELIST himlold;
    PIMLENTRY c = NULL;

    /* Check if the entry already exists */
    c = TOOLBAR_GetImageListEntry(*pies, *cies, id);

    /* If this is a new entry we must create it and insert into the array */
    if (!c)
    {
        PIMLENTRY *pnies;

        c = Alloc(sizeof(IMLENTRY));
	c->id = id;

	pnies = Alloc((*cies + 1) * sizeof(PIMLENTRY));
	memcpy(pnies, *pies, ((*cies) * sizeof(PIMLENTRY)));
	pnies[*cies] = c;
	(*cies)++;

	Free(*pies);
	*pies = pnies;
    }

    himlold = c->himl;
    c->himl = himl;

    return himlold;
}


static VOID TOOLBAR_DeleteImageList(PIMLENTRY **pies, INT *cies)
{
    int i;

    for (i = 0; i < *cies; i++)
	Free((*pies)[i]);

    Free(*pies);

    *cies = 0;
    *pies = NULL;
}


static PIMLENTRY TOOLBAR_GetImageListEntry(const PIMLENTRY *pies, INT cies, INT id)
{
    PIMLENTRY c = NULL;

    if (pies != NULL)
    {
	int i;

        for (i = 0; i < cies; i++)
        {
            if (pies[i]->id == id)
            {
                c = pies[i];
                break;
            }
        }
    }

    return c;
}


static HIMAGELIST TOOLBAR_GetImageList(const PIMLENTRY *pies, INT cies, INT id)
{
    HIMAGELIST himlDef = 0;
    PIMLENTRY pie = TOOLBAR_GetImageListEntry(pies, cies, id);

    if (pie)
        himlDef = pie->himl;

    return himlDef;
}


static BOOL TOOLBAR_GetButtonInfo(const TOOLBAR_INFO *infoPtr, NMTOOLBARW *nmtb)
{
    if (infoPtr->bUnicode)
        return TOOLBAR_SendNotify(&nmtb->hdr, infoPtr, TBN_GETBUTTONINFOW);
    else
    {
        CHAR Buffer[256];
        NMTOOLBARA nmtba;
        BOOL bRet = FALSE;

        nmtba.iItem = nmtb->iItem;
        nmtba.pszText = Buffer;
        nmtba.cchText = 256;
        ZeroMemory(nmtba.pszText, nmtba.cchText);

        if (TOOLBAR_SendNotify(&nmtba.hdr, infoPtr, TBN_GETBUTTONINFOA))
        {
            int ccht = strlen(nmtba.pszText);
            if (ccht)
               MultiByteToWideChar(CP_ACP, 0, nmtba.pszText, -1,
                  nmtb->pszText, nmtb->cchText);

            nmtb->tbButton = nmtba.tbButton;
            bRet = TRUE;
        }

        return bRet;
    }
}


static BOOL TOOLBAR_IsButtonRemovable(const TOOLBAR_INFO *infoPtr, int iItem, const CUSTOMBUTTON *btnInfo)
{
    NMTOOLBARW nmtb;

    /* MSDN states that iItem is the index of the button, rather than the
     * command ID as used by every other NMTOOLBAR notification */
    nmtb.iItem = iItem;
    memcpy(&nmtb.tbButton, &btnInfo->btn, sizeof(TBBUTTON));

    return TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_QUERYDELETE);
}
