Release 980601

Sun May 31 13:40:13 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [if1632/signal.c]
	Added display of exception name.

	* [loader/task.c]
	Yet another attempt at fixing SwitchStackTo/SwitchStackBack.

	* [memory/selector.c] [relay32/builtin32.c] [tools/build.c]
	  [win32/kernel32.c]
	Generate an assembly stub for Win32 register functions to make
	their names available at link time.

	* [programs/*/Makefile.in]
	Added hacks to support old resource compiler.

Fri May 29 16:27:14 1998  Marcus Meissner <marcus@jet.franken.de>

	* [tools/testrun]
	Merge of my testscripts at home into one single perl program
	(tested with perl5). Works only on Linux due to 'ps' and 'ipcs'
	magic.

	* [controls/menu.c]
	Added some DefaultMenuItem stubs.

	* [debugger/stabs.c]
	Fixed stabs loading, now supports (int,int) typeinfo format used
	by gcc-2.8 and egcs-1. If it still crashes, please mail me.

	* [if1632/][relay32/]
	Added msvideo.dll (stubs only)
	Replaced some ptr by str for stringcases
	Added some new stubs (VxDCall, FindCloseNotif....)

	* [misc/network.c]
	Some argument fixes.

	* [misc/registry.c][misc/cpu.c]
	Registry initialization partially rewritten and enhanced.

	* [scheduler/*.c]
	Some additions so we don't do kill(0,SIGUSR1) (kill processgroup
	instead of targeted thread)
	Added SetThreadContext.

Thu May 28 23:59:59 1998  Bertho Stultiens <bertho@akhphd.au.dk>

	* [tools/wrc/*]
	New resource compiler version 1.0.0 (28-May-1998)

	* [Make.rules.in] [Makefile.in]
	Changed and added rc rules to point to tools/wrc/wrc.

	* [configure.in] [include/config.h.in]
	Added check for function 'stricmp'.

	* [include/resource.h]
	Commented out the old resource structure to catch references.
	It also includes wrc_rsc.h.

	* [include/wrc_rsc.h]
	New file. Definitions for the resources generated with wrc.

	* [include/windows.h]
	Added #ifdef RC_INVOKED to exclude stdarg.h.
	Added SS_NOTIFY flag.

	* [include/winnls.h]
	Added SUBLANG_* definitions and corrected some defaults.

	* [loader/libres.c]
	Changed the sysres load functions to support wrc generated
	resources.

	* [resource/sysres_*.rc]
	Added #include <windows.h>

	* [resource/sysres.c]
	Changed declarations to match wrc's output

	* [resource/Makefile.in]
	Changed rules to work with wrc.

	* [tools/makedep.c]
	Changed generation of .rc file dependencies to .s target.

Thu May 28 22:28:39 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [files/file.c][include/windows.c][relay32/kernel32.spec]
	Implemented GetFileAttributesEx32A/W.

	* [misc/imagelist.h][include/commctrl.h][relay32/comctl32.spec]
	Added ImageList_Read and ImageList_Write stubs.
	Added ImageList_AddIcon function.
	Added ImageList_LoadImage. It is the same as ImageList_LoadImage32A.

	* [controls/header.c]
	Fixed bitmap drawing bug.
	Added full bitmap support.

	* [include/commctrl.h]
	Added missing header macros.

	* [controls/toolbar.c][include/toolbar.h][include/commctrl.h]
	  [controls/commctrl.c] [relay32/comctl32.spec]
	First implementation of toolbar control.
	Implemented CreateToolbar, CreateToolbarEx and CreateMappedBitmap.

	* [controls/progress.c][controls/status.c]
	Some code cleanup.

	* [controls/commctrl.c][include/commctrl.h][relay32/comctl32.spec]
	Removed CreateStatusWindow16 and DrawStatusText16.
	CreateStatusWindow is the same as CreateStatusWindow32A.
	DrawStatusText is the same as DrawStatusText32A.

Thu May 28 16:01:28 1998  Matthew J. Francis  <asbel@dial.pipex.com>

	* [objects/bitmap.c] [objects/bitmap.h] [objects/oembitmap.c]
	  [objects/dc.c] [graphics/x11drv/bitblt.c]
	Added partial implementation of CreateDIBSection, with great thanks
	to Ulrich Weigand <weigand@informatik.uni-erlangen.de> for
	contributing the bulk of the patch.

Wed May 27 19:04:31 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [win32/kernel32.c] [if1632/thunk.c] [include/flatthunk.h]
	ThunkConnect16 and related functions moved to emulator.

	* [loader/ne/segment.c]
	Call DllEntryPoint with correct arguments.

	* [relay32/builtin32.c]
	Bugfix: Relay debugging did not work for multiple processes.

	* [controls/menu.c]
	Bugfix: dwItemData was not set for MF_OWNERDRAW menus.

	* [if1632/relay.c] [relay32/relay386.c]
	Relay messages converted to use DPRINTF.

	* [controls/desktop.c] [relay32/user32.spec]
	Implemented PaintDesktop.

	* [files/profile.c] [if1632/kernel.spec] [misc/network.c]
	  [misc/printdrv.c] [relay32/winspool.spec] 
	  [win32/ordinals.c] [relay32/kernel32.spec]
	Some stubs added.

	* [relay32/mpr.spec]
	All ordinals were off by one.

Tue May 26 13:32:57 1998  Bill Hawes <whawes@star.net>

	* [misc/lstr.c] [include/casemap.h] [tools/unimap.pl]
	Added Unicode case conversion routines towupper/towlower,
	with mapping tables casemap.h created by tools/unimap.pl.

	* [misc/ntdll.c] [include/winnls.h] [relay32/ntdll.spec]
	  [relay32/advapi.spec]
	Minimal implementation of IsTextUnicode, just enough to get
	NT4 notepad to open ascii/unicode files.

	* [Make.rules.in] [resources/sysres_En.rc]
	Added include file dlgs.h for building resource files, so that
	resources can refer to defined values (e.g. pshHelp).

	* [misc/crtdll.c] [relay32/crtdll.spec]
	Use towupper/towlower for 32W case conversions.

	* [memory/string.c]
	Use towupper for 32W case conversions.

	* [ole/ole2nls.c]
	Use towupper for 32W case conversions; fix mem leak; minor cleanup

	* [controls/edit.c]
	Added soft break flag to edit state. Print unknown action values
	for WM_VSCROLL (action 190 occurs when running NT4 notepad.)

Mon May 25 22:42:40 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [files/file.c]
	Care for a pathological case in SetFilePointer.

	* [graphics/x11drv/xfont.c]
	Handle longer Font names in LFD_ComposeLFD and try to catch errors.

	* [loader/pe_image.c]
	Unload Dummymodule when PE_LoadLibraryEx32A fails with
	PE_LoadImage (makes Encarta 98 installer proceed).

	* [misc/registry.c]
	Move a check for a special case in RegCreateKeyEx32W after the
	check for existence.

Tue May 25 20:18:26 1998  Matthew Becker <mbecker@glasscity.net>

	* [misc/ntdll.c]
	Added some stubs, just guessing at the size of their param lists.

	* [misc/registry.c]
	Added stubs for RegUnLoadKey, RegSetKeySecurity, RegSaveKey,
	RegRestoreKey, and RegReplaceKey

	* [programs/regtest/regtest.c]
	Updated registry testing program.

Sun May 24 18:11:40 1998  Alex Priem <alexp@sci.kun.nl>

	* [file/profile.c]
	Added flag 'return_values' to PROFILE_GetSection.

Sun May 24 13:41:10 1998  James Juran <jrj120@psu.edu>

	* [misc/shell.c] [files/directory.c]
	Documentation/debugging info additions.

	* [*/*.c] [include/*.h]
	Moved many extern function definitions to appropriate header files.
	Cleaned up a few compile warnings.
	If #include "debug.h" is present, removed #include <stdio.h>.
	debug.h includes stdio.h, so it is not necessary to include both.

	* [graphics/*.c] [if1632/signal.c] [ipc/*.c] [scheduler/*.c]
	  [win32/*.c] [windows/*.c]
	Final patch to convert fprintf statements to new debugging interface.
	Some fprintfs are still left, especially in the debugger/ directory.
	However, IMHO, it's not worth the effort to change the rest.

Fri May 22 21:58:35 1998  Morten Welinder  <terra@diku.dk>

	* [windows/keyboard.c]
	Correct handling of keys "`-=[]\;',./".

Fri May 22 12:06:00 1998  Per Lindström <pelinstr@algonet.se>

	* [include/windows.h] [relay32/kernel32.spec] [win32/console.c]
	Added stub for ReadConsoleOutputCharacter32A.

Thu May 21 16:45:48 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>

	* [ole/ole2nls.c]
	Began better implementation of LCMapString32A.
	Not very well tested yet, and still need improvements.

	* [controls/scroll.c]
	Documented functions.

Wed May 20 21:37:56 1998  Peter Hunnisett <hunnise@nortel.ca>

	* [include/windows.h][misc/main.c]
	Change SystemParameterInfo to support SPI_GETHIGHCONTRAST. Also
	include some missing SPI_ definitions.

	* [include/dsound.h][multimedia/dsound.c][relay32/dplayx.spec]
	Added stubs for DirectPlayLobbyCreate[AW]. Not sure if these
	should go into a new files dplayx.c? Anyone care?

	* [include/winnls.h]
	Added two missing flags for the CompareString32 functions.
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 736c00b..ff92f5c 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -19,6 +19,7 @@
 	scroll.c \
 	static.c \
 	status.c \
+	toolbar.c \
 	uitools.c \
 	updown.c \
 	widgets.c
diff --git a/controls/combo.c b/controls/combo.c
index db24ec3..1b8e1d7 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -6,7 +6,6 @@
  * FIXME: roll up in Netscape 3.01.
  */
 
-#include <stdio.h>
 #include <string.h>
 
 #include "windows.h"
diff --git a/controls/commctrl.c b/controls/commctrl.c
index 245eb86..93de092 100644
--- a/controls/commctrl.c
+++ b/controls/commctrl.c
@@ -11,12 +11,13 @@
 #include "header.h"
 #include "progress.h"
 #include "status.h"
+#include "toolbar.h"
 #include "updown.h"
 #include "debug.h"
 
 
 /***********************************************************************
- *           DrawStatusText32A   (COMCTL32.5)
+ * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
  */
 void WINAPI DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text,
                                UINT32 style )
@@ -55,22 +56,7 @@
 }
 
 /***********************************************************************
- *           DrawStatusText16   (COMCTL32.27)
- */
-void WINAPI DrawStatusText16( HDC16 hdc, LPRECT16 lprc, LPCSTR text,
-			      UINT16 style )
-{
-  if(!lprc)
-    DrawStatusText32A((HDC32)hdc, 0, text, (UINT32)style);
-  else{    
-    RECT32 rect32;
-    CONV_RECT16TO32( lprc, &rect32 );
-    DrawStatusText32A((HDC32)hdc, &rect32, text, (UINT32)style);
-  }
-}
-
-/***********************************************************************
- *           CreateStatusWindow32A   (COMCTL32.6)
+ * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
  */
 HWND32 WINAPI CreateStatusWindow32A( INT32 style, LPCSTR text, HWND32 parent,
                                      UINT32 wid )
@@ -82,18 +68,6 @@
 }
 
 /***********************************************************************
- *           CreateStatusWindow16   (COMCTL32.21)
- */
-HWND16 WINAPI CreateStatusWindow16( INT16 style, LPCSTR text, HWND16 parent,
-				    UINT16 wid )
-{
-    return CreateWindow16(STATUSCLASSNAME16, text, style, 
-			   CW_USEDEFAULT16, CW_USEDEFAULT16,
-			   CW_USEDEFAULT16, CW_USEDEFAULT16, 
-			   parent, wid, 0, 0);
-}
-
-/***********************************************************************
  *           CreateStatusWindow32W   (COMCTL32.22)
  */
 HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent,
@@ -177,7 +151,7 @@
         break;
 
       case ICC_BAR_CLASSES:
-        TRACE (commctrl, "No toolbar class implemented!\n");
+	TOOLBAR_Register ();
 	STATUS_Register ();
         TRACE (commctrl, "No trackbar class implemented!\n");
         TRACE (commctrl, "No tooltip class implemented!\n");
@@ -208,6 +182,7 @@
         TRACE (commctrl, "No month calendar class implemented!\n");
         TRACE (commctrl, "No date picker class implemented!\n");
         TRACE (commctrl, "No time picker class implemented!\n");
+        UPDOWN_Register ();
         break;
 
       case ICC_USEREX_CLASSES:
@@ -288,3 +263,81 @@
             break;
     }
 }
+
+
+/***********************************************************************
+ * CreateToolbarEx [COMCTL32.32]
+ *
+ *
+ *
+ */
+
+HWND32 WINAPI
+CreateToolbarEx (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
+                 HINSTANCE32 hBMInst, UINT32 wBMID, LPCTBBUTTON lpButtons,
+                 INT32 iNumButtons, INT32 dxButton, INT32 dyButton,
+                 INT32 dxBitmap, INT32 dyBitmap, UINT32 uStructSize)
+{
+    HWND32 hwndTB =
+        CreateWindowEx32A(0, TOOLBARCLASSNAME32A, "", style, 0, 0, 0, 0,
+			  hwnd, (HMENU32)wID, 0, NULL);
+    if(hwndTB) {
+	TBADDBITMAP tbab;
+
+        SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
+
+	/* set bitmap and button size */
+
+	/* add bitmaps */
+	tbab.hInst = hBMInst;
+	tbab.nID   = wBMID;
+	SendMessage32A (hwndTB, TB_ADDBITMAP,
+			(WPARAM32)nBitmaps, (LPARAM)&tbab);
+
+	/* add buttons */
+	SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
+			(WPARAM32)iNumButtons, (LPARAM)&lpButtons);
+    }
+
+    return (hwndTB);
+}
+
+
+/***********************************************************************
+ * CreateMappedBitmap [COMCTL32.8]
+ *
+ *
+ *
+ */
+
+HBITMAP32 WINAPI
+CreateMappedBitmap (HINSTANCE32 hInstance, INT32 idBitmap, UINT32 wFlags,
+		    LPCOLORMAP lpColorMap, INT32 iNumMaps)
+{
+    HBITMAP32 hbm;
+
+    FIXME (commctrl, "semi-stub!\n");
+
+    hbm = LoadBitmap32A (hInstance, MAKEINTRESOURCE32A(idBitmap));
+
+    return hbm;
+ }
+
+
+/***********************************************************************
+ * CreateToolbar [COMCTL32.7]
+ *
+ *
+ *
+ */
+
+HWND32 WINAPI
+CreateToolbar (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
+	       HINSTANCE32 hBMInst, UINT32 wBMID,
+	       LPCOLDTBBUTTON lpButtons,INT32 iNumButtons)
+{
+    return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
+			    hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
+			    iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
+}
+
diff --git a/controls/desktop.c b/controls/desktop.c
index 520bb56..52add8a 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -166,6 +166,18 @@
     return 0;
 }
 
+/***********************************************************************
+ *           PaintDesktop   (USER32.415)
+ *
+ */
+BOOL32 WINAPI PaintDesktop(HDC32 hdc)
+{
+    HWND32 hwnd = GetDesktopWindow32();
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
+
+    return DESKTOP_DoEraseBkgnd( hwnd, hdc, infoPtr );
+}
 
 /***********************************************************************
  *           SetDeskPattern   (USER.279)
diff --git a/controls/edit.c b/controls/edit.c
index ab11776..d8407bc 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -11,7 +11,6 @@
  *	please read EDIT.TODO (and update it when you change things)
  */
 
-#include <stdio.h>
 #include "windows.h"
 #include "winnt.h"
 #include "win.h"
@@ -41,6 +40,7 @@
 #define EF_HSCROLL_HACK		0x0040	/* we already have informed the user of the hacked handler */
 #define EF_AFTER_WRAP		0x0080	/* the caret is displayed after the last character of a
 					   wrapped line, instead of in front of the next character */
+#define EF_USE_SOFTBRK		0x0100	/* Enable soft breaks in text. */
 
 typedef BOOL32 *LPBOOL32;
 
@@ -1948,10 +1948,15 @@
  *
  *	EM_FMTLINES
  *
+ * Enable or disable soft breaks.
  */
 static BOOL32 EDIT_EM_FmtLines(WND *wnd, EDITSTATE *es, BOOL32 add_eol)
 {
-	FIXME(edit, "message not implemented\n");
+	es->flags &= ~EF_USE_SOFTBRK;
+	if (add_eol) {
+		es->flags |= EF_USE_SOFTBRK;
+		FIXME(edit, "soft break enabled, not implemented\n");
+	}
 	return add_eol;
 }
 
@@ -1965,7 +1970,7 @@
  *	However, with this message a 32 bit application requests
  *	a handle to 32 bit moveable local heap memory, where it expects
  *	to find the text.
- *	It's a pitty that from this moment on we have to use this
+ *	It's a pity that from this moment on we have to use this
  *	local heap, because applications may rely on the handle
  *	in the future.
  *
@@ -3896,7 +3901,8 @@
 		break;
 
 	default:
-		ERR(edit, "undocumented WM_VSCROLL parameter, please report\n");
+		ERR(edit, "undocumented WM_VSCROLL action %d, please report\n",
+			action);
 		return 0;
 	}
 	if (dy)
diff --git a/controls/header.c b/controls/header.c
index 35a1357..18bbfaa 100644
--- a/controls/header.c
+++ b/controls/header.c
@@ -4,15 +4,20 @@
  *  Copyright 1998 Eric Kohl
  *
  *  TODO:
- *   - Bitmap support (partially).
  *   - Imagelist support (partially).
- *   - Hottrack support (partially).
- *   - Control specific cursors (over dividers).
+ *   - Callback items.
  *   - Owner draw support.
  *   - Order list support.
+ *   - Control specific cursors (over dividers).
+ *   - Hottrack support (partially).
  *   - Custom draw support (including Notifications).
  *   - Drag and Drop support (including Notifications).
  *   - Unicode support.
+ *
+ *  FIXME:
+ *   - Replace DrawText32A by DrawTextEx32A(...|DT_ENDELLIPSIS) in
+ *     HEADER_DrawItem.
+ *   - Little flaw when drawing a bitmap on the right side of the text.
  */
 
 #include "windows.h"
@@ -29,10 +34,6 @@
 #define VERT_BORDER     4
 #define DIVIDER_WIDTH  10
 
-#define UNKNOWN_PARAM(msg, wParam, lParam) WARN(header, \
-        "Unknown parameter(s) for message " #msg     \
-	"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam); 
-
 #define HEADER_GetInfoPtr(wndPtr) ((HEADER_INFO *)wndPtr->wExtra[0])
 
 
@@ -76,6 +77,8 @@
 	    HDC32    hdcBitmap;
 	    INT32    yD, yS, cx, cy, rx, ry;
 
+	    GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
+
 	    ry = r.bottom - r.top;
 	    rx = r.right - r.left;
 
@@ -98,7 +101,6 @@
 		cx = rx - 6;
 	    }
 
-	    GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
 	    hdcBitmap = CreateCompatibleDC32 (hdc);
 	    SelectObject32 (hdcBitmap, phdi->hbm);
 	    BitBlt32 (hdc, r.left + 3, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
@@ -107,24 +109,63 @@
 	    r.left += (bmp.bmWidth + 3);
 	}
 
-/*
+
 	if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
 	    BITMAP32 bmp;
 	    HDC32    hdcBitmap;
+	    INT32    xD, yD, yS, cx, cy, rx, ry, tx;
+	    RECT32   textRect;
 
 	    GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
 
+	    textRect = r;
+            DrawText32A(hdc, phdi->pszText, lstrlen32A(phdi->pszText),
+	   	  &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
+	    tx = textRect.right - textRect.left;
+	    ry = r.bottom - r.top;
+	    rx = r.right - r.left;
 
+	    if (ry >= bmp.bmHeight) {
+		cy = bmp.bmHeight;
+		yD = r.top + (ry - bmp.bmHeight) / 2;
+		yS = 0;
+	    }
+	    else {
+		cy = ry;
+		yD = r.top;
+		yS = (bmp.bmHeight - ry) / 2;
+
+	    }
+
+	    if (r.left + tx + bmp.bmWidth + 9 <= r.right) {
+		cx = bmp.bmWidth;
+		xD = r.left + tx + 6;
+	    }
+	    else {
+		if (rx >= bmp.bmWidth + 6) {
+		    cx = bmp.bmWidth;
+		    xD = r.right - bmp.bmWidth - 3;
+		    r.right = xD - 3;
+		}
+		else {
+		    cx = rx - 3;
+		    xD = r.left;
+		    r.right = r.left;
+		}
+	    }
+
+	    hdcBitmap = CreateCompatibleDC32 (hdc);
+	    SelectObject32 (hdcBitmap, phdi->hbm);
+	    BitBlt32 (hdc, xD, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
+	    DeleteDC32 (hdcBitmap);
 	}
-*/
 
-/*
 	if (phdi->fmt & HDF_IMAGE) {
+	    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
 
-	    ImageList_Draw (....);
 
+//	    ImageList_Draw (infoPtr->himl, phdi->iImage,...);
 	}
-*/
 
         if ((phdi->fmt & HDF_STRING) && (phdi->pszText)) {
             oldBkMode = SetBkMode32(hdc, TRANSPARENT);
diff --git a/controls/listbox.c b/controls/listbox.c
index e6301a7..60ea183 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -5,7 +5,6 @@
  */
 
 #include <string.h>
-#include <stdio.h>
 #include "windows.h"
 #include "winerror.h"
 #include "drive.h"
diff --git a/controls/menu.c b/controls/menu.c
index 78aaf0a..81bc680 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -15,7 +15,6 @@
 #include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 #include "windows.h"
 #include "bitmap.h"
@@ -77,6 +76,7 @@
     HWND32      hWnd;         /* Window containing the menu */
     MENUITEM   *items;        /* Array of menu items */
     UINT32      FocusedItem;  /* Currently focused item */
+    WORD	defitem;      /* default item position. Unused (except for set/get)*/
 } POPUPMENU, *LPPOPUPMENU;
 
 /* internal flags for menu tracking */
@@ -1444,9 +1444,13 @@
         }
     }
     else if (flags & MF_BITMAP) item->text = (LPSTR)(HBITMAP32)LOWORD(str);
-    else if (flags & MF_OWNERDRAW) item->text = (LPSTR)str;
     else item->text = NULL;
 
+    if (flags & MF_OWNERDRAW) 
+        item->dwItemData = (DWORD)str;
+    else
+        item->dwItemData = 0;
+
     if ((item->fType & MF_POPUP) && (flags & MF_POPUP) && (item->hSubMenu != id) )
 	DestroyMenu32( item->hSubMenu );   /* ModifyMenu() spec */
 
@@ -3032,7 +3036,6 @@
 	((POPUPMENU *)USER_HEAP_LIN_ADDR((HMENU16)id))->wFlags |= MF_POPUP;
 
     item->hCheckBit = item->hUnCheckBit = 0;
-    item->dwItemData = 0;
     return TRUE;
 }
 
@@ -3735,7 +3738,7 @@
 					 LPMENUITEMINFO32A lpmii,
 					 BOOL32 unicode)
 {
-  MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos);
+  MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos? MF_BYPOSITION : 0);
     debug_print_menuitem("GetMenuItemInfo32_common: ", menu, "");
     if (!menu)
 	return FALSE;
@@ -3853,7 +3856,7 @@
 BOOL32 WINAPI SetMenuItemInfo32A(HMENU32 hmenu, UINT32 item, BOOL32 bypos,
                                  const MENUITEMINFO32A *lpmii) 
 {
-    return SetMenuItemInfo32_common(MENU_FindItem(&hmenu, &item, bypos),
+    return SetMenuItemInfo32_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0),
 				    lpmii, FALSE);
 }
 
@@ -3863,7 +3866,7 @@
 BOOL32 WINAPI SetMenuItemInfo32W(HMENU32 hmenu, UINT32 item, BOOL32 bypos,
                                  const MENUITEMINFO32W *lpmii)
 {
-    return SetMenuItemInfo32_common(MENU_FindItem(&hmenu, &item, bypos),
+    return SetMenuItemInfo32_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0),
 				    (const MENUITEMINFO32A*)lpmii, TRUE);
 }
 
@@ -3872,14 +3875,36 @@
  */
 BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, BOOL32 bypos)
 {
-    MENUITEM *menu = MENU_FindItem(&hmenu, &item, bypos);
-    if (!menu) return FALSE;
-    debug_print_menuitem("SetMenuDefaultItem32: ", menu, "");
+    MENUITEM *menuitem = MENU_FindItem(&hmenu, &item, bypos);
+    POPUPMENU *menu;
+
+    if (!menuitem) return FALSE;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(hmenu))) return FALSE;
+
+    menu->defitem = item; /* position */
+
+    debug_print_menuitem("SetMenuDefaultItem32: ", menuitem, "");
     FIXME(menu, "(0x%x,%d,%d), empty stub!\n",
 		  hmenu, item, bypos);
     return TRUE;
 }
 
+/**********************************************************************
+ *		GetMenuDefaultItem32    (USER32.260)
+ */
+UINT32 WINAPI GetMenuDefaultItem32(HMENU32 hmenu, UINT32 bypos, UINT32 flags)
+{
+    POPUPMENU *menu;
+
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(hmenu))) return 0; /*FIXME*/
+
+    FIXME(menu, "(0x%x,%d,%d), stub!\n", hmenu, bypos, flags);
+    if (bypos & MF_BYPOSITION)
+    	return menu->defitem;
+    else
+    	return menu->items[menu->defitem].wID;
+}
+
 /*******************************************************************
  *              InsertMenuItem16   (USER.441)
  *
diff --git a/controls/progress.c b/controls/progress.c
index 7937d2b..d83cb93 100644
--- a/controls/progress.c
+++ b/controls/progress.c
@@ -159,9 +159,10 @@
     {
     case WM_CREATE:
       /* allocate memory for info struct */
-      wndPtr->wExtra[0] = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+      infoPtr = (PROGRESS_INFO *)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
                                      sizeof(PROGRESS_INFO));
-      infoPtr = (PROGRESS_INFO *)wndPtr->wExtra[0];
+      wndPtr->wExtra[0] = (DWORD)infoPtr;
+
       /* initialize the info struct */
       infoPtr->MinVal=0; 
       infoPtr->MaxVal=100;
@@ -169,11 +170,11 @@
       infoPtr->Step=10;
       infoPtr->ColorBar=CLR_DEFAULT;
       infoPtr->ColorBk=CLR_DEFAULT;
-      TRACE(updown, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
+      TRACE(progress, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
       break;
     
     case WM_DESTROY:
-      TRACE(updown, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
+      TRACE(progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
       HeapFree (SystemHeap, 0, infoPtr);
       break;
 
@@ -183,10 +184,12 @@
       return 1;
 	
     case WM_GETFONT:
+      FIXME (progress, "WM_GETFONT - empty message!\n");
       /* FIXME: What do we need to do? */
       break;
 
     case WM_SETFONT:
+      FIXME (progress, "WM_SETFONT - empty message!\n");
       /* FIXME: What do we need to do? */
       break;
 
diff --git a/controls/scroll.c b/controls/scroll.c
index ec71eb4..4f844cf 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -6,7 +6,6 @@
  */
 
 #include <stdlib.h>
-#include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "windows.h"
@@ -900,9 +899,23 @@
 
 /*************************************************************************
  *           SetScrollInfo32   (USER32.501)
+ * SetScrollInfo32 can be used to set the position, upper bound, 
+ * lower bound, and page size of a scrollbar control.
+ *
+ * RETURNS
+ *    Scrollbar position
+ *
+ * NOTE
+ *    For 100 lines of text to be displayed in a window of 25 lines,
+ *  one would for instance use info->nMin=0, info->nMax=75
+ *  (corresponding to the 76 different positions of the window on
+ *  the text), and info->nPage=25.
  */
-INT32 WINAPI SetScrollInfo32( HWND32 hwnd, INT32 nBar, const SCROLLINFO *info,
-                              BOOL32 bRedraw )
+INT32 WINAPI SetScrollInfo32( 
+HWND32 hwnd /* [I] Handle of window whose scrollbar will be affected */, 
+INT32 nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */, 
+const SCROLLINFO *info /* [I] Specifies what to change and new values */,
+BOOL32 bRedraw /* [I] Should scrollbar be redrawn afterwards ? */)
 {
     SCROLLBAR_INFO *infoPtr;
     UINT32 new_flags;
@@ -1019,8 +1032,15 @@
 
 /*************************************************************************
  *           GetScrollInfo32   (USER32.284)
+ * GetScrollInfo32 can be used to retrieve the position, upper bound, 
+ * lower bound, and page size of a scrollbar control.
+ *
+ * RETURNS STD
  */
-BOOL32 WINAPI GetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO info )
+BOOL32 WINAPI GetScrollInfo32( 
+  HWND32 hwnd /* [I] Handle of window */ , 
+  INT32 nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */, 
+  LPSCROLLINFO info /* [IO] (info.fMask [I] specifies which values are to retrieve) */)
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -1054,9 +1074,20 @@
 
 /*************************************************************************
  *           SetScrollPos32   (USER32.502)
+ *
+ * RETURNS
+ *    Success: Scrollbar position
+ *    Failure: 0
+ *
+ * REMARKS
+ *    Note the ambiguity when 0 is returned.  Use GetLastError
+ *    to make sure there was an error (and to know which one).
  */
-INT32 WINAPI SetScrollPos32( HWND32 hwnd, INT32 nBar, INT32 nPos,
-                             BOOL32 bRedraw )
+INT32 WINAPI SetScrollPos32( 
+HWND32 hwnd /* [I] Handle of window whose scrollbar will be affected */,
+INT32 nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */,
+INT32 nPos /* [I] New value */,
+BOOL32 bRedraw /* [I] Should scrollbar be redrawn afterwards ? */ )
 {
     SCROLLINFO info;
     SCROLLBAR_INFO *infoPtr;
@@ -1083,8 +1114,18 @@
 
 /*************************************************************************
  *           GetScrollPos32   (USER32.285)
+ *
+ * RETURNS
+ *    Success: Current position
+ *    Failure: 0   
+ *
+ * REMARKS
+ *    Note the ambiguity when 0 is returned.  Use GetLastError
+ *    to make sure there was an error (and to know which one).
  */
-INT32 WINAPI GetScrollPos32( HWND32 hwnd, INT32 nBar )
+INT32 WINAPI GetScrollPos32( 
+HWND32 hwnd, /* [I] Handle of window */
+INT32 nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */)
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -1107,9 +1148,15 @@
 
 /*************************************************************************
  *           SetScrollRange32   (USER32.503)
+ *
+ * RETURNS STD
  */
-BOOL32 WINAPI SetScrollRange32( HWND32 hwnd, INT32 nBar,
-                                INT32 MinVal, INT32 MaxVal, BOOL32 bRedraw )
+BOOL32 WINAPI SetScrollRange32( 
+HWND32 hwnd, /* [I] Handle of window whose scrollbar will be affected */
+INT32 nBar, /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */
+INT32 MinVal, /* [I] New minimum value */
+INT32 MaxVal, /* [I] New maximum value */
+BOOL32 bRedraw /* [I] Should scrollbar be redrawn afterwards ? */)
 {
     SCROLLINFO info;
 
@@ -1172,9 +1219,14 @@
 
 /*************************************************************************
  *           GetScrollRange32   (USER32.286)
+ *
+ * RETURNS STD
  */
-BOOL32 WINAPI GetScrollRange32( HWND32 hwnd, INT32 nBar,
-                                LPINT32 lpMin, LPINT32 lpMax)
+BOOL32 WINAPI GetScrollRange32( 
+HWND32 hwnd, /* [I] Handle of window */
+INT32 nBar, /* [I] One of SB_HORZ, SB_VERT, or SB_CTL  */
+LPINT32 lpMin, /* [O] Where to store minimum value */
+LPINT32 lpMax /* [O] Where to store maximum value */)
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -1201,8 +1253,13 @@
 
 /*************************************************************************
  *           ShowScrollBar32   (USER32.532)
+ *
+ * RETURNS STD
  */
-BOOL32 WINAPI ShowScrollBar32( HWND32 hwnd, INT32 nBar, BOOL32 fShow )
+BOOL32 WINAPI ShowScrollBar32( 
+HWND32 hwnd, /* [I] Handle of window whose scrollbar(s) will be affected   */
+INT32 nBar, /* [I] One of SB_HORZ, SB_VERT, SB_BOTH or SB_CTL */
+BOOL32 fShow /* [I] TRUE = show, FALSE = hide  */)
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
diff --git a/controls/static.c b/controls/static.c
index e088d27..01f386c 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -5,7 +5,6 @@
  *
  */
 
-#include <stdio.h>
 #include "windows.h"
 #include "win.h"
 #include "bitmap.h"
diff --git a/controls/status.c b/controls/status.c
index e1d8b95..a24a47b 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -5,8 +5,6 @@
  * Copyright 1998 Eric Kohl
  */
 
-#include <stdio.h>
-
 #include "windows.h"
 #include "status.h"
 #include "commctrl.h"
@@ -21,16 +19,10 @@
 
 /*
  * Fixme/Todo
- * 1) Don't hard code bar to bottom of window, allow CCS_TOP also
- * 2) Add 'non hack' version of icon drawing code
+ * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
+ + 2) Tooltip support.
  */
 
-#define __GET_ICON_INFO_HACK__
-
-#ifdef __GET_ICON_INFO_HACK__
-#include "bitmap.h"
-#endif
-
 #define _MAX(a,b) (((a)>(b))?(a):(b))
 #define _MIN(a,b) (((a)>(b))?(b):(a))
 
@@ -92,61 +84,20 @@
     RECT32 r = *lprc;
     UINT32 border = BDR_SUNKENOUTER;
 
-    if(style==SBT_POPOUT)
+    if (style==SBT_POPOUT)
       border = BDR_RAISEDOUTER;
-    else if(style==SBT_NOBORDERS)
+    else if (style==SBT_NOBORDERS)
       border = 0;
 
     DrawEdge32(hdc, &r, border, BF_RECT|BF_ADJUST);
 
     /* draw the icon */
     if (hIcon) {
-#ifdef __GET_ICON_INFO_HACK__
-        HBITMAP32 hbmImage;
-        HBITMAP32 hbmMask;
-        CURSORICONINFO *ptr;
-        HDC32 hdcSrc;
-	INT32 y, cy, ry, ty;
+	INT32 cy = r.bottom - r.top;
 
-        if (ptr = (CURSORICONINFO *)GlobalLock16(hIcon)) {
-        hbmMask  = CreateBitmap32 (ptr->nWidth, ptr->nHeight, 1, 1, 
-                                   (char *)(ptr + 1));
-        hbmImage = CreateBitmap32 (ptr->nWidth, ptr->nHeight, ptr->bPlanes,
-                                   ptr->bBitsPerPixel,
-                                   (char *)(ptr + 1) + ptr->nHeight * 
-                                   BITMAP_WIDTH_BYTES(ptr->nWidth, 1));
 	r.left += 2;
-	ry = r.bottom - r.top;
-	if (ry >= ptr->nHeight) {
-	    /* full view of icon */
-	    y = 0;
-	    cy = ptr->nHeight;
-	    ty = r.top + (ry - ptr->nHeight) / 2;
-	}
-	else {
-	    /* partial view of icon */
-	    y = (ptr->nHeight - ry) / 2;
-	    cy = ry;
-	    ty = r.top;
-	}
-
-	    hdcSrc = CreateCompatibleDC32 (hdc);
-	    SelectObject32 (hdcSrc, hbmMask);
-	    BitBlt32 (hdc, r.left, r.top, ptr->nWidth, cy,
-		      hdcSrc, 0, y, SRCAND);
-	    SelectObject32 (hdcSrc, hbmImage);
-	    BitBlt32 (hdc, r.left, r.top, ptr->nWidth, cy,
-		      hdcSrc, 0, y, SRCPAINT);
-	    DeleteDC32 (hdcSrc);
-
-	    r.left += ptr->nWidth;
-	    DeleteObject32 (hbmImage);
-	    DeleteObject32 (hbmMask);
-	    GlobalUnlock16 (hIcon);
-	}
-#else
-	/* FIXME: no "non hack" version available!!! */
-#endif
+	DrawIconEx32 (hdc, r.left, r.top, hIcon, cy, cy, 0, 0, DI_NORMAL);
+	r.left += cy;
     }
 
     /* now draw text */
@@ -378,10 +329,11 @@
     STATUSWINDOWINFO *self;
 
     wndPtr = WIN_FindWndPtr(hwnd);
-    wndPtr->wExtra[0] = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
-				   sizeof(STATUSWINDOWINFO));
+    self = (STATUSWINDOWINFO*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+					 sizeof(STATUSWINDOWINFO));
 
-    self = (STATUSWINDOWINFO*)wndPtr->wExtra[0];
+    wndPtr->wExtra[0] = (DWORD)self;
+
     self->numParts = 1;
     self->parts = 0;
     self->simple = FALSE;
@@ -397,33 +349,33 @@
     self->part0.hIcon = 0;
 
     /* initialize first part */
-    self->parts = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY,
-			    sizeof(STATUSWINDOWPART));
+    self->parts = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+			     sizeof(STATUSWINDOWPART));
     self->parts[0].bound = rect;
     self->parts[0].text = 0;
     self->parts[0].x = -1;
     self->parts[0].style = 0;
     self->parts[0].hIcon = 0;
 
-    if (len = lstrlen32A( lpCreate->lpszName ) ) {
-        self->parts[0].text = HeapAlloc( SystemHeap, 0, len + 1 );
-        lstrcpy32A( self->parts[0].text, lpCreate->lpszName );
+    if ((len = lstrlen32A (lpCreate->lpszName))) {
+        self->parts[0].text = HeapAlloc (SystemHeap, 0, len + 1);
+        lstrcpy32A (self->parts[0].text, lpCreate->lpszName);
     }
 
     height = 20;
-    if ((hdc = GetDC32(0))) {
+    if ((hdc = GetDC32 (0))) {
 	TEXTMETRIC32A tm;
 	GetTextMetrics32A(hdc, &tm);
 	self->textHeight = tm.tmHeight;
 	ReleaseDC32(0, hdc);
     }
 
-    parent = GetParent32(hwnd);
-    GetClientRect32(parent, &rect);
+    parent = GetParent32 (hwnd);
+    GetClientRect32 (parent, &rect);
     width = rect.right - rect.left;
     self->height = self->textHeight + 4 + VERT_BORDER;
-    MoveWindow32(hwnd, lpCreate->x, lpCreate->y-1, width, self->height, FALSE);
-    SW_SetPartBounds(hwnd, self);
+    MoveWindow32 (hwnd, lpCreate->x, lpCreate->y-1, width, self->height, FALSE);
+    SW_SetPartBounds (hwnd, self);
     return 0;
 }
 
@@ -495,12 +447,11 @@
 static LRESULT
 SW_SetMinHeight(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-    INT32	width, height, x, y;
+    INT32	width, x, y;
     RECT32	parent_rect;
     HWND32	parent;
 
     if (IsWindowVisible32 (hwnd)) {
-	/* width and height don't apply */
 	parent = GetParent32(hwnd);
 	GetClientRect32(parent, &parent_rect);
 	self->height = (INT32)wParam + VERT_BORDER;
@@ -531,12 +482,10 @@
 
 
 static LRESULT
-SW_SetIcon(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
+SW_SetIcon (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-    HDC32    hdc;
-    INT32    nPart;
+    INT32  nPart = (INT32)wParam & 0x00ff;
 
-    nPart = (INT32)wParam & 0x00ff;
     if ((nPart < -1) || (nPart >= self->numParts)) return FALSE;
 
     if (nPart == -1) {
@@ -558,7 +507,7 @@
     INT32    nPart;
 
     nPart = (INT32)wParam & 0x00ff;
-    if ((nPart < -1) || (nPart >= self->numParts)) return NULL;
+    if ((nPart < -1) || (nPart >= self->numParts)) return 0;
 
     if (nPart == -1)
         return (self->part0.hIcon);
@@ -663,7 +612,6 @@
 static LRESULT
 SW_NcLButtonDown (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-//    TRACE (status, "WM_NCLBUTTONDOWN\n");
     PostMessage32A (GetParent32 (hwnd), WM_NCLBUTTONDOWN,
 		    wParam, lParam);
     return 0;
@@ -673,7 +621,6 @@
 static LRESULT
 SW_NcLButtonUp (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
-//    TRACE (status, "WM_NCLBUTTONUP\n");
     PostMessage32A (GetParent32 (hwnd), WM_NCLBUTTONUP,
 		    wParam, lParam);
     return 0;
@@ -722,8 +669,8 @@
         HeapFree(SystemHeap, 0, part->text);
     part->text = 0;
     if (lParam && (len = lstrlen32A((LPCSTR)lParam))) {
-        part->text = HeapAlloc(SystemHeap, 0, len+1);
-        lstrcpy32A(part->text, (LPCSTR)lParam);
+        part->text = HeapAlloc (SystemHeap, 0, len+1);
+        lstrcpy32A (part->text, (LPCSTR)lParam);
     }
     InvalidateRect32(hwnd, &part->bound, FALSE);
 
@@ -735,7 +682,7 @@
 SW_Size(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
 {
     /* Need to resize width to match parent */
-    INT32	width, height, x, y;
+    INT32	width, x, y;
     RECT32	parent_rect;
     HWND32	parent;
 
@@ -836,7 +783,7 @@
     case WM_NCHITTEST:
         return SW_NcHitTest (wndPtr, wParam, lParam);
 
-   case WM_NCLBUTTONDOWN:
+    case WM_NCLBUTTONDOWN:
 	return SW_NcLButtonDown (hwnd, wParam, lParam);
 
     case WM_NCLBUTTONUP:
@@ -862,25 +809,25 @@
 
 
 /***********************************************************************
- *           STATUS_Register [Internal]
+ * STATUS_Register [Internal]
  *
  * Registers the status window class.
  */
-void STATUS_Register(void)
+void STATUS_Register (void)
 {
     WNDCLASS32A wndClass;
 
-    if( GlobalFindAtom32A( STATUSCLASSNAME32A ) ) return;
+    if (GlobalFindAtom32A (STATUSCLASSNAME32A)) return;
 
-    ZeroMemory( &wndClass, sizeof( WNDCLASS32A ) );
+    ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
     wndClass.lpfnWndProc   = (WNDPROC32)StatusWindowProc;
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(STATUSWINDOWINFO *);
-    wndClass.hCursor       = LoadCursor32A( 0, IDC_ARROW32A );
+    wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
     wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
     wndClass.lpszClassName = STATUSCLASSNAME32A;
  
-    RegisterClass32A( &wndClass );
+    RegisterClass32A (&wndClass);
 }
 
diff --git a/controls/toolbar.c b/controls/toolbar.c
new file mode 100644
index 0000000..86a1e6c
--- /dev/null
+++ b/controls/toolbar.c
@@ -0,0 +1,1290 @@
+/*
+ * Toolbar control
+ *
+ * Copyright 1998 Eric Kohl
+ *
+ * NOTES
+ *   PLEASE don't try to improve or change this code right now. Many
+ *   features are still missing, but I'm working on it. I want to avoid
+ *   any confusion. This note will be removed as soon as most of the
+ *   features are implemented.
+ *     Eric <ekohl@abo.rhein-zeitung.de>
+ *
+ * TODO:
+ *   - Many messages.
+ *   - All notifications.
+ *   - Tooltip support.
+ *   - Unicode suppport.
+ *   - Internal COMMCTL32 bitmaps.
+ *   - 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.
+ *   - additional features.
+ */
+
+#include "windows.h"
+#include "commctrl.h"
+#include "toolbar.h"
+#include "heap.h"
+#include "win.h"
+#include "debug.h"
+
+
+#define SEPARATOR_WIDTH  12
+
+
+
+
+
+#define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)wndPtr->wExtra[0])
+
+
+static void
+TOOLBAR_DrawButton (WND *wndPtr, TBUTTON_INFO *btnPtr, HDC32 hdc)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    RECT32 rc;
+
+    if (btnPtr->fsState & TBSTATE_HIDDEN) return;
+
+    rc = btnPtr->rect;
+    if (btnPtr->fsStyle & TBSTYLE_SEP) {
+
+    }
+    else {
+	if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
+	    /* button is disabled */
+	    DrawEdge32 (hdc, &rc, EDGE_RAISED,
+			BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+	    ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
+			    rc.left+2, rc.top+2, ILD_NORMAL);
+	    return;
+	}
+
+	/* 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+3, rc.top+3, ILD_NORMAL);
+	    return;
+	}
+	else {
+	    DrawEdge32 (hdc, &rc, EDGE_RAISED,
+			BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
+	    ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
+			    rc.left+2, rc.top+2, ILD_NORMAL);
+	}
+    }
+}
+
+
+
+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++) {
+	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
+	btnPtr++;
+    }
+}
+
+
+static void
+TOOLBAR_CalcToolbar (WND *wndPtr)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    TBUTTON_INFO *btnPtr;
+    RECT32 rect;
+    INT32 i;
+
+    rect.left   = infoPtr->nIndent;
+    rect.top    = infoPtr->nButtonTop;
+//    rect.right  = rect.left + infoPtr->nButtonWidth;
+    rect.bottom = rect.top + infoPtr->nButtonHeight;
+
+    btnPtr = infoPtr->buttons;
+    for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
+	if (btnPtr->fsState & TBSTATE_HIDDEN) {
+	    btnPtr->rect.left = 0;
+	    btnPtr->rect.right = 0;
+	    btnPtr->rect.top = 0;
+	    btnPtr->rect.bottom = 0;
+	    continue;
+	}
+
+	btnPtr->rect = rect;
+	if (btnPtr->fsStyle & TBSTYLE_SEP)
+	    btnPtr->rect.right = btnPtr->rect.left + SEPARATOR_WIDTH;
+	else
+	    btnPtr->rect.right = btnPtr->rect.left + infoPtr->nButtonWidth;
+	rect.left = btnPtr->rect.right;
+    }
+}
+
+
+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++) {
+	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;
+	    }
+
+	}
+
+	btnPtr++;
+    }
+
+//    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++) {
+	if (btnPtr->idCommand == idCommand)
+	    return i;
+	btnPtr++;
+    }
+    return -1;
+}
+
+
+static LRESULT
+TOOLBAR_AddBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
+
+    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 (!(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);
+    }
+
+
+    /* Add bitmaps to the default image list */
+    if (lpAddBmp->hInst == (HINSTANCE32)0) {
+
+	ImageList_Add (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID, 0);
+    }
+    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 */
+	ImageList_SetImageCount (infoPtr->himlDef,
+	    ImageList_GetImageCount (infoPtr->himlDef) + (INT32)wParam);
+    }
+    else {
+	HBITMAP32 hBmp =
+	    LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
+
+	ImageList_Add (infoPtr->himlDef, hBmp, (HBITMAP32)0);
+
+	DeleteObject32 (hBmp); 
+    }
+
+
+    /* Add bitmaps to the disabled image list */
+
+
+    return 0;
+}
+
+
+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 =
+	    HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+		       sizeof (TBUTTON_INFO) * nNewButtons);
+    }
+    else {
+	TBUTTON_INFO *oldButtons = infoPtr->buttons;
+	infoPtr->buttons =
+	    HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+		       sizeof (TBUTTON_INFO) * nNewButtons);
+	memcpy (&infoPtr->buttons[0], &oldButtons[0],
+		nOldButtons * sizeof(TBUTTON_INFO));
+        HeapFree (SystemHeap, 0, oldButtons);
+    }
+
+    infoPtr->nNumButtons = nNewButtons;
+
+    /* insert new button data (bad implementation)*/
+    for (nCount = 0; nCount < nAddButtons; nCount++) {
+	infoPtr->buttons[nOldButtons+nCount].iBitmap   = lpTbb[nCount].iBitmap;
+	infoPtr->buttons[nOldButtons+nCount].idCommand = lpTbb[nCount].idCommand;
+	infoPtr->buttons[nOldButtons+nCount].fsState   = lpTbb[nCount].fsState;
+	infoPtr->buttons[nOldButtons+nCount].fsStyle   = lpTbb[nCount].fsStyle;
+	infoPtr->buttons[nOldButtons+nCount].dwData    = lpTbb[nCount].dwData;
+	infoPtr->buttons[nOldButtons+nCount].iString   = lpTbb[nCount].iString;
+    }
+
+    TOOLBAR_CalcToolbar (wndPtr);
+
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    TOOLBAR_Refresh (wndPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+    return TRUE;
+}
+
+
+// << TOOLBAR_AddString32A >>
+// << TOOLBAR_AutoSize >>
+
+
+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);
+
+    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;
+
+    nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
+    if (nIndex == -1)
+	return FALSE;
+
+    btnPtr = &infoPtr->buttons[nIndex];
+    if (LOWORD(lParam) == FALSE)
+	btnPtr->fsState &= ~TBSTATE_CHECKED;
+    else
+	btnPtr->fsState |= TBSTATE_CHECKED;
+
+    hdc = GetDC32 (wndPtr->hwndSelf);
+    TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
+    ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+    return TRUE;
+}
+*/
+
+
+static LRESULT
+TOOLBAR_CommandToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    return TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
+}
+
+
+// << TOOLBAR_Customize >>
+
+
+static LRESULT
+TOOLBAR_DeleteButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+    INT32 iIndex = (INT32)wParam;
+
+    if ((iIndex < 0) || (iIndex >= infoPtr->nNumButtons))
+	return FALSE;
+
+    if (infoPtr->nNumButtons == 1) {
+	TRACE (toolbar, " simple delete!\n");
+	HeapFree (SystemHeap, 0, infoPtr->buttons);
+	infoPtr->buttons = NULL;
+	infoPtr->nNumButtons = 0;
+    }
+    else {
+
+        TRACE(header, "complex delete! [iIndex=%d]\n", iIndex);
+
+    }
+
+    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;
+    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 0;
+
+    return infoPtr->buttons[nIndex].iBitmap;
+}
+
+
+// << TOOLBAR_GetBitmapFlags >>
+// << TOOLBAR_GetButton >>
+// << ... >>
+
+
+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;
+}
+
+
+static LRESULT
+TOOLBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    return TOOLBAR_InternalHitTest (wndPtr, (LPPOINT32)lParam);
+}
+
+
+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 >>
+// << TOOLBAR_SaveRestore >>
+// << 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;
+}
+
+
+// << TOOLBAR_SetButtonInfo >>
+
+
+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;
+}
+
+
+// << TOOLBAR_SetButtonWidth >>
+
+
+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;
+
+    return TRUE;
+}
+
+
+
+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;
+}
+
+
+
+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);
+
+    return TRUE;
+}
+
+
+// << TOOLBAR_SetToolTips >>
+// << TOOLBAR_SetUnicodeFormat >>
+
+
+static LRESULT
+TOOLBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr;
+
+    /* allocate memory for info structure */
+    infoPtr = (TOOLBAR_INFO *)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
+                                   sizeof(TOOLBAR_INFO));
+    wndPtr->wExtra[0] = (DWORD)infoPtr;
+
+    infoPtr->nButtonHeight = 22;
+    infoPtr->nButtonWidth = 24;
+    infoPtr->nButtonTop = 2;
+    infoPtr->nBitmapHeight = 15;
+    infoPtr->nBitmapWidth = 16;
+
+    infoPtr->nHeight = infoPtr->nButtonHeight + 6;
+
+    infoPtr->bCaptured = 0;
+    infoPtr->nButtonDown = -1;
+    infoPtr->nOldHit = -1;
+
+    return 0;
+}
+
+
+static LRESULT
+TOOLBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
+
+    /* delete button data */
+    if (infoPtr->buttons)
+	HeapFree (SystemHeap, 0, infoPtr->buttons);
+
+    /* 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);
+
+    /* free toolbar info data */
+    HeapFree (SystemHeap, 0, infoPtr);
+
+    return 0;
+}
+
+
+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) {
+	/* customize */
+
+	FIXME (toolbar, "customization not implemented!\n");
+    }
+
+    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;
+
+    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;
+    HDC32   hdc;
+
+    pt.x = (INT32)LOWORD(lParam);
+    pt.y = (INT32)HIWORD(lParam);
+    nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);
+
+    if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
+
+	btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
+
+
+
+
+	btnPtr->fsState &= ~TBSTATE_PRESSED;
+	infoPtr->nButtonDown = -1;
+	infoPtr->nOldHit = -1;
+
+	infoPtr->bCaptured = FALSE;
+	ReleaseCapture ();
+
+	hdc = GetDC32 (wndPtr->hwndSelf);
+	TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
+	ReleaseDC32 (wndPtr->hwndSelf, hdc);
+
+	SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_COMMAND,
+			MAKEWPARAM(btnPtr->idCommand, 0),
+			(LPARAM)wndPtr->hwndSelf);
+    }
+
+    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;
+
+    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;
+}
+
+
+
+
+
+static LRESULT
+TOOLBAR_NCCalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    RECT32 tmpRect = {0, 0, 0, 0};
+    LPRECT32 winRect;
+
+//    DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam);
+
+    winRect = (LPRECT32)lParam;
+
+//    if (wndPtr->dwStyle & WS_BORDER)
+//	InflateRect32 (&tmpRect, 1, 1);
+
+    if (!(wndPtr->dwStyle & CCS_NODIVIDER)) {
+	tmpRect.top -= 2;
+	tmpRect.bottom -= 2;
+    }
+
+    winRect->left   -= tmpRect.left;   
+    winRect->top    -= tmpRect.top;   
+    winRect->right  -= tmpRect.right;   
+    winRect->bottom -= tmpRect.bottom;   
+
+    return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam);
+//    return 0;
+}
+
+
+static LRESULT
+TOOLBAR_NCPaint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
+{
+    HDC32 hdc;
+    RECT32 rect;
+    HWND32 hwnd = wndPtr->hwndSelf;
+
+    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)) {
+	if (!(wndPtr->dwStyle & CCS_NODIVIDER)) {
+	    rect.left = wndPtr->rectClient.left;
+	    rect.top = wndPtr->rectClient.top - 2;
+	    rect.right = wndPtr->rectClient.right;
+
+	    SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DSHADOW));
+	    MoveToEx32 (hdc, rect.left, rect.top, NULL);
+	    LineTo32 (hdc, rect.right, rect.top);
+	    rect.top++;
+	    SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DHILIGHT));
+	    MoveToEx32 (hdc, rect.left, rect.top, NULL);
+	    LineTo32 (hdc, rect.right, rect.top);
+	}
+
+    }
+
+    ReleaseDC32( hwnd, hdc );
+
+    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  flags;
+
+    flags = (INT32) wParam;
+
+    /* FIXME for flags =
+     * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
+     */
+
+//    if (flags == SIZE_RESTORED) {
+	/* width and height don't apply */
+	parent = GetParent32 (wndPtr->hwndSelf);
+	GetClientRect32(parent, &parent_rect);
+        infoPtr->nWidth = parent_rect.right - parent_rect.left;
+	MoveWindow32(wndPtr->hwndSelf, parent_rect.left, parent_rect.top, //0, 0,
+		     infoPtr->nWidth, infoPtr->nHeight, TRUE);
+//    }
+    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_ADDSTRING32A:
+//	    return TOOLBAR_AddString32A (wndPtr, wParam, lParam);
+
+//	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:
+
+	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:
+//	case TB_GETDISABLEDIMAGELIST:		/* 4.70 */
+//	case TB_GETEXTENDEDSTYLE:		/* 4.71 */
+//	case TB_GETHOTIMAGELIST:		/* 4.70 */
+//	case TB_GETHOTITEM:			/* 4.71 */
+//	case TB_GETIMAGELIST:			/* 4.70 */
+//	case TB_GETINSERTMARK:			/* 4.71 */
+//	case TB_GETINSERTMARKCOLOR:		/* 4.71 */
+//	case TB_GETITEMRECT:
+//	case TB_GETMAXSIZE:			/* 4.71 */
+//	case TB_GETOBJECT:			/* 4.71 */
+//	case TB_GETPADDING:			/* 4.71 */
+//	case TB_GETRECT:			/* 4.70 */
+//	case TB_GETROWS:
+//	case TB_GETSTATE:
+//	case TB_GETSTYLE:			/* 4.70 */
+//	case TB_GETTEXTROWS:			/* 4.70 */
+//	case TB_GETTOOLTIPS:
+//	case TB_GETUNICODEFORMAT:
+
+	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_INSERTBUTTON:
+//	    return TOOLBAR_InsertButton (wndPtr, wParam, lParam);
+
+//	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_MAPACCELERATOR:			/* 4.71 */
+
+//	case TB_MARKBUTTON:			/* 4.71 */
+//	    return TOOLBAR_MarkButton (wndPtr, wParam, lParam);
+
+//	case TB_MOVEBUTTON:			/* 4.71 */
+
+	case TB_PRESSBUTTON:
+	    return TOOLBAR_PressButton (wndPtr, wParam, lParam);
+
+//	case TB_REPLACEBITMAP:
+//	case TB_SAVERESTORE:
+//	case TB_SETANCHORHIGHLIGHT:		/* 4.71 */
+
+	case TB_SETBITMAPSIZE:
+	    return TOOLBAR_SetBitmapSize (wndPtr, wParam, lParam);
+
+//	case TB_SETBUTTONINFO:			/* 4.71 */
+
+	case TB_SETBUTTONSIZE:
+	    return TOOLBAR_SetButtonSize (wndPtr, wParam, lParam);
+
+//	case TB_SETBUTTONWIDTH:			/* 4.70 */
+
+	case TB_SETCMDID:
+	    return TOOLBAR_SetCmdId (wndPtr, wParam, lParam);
+
+//	case TB_SETCOLORSCHEME:			/* 4.71 */
+//	case TB_SETDISABLEDIMAGELIST:		/* 4.70 */
+//	case TB_SETDRAWTEXTFLAGS:		/* 4.71 */
+//	case TB_SETEXTENDEDSTYLE:		/* 4.71 */
+//	case TB_SETHOTIMAGELIST:		/* 4.70 */
+//	case TB_SETHOTITEM:			/* 4.71 */
+//	case TB_SETIMAGELIST:			/* 4.70 */
+
+	case TB_SETINDENT:
+	    return TOOLBAR_SetIndent (wndPtr, wParam, lParam);
+
+//	case TB_SETINSERTMARK:			/* 4.71 */
+//	case TB_SETINSERTMARKCOLOR:		/* 4.71 */
+//	case TB_SETMAXTEXTROWS:			/* 4.70 */
+//	case TB_SETPADDING:			/* 4.71 */
+//	case TB_SETPARENT:
+//	case TB_SETROWS:
+
+	case TB_SETSTATE:
+	    return TOOLBAR_SetState (wndPtr, wParam, lParam);
+
+	case TB_SETSTYLE:
+	    return TOOLBAR_SetStyle (wndPtr, wParam, lParam);
+
+//	case TB_SETTOOLTIPS:
+//	case TB_SETUNICODEFORMAT:
+
+	case WM_CREATE:
+	    return TOOLBAR_Create (wndPtr, wParam, lParam);
+
+	case WM_DESTROY:
+	    return TOOLBAR_Destroy (wndPtr, wParam, lParam);
+
+	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_NCPAINT:
+	    return TOOLBAR_NCPaint (wndPtr, wParam, lParam);
+
+//	case WM_NOTIFY:
+
+	case WM_PAINT:
+	    return TOOLBAR_Paint (wndPtr, wParam);
+
+	case WM_SIZE:
+	    return TOOLBAR_Size (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);
+}
+
diff --git a/controls/uitools.c b/controls/uitools.c
index dd58668..0169b00 100644
--- a/controls/uitools.c
+++ b/controls/uitools.c
@@ -5,7 +5,6 @@
  * Copyright 1997 Bertho A. Stultiens
  */
 
-#include <stdio.h>
 #include "windows.h"
 #include "debug.h"
 
diff --git a/controls/updown.c b/controls/updown.c
index 66c2532..d71ba9d 100644
--- a/controls/updown.c
+++ b/controls/updown.c
@@ -25,7 +25,6 @@
  */
 
 #include <stdlib.h>
-#include <stdio.h>
 #include <assert.h>
 #include <string.h>
 #include "windows.h"