/*
 * Toolbar control
 *
 * Copyright 1998 Eric Kohl
 *
 * TODO:
 *   - Button wrapping.
 *   - Messages.
 *   - Notifications.
 *   - Fix TB_GETROWS and TB_SETROWS.
 *   - Tooltip support (almost complete).
 *   - Unicode suppport.
 *   - Internal COMMCTL32 bitmaps.
 *   - Fix TOOLBAR_SetButtonInfo32A.
 *   - Fix TOOLBAR_Customize. (Customize dialog.)
 *
 * 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.
 *   - Microsofts controlspy examples.
 */

#include "windows.h"
#include "commctrl.h"
#include "sysmetrics.h"
#include "cache.h"
#include "toolbar.h"
#include "win.h"
#include "debug.h"


#define SEPARATOR_WIDTH    8
#define SEPARATOR_HEIGHT   5
#define TOP_BORDER         2
#define BOTTOM_BORDER      2



#define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)wndPtr->wExtra[0])


static void
TOOLBAR_DrawFlatSeparator (LPRECT32 lpRect, HDC32 hdc)
{
    INT32 x = (lpRect->left + lpRect->right) / 2 - 1;
    INT32 yBottom = lpRect->bottom - 3;
    INT32 yTop = lpRect->top + 1;

    SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DSHADOW));
    MoveToEx32 (hdc, x, yBottom, NULL);
    LineTo32 (hdc, x, yTop);
    x++;
    SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DHILIGHT));
    MoveToEx32 (hdc, x, yBottom, NULL);
    LineTo32 (hdc, x, yTop);
}


static void
TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
		    HDC32 hdc, INT32 nState)
{
    RECT32   rcText = btnPtr->rect;
    HFONT32  hOldFont;
    INT32    nOldBkMode;
    COLORREF clrOld;

    /* draw text */
    if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
	InflateRect32 (&rcText, -3, -3);
	rcText.top += infoPtr->nBitmapHeight;
	if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
	    OffsetRect32 (&rcText, 1, 1);

	hOldFont = SelectObject32 (hdc, infoPtr->hFont);
	nOldBkMode = SetBkMode32 (hdc, TRANSPARENT);
	if (!(nState & TBSTATE_ENABLED)) {
	    clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT));
	    OffsetRect32 (&rcText, 1, 1);
	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
			 &rcText, infoPtr->dwDTFlags);
	    SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
	    OffsetRect32 (&rcText, -1, -1);
	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
			 &rcText, infoPtr->dwDTFlags);
	}
	else if (nState & TBSTATE_INDETERMINATE) {
	    clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
			 &rcText, infoPtr->dwDTFlags);
	}
	else {
	    clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_BTNTEXT));
	    DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
			 &rcText, infoPtr->dwDTFlags);
	}

	SetTextColor32 (hdc, clrOld);
	SelectObject32 (hdc, hOldFont);
	if (nOldBkMode != TRANSPARENT)
	    SetBkMode32 (hdc, nOldBkMode);
    }
}


static void
TOOLBAR_DrawPattern (HDC32 hdc, LPRECT32 lpRect)
{
    HBRUSH32 hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
    INT32 cx = lpRect->right - lpRect->left;
    INT32 cy = lpRect->bottom - lpRect->top;
    PatBlt32 (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
    SelectObject32 (hdc, hbr);
}


static void
TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
		    HDC32 hdc, INT32 x, INT32 y)
{
    /* FIXME: this function is a hack since it uses image list
	      internals directly */

    HDC32 hdcImageList = CreateCompatibleDC32 (0);
    HIMAGELIST himl = infoPtr->himlDef;

    /* draw the mask */
    SelectObject32 (hdcImageList, himl->hbmMask);
    SetBkColor32 (hdcImageList, RGB(255, 255, 255));
    SetTextColor32 (hdcImageList, RGB(0, 0, 0));

    SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DHILIGHT));
    BitBlt32 (hdc, x+1, y+1, himl->cx, himl->cy,
	      hdcImageList, himl->cx * btnPtr->iBitmap, 0,
		  0xB8074A);

    SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DSHADOW));
    BitBlt32 (hdc, x, y, himl->cx, himl->cy,
	      hdcImageList, himl->cx * btnPtr->iBitmap, 0,
		  0xB8074A);

    DeleteDC32 (hdcImageList);
}


static void
TOOLBAR_DrawButton (WND *wndPtr, TBUTTON_INFO *btnPtr, HDC32 hdc)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    BOOL32 bFlat = (wndPtr->dwStyle & TBSTYLE_FLAT);
    RECT32 rc;

    if (btnPtr->fsState & TBSTATE_HIDDEN) return;

    rc = btnPtr->rect;
    if (btnPtr->fsStyle & TBSTYLE_SEP) {
	if ((bFlat) && (btnPtr->idCommand == 0))
	    TOOLBAR_DrawFlatSeparator (&btnPtr->rect, hdc);
	return;
    }

    /* disabled */
    if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
	DrawEdge32 (hdc, &rc, EDGE_RAISED,
		    BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);

	TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);

	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
	return;
    }

    /* pressed TBSTYLE_BUTTON */
    if (btnPtr->fsState & TBSTATE_PRESSED) {
	DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
		    BF_RECT | BF_MIDDLE | BF_ADJUST);
	ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
			rc.left+2, rc.top+2, ILD_NORMAL);
	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
	return;
    }

    /* checked TBSTYLE_CHECK*/
    if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
	(btnPtr->fsState & TBSTATE_CHECKED)) {
	if (bFlat)
	    DrawEdge32 (hdc, &rc, BDR_SUNKENOUTER,
			BF_RECT | BF_MIDDLE | BF_ADJUST);
	else
	    DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
			BF_RECT | BF_MIDDLE | BF_ADJUST);

	TOOLBAR_DrawPattern (hdc, &rc);
	ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
			rc.left+2, rc.top+2, ILD_NORMAL);
	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
	return;
    }

    /* indeterminate */	
    if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
	DrawEdge32 (hdc, &rc, EDGE_RAISED,
		    BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);

	TOOLBAR_DrawPattern (hdc, &rc);
	TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
	TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
	return;
    }

    /* normal state */
    DrawEdge32 (hdc, &rc, EDGE_RAISED,
		BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
    ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
		    rc.left+1, rc.top+1, ILD_NORMAL);
    TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
}


static void
TOOLBAR_Refresh (WND *wndPtr, HDC32 hdc)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    INT32 i;

    /* draw buttons */
    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
}


static void
TOOLBAR_CalcStrings (WND *wndPtr, LPSIZE32 lpSize)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    INT32 i;
    HDC32 hdc;
    HFONT32 hOldFont;
    SIZE32 sz;

    lpSize->cx = 0;
    lpSize->cy = 0;
    hdc = GetDC32 (0);
    hOldFont = SelectObject32 (hdc, infoPtr->hFont);

    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
	if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
	    (btnPtr->iString > -1) &&
	    (btnPtr->iString < infoPtr->nNumStrings)) {
	    LPSTR lpText = infoPtr->strings[btnPtr->iString];
	    GetTextExtentPoint32A (hdc, lpText, lstrlen32A(lpText), &sz);
	    if (sz.cx > lpSize->cx)
		lpSize->cx = sz.cx;
	    if (sz.cy > lpSize->cy)
		lpSize->cy = sz.cy;
	}
    }

    SelectObject32 (hdc, hOldFont);
    ReleaseDC32 (0, hdc);

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


static void
TOOLBAR_CalcToolbar (WND *wndPtr)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    INT32 i, j, nRows;
    INT32 x, y, cx, cy;
    BOOL32 bVertical;
    SIZE32  sizeString;

    TOOLBAR_CalcStrings (wndPtr, &sizeString);

    if (sizeString.cy > 0)
	infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
    else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
	infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;

    if (sizeString.cx > infoPtr->nBitmapWidth)
	infoPtr->nButtonWidth = sizeString.cx + 6;
    else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
	infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;

    x  = infoPtr->nIndent;
    y  = TOP_BORDER;
    cx = infoPtr->nButtonWidth;
    cy = infoPtr->nButtonHeight;
    nRows = 1;

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

    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
	bVertical = FALSE;

	if (btnPtr->fsState & TBSTATE_HIDDEN)
	    continue;

	if (btnPtr->fsStyle & TBSTYLE_SEP) {
	    /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
	    /* it is the actual width of the separator. This is used for */
	    /* custom controls in toolbars.                              */
	    if ((wndPtr->dwStyle & TBSTYLE_WRAPABLE) &&
		(btnPtr->fsState & TBSTATE_WRAP)) {
		x = 0;
		y += cy;
		cx = infoPtr->nWidth;
		cy = ((btnPtr->iBitmap > 0) ?
		     btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
		nRows++;
		bVertical = TRUE;
	    }
	    else
		cx = (btnPtr->iBitmap > 0) ?
		     btnPtr->iBitmap : SEPARATOR_WIDTH;
	}
	else {
	    /* this must be a button */
	    cx = infoPtr->nButtonWidth;
	}

	btnPtr->rect.left   = x;
	btnPtr->rect.top    = y;
	btnPtr->rect.right  = x + cx;
	btnPtr->rect.bottom = y + cy;

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

	if (infoPtr->hwndToolTip) {
	    TTTOOLINFO32A ti;

	    ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
	    ti.cbSize = sizeof(TTTOOLINFO32A);
	    ti.hwnd = wndPtr->hwndSelf;
	    ti.uId = btnPtr->idCommand;
	    ti.rect = btnPtr->rect;
	    SendMessage32A (infoPtr->hwndToolTip, TTM_NEWTOOLRECT32A,
			    0, (LPARAM)&ti);
	}

	if (bVertical) {
	    x = 0;
	    y += cy;
	    if (i < infoPtr->nNumButtons)
		nRows++;
	}
	else
	    x += cx;
    }

    infoPtr->nHeight = y + cy + BOTTOM_BORDER;
    TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
}


static INT32
TOOLBAR_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    INT32 i;
    
    btnPtr = infoPtr->buttons;
    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
	if (btnPtr->fsState & TBSTATE_HIDDEN)
	    continue;

	if (btnPtr->fsStyle & TBSTYLE_SEP) {
	    if (PtInRect32 (&btnPtr->rect, *lpPt)) {
		TRACE (toolbar, " ON SEPARATOR %d!\n", i);
		return -i;
	    }
	}
	else {
	    if (PtInRect32 (&btnPtr->rect, *lpPt)) {
		TRACE (toolbar, " ON BUTTON %d!\n", i);
		return i;
	    }
	}
    }

    TRACE (toolbar, " NOWHERE!\n");
    return -1;
}


static INT32
TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT32 idCommand)
{
    TBUTTON_INFO *btnPtr;
    INT32 i;

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


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

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

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

    /* check previous buttons */
    nRunIndex = nIndex - 1;
    while (nRunIndex >= 0) {
	btnPtr = &infoPtr->buttons[nRunIndex];
	if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
	    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 & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
	    if (btnPtr->fsState & TBSTATE_CHECKED)
		return nRunIndex;
	}
	else
	    break;
	nRunIndex++;
    }

    return -1;
}


static VOID
TOOLBAR_RelayEvent (HWND32 hwndTip, HWND32 hwndMsg, UINT32 uMsg,
		    WPARAM32 wParam, LPARAM lParam)
{
    MSG32 msg;

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

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


static LRESULT
TOOLBAR_AddBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
    INT32 nIndex = 0;

    if ((!lpAddBmp) || ((INT32)wParam <= 0))
	return -1;

    TRACE (toolbar, "adding %d bitmaps!\n", wParam);

    if (!(infoPtr->himlDef)) {
	/* create new default image list */
	TRACE (toolbar, "creating default image list!\n");
	infoPtr->himlDef =
	    ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
			      ILC_COLOR | ILC_MASK, (INT32)wParam, 2);
    }

#if 0
    if (!(infoPtr->himlDis)) {
	/* create new disabled image list */
	TRACE (toolbar, "creating disabled image list!\n");
	infoPtr->himlDis =
	    ImageList_Create (infoPtr->nBitmapWidth, 
			      infoPtr->nBitmapHeight, ILC_COLOR | ILC_MASK,
			      (INT32)wParam, 2);
    }
#endif

    /* Add bitmaps to the default image list */
    if (lpAddBmp->hInst == (HINSTANCE32)0) {
	nIndex = 
	    ImageList_AddMasked (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID,
				 CLR_DEFAULT);
    }
    else if (lpAddBmp->hInst == HINST_COMMCTRL) {
	/* add internal bitmaps */
	FIXME (toolbar, "internal bitmaps not supported!\n");

	/* Hack to "add" some reserved images within the image list 
	   to get the right image indices */
	nIndex = ImageList_GetImageCount (infoPtr->himlDef);
	ImageList_SetImageCount (infoPtr->himlDef, nIndex + (INT32)wParam);
    }
    else {
	HBITMAP32 hBmp =
	    LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);

	nIndex = ImageList_AddMasked (infoPtr->himlDef, hBmp, CLR_DEFAULT);

	DeleteObject32 (hBmp); 
    }


    infoPtr->nNumBitmaps += (INT32)wParam;

    return nIndex;
}


static LRESULT
TOOLBAR_AddButtons32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
    INT32 nOldButtons, nNewButtons, nAddButtons, nCount;
    HDC32 hdc;

    TRACE (toolbar, "adding %d buttons!\n", wParam);

    nAddButtons = (UINT32)wParam;
    nOldButtons = infoPtr->nNumButtons;
    nNewButtons = nOldButtons + nAddButtons;

    if (infoPtr->nNumButtons == 0) {
	infoPtr->buttons =
	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
    }
    else {
	TBUTTON_INFO *oldButtons = infoPtr->buttons;
	infoPtr->buttons =
	    COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
	memcpy (&infoPtr->buttons[0], &oldButtons[0],
		nOldButtons * sizeof(TBUTTON_INFO));
        COMCTL32_Free (oldButtons);
    }

    infoPtr->nNumButtons = nNewButtons;

    /* insert new button data */
    for (nCount = 0; nCount < nAddButtons; nCount++) {
	TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
	btnPtr->iBitmap   = lpTbb[nCount].iBitmap;
	btnPtr->idCommand = lpTbb[nCount].idCommand;
	btnPtr->fsState   = lpTbb[nCount].fsState;
	btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
	btnPtr->dwData    = lpTbb[nCount].dwData;
	btnPtr->iString   = lpTbb[nCount].iString;

	if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
	    TTTOOLINFO32A ti;

	    ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
	    ti.cbSize   = sizeof (TTTOOLINFO32A);
	    ti.hwnd     = wndPtr->hwndSelf;
	    ti.uId      = btnPtr->idCommand;
	    ti.hinst    = 0;
	    ti.lpszText = LPSTR_TEXTCALLBACK32A;

	    SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A,
			    0, (LPARAM)&ti);
	}
    }

    TOOLBAR_CalcToolbar (wndPtr);

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


// << TOOLBAR_AddButtons32W >>


static LRESULT
TOOLBAR_AddString32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

    if (wParam) {
	char szString[256];
	INT32 len;
	TRACE (toolbar, "adding string from resource!\n");

	len = LoadString32A ((HINSTANCE32)wParam, (UINT32)lParam,
			     szString, 256);

	TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
	nIndex = infoPtr->nNumStrings;
	if (infoPtr->nNumStrings == 0) {
	    infoPtr->strings =
		COMCTL32_Alloc (sizeof(char *));
	}
	else {
	    char **oldStrings = infoPtr->strings;
	    infoPtr->strings =
		COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1));
	    memcpy (&infoPtr->strings[0], &oldStrings[0],
		    sizeof(char *) * infoPtr->nNumStrings);
	    COMCTL32_Free (oldStrings);
	}

	infoPtr->strings[infoPtr->nNumStrings] =
	    COMCTL32_Alloc (sizeof(char)*(len+1));
	lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], szString);
	infoPtr->nNumStrings++;
    }
    else {
	char *p = (char*)lParam;
	INT32 len;

	if (p == NULL) return -1;
	TRACE (toolbar, "adding string(s) from array!\n");
	nIndex = infoPtr->nNumStrings;
	while (*p) {
	    len = lstrlen32A (p);
	    TRACE (toolbar, "len=%d \"%s\"\n", len, p);

	    if (infoPtr->nNumStrings == 0) {
		infoPtr->strings =
		    COMCTL32_Alloc (sizeof(char *));
	    }
	    else {
		char **oldStrings = infoPtr->strings;
		infoPtr->strings =
		    COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1));
		memcpy (&infoPtr->strings[0], &oldStrings[0],
			sizeof(char *) * infoPtr->nNumStrings);
		COMCTL32_Free (oldStrings);
	    }

	    infoPtr->strings[infoPtr->nNumStrings] =
		COMCTL32_Alloc (sizeof(char)*(len+1));
	    lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], p);
	    infoPtr->nNumStrings++;

	    p += (len+1);
	}
    }

    return nIndex;
}


// << TOOLBAR_AddString32W >>


static LRESULT
TOOLBAR_AutoSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    RECT32 parent_rect;
    HWND32 parent;
    INT32  x, y, cx, cy;
    UINT32 uPosFlags = 0;

    TRACE (toolbar, "resize forced!\n");

    parent = GetParent32 (wndPtr->hwndSelf);
    GetClientRect32(parent, &parent_rect);

    if (wndPtr->dwStyle & CCS_NORESIZE) {
	uPosFlags |= SWP_NOSIZE;
	cx = 0;
	cy = 0;
    }
    else {
	infoPtr->nWidth = parent_rect.right - parent_rect.left;
	TOOLBAR_CalcToolbar (wndPtr);
	cy = infoPtr->nHeight;
	cx = infoPtr->nWidth;
    }

    if (wndPtr->dwStyle & CCS_NOPARENTALIGN)
	uPosFlags |= SWP_NOMOVE;

    if (!(wndPtr->dwStyle & CCS_NODIVIDER))
	cy += sysMetrics[SM_CYEDGE];

    infoPtr->bAutoSize = TRUE;
    SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, parent_rect.left, parent_rect.top,
		    cx, cy, uPosFlags);

    return 0;
}


static LRESULT
TOOLBAR_ButtonCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    return infoPtr->nNumButtons;
}


static LRESULT
TOOLBAR_ButtonStructSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr == NULL) {
	ERR (toolbar, "(0x%08lx, 0x%08x, 0x%08lx)\n", (DWORD)wndPtr, wParam, lParam);
	ERR (toolbar, "infoPtr == NULL!\n");
	return 0;
    }

    infoPtr->dwStructSize = (DWORD)wParam;

    return 0;
}


static LRESULT
TOOLBAR_ChangeBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    btnPtr->iBitmap = LOWORD(lParam);

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


static LRESULT
TOOLBAR_CheckButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;
    INT32 nOldIndex = -1;

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

    btnPtr = &infoPtr->buttons[nIndex];

    if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
	return FALSE;

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

    hdc = GetDC32 (wndPtr->hwndSelf);
    if (nOldIndex != -1)
	TOOLBAR_DrawButton (wndPtr, &infoPtr->buttons[nOldIndex], hdc);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    /* FIXME: Send a WM_NOTIFY?? */

    return TRUE;
}


static LRESULT
TOOLBAR_CommandToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    return TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
}


static LRESULT
TOOLBAR_Customize (WND *wndPtr)
{
    FIXME (toolbar, "customization not implemented!\n");

    return 0;
}


static LRESULT
TOOLBAR_DeleteButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex = (INT32)wParam;

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

    if ((infoPtr->hwndToolTip) && 
	!(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
	TTTOOLINFO32A ti;

	ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
	ti.cbSize   = sizeof (TTTOOLINFO32A);
	ti.hwnd     = wndPtr->hwndSelf;
	ti.uId      = infoPtr->buttons[nIndex].idCommand;

	SendMessage32A (infoPtr->hwndToolTip, TTM_DELTOOL32A, 0, (LPARAM)&ti);
    }

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

	infoPtr->nNumButtons--;
	infoPtr->buttons = COMCTL32_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));
        }

	COMCTL32_Free (oldButtons);
    }

    TOOLBAR_CalcToolbar (wndPtr);

    InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
    UpdateWindow32 (wndPtr->hwndSelf);

    return TRUE;
}


static LRESULT
TOOLBAR_EnableButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    if (LOWORD(lParam) == FALSE)
	btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
    else
	btnPtr->fsState |= TBSTATE_ENABLED;

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


// << TOOLBAR_GetAnchorHighlight >>


static LRESULT
TOOLBAR_GetBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
    if (nIndex == -1)
	return -1;

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


static __inline__ LRESULT
TOOLBAR_GetBitmapFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    return (GetDeviceCaps32 (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
}


static LRESULT
TOOLBAR_GetButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
    INT32 nIndex = (INT32)wParam;
    TBUTTON_INFO *btnPtr;

    if (infoPtr == NULL) return FALSE;
    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->dwData    = btnPtr->dwData;
    lpTbb->iString   = btnPtr->iString;

    return TRUE;
}


static LRESULT
TOOLBAR_GetButtonInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBBUTTONINFO32A lpTbInfo = (LPTBBUTTONINFO32A)lParam;
    TBUTTON_INFO *btnPtr;
    INT32 nIndex;

    if (infoPtr == NULL) return -1;
    if (lpTbInfo == NULL) return -1;
    if (lpTbInfo->cbSize < sizeof(LPTBBUTTONINFO32A)) return -1;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
    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)
	lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
    if (lpTbInfo->dwMask & TBIF_STATE)
	lpTbInfo->fsState = btnPtr->fsState;
    if (lpTbInfo->dwMask & TBIF_STYLE)
	lpTbInfo->fsStyle = btnPtr->fsStyle;
    if (lpTbInfo->dwMask & TBIF_TEXT) {
	if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
	    lstrcpyn32A (lpTbInfo->pszText, 
			 (LPSTR)infoPtr->strings[btnPtr->iString],
			 lpTbInfo->cchText);
    }

    return nIndex;
}


// << TOOLBAR_GetButtonInfo32W >>


static LRESULT
TOOLBAR_GetButtonSize (WND *wndPtr)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    return MAKELONG((WORD)infoPtr->nButtonWidth,
		    (WORD)infoPtr->nButtonHeight);
}


static LRESULT
TOOLBAR_GetButtonText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex, nStringIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
    if (nIndex == -1)
	return -1;

    nStringIndex = infoPtr->buttons[nIndex].iString;

    TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);

    if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
	return -1;

    if (lParam == 0) return -1;

    lstrcpy32A ((LPSTR)lParam, (LPSTR)infoPtr->strings[nStringIndex]);

    return lstrlen32A ((LPSTR)infoPtr->strings[nStringIndex]);
}


// << TOOLBAR_GetButtonText32W >>
// << TOOLBAR_GetColorScheme >>


static LRESULT
TOOLBAR_GetDisabledImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (wndPtr->dwStyle & TBSTYLE_FLAT)
	return (LRESULT)infoPtr->himlDis;
    else
	return 0;
}


__inline__ static LRESULT
TOOLBAR_GetExtendedStyle (WND *wndPtr)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    return infoPtr->dwExStyle;
}


static LRESULT
TOOLBAR_GetHotImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (wndPtr->dwStyle & TBSTYLE_FLAT)
	return (LRESULT)infoPtr->himlHot;
    else
	return 0;
}


// << TOOLBAR_GetHotItem >>


static LRESULT
TOOLBAR_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (wndPtr->dwStyle & TBSTYLE_FLAT)
	return (LRESULT)infoPtr->himlDef;
    else
	return 0;
}


// << TOOLBAR_GetInsertMark >>
// << TOOLBAR_GetInsertMarkColor >>


static LRESULT
TOOLBAR_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    LPRECT32     lpRect;
    INT32        nIndex;

    if (infoPtr == NULL) return FALSE;
    nIndex = (INT32)wParam;
    btnPtr = &infoPtr->buttons[nIndex];
    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
	return FALSE;
    lpRect = (LPRECT32)lParam;
    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 (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPSIZE32 lpSize = (LPSIZE32)lParam;

    if (lpSize == NULL)
	return FALSE;

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

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

    return TRUE;
}


// << TOOLBAR_GetObject >>
// << TOOLBAR_GetPadding >>


static LRESULT
TOOLBAR_GetRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    LPRECT32     lpRect;
    INT32        nIndex;

    if (infoPtr == NULL) return FALSE;
    nIndex = (INT32)wParam;
    btnPtr = &infoPtr->buttons[nIndex];
    if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
	return FALSE;
    lpRect = (LPRECT32)lParam;
    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 LRESULT
TOOLBAR_GetRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (wndPtr->dwStyle & TBSTYLE_WRAPABLE)
	return infoPtr->nMaxRows;
    else
	return 1;
}


static LRESULT
TOOLBAR_GetState (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
    if (nIndex == -1) return -1;

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


static LRESULT
TOOLBAR_GetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
    if (nIndex == -1) return -1;

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


static LRESULT
TOOLBAR_GetTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr == NULL)
	return 0;

    return infoPtr->nMaxTextRows;
}


static LRESULT
TOOLBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr == NULL) return 0;
    return infoPtr->hwndToolTip;
}


static LRESULT
TOOLBAR_GetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    TRACE (toolbar, "%s hwnd=0x%04x stub!\n", 
	   infoPtr->bUnicode ? "TRUE" : "FALSE", wndPtr->hwndSelf);

    return infoPtr->bUnicode;
}


static LRESULT
TOOLBAR_HideButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    if (LOWORD(lParam) == FALSE)
	btnPtr->fsState &= ~TBSTATE_HIDDEN;
    else
	btnPtr->fsState |= TBSTATE_HIDDEN;

    TOOLBAR_CalcToolbar (wndPtr);

    InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
    UpdateWindow32 (wndPtr->hwndSelf);

    return TRUE;
}


__inline__ static LRESULT
TOOLBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    return TOOLBAR_InternalHitTest (wndPtr, (LPPOINT32)lParam);
}


static LRESULT
TOOLBAR_Indeterminate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    if (LOWORD(lParam) == FALSE)
	btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
    else
	btnPtr->fsState |= TBSTATE_INDETERMINATE;

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


static LRESULT
TOOLBAR_InsertButton32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
    INT32 nIndex = (INT32)wParam;
    TBUTTON_INFO *oldButtons;
    HDC32 hdc;

    if (lpTbb == NULL) return FALSE;
    if (nIndex < 0) return FALSE;

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

    oldButtons = infoPtr->buttons;
    infoPtr->nNumButtons++;
    infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
    /* pre insert copy */
    if (nIndex > 0) {
	memcpy (&infoPtr->buttons[0], &oldButtons[0],
		nIndex * sizeof(TBUTTON_INFO));
    }

    /* insert new button */
    infoPtr->buttons[nIndex].iBitmap   = lpTbb->iBitmap;
    infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
    infoPtr->buttons[nIndex].fsState   = lpTbb->fsState;
    infoPtr->buttons[nIndex].fsStyle   = lpTbb->fsStyle;
    infoPtr->buttons[nIndex].dwData    = lpTbb->dwData;
    infoPtr->buttons[nIndex].iString   = lpTbb->iString;

    if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
	TTTOOLINFO32A ti;

	ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
	ti.cbSize   = sizeof (TTTOOLINFO32A);
	ti.hwnd     = wndPtr->hwndSelf;
	ti.uId      = lpTbb->idCommand;
	ti.hinst    = 0;
	ti.lpszText = LPSTR_TEXTCALLBACK32A;

	SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A,
			0, (LPARAM)&ti);
    }

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

    COMCTL32_Free (oldButtons);

    TOOLBAR_CalcToolbar (wndPtr);

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


// << TOOLBAR_InsertButton32W >>
// << TOOLBAR_InsertMarkHitTest >>


static LRESULT
TOOLBAR_IsButtonChecked (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

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

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


static LRESULT
TOOLBAR_IsButtonEnabled (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

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

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


static LRESULT
TOOLBAR_IsButtonHidden (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

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

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


static LRESULT
TOOLBAR_IsButtonHighlighted (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

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

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


static LRESULT
TOOLBAR_IsButtonIndeterminate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

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

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


static LRESULT
TOOLBAR_IsButtonPressed (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex;

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

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


// << TOOLBAR_LoadImages >>
// << TOOLBAR_MapAccelerator >>
// << TOOLBAR_MarkButton >>
// << TOOLBAR_MoveButton >>


static LRESULT
TOOLBAR_PressButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    if (LOWORD(lParam) == FALSE)
	btnPtr->fsState &= ~TBSTATE_PRESSED;
    else
	btnPtr->fsState |= TBSTATE_PRESSED;

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


// << TOOLBAR_ReplaceBitmap >>


static LRESULT
TOOLBAR_SaveRestore32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
#if 0
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBSAVEPARAMS32A lpSave = (LPTBSAVEPARAMS32A)lParam;

    if (lpSave == NULL) return 0;

    if ((BOOL32)wParam) {
	/* save toolbar information */
	FIXME (toolbar, "save to \"%s\" \"%s\"\n",
	       lpSave->pszSubKey, lpSave->pszValueName);


    }
    else {
	/* restore toolbar information */

	FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
	       lpSave->pszSubKey, lpSave->pszValueName);


    }
#endif

    return 0;
}


// << TOOLBAR_SaveRestore32W >>
// << TOOLBAR_SetAnchorHighlight >>


static LRESULT
TOOLBAR_SetBitmapSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
	return FALSE;

    infoPtr->nBitmapWidth = (INT32)LOWORD(lParam);
    infoPtr->nBitmapHeight = (INT32)HIWORD(lParam);

    return TRUE;
}


static LRESULT
TOOLBAR_SetButtonInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPTBBUTTONINFO32A lptbbi = (LPTBBUTTONINFO32A)lParam;
    TBUTTON_INFO *btnPtr;
    INT32 nIndex;

    if (lptbbi == NULL)
	return FALSE;
    if (lptbbi->cbSize < sizeof(LPTBBUTTONINFO32A))
	return FALSE;
    
    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
    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) {
	if ((btnPtr->iString >= 0) || 
	    (btnPtr->iString < infoPtr->nNumStrings)) {
#if 0
	    CHAR **lpString = &infoPtr->strings[btnPtr->iString];
	    INT32 len = lstrlen32A (lptbbi->pszText);
	    *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
#endif

	    /* this is the ultimate sollution */
//	    Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText);
	}
    }

    return TRUE;
}


// << TOOLBAR_SetButtonInfo32W >>


static LRESULT
TOOLBAR_SetButtonSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
	return FALSE;

    infoPtr->nButtonWidth = (INT32)LOWORD(lParam);
    infoPtr->nButtonHeight = (INT32)HIWORD(lParam);

    return TRUE;
}


static LRESULT
TOOLBAR_SetButtonWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr == NULL)
	return FALSE;

    infoPtr->cxMin = (INT32)LOWORD(lParam);
    infoPtr->cxMax = (INT32)HIWORD(lParam);

    return TRUE;
}


static LRESULT
TOOLBAR_SetCmdId (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    INT32 nIndex = (INT32)wParam;

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

    infoPtr->buttons[nIndex].idCommand = (INT32)lParam;

    if (infoPtr->hwndToolTip) {

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

    }

    return TRUE;
}


// << TOOLBAR_SetColorScheme >>


static LRESULT
TOOLBAR_SetDisabledImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    HIMAGELIST himlTemp;

    if (!(wndPtr->dwStyle & TBSTYLE_FLAT))
	return 0;

    himlTemp = infoPtr->himlDis;
    infoPtr->himlDis = (HIMAGELIST)lParam;

    /* FIXME: redraw ? */

    return (LRESULT)himlTemp; 
}


static LRESULT
TOOLBAR_SetDrawTextFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    DWORD dwTemp;

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

    return (LRESULT)dwTemp;
}


static LRESULT
TOOLBAR_SetExtendedStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    DWORD dwTemp;

    dwTemp = infoPtr->dwExStyle;
    infoPtr->dwExStyle = (DWORD)lParam;

    return (LRESULT)dwTemp; 
}


static LRESULT
TOOLBAR_SetHotImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    HIMAGELIST himlTemp;

    if (!(wndPtr->dwStyle & TBSTYLE_FLAT))
	return 0;

    himlTemp = infoPtr->himlHot;
    infoPtr->himlHot = (HIMAGELIST)lParam;

    /* FIXME: redraw ? */

    return (LRESULT)himlTemp; 
}


// << TOOLBAR_SetHotItem >>


static LRESULT
TOOLBAR_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    HIMAGELIST himlTemp;

    if (!(wndPtr->dwStyle & TBSTYLE_FLAT))
	return 0;

    himlTemp = infoPtr->himlDef;
    infoPtr->himlDef = (HIMAGELIST)lParam;

    /* FIXME: redraw ? */

    return (LRESULT)himlTemp; 
}


static LRESULT
TOOLBAR_SetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    HDC32 hdc;

    infoPtr->nIndent = (INT32)wParam;
    TOOLBAR_CalcToolbar (wndPtr);
    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


// << TOOLBAR_SetInsertMark >>


static LRESULT
TOOLBAR_SetInsertMarkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    infoPtr->clrInsertMark = (COLORREF)lParam;

    /* FIXME : redraw ??*/

    return 0;
}


static LRESULT
TOOLBAR_SetMaxTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr == NULL)
	return FALSE;

    infoPtr->nMaxTextRows = (INT32)wParam;

    return TRUE;
}


// << TOOLBAR_SetPadding >>


static LRESULT
TOOLBAR_SetParent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    HWND32 hwndOldNotify;

    if (infoPtr == NULL) return 0;
    hwndOldNotify = infoPtr->hwndNotify;
    infoPtr->hwndNotify = (HWND32)wParam;

    return hwndOldNotify;
}


static LRESULT
TOOLBAR_SetRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPRECT32 lprc = (LPRECT32)lParam;
    HDC32 hdc;

    if (LOWORD(wParam) > 1) {

	FIXME (toolbar, "multiple rows not supported!\n");

    }

    /* recalculate toolbar */
    TOOLBAR_CalcToolbar (wndPtr);

    /* 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;
    }

    /* repaint toolbar */
    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return 0;
}


static LRESULT
TOOLBAR_SetState (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    btnPtr->fsState = LOWORD(lParam);

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return TRUE;
}


static LRESULT
TOOLBAR_SetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    HDC32 hdc;
    INT32 nIndex;

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

    btnPtr = &infoPtr->buttons[nIndex];
    btnPtr->fsStyle = LOWORD(lParam);

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    if (infoPtr->hwndToolTip) {

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

    }

    return TRUE;
}


__inline__ static LRESULT
TOOLBAR_SetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr == NULL) return 0;
    infoPtr->hwndToolTip = (HWND32)wParam;
    return 0;
}


static LRESULT
TOOLBAR_SetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    BOOL32 bTemp;

    TRACE (toolbar, "%s hwnd=0x%04x stub!\n", 
	   ((BOOL32)wParam) ? "TRUE" : "FALSE", wndPtr->hwndSelf);

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

    return bTemp;
}


static LRESULT
TOOLBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LOGFONT32A logFont;

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

    infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
    infoPtr->nMaxRows = 1;
    infoPtr->nMaxTextRows = 1;
    infoPtr->cxMin = -1;
    infoPtr->cxMax = -1;

    infoPtr->bCaptured = FALSE;
    infoPtr->bUnicode = FALSE;
    infoPtr->nButtonDown = -1;
    infoPtr->nOldHit = -1;

    infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf);
    infoPtr->bTransparent = (wndPtr->dwStyle & TBSTYLE_FLAT);
    infoPtr->nHotItem = -1;
    infoPtr->dwDTFlags = DT_CENTER;

    SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
    infoPtr->hFont = CreateFontIndirect32A (&logFont);

    if (wndPtr->dwStyle & TBSTYLE_TOOLTIPS) {
	/* Create tooltip control */
	infoPtr->hwndToolTip =
	    CreateWindowEx32A (0, TOOLTIPS_CLASS32A, NULL, TTS_ALWAYSTIP,
			       CW_USEDEFAULT32, CW_USEDEFAULT32,
			       CW_USEDEFAULT32, CW_USEDEFAULT32,
			       wndPtr->hwndSelf, 0, 0, 0);

	/* Send NM_TOOLTIPSCREATED notification */
	if (infoPtr->hwndToolTip) {
	    NMTOOLTIPSCREATED nmttc;

	    nmttc.hdr.hwndFrom = wndPtr->hwndSelf;
	    nmttc.hdr.idFrom = wndPtr->wIDmenu;
	    nmttc.hdr.code = NM_TOOLTIPSCREATED;
	    nmttc.hwndToolTips = infoPtr->hwndToolTip;

	    SendMessage32A (infoPtr->hwndNotify, WM_NOTIFY,
			    (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmttc);
	}
    }

    return 0;
}


static LRESULT
TOOLBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

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

    /* delete button data */
    if (infoPtr->buttons)
	COMCTL32_Free (infoPtr->buttons);

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

	COMCTL32_Free (infoPtr->strings);
    }

    /* destroy default image list */
    if (infoPtr->himlDef)
	ImageList_Destroy (infoPtr->himlDef);

    /* destroy disabled image list */
    if (infoPtr->himlDis)
	ImageList_Destroy (infoPtr->himlDis);

    /* destroy hot image list */
    if (infoPtr->himlHot)
	ImageList_Destroy (infoPtr->himlHot);

    /* delete default font */
    if (infoPtr->hFont)
	DeleteObject32 (infoPtr->hFont);

    /* free toolbar info data */
    COMCTL32_Free (infoPtr);

    return 0;
}


static LRESULT
TOOLBAR_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);

    if (infoPtr->bTransparent)
	return SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_ERASEBKGND,
			       wParam, lParam);

    return DefWindowProc32A (wndPtr->hwndSelf, WM_ERASEBKGND, wParam, lParam);
}


static LRESULT
TOOLBAR_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    POINT32 pt;
    INT32   nHit;
    HDC32   hdc;

    pt.x = (INT32)LOWORD(lParam);
    pt.y = (INT32)HIWORD(lParam);
    nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);

    if (nHit >= 0) {
	btnPtr = &infoPtr->buttons[nHit];
	if (!(btnPtr->fsState & TBSTATE_ENABLED))
	    return 0;
	SetCapture32 (wndPtr->hwndSelf);
	infoPtr->bCaptured = TRUE;
	infoPtr->nButtonDown = nHit;

	btnPtr->fsState |= TBSTATE_PRESSED;

	hdc = GetDC32 (wndPtr->hwndSelf);
	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
	ReleaseDC32 (wndPtr->hwndSelf, hdc);
    }
    else if (wndPtr->dwStyle & CCS_ADJUSTABLE)
	TOOLBAR_Customize (wndPtr);

    return 0;
}


static LRESULT
TOOLBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    POINT32 pt;
    INT32   nHit;
    HDC32   hdc;

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

    pt.x = (INT32)LOWORD(lParam);
    pt.y = (INT32)HIWORD(lParam);
    nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);

    if (nHit >= 0) {
	btnPtr = &infoPtr->buttons[nHit];
	if (!(btnPtr->fsState & TBSTATE_ENABLED))
	    return 0;

	SetCapture32 (wndPtr->hwndSelf);
	infoPtr->bCaptured = TRUE;
	infoPtr->nButtonDown = nHit;
	infoPtr->nOldHit = nHit;

	btnPtr->fsState |= TBSTATE_PRESSED;

	hdc = GetDC32 (wndPtr->hwndSelf);
	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
	ReleaseDC32 (wndPtr->hwndSelf, hdc);
    }

    return 0;
}


static LRESULT
TOOLBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    POINT32 pt;
    INT32   nHit;
    INT32   nOldIndex = -1;
    HDC32   hdc;
    BOOL32  bSendMessage = TRUE;

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

    pt.x = (INT32)LOWORD(lParam);
    pt.y = (INT32)HIWORD(lParam);
    nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);

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

	if (nHit == infoPtr->nButtonDown) {
	    if (btnPtr->fsStyle & TBSTYLE_CHECK) {
		if (btnPtr->fsStyle & TBSTYLE_GROUP) {
		    nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
			infoPtr->nButtonDown);
		    if (nOldIndex == infoPtr->nButtonDown)
			bSendMessage = FALSE;
		    if ((nOldIndex != infoPtr->nButtonDown) && 
			(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;
		}
	    }
	}
	else
	    bSendMessage = FALSE;

	hdc = GetDC32 (wndPtr->hwndSelf);
	if (nOldIndex != -1)
	    TOOLBAR_DrawButton (wndPtr, &infoPtr->buttons[nOldIndex], hdc);
	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
	ReleaseDC32 (wndPtr->hwndSelf, hdc);

	if (bSendMessage)
	    SendMessage32A (infoPtr->hwndNotify, WM_COMMAND,
			    MAKEWPARAM(btnPtr->idCommand, 0),
			    (LPARAM)wndPtr->hwndSelf);

	infoPtr->nButtonDown = -1;
	infoPtr->nOldHit = -1;
    }

    return 0;
}


static LRESULT
TOOLBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    TBUTTON_INFO *btnPtr;
    POINT32 pt;
    INT32   nHit;
    HDC32   hdc;

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

    pt.x = (INT32)LOWORD(lParam);
    pt.y = (INT32)HIWORD(lParam);
    nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);

    if (infoPtr->bCaptured) {
	if (infoPtr->nOldHit != nHit) {
	    btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
	    if (infoPtr->nOldHit == infoPtr->nButtonDown) {
		btnPtr->fsState &= ~TBSTATE_PRESSED;
		hdc = GetDC32 (wndPtr->hwndSelf);
		TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
		ReleaseDC32 (wndPtr->hwndSelf, hdc);
	    }
	    else if (nHit == infoPtr->nButtonDown) {
		btnPtr->fsState |= TBSTATE_PRESSED;
		hdc = GetDC32 (wndPtr->hwndSelf);
		TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
		ReleaseDC32 (wndPtr->hwndSelf, hdc);
	    }
	}
	infoPtr->nOldHit = nHit;
    }

    return 0;
}


__inline__ static LRESULT
TOOLBAR_NCActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
//    if (wndPtr->dwStyle & CCS_NODIVIDER)
	return DefWindowProc32A (wndPtr->hwndSelf, WM_NCACTIVATE,
				 wParam, lParam);
//    else
//	return TOOLBAR_NCPaint (wndPtr, wParam, lParam);
}


__inline__ static LRESULT
TOOLBAR_NCCalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    if (!(wndPtr->dwStyle & CCS_NODIVIDER))
	((LPRECT32)lParam)->top += sysMetrics[SM_CYEDGE];

    return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam);
}


static LRESULT
TOOLBAR_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr;

    /* allocate memory for info structure */
    infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
    wndPtr->wExtra[0] = (DWORD)infoPtr;

    if (infoPtr == NULL) {
	ERR (toolbar, "could not allocate info memory!\n");
	return 0;
    }

    if ((TOOLBAR_INFO*)wndPtr->wExtra[0] != infoPtr) {
	ERR (toolbar, "pointer assignment error!\n");
	return 0;
    }

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

    /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
    if (!wndPtr->hInstance)
	wndPtr->hInstance = wndPtr->parent->hInstance;

    return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
}


static LRESULT
TOOLBAR_NCPaint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    HWND32 hwnd = wndPtr->hwndSelf;
    HDC32 hdc;

    if ( wndPtr->dwStyle & WS_MINIMIZE ||
	!WIN_IsWindowDrawable( wndPtr, 0 )) return 0; /* Nothing to do */

    DefWindowProc32A (hwnd, WM_NCPAINT, wParam, lParam);

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

    if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
		        wndPtr->rectClient.top-wndPtr->rectWindow.top,
		        wndPtr->rectClient.right-wndPtr->rectWindow.left,
		        wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
	== NULLREGION){
	ReleaseDC32( hwnd, hdc );
	return 0;
    }

    if (!(wndPtr->flags & WIN_MANAGED) && !(wndPtr->dwStyle & CCS_NODIVIDER))
	DrawEdge32 (hdc, &wndPtr->rectWindow, EDGE_ETCHED, BF_TOP);

    ReleaseDC32( hwnd, hdc );

    return 0;
}


__inline__ static LRESULT
TOOLBAR_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    LPNMHDR lpnmh = (LPNMHDR)lParam;

    TRACE (toolbar, "passing WM_NOTIFY!\n");

    if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
	SendMessage32A (infoPtr->hwndNotify, WM_NOTIFY,	wParam, lParam);

#if 0
	if (lpnmh->code == TTN_GETDISPINFO32A) {
	    LPNMTTDISPINFO32A lpdi = (LPNMTTDISPINFO32A)lParam;

	    FIXME (toolbar, "retrieving ASCII string\n");

	}
	else if (lpnmh->code == TTN_GETDISPINFO32W) {
	    LPNMTTDISPINFO32W lpdi = (LPNMTTDISPINFO32W)lParam;

	    FIXME (toolbar, "retrieving UNICODE string\n");

	}
#endif
    }

    return 0;
}


static LRESULT
TOOLBAR_Paint (WND *wndPtr, WPARAM32 wParam)
{
    HDC32 hdc;
    PAINTSTRUCT32 ps;

    hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
    TOOLBAR_Refresh (wndPtr, hdc);
    if (!wParam)
	EndPaint32 (wndPtr->hwndSelf, &ps);
    return 0;
}


static LRESULT
TOOLBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
    RECT32 parent_rect;
    HWND32 parent;
    INT32  x, y, cx, cy;
    INT32  flags;
    UINT32 uPosFlags = 0;

    /* Resize deadlock check */
    if (infoPtr->bAutoSize) {
	infoPtr->bAutoSize = FALSE;
	return 0;
    }

    flags = (INT32) wParam;

    /* FIXME for flags =
     * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
     */

    TRACE (toolbar, "sizing toolbar!\n");

    if (flags == SIZE_RESTORED) {
	/* width and height don't apply */
	parent = GetParent32 (wndPtr->hwndSelf);
	GetClientRect32(parent, &parent_rect);

	if (wndPtr->dwStyle & CCS_NORESIZE) {
	    uPosFlags |= SWP_NOSIZE;

	    /* FIXME */
//	    infoPtr->nWidth = parent_rect.right - parent_rect.left;
	    cy = infoPtr->nHeight;
	    cx = infoPtr->nWidth;
	    TOOLBAR_CalcToolbar (wndPtr);
	    infoPtr->nWidth = cx;
	    infoPtr->nHeight = cy;
	}
	else {
	    infoPtr->nWidth = parent_rect.right - parent_rect.left;
	    TOOLBAR_CalcToolbar (wndPtr);
	    cy = infoPtr->nHeight;
	    cx = infoPtr->nWidth;
	}

	if (wndPtr->dwStyle & CCS_NOPARENTALIGN) {
	    uPosFlags |= SWP_NOMOVE;
	    cy = infoPtr->nHeight;
	    cx = infoPtr->nWidth;
	}

	if (!(wndPtr->dwStyle & CCS_NODIVIDER))
	    cy += sysMetrics[SM_CYEDGE];

	SetWindowPos32 (wndPtr->hwndSelf, 0, parent_rect.left, parent_rect.top,
			cx, cy, uPosFlags | SWP_NOZORDER);
    }
    return 0;
}


static LRESULT
TOOLBAR_StyleChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
    HDC32 hdc;

    TOOLBAR_AutoSize (wndPtr, wParam, lParam);

    hdc = GetDC32 (wndPtr->hwndSelf);
    TOOLBAR_Refresh (wndPtr, hdc);
    ReleaseDC32 (wndPtr->hwndSelf, hdc);

    return 0;
}



LRESULT WINAPI
ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
    WND *wndPtr = WIN_FindWndPtr(hwnd);

    switch (uMsg)
    {
	case TB_ADDBITMAP:
	    return TOOLBAR_AddBitmap (wndPtr, wParam, lParam);

	case TB_ADDBUTTONS32A:
	    return TOOLBAR_AddButtons32A (wndPtr, wParam, lParam);

//	case TB_ADDBUTTONS32W:

	case TB_ADDSTRING32A:
	    return TOOLBAR_AddString32A (wndPtr, wParam, lParam);

//	case TB_ADDSTRING32W:

	case TB_AUTOSIZE:
	    return TOOLBAR_AutoSize (wndPtr, wParam, lParam);

	case TB_BUTTONCOUNT:
	    return TOOLBAR_ButtonCount (wndPtr, wParam, lParam);

	case TB_BUTTONSTRUCTSIZE:
	    return TOOLBAR_ButtonStructSize (wndPtr, wParam, lParam);

	case TB_CHANGEBITMAP:
	    return TOOLBAR_ChangeBitmap (wndPtr, wParam, lParam);

	case TB_CHECKBUTTON:
	    return TOOLBAR_CheckButton (wndPtr, wParam, lParam);

	case TB_COMMANDTOINDEX:
	    return TOOLBAR_CommandToIndex (wndPtr, wParam, lParam);

	case TB_CUSTOMIZE:
	    return TOOLBAR_Customize (wndPtr);

	case TB_DELETEBUTTON:
	    return TOOLBAR_DeleteButton (wndPtr, wParam, lParam);

	case TB_ENABLEBUTTON:
	    return TOOLBAR_EnableButton (wndPtr, wParam, lParam);

//	case TB_GETANCHORHIGHLIGHT:		/* 4.71 */

	case TB_GETBITMAP:
	    return TOOLBAR_GetBitmap (wndPtr, wParam, lParam);

	case TB_GETBITMAPFLAGS:
	    return TOOLBAR_GetBitmapFlags (wndPtr, wParam, lParam);

	case TB_GETBUTTON:
	    return TOOLBAR_GetButton (wndPtr, wParam, lParam);

	case TB_GETBUTTONINFO32A:
	    return TOOLBAR_GetButtonInfo32A (wndPtr, wParam, lParam);

//	case TB_GETBUTTONINFO32W:		/* 4.71 */

	case TB_GETBUTTONSIZE:
	    return TOOLBAR_GetButtonSize (wndPtr);

	case TB_GETBUTTONTEXT32A:
	    return TOOLBAR_GetButtonText32A (wndPtr, wParam, lParam);

//	case TB_GETBUTTONTEXT32W:
//	case TB_GETCOLORSCHEME:			/* 4.71 */

	case TB_GETDISABLEDIMAGELIST:
	    return TOOLBAR_GetDisabledImageList (wndPtr, wParam, lParam);

	case TB_GETEXTENDEDSTYLE:
	    return TOOLBAR_GetExtendedStyle (wndPtr);

	case TB_GETHOTIMAGELIST:
	    return TOOLBAR_GetHotImageList (wndPtr, wParam, lParam);

//	case TB_GETHOTITEM:			/* 4.71 */

	case TB_GETIMAGELIST:
	    return TOOLBAR_GetImageList (wndPtr, wParam, lParam);

//	case TB_GETINSERTMARK:			/* 4.71 */
//	case TB_GETINSERTMARKCOLOR:		/* 4.71 */

	case TB_GETITEMRECT:
	    return TOOLBAR_GetItemRect (wndPtr, wParam, lParam);

	case TB_GETMAXSIZE:
	    return TOOLBAR_GetMaxSize (wndPtr, wParam, lParam);

//	case TB_GETOBJECT:			/* 4.71 */
//	case TB_GETPADDING:			/* 4.71 */

	case TB_GETRECT:
	    return TOOLBAR_GetRect (wndPtr, wParam, lParam);

	case TB_GETROWS:
	    return TOOLBAR_GetRows (wndPtr, wParam, lParam);

	case TB_GETSTATE:
	    return TOOLBAR_GetState (wndPtr, wParam, lParam);

	case TB_GETSTYLE:
	    return TOOLBAR_GetStyle (wndPtr, wParam, lParam);

	case TB_GETTEXTROWS:
	    return TOOLBAR_GetTextRows (wndPtr, wParam, lParam);

	case TB_GETTOOLTIPS:
	    return TOOLBAR_GetToolTips (wndPtr, wParam, lParam);

	case TB_GETUNICODEFORMAT:
	    return TOOLBAR_GetUnicodeFormat (wndPtr, wParam, lParam);

	case TB_HIDEBUTTON:
	    return TOOLBAR_HideButton (wndPtr, wParam, lParam);

	case TB_HITTEST:
	    return TOOLBAR_HitTest (wndPtr, wParam, lParam);

	case TB_INDETERMINATE:
	    return TOOLBAR_Indeterminate (wndPtr, wParam, lParam);

	case TB_INSERTBUTTON32A:
	    return TOOLBAR_InsertButton32A (wndPtr, wParam, lParam);

//	case TB_INSERTBUTTON32W:
//	case TB_INSERTMARKHITTEST:		/* 4.71 */

	case TB_ISBUTTONCHECKED:
	    return TOOLBAR_IsButtonChecked (wndPtr, wParam, lParam);

	case TB_ISBUTTONENABLED:
	    return TOOLBAR_IsButtonEnabled (wndPtr, wParam, lParam);

	case TB_ISBUTTONHIDDEN:
	    return TOOLBAR_IsButtonHidden (wndPtr, wParam, lParam);

	case TB_ISBUTTONHIGHLIGHTED:
	    return TOOLBAR_IsButtonHighlighted (wndPtr, wParam, lParam);

	case TB_ISBUTTONINDETERMINATE:
	    return TOOLBAR_IsButtonIndeterminate (wndPtr, wParam, lParam);

	case TB_ISBUTTONPRESSED:
	    return TOOLBAR_IsButtonPressed (wndPtr, wParam, lParam);

//	case TB_LOADIMAGES:			/* 4.70 */
//	case TB_MAPACCELERATOR32A:		/* 4.71 */
//	case TB_MAPACCELERATOR32W:		/* 4.71 */
//	case TB_MARKBUTTON:			/* 4.71 */
//	case TB_MOVEBUTTON:			/* 4.71 */

	case TB_PRESSBUTTON:
	    return TOOLBAR_PressButton (wndPtr, wParam, lParam);

//	case TB_REPLACEBITMAP:

	case TB_SAVERESTORE32A:
	    return TOOLBAR_SaveRestore32A (wndPtr, wParam, lParam);

//	case TB_SAVERESTORE32W:
//	case TB_SETANCHORHIGHLIGHT:		/* 4.71 */

	case TB_SETBITMAPSIZE:
	    return TOOLBAR_SetBitmapSize (wndPtr, wParam, lParam);

	case TB_SETBUTTONINFO32A:
	    return TOOLBAR_SetButtonInfo32A (wndPtr, wParam, lParam);

//	case TB_SETBUTTONINFO32W:		/* 4.71 */

	case TB_SETBUTTONSIZE:
	    return TOOLBAR_SetButtonSize (wndPtr, wParam, lParam);

	case TB_SETBUTTONWIDTH:
	    return TOOLBAR_SetButtonWidth (wndPtr, wParam, lParam);

	case TB_SETCMDID:
	    return TOOLBAR_SetCmdId (wndPtr, wParam, lParam);

//	case TB_SETCOLORSCHEME:			/* 4.71 */

	case TB_SETDISABLEDIMAGELIST:
	    return TOOLBAR_SetDisabledImageList (wndPtr, wParam, lParam);

	case TB_SETDRAWTEXTFLAGS:
	    return TOOLBAR_SetDrawTextFlags (wndPtr, wParam, lParam);

	case TB_SETEXTENDEDSTYLE:
	    return TOOLBAR_SetExtendedStyle (wndPtr, wParam, lParam);

	case TB_SETHOTIMAGELIST:
	    return TOOLBAR_SetHotImageList (wndPtr, wParam, lParam);

//	case TB_SETHOTITEM:			/* 4.71 */

	case TB_SETIMAGELIST:
	    return TOOLBAR_SetImageList (wndPtr, wParam, lParam);

	case TB_SETINDENT:
	    return TOOLBAR_SetIndent (wndPtr, wParam, lParam);

//	case TB_SETINSERTMARK:			/* 4.71 */

	case TB_SETINSERTMARKCOLOR:
	    return TOOLBAR_SetInsertMarkColor (wndPtr, wParam, lParam);

	case TB_SETMAXTEXTROWS:
	    return TOOLBAR_SetMaxTextRows (wndPtr, wParam, lParam);

//	case TB_SETPADDING:			/* 4.71 */

	case TB_SETPARENT:
	    return TOOLBAR_SetParent (wndPtr, wParam, lParam);

	case TB_SETROWS:
	    return TOOLBAR_SetRows (wndPtr, wParam, lParam);

	case TB_SETSTATE:
	    return TOOLBAR_SetState (wndPtr, wParam, lParam);

	case TB_SETSTYLE:
	    return TOOLBAR_SetStyle (wndPtr, wParam, lParam);

	case TB_SETTOOLTIPS:
	    return TOOLBAR_SetToolTips (wndPtr, wParam, lParam);

	case TB_SETUNICODEFORMAT:
	    return TOOLBAR_SetUnicodeFormat (wndPtr, wParam, lParam);


//	case WM_CHAR:

	case WM_CREATE:
	    return TOOLBAR_Create (wndPtr, wParam, lParam);

	case WM_DESTROY:
	    return TOOLBAR_Destroy (wndPtr, wParam, lParam);

	case WM_ERASEBKGND:
	    return TOOLBAR_EraseBackground (wndPtr, wParam, lParam);

//	case WM_GETFONT:
//	case WM_KEYDOWN:
//	case WM_KILLFOCUS:

	case WM_LBUTTONDBLCLK:
	    return TOOLBAR_LButtonDblClk (wndPtr, wParam, lParam);

	case WM_LBUTTONDOWN:
	    return TOOLBAR_LButtonDown (wndPtr, wParam, lParam);

	case WM_LBUTTONUP:
	    return TOOLBAR_LButtonUp (wndPtr, wParam, lParam);

	case WM_MOUSEMOVE:
	    return TOOLBAR_MouseMove (wndPtr, wParam, lParam);

	case WM_NCACTIVATE:
	    return TOOLBAR_NCActivate (wndPtr, wParam, lParam);

	case WM_NCCALCSIZE:
	    return TOOLBAR_NCCalcSize (wndPtr, wParam, lParam);

	case WM_NCCREATE:
	    return TOOLBAR_NCCreate (wndPtr, wParam, lParam);

	case WM_NCPAINT:
	    return TOOLBAR_NCPaint (wndPtr, wParam, lParam);

	case WM_NOTIFY:
	    return TOOLBAR_Notify (wndPtr, wParam, lParam);

//	case WM_NOTIFYFORMAT:

	case WM_PAINT:
	    return TOOLBAR_Paint (wndPtr, wParam);

	case WM_SIZE:
	    return TOOLBAR_Size (wndPtr, wParam, lParam);

	case WM_STYLECHANGED:
	    return TOOLBAR_StyleChanged (wndPtr, wParam, lParam);

//	case WM_SYSCOLORCHANGE:

//	case WM_WININICHANGE:

	case WM_CHARTOITEM:
	case WM_COMMAND:
	case WM_DRAWITEM:
	case WM_MEASUREITEM:
	case WM_VKEYTOITEM:
	    return SendMessage32A (GetParent32 (hwnd), uMsg, wParam, lParam);

	default:
	    if (uMsg >= WM_USER)
		ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
		     uMsg, wParam, lParam);
	    return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
    }
    return 0;
}


void TOOLBAR_Register (void)
{
    WNDCLASS32A wndClass;

    if (GlobalFindAtom32A (TOOLBARCLASSNAME32A)) return;

    ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc   = (WNDPROC32)ToolbarWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
    wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
    wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
    wndClass.lpszClassName = TOOLBARCLASSNAME32A;
 
    RegisterClass32A (&wndClass);
}
