- Add support for multiple image lists.
- Add TBN_INITCUSTOMIZE notification.
- Correctly populate TBN_QUERYDELETE.
- Support TBN_GETBUTTONINFOW.

diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index 1b7262a..c0050a1 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -96,6 +96,12 @@
 
 typedef struct
 {
+    HIMAGELIST himl;
+    INT id;
+} IMLENTRY, *PIMLENTRY;
+
+typedef struct
+{
     DWORD      dwStructSize;   /* size of TBBUTTON struct */
     INT      nHeight;        /* height of the toolbar */
     INT      nWidth;         /* width of the toolbar */
@@ -124,9 +130,12 @@
     HFONT    hDefaultFont;
     HFONT    hFont;           /* text font */
     HIMAGELIST himlInt;         /* image list created internally */
-    HIMAGELIST himlDef;         /* default image list */
-    HIMAGELIST himlHot;         /* hot image list */
-    HIMAGELIST himlDis;         /* disabled image list */
+    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 */
@@ -163,7 +172,7 @@
     TBBUTTON btn;
     BOOL     bVirtual;
     BOOL     bRemovable;
-    CHAR     text[64];
+    WCHAR    text[64];
 } CUSTOMBUTTON, *PCUSTOMBUTTON;
 
 
@@ -182,6 +191,19 @@
                         TBSTYLE_EX_MIXEDBUTTONS | \
                         TBSTYLE_EX_HIDECLIPPEDBUTTONS)
 
+#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 BOOL TOOLBAR_GetButtonInfo(TOOLBAR_INFO *infoPtr, NMTOOLBARW *nmtb);
+static BOOL TOOLBAR_IsButtonRemovable(TOOLBAR_INFO *infoPtr, int iItem, PCUSTOMBUTTON btnInfo);
+static HIMAGELIST TOOLBAR_GetImageList(PIMLENTRY *pies, INT cies, INT id);
+static PIMLENTRY TOOLBAR_GetImageListEntry(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_NotifyFormat(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam);
 
@@ -205,8 +227,8 @@
 {
     if (TRACE_ON(toolbar)){
 	TRACE("button %d id %d, bitmap=%d, state=%02x, style=%02x, data=%08lx, stringid=0x%08x\n",
-	      btn_num, bP->idCommand,
-	      bP->iBitmap, bP->fsState, bP->fsStyle, bP->dwData, bP->iString);
+              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)));
 	if (internal)
 	    TRACE("button %d id %d, hot=%s, row=%d, rect=(%d,%d)-(%d,%d)\n",
@@ -308,6 +330,10 @@
 	TRACE("TBN_GETDISPINFOA returned bitmap id %d, mask=%08lx, nNumBitmaps=%d\n",
 	      ret, nmgd.dwMask, infoPtr->nNumBitmaps);
     }
+
+    if (ret != I_IMAGENONE)
+        ret = GETIBITMAP(infoPtr, ret);
+
     return ret;
 }
 
@@ -315,8 +341,13 @@
 static BOOL
 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
 {
-    if (((index>=0) && (index <= infoPtr->nNumBitmaps)) ||
-	(index == I_IMAGECALLBACK))
+    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;
@@ -545,7 +576,7 @@
     /* FIXME: this function is a hack since it uses image list
 	      internals directly */
 
-    HIMAGELIST himl = infoPtr->himlDef;
+    HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, 0);
     HBITMAP hbmMask;
     HDC hdcImageList;
     HDC hdcMask;
@@ -612,6 +643,7 @@
     NMTBCUSTOMDRAW tbcd;
     DWORD ntfret;
     INT offset;
+    HIMAGELIST himlDef;
 
     if (btnPtr->fsState & TBSTATE_HIDDEN)
 	return;
@@ -656,7 +688,7 @@
 
 	InflateRect (&rcText, -3, -3);
 
-	if (infoPtr->himlDef &&
+	if (GETDEFIMAGELIST(infoPtr, 0) &&
             TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
 	        /* The following test looked like this before
 		 * I changed it. IE4 "Links" toolbar would not
@@ -755,8 +787,12 @@
 	goto FINALNOTIFY;
     }
 
+    /* Determine index of image list */
+    himlDef = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
+
     /* disabled */
     if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
+	HIMAGELIST himlDis = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap));
 	if (!(dwStyle & TBSTYLE_FLAT) && !(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES))
 	{
 	    DrawEdge (hdc, &rc, EDGE_RAISED,
@@ -772,7 +808,7 @@
 	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_3DSHADOW);
 	}
 
-	if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDis,
+	if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDis,
 				   hdc, rcBitmap.left, rcBitmap.top,
 				   ILD_NORMAL))
 	    TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
@@ -803,7 +839,7 @@
         if (hasDropDownArrow)
 	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
 
-	TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
+	TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
 			       hdc, rcBitmap.left+offset, rcBitmap.top+offset,
 			       ILD_NORMAL);
 
@@ -826,7 +862,7 @@
 
 	TOOLBAR_DrawPattern (hdc, &rc);
 
-	TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
+	TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
 			       hdc, rcBitmap.left+1, rcBitmap.top+1,
 			       ILD_NORMAL);
 
@@ -887,17 +923,19 @@
 	    TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top, COLOR_WINDOWFRAME);
 
 	if (btnPtr->bHot) {
+            HIMAGELIST himlHot = GETHOTIMAGELIST(infoPtr, 
+                GETHIMLID(infoPtr, btnPtr->iBitmap));
 	    /* if hot, attempt to draw with himlHot, if fails, use himlDef */
 	    if (!TOOLBAR_DrawImageList (infoPtr, btnPtr,
-					infoPtr->himlHot,
+					himlHot,
 					hdc, rcBitmap.left,
 					rcBitmap.top, ILD_NORMAL))
-		TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
+		TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
 				       hdc, rcBitmap.left, rcBitmap.top,
 				       ILD_NORMAL);
 	}
 	else
-	    TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
+	    TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
 				   hdc, rcBitmap.left, rcBitmap.top,
 				   ILD_NORMAL);
     }
@@ -915,7 +953,7 @@
 	    TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
 	}
 
-	TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
+	TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef,
 			       hdc, rcBitmap.left, rcBitmap.top,
 			       ILD_NORMAL);}
 
@@ -952,8 +990,12 @@
 
     /* if imagelist belongs to the app, it can be changed
        by the app after setting it */
-    if (infoPtr->himlDef != infoPtr->himlInt)
-        infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
+    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__);
 
@@ -1407,7 +1449,7 @@
 	      /* toolbars with native control (v4.71).  -  GA 8/01    */
               cx = sz.cx + 6 + 5 + 5;
 	      if ((dwStyle & TBSTYLE_LIST) &&
-		  (TOOLBAR_TestImageExist (infoPtr, btnPtr, infoPtr->himlDef)))
+		  (TOOLBAR_TestImageExist (infoPtr, btnPtr, GETDEFIMAGELIST(infoPtr,0))))
 		  cx += infoPtr->nBitmapWidth;
             }
             else
@@ -1645,7 +1687,7 @@
 
 	    if (custInfo)
 	    {
-		char Buffer[256];
+		WCHAR Buffer[256];
 		int i = 0;
 		int index;
 
@@ -1657,20 +1699,24 @@
 		if (!TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_QUERYINSERT))
 		    return FALSE;
 
+		/* Send TBN_INITCUSTOMIZE notification */
+		if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_INITCUSTOMIZE) ==
+                    TBNRF_HIDEHELP)
+                {
+                    FIXME("TBNRF_HIDEHELP not supported\n");
+                }
+
 		/* add items to 'toolbar buttons' list and check if removable */
 		for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
-		{
+                {
 		    btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
-		    memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
-		    btnInfo->btn.fsStyle = TBSTYLE_SEP;
-		    btnInfo->bVirtual = FALSE;
-		    LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
+                    memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
+                    btnInfo->btn.fsStyle = TBSTYLE_SEP;
+                    btnInfo->bVirtual = FALSE;
+		    LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
 
 		    /* send TBN_QUERYDELETE notification */
-		    nmtb.iItem = i;
-		    btnInfo->bRemovable = TOOLBAR_SendNotify ((NMHDR *) &nmtb,
-						      infoPtr,
-						      TBN_QUERYDELETE);
+                    btnInfo->bRemovable = TOOLBAR_IsButtonRemovable(infoPtr, i, btnInfo);
 
 		    index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
 		    SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
@@ -1682,7 +1728,7 @@
 		btnInfo->btn.fsStyle = TBSTYLE_SEP;
 		btnInfo->bVirtual = FALSE;
 		btnInfo->bRemovable = TRUE;
-		LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
+		LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
 		index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
 		SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
 
@@ -1690,37 +1736,53 @@
 		for (i = 0;; i++)
 		{
 		    /* send TBN_GETBUTTONINFO notification */
+                    NMTOOLBARW nmtb;
 		    nmtb.iItem = i;
 		    nmtb.pszText = Buffer;
 		    nmtb.cchText = 256;
 
-		    if (!TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_GETBUTTONINFOA))
+                    /* Clear previous button's text */
+                    ZeroMemory(nmtb.pszText, nmtb.cchText * sizeof(WCHAR));
+
+                    if (!TOOLBAR_GetButtonInfo(infoPtr, &nmtb))
 			break;
 
-		    TRACE("style: %x\n", nmtb.tbButton.fsStyle);
+		    TRACE("WM_INITDIALOG style: %x iItem(%d) idCommand(%d) iString(%d) %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 apropriate list */
 		    index = TOOLBAR_GetButtonIndex (custInfo->tbInfo, nmtb.tbButton.idCommand, FALSE);
 		    if (index == -1)
 		    {
 			btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
-			memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
 			btnInfo->bVirtual = FALSE;
 			btnInfo->bRemovable = TRUE;
-			if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
-			    strcpy (btnInfo->text, nmtb.pszText);
 
 			index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
-			SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
+			SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, 
+				LB_SETITEMDATA, index, (LPARAM)btnInfo);
 		    }
 		    else
 		    {
-			btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
-			memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
-			if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
-			    strcpy (btnInfo->text, nmtb.pszText);
+                        btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, 
+                            IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
+                    }
 
-			SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
+                    memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
+                    if (!(nmtb.tbButton.fsStyle & TBSTYLE_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]);
+                        }
 		    }
 		}
 
@@ -1733,7 +1795,7 @@
 		btnInfo->btn.fsStyle = TBSTYLE_SEP;
 		btnInfo->bVirtual = TRUE;
 		btnInfo->bRemovable = FALSE;
-		LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
+		LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
 		index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
 		SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
 
@@ -1881,12 +1943,17 @@
 			int index;
 
 			index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
+
+			if (LB_ERR == index)
+				break;
+
 			TRACE("Remove: index %d\n", index);
 
+			btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, 
+				LB_GETITEMDATA, index, 0);
+
 			/* send TBN_QUERYDELETE notification */
-			nmtb.iItem = index;
-		        if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
-					    TBN_QUERYDELETE))
+			if (TOOLBAR_IsButtonRemovable(infoPtr, index, btnInfo))
 			{
 			    btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
 			    SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
@@ -1989,6 +2056,7 @@
 	    if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
 	    {
 		LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
+    	DWORD dwStyle = GetWindowLongA (infoPtr->hwndSelf, GWL_STYLE);
 		RECT rcButton;
 		RECT rcText;
 		HPEN hPen, hOldPen;
@@ -2031,13 +2099,17 @@
 		    DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
 
 		/* draw button */
+		if (!(dwStyle & TBSTYLE_FLAT))
 		DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
 
 		/* draw image and text */
-		if ((btnInfo->btn.fsStyle & TBSTYLE_SEP) == 0)
-		    ImageList_Draw (custInfo->tbInfo->himlDef, btnInfo->btn.iBitmap, lpdis->hDC,
-				    rcButton.left+3, rcButton.top+3, ILD_NORMAL);
-		DrawTextA (lpdis->hDC,  btnInfo->text, -1, &rcText,
+		if ((btnInfo->btn.fsStyle & TBSTYLE_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 */
@@ -2081,6 +2153,7 @@
     LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
     INT nIndex = 0, nButtons, nCount;
     HBITMAP hbmLoad;
+    HIMAGELIST himlDef;
 
     TRACE("hwnd=%p wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
     if (!lpAddBmp)
@@ -2131,23 +2204,31 @@
 	TRACE ("adding %d bitmaps!\n", nButtons);
     }
 
-    if (!(infoPtr->himlDef)) {
+    if (!infoPtr->cimlDef) {
 	/* create new default image list */
 	TRACE ("creating default image list!\n");
 
-	infoPtr->himlDef =
-	    ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
-			      ILC_COLOR | ILC_MASK, nButtons, 2);
-	infoPtr->himlInt = infoPtr->himlDef;
+    himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, 
+		ILC_COLOR | ILC_MASK, nButtons, 2);
+	TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0);
+    infoPtr->himlInt = himlDef;
+    }
+    else {
+        himlDef = GETDEFIMAGELIST(infoPtr, 0);
     }
 
-    nCount = ImageList_GetImageCount(infoPtr->himlDef);
+    if (!himlDef) {
+        WARN("No default image list available\n");
+        return -1;
+    }
+
+    nCount = ImageList_GetImageCount(himlDef);
 
     /* Add bitmaps to the default image list */
     if (lpAddBmp->hInst == (HINSTANCE)0)
     {
 	nIndex =
-	    ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
+	    ImageList_AddMasked (himlDef, (HBITMAP)lpAddBmp->nID,
 				 CLR_DEFAULT);
     }
     else if (lpAddBmp->hInst == HINST_COMMCTRL)
@@ -2158,7 +2239,7 @@
 	    case IDB_STD_SMALL_COLOR:
 		hbmLoad = LoadBitmapA (COMCTL32_hModule,
 				       MAKEINTRESOURCEA(IDB_STD_SMALL));
-		nIndex = ImageList_AddMasked (infoPtr->himlDef,
+		nIndex = ImageList_AddMasked (himlDef,
 					      hbmLoad, CLR_DEFAULT);
 		DeleteObject (hbmLoad);
 		break;
@@ -2166,7 +2247,7 @@
 	    case IDB_STD_LARGE_COLOR:
 		hbmLoad = LoadBitmapA (COMCTL32_hModule,
 				       MAKEINTRESOURCEA(IDB_STD_LARGE));
-		nIndex = ImageList_AddMasked (infoPtr->himlDef,
+		nIndex = ImageList_AddMasked (himlDef,
 					      hbmLoad, CLR_DEFAULT);
 		DeleteObject (hbmLoad);
 		break;
@@ -2174,7 +2255,7 @@
 	    case IDB_VIEW_SMALL_COLOR:
 		hbmLoad = LoadBitmapA (COMCTL32_hModule,
 				       MAKEINTRESOURCEA(IDB_VIEW_SMALL));
-		nIndex = ImageList_AddMasked (infoPtr->himlDef,
+		nIndex = ImageList_AddMasked (himlDef,
 					      hbmLoad, CLR_DEFAULT);
 		DeleteObject (hbmLoad);
 		break;
@@ -2182,7 +2263,7 @@
 	    case IDB_VIEW_LARGE_COLOR:
 		hbmLoad = LoadBitmapA (COMCTL32_hModule,
 				       MAKEINTRESOURCEA(IDB_VIEW_LARGE));
-		nIndex = ImageList_AddMasked (infoPtr->himlDef,
+		nIndex = ImageList_AddMasked (himlDef,
 					      hbmLoad, CLR_DEFAULT);
 		DeleteObject (hbmLoad);
 		break;
@@ -2190,7 +2271,7 @@
 	    case IDB_HIST_SMALL_COLOR:
 		hbmLoad = LoadBitmapA (COMCTL32_hModule,
 				       MAKEINTRESOURCEA(IDB_HIST_SMALL));
-		nIndex = ImageList_AddMasked (infoPtr->himlDef,
+		nIndex = ImageList_AddMasked (himlDef,
 					      hbmLoad, CLR_DEFAULT);
 		DeleteObject (hbmLoad);
 		break;
@@ -2198,13 +2279,13 @@
 	    case IDB_HIST_LARGE_COLOR:
 		hbmLoad = LoadBitmapA (COMCTL32_hModule,
 				       MAKEINTRESOURCEA(IDB_HIST_LARGE));
-		nIndex = ImageList_AddMasked (infoPtr->himlDef,
+		nIndex = ImageList_AddMasked (himlDef,
 					      hbmLoad, CLR_DEFAULT);
 		DeleteObject (hbmLoad);
 		break;
 
 	    default:
-	nIndex = ImageList_GetImageCount (infoPtr->himlDef);
+	nIndex = ImageList_GetImageCount (himlDef);
 		ERR ("invalid imagelist!\n");
 		break;
 	}
@@ -2212,7 +2293,7 @@
     else
     {
 	hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
-	nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
+	nIndex = ImageList_AddMasked (himlDef, hbmLoad, CLR_DEFAULT);
 	DeleteObject (hbmLoad);
     }
 
@@ -2238,7 +2319,7 @@
 
     if (nIndex != -1)
     {
-       INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
+       INT imagecount = ImageList_GetImageCount(himlDef);
 
        if (infoPtr->nNumBitmaps + nButtons != imagecount)
        {
@@ -3074,9 +3155,7 @@
 static LRESULT
 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
-
-    return (LRESULT)infoPtr->himlDis;
+    return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
 }
 
 
@@ -3092,9 +3171,7 @@
 static LRESULT
 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
-
-    return (LRESULT)infoPtr->himlHot;
+    return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
 }
 
 
@@ -3114,11 +3191,9 @@
 
 
 static LRESULT
-TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
+TOOLBAR_GetDefImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
-
-    return (LRESULT)infoPtr->himlDef;
+    return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), 0);
 }
 
 
@@ -3679,6 +3754,7 @@
     LPTBREPLACEBITMAP lpReplace = (LPTBREPLACEBITMAP) lParam;
     HBITMAP hBitmap;
     int i = 0, nOldButtons = 0, pos = 0;
+    HIMAGELIST himlDef = 0;
 
     TRACE("hInstOld %p nIDOld %x hInstNew %p nIDNew %x nButtons %x\n",
           lpReplace->hInstOld, lpReplace->nIDOld, lpReplace->hInstNew, lpReplace->nIDNew,
@@ -3724,14 +3800,15 @@
 
     infoPtr->nNumBitmaps = infoPtr->nNumBitmaps - nOldButtons + lpReplace->nButtons;
 
-    /* ImageList_Replace(infoPtr->himlDef, pos, hBitmap, NULL); */
+    /* ImageList_Replace(GETDEFIMAGELIST(), pos, hBitmap, NULL); */
 
 
+	himlDef = GETDEFIMAGELIST(infoPtr, 0);
     for (i = pos + nOldButtons - 1; i >= pos; i--) {
-        ImageList_Remove(infoPtr->himlDef, i);
+        ImageList_Remove(himlDef, i);
     }
 
-    ImageList_AddMasked(infoPtr->himlDef, hBitmap, CLR_DEFAULT);
+    ImageList_AddMasked(himlDef, hBitmap, CLR_DEFAULT);
 
     InvalidateRect(hwnd, NULL, FALSE);
 
@@ -3815,6 +3892,7 @@
 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+    HIMAGELIST himlDef = GETDEFIMAGELIST(infoPtr, 0);
 
     if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
 	return FALSE;
@@ -3829,9 +3907,9 @@
     infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
 
     /* uses image list internals directly */
-    if (infoPtr->himlDef) {
-        infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
-        infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
+    if (himlDef) {
+        himlDef->cx = infoPtr->nBitmapWidth;
+        himlDef->cy = infoPtr->nBitmapHeight;
     }
 
     return TRUE;
@@ -4019,16 +4097,15 @@
 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
+    HIMAGELIST himl = (HIMAGELIST)lParam;
     HIMAGELIST himlTemp;
+    INT id = 0;
 
+    if (infoPtr->iVersion >= 5)
+        id = wParam;
 
-    if (wParam != 0) {
-	FIXME("no support for multiple image lists\n");
-	return 0;
-    }
-
-    himlTemp = infoPtr->himlDis;
-    infoPtr->himlDis = (HIMAGELIST)lParam;
+    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlDis, 
+        &infoPtr->cimlDis, himl, id);
 
     /* FIXME: redraw ? */
 
@@ -4080,14 +4157,14 @@
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
     HIMAGELIST himlTemp;
+    HIMAGELIST himl = (HIMAGELIST)lParam;
+    INT id = 0;
 
-    if (wParam != 0) {
-	FIXME("no support for multiple image lists\n");
-	return 0;
-    }
+    if (infoPtr->iVersion >= 5)
+        id = wParam;
 
-    himlTemp = infoPtr->himlHot;
-    infoPtr->himlHot = (HIMAGELIST)lParam;
+    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlHot, 
+        &infoPtr->cimlHot, himl, id);
 
     /* FIXME: redraw ? */
 
@@ -4137,18 +4214,20 @@
 {
     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
     HIMAGELIST himlTemp;
+    HIMAGELIST himl = (HIMAGELIST)lParam;
+    INT i, id = 0;
 
-    if (wParam != 0) {
-	FIXME("no support for multiple image lists\n");
-	return 0;
-    }
+    if (infoPtr->iVersion >= 5)
+        id = wParam;
 
-    himlTemp = infoPtr->himlDef;
-    infoPtr->himlDef = (HIMAGELIST)lParam;
+    himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlDef, 
+        &infoPtr->cimlDef, himl, id);
 
-    infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
+    infoPtr->nNumBitmaps = 0;
+    for (i = 0; i < infoPtr->cimlDef; i++)
+        infoPtr->nNumBitmaps += ImageList_GetImageCount(infoPtr->himlDef[i]->himl);
 
-    ImageList_GetIconSize(infoPtr->himlDef, &infoPtr->nBitmapWidth,
+    ImageList_GetIconSize(himl, &infoPtr->nBitmapWidth,
 			  &infoPtr->nBitmapHeight);
     TRACE("hwnd %p, new himl=%08x, count=%d, bitmap w=%d, h=%d\n",
 	  hwnd, (INT)infoPtr->himlDef, infoPtr->nNumBitmaps,
@@ -4407,6 +4486,9 @@
 
     infoPtr->iVersion = iVersion;
 
+    if (infoPtr->iVersion >= 5)
+        TOOLBAR_SetUnicodeFormat(hwnd, (WPARAM)TRUE, (LPARAM)0);
+
     return iOldVersion;
 }
 
@@ -4617,6 +4699,10 @@
     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 */
     if (infoPtr->hFont)
 	DeleteObject (infoPtr->hDefaultFont);
@@ -5567,7 +5653,7 @@
 	    return TOOLBAR_GetHotItem (hwnd);
 
 	case TB_GETIMAGELIST:
-	    return TOOLBAR_GetImageList (hwnd, wParam, lParam);
+	    return TOOLBAR_GetDefImageList (hwnd, wParam, lParam);
 
 /*	case TB_GETINSERTMARK:			*/ /* 4.71 */
 /*	case TB_GETINSERTMARKCOLOR:		*/ /* 4.71 */
@@ -5875,3 +5961,125 @@
 {
     UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)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 = (PIMLENTRY) COMCTL32_Alloc(sizeof(IMLENTRY));
+	c->id = id;
+
+	pnies = COMCTL32_Alloc((*cies + 1) * sizeof(PIMLENTRY));
+	memcpy(pnies, *pies, ((*cies) * sizeof(PIMLENTRY)));
+	pnies[*cies] = c;
+	(*cies)++;
+
+	COMCTL32_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++)
+	COMCTL32_Free((*pies)[i]);
+
+    COMCTL32_Free(*pies);
+
+    *cies = 0;
+    *pies = NULL;
+}
+
+
+static PIMLENTRY TOOLBAR_GetImageListEntry(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(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(TOOLBAR_INFO *infoPtr, NMTOOLBARW *nmtb)
+{
+    if (infoPtr->bUnicode)
+        return TOOLBAR_SendNotify ((NMHDR *) nmtb, 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 ((NMHDR *) &nmtba, infoPtr, TBN_GETBUTTONINFOA))
+        {
+            int ccht = strlen(nmtba.pszText);
+            if (ccht)
+               MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmtba.pszText, -1, 
+                  nmtb->pszText, nmtb->cchText);
+
+            memcpy(&nmtb->tbButton, &nmtba.tbButton, sizeof(TBBUTTON));
+            bRet = TRUE;
+        }
+
+        return bRet;
+    }
+}
+
+
+static BOOL TOOLBAR_IsButtonRemovable(TOOLBAR_INFO *infoPtr,
+	int iItem, PCUSTOMBUTTON btnInfo)
+{
+    NMTOOLBARA nmtb;
+
+    nmtb.iItem = iItem;
+    memcpy(&nmtb.tbButton, &btnInfo->btn, sizeof(TBBUTTON));
+
+    return TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_QUERYDELETE);
+}
diff --git a/include/commctrl.h b/include/commctrl.h
index 640cddc..953a40a 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -1142,6 +1142,8 @@
 #define TBN_GETINFOTIPA       (TBN_FIRST-18)
 #define TBN_GETINFOTIPW       (TBN_FIRST-19)
 #define TBN_GETINFOTIP WINELIB_NAME_AW(TBN_GETINFOTIP)
+#define TBN_INITCUSTOMIZE	(TBN_FIRST-23)
+#define TBNRF_HIDEHELP		0x00000001
 
 
 /* Return values from TBN_DROPDOWN */