Moved most builtin controls structures into their respective C file.
Created new controls.h file private to user32.dll and moved remaining
builtin controls definitions there.

diff --git a/Make.rules.in b/Make.rules.in
index 2830551..e353e99 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -38,7 +38,7 @@
 LDSHARED  = @LDSHARED@
 RANLIB    = @RANLIB@
 LN_S      = @LN_S@
-DIVINCL   = -I$(SRCDIR) -I. -I$(TOPSRCDIR)/include -I$(TOPOBJDIR)/include
+DIVINCL   = -I$(SRCDIR) -I. -I$(TOPSRCDIR)/include -I$(TOPOBJDIR)/include $(EXTRAINCL)
 ALLCFLAGS = $(DIVINCL) $(CFLAGS) $(DEFS) $(OPTIONS) $(X_CFLAGS)
 LDCOMBINE = @LDCOMBINE@
 LDFLAGS   = @LDFLAGS@
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 03e57e1..8015432 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -4,6 +4,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = controls
+EXTRAINCL = -I$(TOPSRCDIR)/dlls/user
 
 C_SRCS = \
 	button.c \
@@ -15,8 +16,7 @@
 	menu.c \
 	scroll.c \
 	static.c \
-	uitools.c \
-	widgets.c
+	uitools.c
 
 GLUE = edit.c
 
diff --git a/controls/button.c b/controls/button.c
index 1250bdf..d75004d 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -8,13 +8,36 @@
 #include <string.h>
 #include <stdlib.h>	/* for abs() */
 #include "win.h"
-#include "button.h"
 #include "winbase.h"
 #include "windef.h"
 #include "wingdi.h"
 #include "wine/winuser16.h"
+#include "controls.h"
 #include "tweak.h"
 
+/* Note: under MS-Windows, state is a BYTE and this structure is
+ * only 3 bytes long. I don't think there are programs out there
+ * broken enough to rely on this :-)
+ */
+typedef struct
+{
+    WORD     state;   /* Current state */
+    HFONT16  hFont;   /* Button font (or 0 for system font) */
+    HANDLE   hImage;  /* Handle to the image or the icon */
+} BUTTONINFO;
+
+  /* Button state values */
+#define BUTTON_UNCHECKED       0x00
+#define BUTTON_CHECKED         0x01
+#define BUTTON_3STATE          0x02
+#define BUTTON_HIGHLIGHTED     0x04
+#define BUTTON_HASFOCUS        0x08
+#define BUTTON_NSTATES         0x0F
+  /* undocumented flags */
+#define BUTTON_BTNPRESSED      0x40
+#define BUTTON_UNKNOWN2        0x20
+#define BUTTON_UNKNOWN3        0x10
+
 static void PB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void CB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void GB_Paint( WND *wndPtr, HDC hDC, WORD action );
@@ -22,6 +45,8 @@
 static void OB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void BUTTON_CheckAutoRadioButton( WND *wndPtr );
 static void BUTTON_DrawPushButton( WND *wndPtr, HDC hDC, WORD action, BOOL pushedState);
+static LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+static LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
 
 #define MAX_BTN_TYPE  12
 
@@ -73,6 +98,21 @@
 static WORD checkBoxWidth = 0, checkBoxHeight = 0;
 
 
+/*********************************************************************
+ * button class descriptor
+ */
+const struct builtin_class_descr BUTTON_builtin_class =
+{
+    "Button",            /* name */
+    CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style  */
+    ButtonWndProcA,      /* procA */
+    ButtonWndProcW,      /* procW */
+    sizeof(BUTTONINFO),  /* extra */
+    IDC_ARROWA,          /* cursor */
+    0                    /* brush */
+};
+
+
 /***********************************************************************
  *           ButtonWndProc_locked
  * 
@@ -365,7 +405,7 @@
  * the passed HWND and calls the real window procedure (with a WND*
  * pointer pointing to the locked windowstructure).
  */
-LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+static LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
 {
     LRESULT res;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
@@ -380,7 +420,7 @@
 /***********************************************************************
  *           ButtonWndProcA
  */
-LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+static LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
 {
     LRESULT res;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
diff --git a/controls/combo.c b/controls/combo.c
index 3d09d52..b8860fe 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -17,7 +17,7 @@
 #include "spy.h"
 #include "user.h"
 #include "heap.h"
-#include "combo.h"
+#include "controls.h"
 #include "drive.h"
 #include "debugtools.h"
 #include "tweak.h"
@@ -57,6 +57,24 @@
 #define COMBO_EDITBUTTONSPACE()  ( (TWEAK_WineLook == WIN31_LOOK) ? 8 : 0 )
 #define EDIT_CONTROL_PADDING()   ( (TWEAK_WineLook == WIN31_LOOK) ? 0 : 1 )
 
+static LRESULT WINAPI ComboWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
+
+
+/*********************************************************************
+ * combo class descriptor
+ */
+const struct builtin_class_descr COMBO_builtin_class =
+{
+    "ComboBox",           /* name */
+    CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, /* style  */
+    ComboWndProcA,        /* procA */
+    NULL,                 /* procW (FIXME) */
+    sizeof(HEADCOMBO *),  /* extra */
+    IDC_ARROWA,           /* cursor */
+    0                     /* brush */
+};
+
+
 /***********************************************************************
  *           COMBO_Init
  *
@@ -2147,18 +2165,16 @@
 }
 
 /***********************************************************************
- *           ComboWndProc
+ *           ComboWndProcA
  *
  * This is just a wrapper for the real ComboWndProc which locks/unlocks
  * window structs.
  */
-LRESULT WINAPI ComboWndProc( HWND hwnd, UINT message,
-                             WPARAM wParam, LPARAM lParam )
+static LRESULT WINAPI ComboWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
     WND*	pWnd = WIN_FindWndPtr(hwnd);
     LRESULT retvalue = ComboWndProc_locked(pWnd,message,wParam,lParam);
 
-    
     WIN_ReleaseWndPtr(pWnd);
     return retvalue;
 }
diff --git a/controls/desktop.c b/controls/desktop.c
index a1b70c1..ca91c8b 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -8,14 +8,39 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "desktop.h"
 #include "windef.h"
 #include "wingdi.h"
 #include "heap.h"
 #include "user.h"
 #include "win.h"
+#include "controls.h"
 #include "wine/winuser16.h"
 
+typedef struct
+{
+    HBRUSH        hbrushPattern;
+    HBITMAP       hbitmapWallPaper;
+    SIZE          bitmapSize;
+    BOOL          fTileWallPaper;
+} DESKTOP;
+
+static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
+
+
+/*********************************************************************
+ * desktop class descriptor
+ */
+const struct builtin_class_descr DESKTOP_builtin_class =
+{
+    DESKTOP_CLASS_ATOM,   /* name */
+    CS_GLOBALCLASS,       /* style */
+    NULL,                 /* procA (winproc is Unicode only) */
+    DesktopWndProc,       /* procW */
+    sizeof(DESKTOP),      /* extra */
+    IDC_ARROWA,           /* cursor */
+    COLOR_BACKGROUND+1    /* brush */
+};
+
 
 /***********************************************************************
  *           DESKTOP_LoadBitmap
@@ -183,8 +208,7 @@
  * This is just a wrapper for the DesktopWndProc which does windows
  * locking and unlocking.
  */
-LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message,
-                               WPARAM wParam, LPARAM lParam )
+static LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     LRESULT retvalue = DesktopWndProc_locked(wndPtr,message,wParam,lParam);
diff --git a/controls/edit.c b/controls/edit.c
index f4482a2..51f0191 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -21,7 +21,7 @@
 #include "win.h"
 #include "wine/winbase16.h"
 #include "wine/winuser16.h"
-#include "combo.h"
+#include "controls.h"
 #include "local.h"
 #include "selectors.h"
 #include "debugtools.h"
@@ -253,6 +253,24 @@
 static LRESULT	EDIT_WM_VScroll(WND *wnd, EDITSTATE *es, INT action, INT pos);
 static void EDIT_UpdateText(WND *wnd, LPRECT rc, BOOL bErase);
 
+LRESULT WINAPI EditWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
+
+
+
+/*********************************************************************
+ * edit class descriptor
+ */
+const struct builtin_class_descr EDIT_builtin_class =
+{
+    "Edit",               /* name */
+    CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,   /* style */
+    EditWndProc,         /* procA */
+    NULL,                 /* procW (FIXME) */
+    sizeof(EDITSTATE *),  /* extra */
+    IDC_IBEAMA,           /* cursor */
+    0                     /* brush */
+};
+
 
 /*********************************************************************
  *
@@ -342,7 +360,7 @@
 
 /*********************************************************************
  *
- *	EditWndProc()
+ *	EditWndProc   (USER32.@)
  *
  *	The messages are in the order of the actual integer values
  *	(which can be found in include/windows.h)
@@ -353,8 +371,7 @@
  *	names).
  *
  */
-LRESULT WINAPI EditWndProc( HWND hwnd, UINT msg,
-                            WPARAM wParam, LPARAM lParam )
+LRESULT WINAPI EditWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
 {
 	WND *wnd = WIN_FindWndPtr(hwnd);
 	EDITSTATE *es = *(EDITSTATE **)((wnd)->wExtra);
diff --git a/controls/icontitle.c b/controls/icontitle.c
index edee6fb..85f9c5b 100644
--- a/controls/icontitle.c
+++ b/controls/icontitle.c
@@ -12,24 +12,30 @@
 #include "winuser.h"
 #include "wine/winuser16.h"
 #include "wine/unicode.h"
+#include "controls.h"
 #include "win.h"
 #include "heap.h"
 
 static BOOL bMultiLineTitle;
 static HFONT hIconTitleFont;
 
-/***********************************************************************
- *           ICONTITLE_Init
- */
-BOOL ICONTITLE_Init(void)
-{
-    LOGFONTA logFont;
+static LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
 
-    SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &logFont, 0 );
-    SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &bMultiLineTitle, 0 );
-    hIconTitleFont = CreateFontIndirectA( &logFont );
-    return (hIconTitleFont) ? TRUE : FALSE;
-}
+/*********************************************************************
+ * icon title class descriptor
+ */
+const struct builtin_class_descr ICONTITLE_builtin_class =
+{
+    ICONTITLE_CLASS_ATOM, /* name */
+    CS_GLOBALCLASS,       /* style */
+    NULL,                 /* procA (winproc is Unicode only) */
+    IconTitleWndProc,     /* procW */
+    0,                    /* extra */
+    IDC_ARROWA,           /* cursor */
+    0                     /* brush */
+};
+
+
 
 /***********************************************************************
  *           ICONTITLE_Create
@@ -194,6 +200,16 @@
 
     switch( msg )
     {
+        case WM_CREATE:
+            if (!hIconTitleFont)
+            {
+                LOGFONTA logFont;
+                SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &logFont, 0 );
+                SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &bMultiLineTitle, 0 );
+                hIconTitleFont = CreateFontIndirectA( &logFont );
+            }
+            retvalue = (hIconTitleFont) ? 0 : -1;
+            goto END;
 	case WM_NCHITTEST:
 	     retvalue = HTCAPTION;
              goto END;
@@ -243,7 +259,7 @@
 	     }
     }
 
-    retvalue = DefWindowProcA( hWnd, msg, wParam, lParam );
+    retvalue = DefWindowProcW( hWnd, msg, wParam, lParam );
 END:
     WIN_ReleaseWndPtr(wnd);
     return retvalue;
diff --git a/controls/listbox.c b/controls/listbox.c
index 0959e2a..e4e69c9 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -18,7 +18,7 @@
 #include "spy.h"
 #include "selectors.h"
 #include "win.h"
-#include "combo.h"
+#include "controls.h"
 #include "debugtools.h"
 #include "tweak.h"
 
@@ -111,6 +111,39 @@
 
 static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE;
 
+static LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
+static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
+
+
+/*********************************************************************
+ * listbox class descriptor
+ */
+const struct builtin_class_descr LISTBOX_builtin_class =
+{
+    "ListBox",            /* name */
+    CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,  /* style */
+    ListBoxWndProcA,      /* procA */
+    NULL,                 /* procW (FIXME) */
+    sizeof(LB_DESCR *),   /* extra */
+    IDC_ARROWA,           /* cursor */
+    0                     /* brush */
+};
+
+
+/*********************************************************************
+ * combolbox class descriptor
+ */
+const struct builtin_class_descr COMBOLBOX_builtin_class =
+{
+    "ComboLBox",          /* name */
+    CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS,  /* style */
+    ComboLBWndProcA,      /* procA */
+    NULL,                 /* procW (FIXME) */
+    sizeof(LB_DESCR *),   /* extra */
+    IDC_ARROWA,           /* cursor */
+    0                     /* brush */
+};
+
 
 /***********************************************************************
  *           LISTBOX_Dump
@@ -2855,13 +2888,12 @@
 }
 
 /***********************************************************************
- *           ListBoxWndProc
+ *           ListBoxWndProcA
  *
  * This is just a wrapper for the real wndproc, it only does window locking
  * and unlocking.
  */
-LRESULT WINAPI ListBoxWndProc( HWND hwnd, UINT msg,
-                               WPARAM wParam, LPARAM lParam )
+static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
 {
     WND*	wndPtr = WIN_FindWndPtr( hwnd );
     LRESULT	res = ListBoxWndProc_locked(wndPtr,msg,wParam,lParam);
@@ -2968,7 +3000,7 @@
 		       /*
 			* If we are in Win3.1 look, go with the default behavior.
 			*/
-		       return ListBoxWndProc( hwnd, msg, wParam, lParam );
+		       return ListBoxWndProcA( hwnd, msg, wParam, lParam );
 		     }
   	        case WM_LBUTTONUP:
 		     if (TWEAK_WineLook > WIN31_LOOK)
@@ -3029,7 +3061,7 @@
 
 		case LB_SETCURSEL16:
 		case LB_SETCURSEL:
-		     lRet = ListBoxWndProc( hwnd, msg, wParam, lParam );
+		     lRet = ListBoxWndProcA( hwnd, msg, wParam, lParam );
 		     lRet =(lRet == LB_ERR) ? lRet : descr->selected_item; 
 		     return lRet;
 		case WM_NCDESTROY:
@@ -3038,7 +3070,7 @@
 		     /* fall through */
 
 	        default:
-                    return ListBoxWndProc( hwnd, msg, wParam, lParam );
+                    return ListBoxWndProcA( hwnd, msg, wParam, lParam );
 	    }
         }
         lRet = DefWindowProcA( hwnd, msg, wParam, lParam );
@@ -3057,7 +3089,7 @@
  * This is just a wrapper for the real wndproc, it only does window locking
  * and unlocking.
  */
-LRESULT WINAPI ComboLBWndProc( HWND hwnd, UINT msg,
+LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg,
                                WPARAM wParam, LPARAM lParam )
 {
     WND *wnd = WIN_FindWndPtr( hwnd );
diff --git a/controls/menu.c b/controls/menu.c
index 0b10c9a..f825a38 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -26,7 +26,7 @@
 #include "win.h"
 #include "task.h"
 #include "heap.h"
-#include "menu.h"
+#include "controls.h"
 #include "nonclient.h"
 #include "user.h"
 #include "message.h"
@@ -176,6 +176,23 @@
   /* Flag set by EndMenu() to force an exit from menu tracking */
 static BOOL fEndMenu = FALSE;
 
+static LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
+
+
+/*********************************************************************
+ * menu class descriptor
+ */
+const struct builtin_class_descr MENU_builtin_class =
+{
+    POPUPMENU_CLASS_ATOM,          /* name */
+    CS_GLOBALCLASS | CS_SAVEBITS,  /* style */
+    NULL,                          /* procA (winproc is Unicode only) */
+    PopupMenuWndProc,              /* procW */
+    sizeof(HMENU),                 /* extra */
+    IDC_ARROWA,                    /* cursor */
+    COLOR_MENU+1                   /* brush */
+};
+
 
 /***********************************************************************
  *           debug_print_menuitem
@@ -3163,12 +3180,8 @@
  *
  * NOTE: Windows has totally different (and undocumented) popup wndproc.
  */
-LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam,
-                                 LPARAM lParam )
-{    
-    WND* wndPtr = WIN_FindWndPtr(hwnd);
-    LRESULT retvalue;
-
+static LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
     TRACE("hwnd=0x%04x msg=0x%04x wp=0x%04x lp=0x%08lx\n",
     hwnd, message, wParam, lParam);
 
@@ -3176,15 +3189,13 @@
     {
     case WM_CREATE:
 	{
-	    CREATESTRUCTA *cs = (CREATESTRUCTA*)lParam;
-	    SetWindowLongA( hwnd, 0, (LONG)cs->lpCreateParams );
-            retvalue = 0;
-            goto END;
+	    CREATESTRUCTW *cs = (CREATESTRUCTW*)lParam;
+	    SetWindowLongW( hwnd, 0, (LONG)cs->lpCreateParams );
+            return 0;
 	}
 
     case WM_MOUSEACTIVATE:  /* We don't want to be activated */
-        retvalue = MA_NOACTIVATE;
-        goto END;
+        return MA_NOACTIVATE;
 
     case WM_PAINT:
 	{
@@ -3193,12 +3204,10 @@
 	    MENU_DrawPopupMenu( hwnd, ps.hdc,
                                 (HMENU)GetWindowLongA( hwnd, 0 ) );
 	    EndPaint( hwnd, &ps );
-            retvalue = 0;
-            goto END;
+            return 0;
 	}
     case WM_ERASEBKGND:
-        retvalue = 1;
-        goto END;
+        return 1;
 
     case WM_DESTROY:
 
@@ -3224,31 +3233,23 @@
 
 	if( wParam )
 	{
-	    if( !(*(HMENU*)wndPtr->wExtra) )
-		ERR("no menu to display\n");
+            if (!GetWindowLongW( hwnd, 0 )) ERR("no menu to display\n");
 	}
 	else
-	    *(HMENU*)wndPtr->wExtra = 0;
+            SetWindowLongW( hwnd, 0, 0 );
 	break;
 
     case MM_SETMENUHANDLE:
-
-	*(HMENU*)wndPtr->wExtra = (HMENU)wParam;
+        SetWindowLongW( hwnd, 0, wParam );
         break;
 
     case MM_GETMENUHANDLE:
-
-        retvalue = *(HMENU*)wndPtr->wExtra;
-        goto END;
+        return GetWindowLongW( hwnd, 0 );
 
     default:
-        retvalue = DefWindowProcA( hwnd, message, wParam, lParam );
-        goto END;
+        return DefWindowProcW( hwnd, message, wParam, lParam );
     }
-    retvalue = 0;
-END:
-    WIN_ReleaseWndPtr(wndPtr);
-    return retvalue;
+    return 0;
 }
 
 
diff --git a/controls/scroll.c b/controls/scroll.c
index 102ccfd..ec7049f 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -8,7 +8,7 @@
 #include "windef.h"
 #include "wingdi.h"
 #include "wine/winuser16.h"
-#include "scroll.h"
+#include "controls.h"
 #include "heap.h"
 #include "win.h"
 #include "debugtools.h"
@@ -17,19 +17,28 @@
 
 DEFAULT_DEBUG_CHANNEL(scroll);
 
+typedef struct
+{
+    INT   CurVal;   /* Current scroll-bar value */
+    INT   MinVal;   /* Minimum scroll-bar value */
+    INT   MaxVal;   /* Maximum scroll-bar value */
+    INT   Page;     /* Page size of scroll bar (Win32) */
+    UINT  flags;    /* EnableScrollBar flags */
+} SCROLLBAR_INFO;
 
-static HBITMAP hUpArrow = 0;
-static HBITMAP hDnArrow = 0;
-static HBITMAP hLfArrow = 0;
-static HBITMAP hRgArrow = 0;
-static HBITMAP hUpArrowD = 0;
-static HBITMAP hDnArrowD = 0;
-static HBITMAP hLfArrowD = 0;
-static HBITMAP hRgArrowD = 0;
-static HBITMAP hUpArrowI = 0;
-static HBITMAP hDnArrowI = 0;
-static HBITMAP hLfArrowI = 0;
-static HBITMAP hRgArrowI = 0;
+
+static HBITMAP hUpArrow;
+static HBITMAP hDnArrow;
+static HBITMAP hLfArrow;
+static HBITMAP hRgArrow;
+static HBITMAP hUpArrowD;
+static HBITMAP hDnArrowD;
+static HBITMAP hLfArrowD;
+static HBITMAP hRgArrowD;
+static HBITMAP hUpArrowI;
+static HBITMAP hDnArrowI;
+static HBITMAP hLfArrowI;
+static HBITMAP hRgArrowI;
 
 #define TOP_ARROW(flags,pressed) \
    (((flags)&ESB_DISABLE_UP) ? hUpArrowI : ((pressed) ? hUpArrowD:hUpArrow))
@@ -98,6 +107,22 @@
 				    INT thumbSize, INT thumbPos,
 				    UINT flags, BOOL vertical,
 				    BOOL top_selected, BOOL bottom_selected );
+static LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
+
+
+/*********************************************************************
+ * scrollbar class descriptor
+ */
+const struct builtin_class_descr SCROLL_builtin_class =
+{
+    "ScrollBar",            /* name */
+    CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style  */
+    NULL,                   /* procA (winproc is Unicode only) */
+    ScrollBarWndProc,       /* procW */
+    sizeof(SCROLLBAR_INFO), /* extra */
+    IDC_ARROWA,             /* cursor */
+    0                       /* brush */
+};
 
 
 /***********************************************************************
@@ -878,7 +903,7 @@
         WIN_ReleaseWndPtr(wndPtr);
         return;
     }
-    SendMessageA( GetParent(hwnd),
+    SendMessageW( GetParent(hwnd),
                     (wndPtr->dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
                     msg, hwnd );
     WIN_ReleaseWndPtr(wndPtr);
@@ -1109,20 +1134,18 @@
 /***********************************************************************
  *           ScrollBarWndProc
  */
-LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT message, WPARAM wParam,
-                                 LPARAM lParam )
+static LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
     switch(message)
     {
     case WM_CREATE:
         {
-	    CREATESTRUCTA *lpCreat = (CREATESTRUCTA *)lParam;
+            CREATESTRUCTW *lpCreat = (CREATESTRUCTW *)lParam;
             if (lpCreat->style & SBS_SIZEBOX)
             {
                 FIXME("Unimplemented style SBS_SIZEBOX.\n" );
                 return 0;
             }
-            
 	    if (lpCreat->style & SBS_VERT)
             {
                 if (lpCreat->style & SBS_LEFTALIGN)
@@ -1285,7 +1308,7 @@
         if (message >= WM_USER)
             WARN("unknown msg %04x wp=%04x lp=%08lx\n",
 			 message, wParam, lParam );
-        return DefWindowProcA( hwnd, message, wParam, lParam );
+        return DefWindowProcW( hwnd, message, wParam, lParam );
     }
     return 0;
 }
diff --git a/controls/static.c b/controls/static.c
index f27b30b..951e4ad 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -10,7 +10,7 @@
 #include "wine/winuser16.h"
 #include "win.h"
 #include "cursoricon.h"
-#include "static.h"
+#include "controls.h"
 #include "heap.h"
 #include "debugtools.h"
 #include "tweak.h"
@@ -23,9 +23,16 @@
 static void STATIC_PaintIconfn( WND *wndPtr, HDC hdc );
 static void STATIC_PaintBitmapfn( WND *wndPtr, HDC hdc );
 static void STATIC_PaintEtchedfn( WND *wndPtr, HDC hdc );
+static LRESULT WINAPI StaticWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
 
 static COLORREF color_windowframe, color_background, color_window;
 
+typedef struct
+{
+    HFONT16  hFont;   /* Control font (or 0 for system font) */
+    WORD     dummy;   /* Don't know what MS-Windows puts in there */
+    HICON16  hIcon;   /* Icon handle for SS_ICON controls */
+} STATICINFO;
 
 typedef void (*pfPaint)( WND *, HDC );
 
@@ -53,6 +60,21 @@
 };
 
 
+/*********************************************************************
+ * static class descriptor
+ */
+const struct builtin_class_descr STATIC_builtin_class =
+{
+    "Static",            /* name */
+    CS_GLOBALCLASS | CS_DBLCLKS | CS_PARENTDC, /* style  */
+    StaticWndProcA,      /* procA */
+    NULL,                /* procW (FIXME) */
+    sizeof(STATICINFO),  /* extra */
+    IDC_ARROWA,          /* cursor */
+    0                    /* brush */
+};
+
+
 /***********************************************************************
  *           STATIC_SetIcon
  *
@@ -135,10 +157,9 @@
 
 
 /***********************************************************************
- *           StaticWndProc
+ *           StaticWndProcA
  */
-LRESULT WINAPI StaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
-                              LPARAM lParam )
+static LRESULT WINAPI StaticWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
 {
     LRESULT lResult = 0;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
diff --git a/controls/widgets.c b/controls/widgets.c
deleted file mode 100644
index bc7ab1d..0000000
--- a/controls/widgets.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Windows widgets (built-in window classes)
- *
- * Copyright 1993 Alexandre Julliard
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "win.h"
-#include "button.h"
-#include "combo.h"
-#include "desktop.h"
-#include "gdi.h"
-#include "heap.h"
-#include "mdi.h"
-#include "menu.h"
-#include "scroll.h"
-#include "static.h"
-#include "wine/unicode.h"
-
-struct builtin_class
-{
-    LPCSTR  name;
-    UINT    style;
-    WNDPROC procA;
-    WNDPROC procW;
-    INT     extra;
-    LPCSTR  cursor;
-    HBRUSH  brush;
-};
-
-/* Under NT all builtin classes have both ASCII and Unicode window
- * procedures except ScrollBar, PopupMenu, Desktop, WinSwitch and
- * IconTitle which are Unicode-only.
- */
-static const struct builtin_class classes[] =
-{
-    { "Button", CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-      ButtonWndProcA, ButtonWndProcW, sizeof(BUTTONINFO), IDC_ARROWA, 0 },
-    { "Edit", CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,
-      EditWndProc, NULL, sizeof(void *), IDC_IBEAMA, 0 },
-    { "ListBox", CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/,
-      ListBoxWndProc, NULL, sizeof(void *), IDC_ARROWA, 0 },
-    { "ComboBox", CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS,
-      ComboWndProc, NULL, sizeof(void *), IDC_ARROWA, 0 },
-    { "ComboLBox", CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS,
-      ComboLBWndProc, NULL, sizeof(void *), IDC_ARROWA, 0 },
-    { "Static", CS_GLOBALCLASS | CS_DBLCLKS | CS_PARENTDC,
-      StaticWndProc, NULL, sizeof(STATICINFO), IDC_ARROWA, 0 },
-    { "ScrollBar", CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-      ScrollBarWndProc, NULL, sizeof(SCROLLBAR_INFO), IDC_ARROWA, 0 },
-    { "MDIClient", CS_GLOBALCLASS,
-      MDIClientWndProc, NULL, sizeof(MDICLIENTINFO), IDC_ARROWA, STOCK_LTGRAY_BRUSH },
-    { POPUPMENU_CLASS_NAME, CS_GLOBALCLASS | CS_SAVEBITS,
-      PopupMenuWndProc, NULL, sizeof(HMENU), IDC_ARROWA, COLOR_MENU+1 },
-    { DESKTOP_CLASS_NAME, CS_GLOBALCLASS,
-      DesktopWndProc, NULL, sizeof(DESKTOP), IDC_ARROWA, COLOR_BACKGROUND+1 },
-    { DIALOG_CLASS_NAME, CS_GLOBALCLASS | CS_SAVEBITS,
-      DefDlgProcA, DefDlgProcW, DLGWINDOWEXTRA, IDC_ARROWA, 0 },
-    { ICONTITLE_CLASS_NAME, CS_GLOBALCLASS,
-      IconTitleWndProc, NULL, 0, IDC_ARROWA, 0 }
-};
-
-
-/***********************************************************************
- *           WIDGETS_Init
- * 
- * Initialize the built-in window classes.
- */
-BOOL WIDGETS_Init(void)
-{
-    const struct builtin_class *cls = classes;
-    int i;
-
-    for (i = 0; i < sizeof(classes)/sizeof(classes[0]); i++, cls++)
-    {
-        if (!CLASS_RegisterBuiltinClass( cls->name, cls->style, cls->extra, cls->cursor,
-                                         cls->brush, cls->procA, cls->procW ))
-            return FALSE;
-    }
-    return TRUE;
-}
diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h
index 615a943..2e27389 100644
--- a/dlls/ttydrv/ttydrv.h
+++ b/dlls/ttydrv/ttydrv.h
@@ -143,7 +143,7 @@
 
 extern void TTYDRV_WND_Initialize(struct tagWND *wndPtr);
 extern void TTYDRV_WND_Finalize(struct tagWND *wndPtr);
-extern BOOL TTYDRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, BOOL bUnicode);
+extern BOOL TTYDRV_WND_CreateDesktopWindow(struct tagWND *wndPtr);
 extern BOOL TTYDRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode);
 extern BOOL TTYDRV_WND_DestroyWindow(struct tagWND *pWnd);
 extern struct tagWND *TTYDRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index 5d0eebb..eed7a96 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -88,12 +88,12 @@
 /**********************************************************************
  *		TTYDRV_WND_CreateDesktopWindow
  */
-BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr, BOOL bUnicode)
+BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr)
 {
   TTYDRV_WND_DATA *pWndDriverData =
     (TTYDRV_WND_DATA *) wndPtr->pDriverData;
 
-  TRACE("(%p, %d)\n", wndPtr, bUnicode);
+  TRACE("(%p)\n", wndPtr);
 
   if(!pWndDriverData) { ERR("WND never initialized\n"); return FALSE; }
 
diff --git a/dlls/user/controls.h b/dlls/user/controls.h
new file mode 100644
index 0000000..2aa8e83
--- /dev/null
+++ b/dlls/user/controls.h
@@ -0,0 +1,146 @@
+/*
+ * User controls definitions
+ *
+ * Copyright 2000 Alexandre Julliard
+ */
+
+#ifndef __WINE_CONTROLS_H
+#define __WINE_CONTROLS_H
+
+#include "winuser.h"
+#include "winproc.h"
+
+struct tagWND;
+
+/* Built-in class names (see _Undocumented_Windows_ p.418) */
+#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768)  /* PopupMenu */
+#define DESKTOP_CLASS_ATOM   MAKEINTATOM(32769)  /* Desktop */
+#define DIALOG_CLASS_ATOM    MAKEINTATOM(32770)  /* Dialog */
+#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771)  /* WinSwitch */
+#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772)  /* IconTitle */
+
+/* Built-in class descriptor */
+struct builtin_class_descr
+{
+    LPCSTR  name;    /* class name */
+    UINT    style;   /* class style */
+    WNDPROC procA;   /* ASCII window procedure */
+    WNDPROC procW;   /* Unicode window procedure */
+    INT     extra;   /* window extra bytes */
+    LPCSTR  cursor;  /* cursor name */
+    HBRUSH  brush;   /* brush or system color */
+};
+
+
+/* desktop */
+extern BOOL DESKTOP_SetPattern( LPCSTR pattern );
+
+/* icon title */
+extern HWND ICONTITLE_Create( struct tagWND * );
+
+/* MDI client */
+extern HWND MDI_CreateMDIWindowA(LPCSTR,LPCSTR,DWORD,INT,INT,INT,INT,HWND,HINSTANCE,LPARAM);
+extern HWND MDI_CreateMDIWindowW(LPCWSTR,LPCWSTR,DWORD,INT,INT,INT,INT,HWND,HINSTANCE,LPARAM);
+
+/* menu controls */
+extern BOOL MENU_Init(void);
+extern BOOL MENU_IsMenuActive(void);
+extern HMENU MENU_GetSysMenu(HWND hWndOwner, HMENU hSysPopup);
+extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth,
+                                     INT orgX, INT orgY );
+extern BOOL MENU_PatchResidentPopup( HQUEUE16, struct tagWND* );
+extern void MENU_TrackMouseMenuBar( struct tagWND *wnd, INT ht, POINT pt );
+extern void MENU_TrackKbdMenuBar( struct tagWND *wnd, UINT wParam, INT vkey );
+extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
+                                HWND hwnd, BOOL suppress_draw );
+extern UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget );
+
+/* scrollbar */
+extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, BOOL arrows, BOOL interior );
+extern void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt );
+extern INT SCROLL_SetNCSbState( struct tagWND *wndPtr, int vMin, int vMax, int vPos,
+                                int hMin, int hMax, int hPos );
+
+/* combo box */
+
+#define ID_CB_LISTBOX           1000
+#define ID_CB_EDIT              1001
+
+/* internal flags */
+#define CBF_DROPPED             0x0001
+#define CBF_BUTTONDOWN          0x0002
+#define CBF_NOROLLUP            0x0004
+#define CBF_MEASUREITEM         0x0008
+#define CBF_FOCUSED             0x0010
+#define CBF_CAPTURE             0x0020
+#define CBF_EDIT                0x0040
+#define CBF_NORESIZE            0x0080
+#define CBF_NOTIFY              0x0100
+#define CBF_NOREDRAW            0x0200
+#define CBF_SELCHANGE           0x0400
+#define CBF_NOEDITNOTIFY        0x1000
+#define CBF_NOLBSELECT          0x2000  /* do not change current selection */
+#define CBF_EUI                 0x8000
+
+/* combo state struct */
+typedef struct
+{
+   struct tagWND *self;
+   HWND           owner;
+   UINT           dwStyle;
+   HWND           hWndEdit;
+   HWND           hWndLBox;
+   UINT           wState;
+   HFONT          hFont;
+   RECT           textRect;
+   RECT           buttonRect;
+   RECT           droppedRect;
+   INT            droppedIndex;
+   INT            fixedOwnerDrawHeight;
+   INT            droppedWidth;   /* last two are not used unless set */
+   INT            editHeight;     /* explicitly */
+} HEADCOMBO,*LPHEADCOMBO;
+
+/* Note, that CBS_DROPDOWNLIST style is actually (CBS_SIMPLE | CBS_DROPDOWN) */
+#define CB_GETTYPE( lphc )    ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
+#define CB_DISABLED( lphc )   ((lphc)->self->dwStyle & WS_DISABLED)
+#define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
+#define CB_HASSTRINGS( lphc ) ((lphc)->dwStyle & CBS_HASSTRINGS)
+#define CB_HWND( lphc )       ((lphc)->self->hwndSelf)
+
+extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL );
+extern LRESULT COMBO_Directory( LPHEADCOMBO, UINT, LPSTR, BOOL );
+
+
+/* Dialog info structure.
+ * This structure is stored into the window extra bytes (cbWndExtra).
+ * sizeof(DIALOGINFO) must be <= DLGWINDOWEXTRA (=30).
+ */
+#include "pshpack1.h"
+
+typedef struct
+{
+    INT         msgResult;   /* 00 Last message result */
+    HWINDOWPROC dlgProc;     /* 04 Dialog procedure */
+    LONG        userInfo;    /* 08 User information (for DWL_USER) */
+
+    /* implementation-dependent part */
+
+    HWND16      hwndFocus;   /* 0c Current control with focus */
+    HFONT16     hUserFont;   /* 0e Dialog font */
+    HMENU16     hMenu;       /* 10 Dialog menu */
+    WORD        xBaseUnit;   /* 12 Dialog units (depends on the font) */
+    WORD        yBaseUnit;   /* 14 */
+    INT         idResult;    /* 16 EndDialog() result / default pushbutton ID */
+    UINT16      flags;       /* 1a EndDialog() called for this dialog */
+    HGLOBAL16   hDialogHeap; /* 1c */
+} DIALOGINFO;
+
+#include "poppack.h"
+
+#define DF_END  0x0001
+#define DF_OWNERENABLED 0x0002
+
+extern BOOL DIALOG_Init(void);
+
+#endif  /* __WINE_CONTROLS_H */
diff --git a/dlls/user/resources/user32.rc b/dlls/user/resources/user32.rc
index eabbdf2..60b0d33 100644
--- a/dlls/user/resources/user32.rc
+++ b/dlls/user/resources/user32.rc
@@ -7,7 +7,9 @@
 #include "winuser.h"
 #include "winnls.h"
 #include "dlgs.h"
-#include "mdi.h"
+
+#define MDI_IDC_LISTBOX         100
+#define MDI_IDS_MOREWINDOWS     13
 
 /*
  * Everything that does not depend on language,
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 09b72b7..af7b2a9 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -9,12 +9,11 @@
 #include "wine/winbase16.h"
 #include "wine/winuser16.h"
 
+#include "controls.h"
 #include "dce.h"
-#include "dialog.h"
 #include "global.h"
 #include "input.h"
 #include "keyboard.h"
-#include "menu.h"
 #include "message.h"
 #include "queue.h"
 #include "spy.h"
@@ -95,6 +94,41 @@
 
 
 /***********************************************************************
+ *           controls_init
+ *
+ * Register the classes for the builtin controls
+ */
+static void controls_init(void)
+{
+    extern const struct builtin_class_descr BUTTON_builtin_class;
+    extern const struct builtin_class_descr COMBO_builtin_class;
+    extern const struct builtin_class_descr COMBOLBOX_builtin_class;
+    extern const struct builtin_class_descr DIALOG_builtin_class;
+    extern const struct builtin_class_descr DESKTOP_builtin_class;
+    extern const struct builtin_class_descr EDIT_builtin_class;
+    extern const struct builtin_class_descr ICONTITLE_builtin_class;
+    extern const struct builtin_class_descr LISTBOX_builtin_class;
+    extern const struct builtin_class_descr MDICLIENT_builtin_class;
+    extern const struct builtin_class_descr MENU_builtin_class;
+    extern const struct builtin_class_descr SCROLL_builtin_class;
+    extern const struct builtin_class_descr STATIC_builtin_class;
+
+    CLASS_RegisterBuiltinClass( &BUTTON_builtin_class );
+    CLASS_RegisterBuiltinClass( &COMBO_builtin_class );
+    CLASS_RegisterBuiltinClass( &COMBOLBOX_builtin_class );
+    CLASS_RegisterBuiltinClass( &DIALOG_builtin_class );
+    CLASS_RegisterBuiltinClass( &DESKTOP_builtin_class );
+    CLASS_RegisterBuiltinClass( &EDIT_builtin_class );
+    CLASS_RegisterBuiltinClass( &ICONTITLE_builtin_class );
+    CLASS_RegisterBuiltinClass( &LISTBOX_builtin_class );
+    CLASS_RegisterBuiltinClass( &MDICLIENT_builtin_class );
+    CLASS_RegisterBuiltinClass( &MENU_builtin_class );
+    CLASS_RegisterBuiltinClass( &SCROLL_builtin_class );
+    CLASS_RegisterBuiltinClass( &STATIC_builtin_class );
+}
+
+
+/***********************************************************************
  *           palette_init
  *
  * Patch the function pointers in GDI for SelectPalette and RealizePalette
@@ -149,7 +183,7 @@
     if (!WINPROC_Init()) return FALSE;
 
     /* Initialize built-in window classes */
-    if (!WIDGETS_Init()) return FALSE;
+    controls_init();
 
     /* Initialize dialog manager */
     if (!DIALOG_Init()) return FALSE;
diff --git a/include/button.h b/include/button.h
deleted file mode 100644
index 09d9590..0000000
--- a/include/button.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Button-class extra info
- *
- * Copyright 1994 Alexandre Julliard
- */
-
-#ifndef __WINE_BUTTON_H
-#define __WINE_BUTTON_H
-
-#include "windef.h"
-#include "wingdi.h"
-
-  /* Extra info for BUTTON windows */
-  /* Note: under MS-Windows, state is a BYTE and this structure is */
-  /* only 3 bytes long. I don't think there are programs out there */
-  /* broken enough to rely on this :-) */
-typedef struct
-{
-    WORD     state;   /* Current state */
-    HFONT16  hFont;   /* Button font (or 0 for system font) */
-    HANDLE   hImage;  /* Handle to the image or the icon */
-} BUTTONINFO;
-
-  /* Button state values */
-#define BUTTON_UNCHECKED       0x00
-#define BUTTON_CHECKED         0x01
-#define BUTTON_3STATE          0x02
-#define BUTTON_HIGHLIGHTED     0x04
-#define BUTTON_HASFOCUS        0x08
-#define BUTTON_NSTATES         0x0F
-  /* undocumented flags */
-#define BUTTON_BTNPRESSED      0x40
-#define BUTTON_UNKNOWN2        0x20
-#define BUTTON_UNKNOWN3        0x10
-
-#define BUTTON_STATE(hwnd)     ((WIN_FindWndPtr(hwnd))->wExtra[0])
-
-extern LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
-extern LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
-
-#endif  /* __WINE_BUTTON_H */
diff --git a/include/combo.h b/include/combo.h
deleted file mode 100644
index 29ac1af..0000000
--- a/include/combo.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Combo box definitions
- */
-
-#ifndef __WINE_COMBO_H
-#define __WINE_COMBO_H
-
-#include "windef.h"
-
-struct tagWND;
-
-#define ID_CB_LISTBOX           1000
-#define ID_CB_EDIT              1001
-
-/* Internal flags */
-
-#define CBF_DROPPED             0x0001
-#define CBF_BUTTONDOWN          0x0002
-#define CBF_NOROLLUP            0x0004
-#define CBF_MEASUREITEM		0x0008
-#define CBF_FOCUSED             0x0010
-#define CBF_CAPTURE             0x0020
-#define CBF_EDIT                0x0040
-#define CBF_NORESIZE		0x0080
-#define CBF_NOTIFY		0x0100
-#define CBF_NOREDRAW            0x0200
-#define CBF_SELCHANGE		0x0400
-#define CBF_NOEDITNOTIFY        0x1000
-#define CBF_NOLBSELECT          0x2000  /* do not change current selection */
-#define CBF_EUI                 0x8000
-
-/* Combo state struct */
-
-typedef struct
-{
-   struct tagWND *self;
-   HWND  	owner;
-   UINT  	dwStyle;
-   HWND  	hWndEdit;
-   HWND  	hWndLBox;
-   UINT  	wState;
-   HFONT 	hFont;
-   RECT         textRect;
-   RECT         buttonRect;
-   RECT         droppedRect;
-   INT          droppedIndex;
-   INT          fixedOwnerDrawHeight;
-   INT   	droppedWidth;		/* last two are not used unless set */
-   INT   	editHeight;		/* explicitly */
-} HEADCOMBO,*LPHEADCOMBO;
-
-/*
- * Note, that CBS_DROPDOWNLIST style is actually (CBS_SIMPLE | CBS_DROPDOWN)!
- */
-
-#define CB_GETTYPE( lphc )    ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
-#define CB_DISABLED( lphc )   ((lphc)->self->dwStyle & WS_DISABLED)
-#define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
-#define CB_HASSTRINGS( lphc ) ((lphc)->dwStyle & CBS_HASSTRINGS)
-#define CB_HWND( lphc )       ((lphc)->self->hwndSelf)
-
-LRESULT WINAPI ComboWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
-
-BOOL 	COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL );
-LRESULT COMBO_Directory( LPHEADCOMBO, UINT, LPSTR, BOOL );
-
-#endif /* __WINE_COMBO_H */
-
diff --git a/include/desktop.h b/include/desktop.h
deleted file mode 100644
index 9e130ab..0000000
--- a/include/desktop.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Desktop window definitions.
- *
- * Copyright 1994 Alexandre Julliard
- */
-
-#ifndef __WINE_DESKTOP_H
-#define __WINE_DESKTOP_H
-
-#include "windef.h"
-
-typedef struct tagDESKTOP
-{
-  HBRUSH                hbrushPattern;
-  HBITMAP               hbitmapWallPaper;
-  SIZE                  bitmapSize;
-  BOOL                  fTileWallPaper;
-} DESKTOP;
-
-extern BOOL DESKTOP_SetPattern( LPCSTR pattern );
-extern LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message,
-                                      WPARAM wParam, LPARAM lParam );
-
-#endif  /* __WINE_DESKTOP_H */
diff --git a/include/dialog.h b/include/dialog.h
deleted file mode 100644
index bc92be9..0000000
--- a/include/dialog.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Dialog definitions
- *
- * Copyright 1993 Alexandre Julliard
- */
-
-#ifndef __WINE_DIALOG_H
-#define __WINE_DIALOG_H
-
-#include "winproc.h"
-
-  /* Dialog info structure.
-   * This structure is stored into the window extra bytes (cbWndExtra).
-   * sizeof(DIALOGINFO) must be <= DLGWINDOWEXTRA (=30).
-   */
-
-#include "pshpack1.h"
-
-typedef struct
-{
-    INT       msgResult;   /* +00 Last message result */
-    HWINDOWPROC dlgProc;     /* +04 Dialog procedure */
-    LONG        userInfo;    /* +08 User information (for DWL_USER) */
-
-    /* implementation-dependent part */
-
-    HWND16      hwndFocus;   /* Current control with focus */
-    HFONT16     hUserFont;   /* Dialog font */
-    HMENU16     hMenu;       /* Dialog menu */
-    UINT16      xBaseUnit;   /* Dialog units (depends on the font) */
-    UINT16      yBaseUnit;
-    INT	idResult;    /* EndDialog() result / default pushbutton ID */
-    UINT16      flags;       /* EndDialog() called for this dialog */
-    HGLOBAL16   hDialogHeap;
-} DIALOGINFO;
-
-#include "poppack.h"
-
-#define DF_END  0x0001
-#define DF_OWNERENABLED 0x0002
-
-extern BOOL DIALOG_Init(void);
-
-#endif  /* __WINE_DIALOG_H */
diff --git a/include/mdi.h b/include/mdi.h
deleted file mode 100644
index ee501df..0000000
--- a/include/mdi.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* MDI.H
- *
- * Copyright 1994, Bob Amstadt
- *           1995  Alex Korobka
- *
- * MDI structure definitions.
- */
-
-#ifndef __WINE_MDI_H
-#define __WINE_MDI_H
-
-#include "windef.h"
-
-#define MDI_MAXLISTLENGTH	0x40
-#define MDI_MAXTITLELENGTH	0xA1
-
-#define MDI_NOFRAMEREPAINT	0
-#define MDI_REPAINTFRAMENOW	1
-#define MDI_REPAINTFRAME	2
-
-#define WM_MDICALCCHILDSCROLL   0x10AC /* this is exactly what Windows uses */
-
-/* "More Windows..." definitions */
-#define MDI_MOREWINDOWSLIMIT    9       /* after this number of windows, a "More Windows..." 
-                                           option will appear under the Windows menu */
-#define MDI_IDC_LISTBOX         100
-#define MDI_IDS_MOREWINDOWS     13
-
-extern LRESULT WINAPI MDIClientWndProc( HWND hwnd, UINT message, 
-                                        WPARAM wParam, LPARAM lParam );
-
-typedef struct 
-{
-    UINT      nActiveChildren;
-    HWND      hwndChildMaximized;
-    HWND      hwndActiveChild;
-    HMENU     hWindowMenu;
-    UINT      idFirstChild;
-    LPWSTR    frameTitle;
-    UINT      nTotalCreated;
-    UINT      mdiFlags;
-    UINT      sbRecalc;   /* SB_xxx flags for scrollbar fixup */
-    HWND      self;
-} MDICLIENTINFO;
-
-extern HWND  MDI_CreateMDIWindowA(LPCSTR,LPCSTR,DWORD,INT,INT,
-                                INT,INT,HWND,HINSTANCE,LPARAM);
-extern HWND  MDI_CreateMDIWindowW(LPCWSTR,LPCWSTR,DWORD,INT,INT,
-                                INT,INT,HWND,HINSTANCE,LPARAM);
-#endif /* __WINE_MDI_H */
-
diff --git a/include/menu.h b/include/menu.h
deleted file mode 100644
index 855a897..0000000
--- a/include/menu.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Menu definitions
- */
-
-#ifndef __WINE_MENU_H
-#define __WINE_MENU_H
-
-#include "windef.h"
-
-struct tagWND;
-
-LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam,
-                                 LPARAM lParam );
-
-extern BOOL MENU_Init(void);
-extern BOOL MENU_IsMenuActive(void);
-extern HMENU MENU_GetSysMenu(HWND hWndOwner, HMENU hSysPopup);
-extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth,
-                                     INT orgX, INT orgY );
-extern BOOL MENU_PatchResidentPopup( HQUEUE16, struct tagWND* );
-extern void MENU_TrackMouseMenuBar( struct tagWND *wnd, INT ht, POINT pt );
-extern void MENU_TrackKbdMenuBar( struct tagWND *wnd, UINT wParam, INT vkey );
-extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
-                                HWND hwnd, BOOL suppress_draw );
-extern UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget );
-
-#endif /* __WINE_MENU_H */
diff --git a/include/scroll.h b/include/scroll.h
deleted file mode 100644
index f8f10b1..0000000
--- a/include/scroll.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Scroll-bar class extra info
- *
- * Copyright 1993 Martin Ayotte
- * Copyright 1994 Alexandre Julliard
- */
-
-#ifndef __WINE_SCROLL_H
-#define __WINE_SCROLL_H
-
-#include "windef.h"
-
-struct tagWND;
-
-typedef struct
-{
-    INT   CurVal;   /* Current scroll-bar value */
-    INT   MinVal;   /* Minimum scroll-bar value */
-    INT   MaxVal;   /* Maximum scroll-bar value */
-    INT   Page;     /* Page size of scroll bar (Win32) */
-    UINT  flags;    /* EnableScrollBar flags */
-} SCROLLBAR_INFO;
-
-extern LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT uMsg,
-                                        WPARAM wParam, LPARAM lParam );
-
-extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar,
-                                  BOOL arrows, BOOL interior );
-extern void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar,
-                                      UINT msg, POINT pt );
-extern INT SCROLL_SetNCSbState( struct tagWND *wndPtr, int vMin, int vMax, int vPos,
-				int hMin, int hMax, int hPos );
-#endif  /* __WINE_SCROLL_H */
-
-
diff --git a/include/static.h b/include/static.h
deleted file mode 100644
index 2f5332e..0000000
--- a/include/static.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Static-class extra info
- *
- * Copyright 1994 Alexandre Julliard
- */
-
-#ifndef __WINE_STATIC_H
-#define __WINE_STATIC_H
-
-#include "windef.h"
-
-  /* Extra info for STATIC windows */
-typedef struct
-{
-    HFONT16  hFont;   /* Control font (or 0 for system font) */
-    WORD     dummy;   /* Don't know what MS-Windows puts in there */
-    HICON16  hIcon;   /* Icon handle for SS_ICON controls */ 
-} STATICINFO;
-
-extern LRESULT WINAPI StaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
-                                     LPARAM lParam );
-
-#endif  /* __WINE_STATIC_H */
diff --git a/include/win.h b/include/win.h
index b6a65c6..f139ccc 100644
--- a/include/win.h
+++ b/include/win.h
@@ -15,19 +15,6 @@
 
 #define WND_MAGIC     0x444e4957  /* 'WIND' */
 
-  /* Built-in class names (see _Undocumented_Windows_ p.418) */
-#define POPUPMENU_CLASS_NAME "#32768"  /* PopupMenu */
-#define DESKTOP_CLASS_NAME   "#32769"  /* Desktop */
-#define DIALOG_CLASS_NAME    "#32770"  /* Dialog */
-#define WINSWITCH_CLASS_NAME "#32771"  /* WinSwitch */
-#define ICONTITLE_CLASS_NAME "#32772"  /* IconTitle */
-
-#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768)  /* PopupMenu */
-#define DESKTOP_CLASS_ATOM   ((ATOM)32769)       /* Desktop */
-#define DIALOG_CLASS_ATOM    MAKEINTATOM(32770)  /* Dialog */
-#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771)  /* WinSwitch */
-#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772)  /* IconTitle */
-
   /* PAINT_RedrawWindow() control flags */
 #define RDW_EX_USEHRGN		0x0001
 #define RDW_EX_DELETEHRGN	0x0002
@@ -102,7 +89,7 @@
 {
     void   (*pInitialize)(WND *);
     void   (*pFinalize)(WND *);
-    BOOL   (*pCreateDesktopWindow)(WND *, BOOL);
+    BOOL   (*pCreateDesktopWindow)(WND *);
     BOOL   (*pCreateWindow)(WND *, CREATESTRUCTA *, BOOL);
     BOOL (*pDestroyWindow)(WND *);
     WND*   (*pSetParent)(WND *, WND *);
@@ -201,33 +188,17 @@
 
 /* Classes functions */
 struct tagCLASS;  /* opaque structure */
-extern ATOM CLASS_RegisterBuiltinClass( LPCSTR name, DWORD style, INT winExtra, LPCSTR cursor,
-                                        HBRUSH brush, WNDPROC wndProcA, WNDPROC wndProcW );
+struct builtin_class_descr;
+extern ATOM CLASS_RegisterBuiltinClass( const struct builtin_class_descr *descr );
 extern struct tagCLASS *CLASS_AddWindow( ATOM atom, HINSTANCE inst, WINDOWPROCTYPE type,
                                          INT *winExtra, WNDPROC *winproc,
                                          DWORD *style, struct tagDCE **dce );
 extern void CLASS_RemoveWindow( struct tagCLASS *cls );
 extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
 
-/* controls/widgets.c */
-extern BOOL WIDGETS_Init( void );
-
-/* controls/icontitle.c */
-extern LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
-
-extern HWND ICONTITLE_Create( WND* );
-extern BOOL ICONTITLE_Init( void );
-
 /* windows/focus.c */
 extern void FOCUS_SwitchFocus( struct tagMESSAGEQUEUE *pMsgQ, HWND , HWND );
 
-/* windows/edit.c */
-extern LRESULT WINAPI EditWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
-
-/* windows/listbox.c */
-extern LRESULT WINAPI ListBoxWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
-extern LRESULT WINAPI ComboLBWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
-
 /* generic method that returns TRUE if the window properties ask for a 
    window manager type of border */
 extern BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle );
diff --git a/include/x11drv.h b/include/x11drv.h
index 56451f1..f0b391f 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -417,7 +417,7 @@
 
 extern void X11DRV_WND_Initialize(struct tagWND *wndPtr);
 extern void X11DRV_WND_Finalize(struct tagWND *wndPtr);
-extern BOOL X11DRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, BOOL bUnicode);
+extern BOOL X11DRV_WND_CreateDesktopWindow(struct tagWND *wndPtr);
 extern BOOL X11DRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode);
 extern BOOL X11DRV_WND_DestroyWindow(struct tagWND *pWnd);
 extern struct tagWND *X11DRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent);
diff --git a/windows/Makefile.in b/windows/Makefile.in
index 036b1c7..be747dd 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -4,6 +4,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = windows
+EXTRAINCL = -I$(TOPSRCDIR)/dlls/user
 
 C_SRCS = \
 	caret.c \
diff --git a/windows/class.c b/windows/class.c
index ff15fa4..05d41ff 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -22,6 +22,7 @@
 #include "wine/unicode.h"
 #include "heap.h"
 #include "win.h"
+#include "controls.h"
 #include "dce.h"
 #include "ldt.h"
 #include "toolhelp.h"
@@ -348,27 +349,26 @@
  * Register a builtin control class.
  * This allows having both ASCII and Unicode winprocs for the same class.
  */
-ATOM CLASS_RegisterBuiltinClass( LPCSTR name, DWORD style, INT winExtra, LPCSTR cursor,
-                                 HBRUSH brush, WNDPROC wndProcA, WNDPROC wndProcW )
+ATOM CLASS_RegisterBuiltinClass( const struct builtin_class_descr *descr )
 {
     ATOM atom;
     CLASS *classPtr;
 
-    if (!(atom = GlobalAddAtomA( name ))) return 0;
+    if (!(atom = GlobalAddAtomA( descr->name ))) return 0;
 
-    if (!(classPtr = CLASS_RegisterClass( atom, 0, style, 0, winExtra )))
+    if (!(classPtr = CLASS_RegisterClass( atom, 0, descr->style, 0, descr->extra )))
     {
         GlobalDeleteAtom( atom );
         return 0;
     }
 
-    classPtr->hCursor       = LoadCursorA( 0, cursor );
-    classPtr->hbrBackground = brush;
+    classPtr->hCursor       = LoadCursorA( 0, descr->cursor );
+    classPtr->hbrBackground = descr->brush;
 
-    if (wndProcA) WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wndProcA,
-                                   WIN_PROC_32A, WIN_PROC_CLASS );
-    if (wndProcW) WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)wndProcW,
-                                   WIN_PROC_32W, WIN_PROC_CLASS );
+    if (descr->procA) WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)descr->procA,
+                                       WIN_PROC_32A, WIN_PROC_CLASS );
+    if (descr->procW) WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)descr->procW,
+                                       WIN_PROC_32W, WIN_PROC_CLASS );
     return atom;
 }
 
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 3958570..990a89c 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -9,7 +9,7 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "wine/winuser16.h"
-#include "dialog.h"
+#include "controls.h"
 #include "win.h"
 #include "winproc.h"
 
diff --git a/windows/dialog.c b/windows/dialog.c
index ecbc93d..51e0363 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -18,8 +18,7 @@
 #include "wine/winuser16.h"
 #include "wine/winbase16.h"
 #include "wine/unicode.h"
-#include "dialog.h"
-#include "drive.h"
+#include "controls.h"
 #include "heap.h"
 #include "win.h"
 #include "user.h"
@@ -79,6 +78,21 @@
 static WORD xBaseUnit = 0, yBaseUnit = 0;
 
 
+/*********************************************************************
+ * dialog class descriptor
+ */
+const struct builtin_class_descr DIALOG_builtin_class =
+{
+    DIALOG_CLASS_ATOM,  /* name */
+    CS_GLOBALCLASS | CS_SAVEBITS, /* style  */
+    DefDlgProcA,        /* procA */
+    DefDlgProcW,        /* procW */
+    DLGWINDOWEXTRA,     /* extra */
+    IDC_ARROWA,         /* cursor */
+    0                   /* brush */
+};
+
+
 /***********************************************************************
  *           DIALOG_EnableOwner
  *
@@ -2216,7 +2230,6 @@
 static INT DIALOG_DlgDirList( HWND hDlg, LPSTR spec, INT idLBox,
                                 INT idStatic, UINT attrib, BOOL combo )
 {
-    int drive;
     HWND hwnd;
     LPSTR orig_spec = spec;
 
@@ -2227,16 +2240,8 @@
     TRACE("%04x '%s' %d %d %04x\n",
                     hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib );
 
-    if (spec && spec[0] && (spec[1] == ':'))
-    {
-        drive = toupper( spec[0] ) - 'A';
-        spec += 2;
-        if (!DRIVE_SetCurrentDrive( drive )) return FALSE;
-    }
-    else drive = DRIVE_GetCurrentDrive();
-
     /* If the path exists and is a directory, chdir to it */
-    if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*";
+    if (!spec || !spec[0] || SetCurrentDirectoryA( spec )) spec = "*.*";
     else
     {
         char *p, *p2;
@@ -2247,7 +2252,7 @@
         {
             char sep = *p;
             *p = 0;
-            if (!DRIVE_Chdir( drive, spec ))
+            if (!SetCurrentDirectoryA( spec ))
             {
                 *p = sep;  /* Restore the original spec */
                 return FALSE;
@@ -2256,8 +2261,7 @@
         }
     }
 
-    TRACE("path=%c:\\%s mask=%s\n",
-                    'A' + drive, DRIVE_GetDosCwd(drive), spec );
+    TRACE( "mask=%s\n", spec );
 
     if (idLBox && ((hwnd = GetDlgItem( hDlg, idLBox )) != 0))
     {
@@ -2286,11 +2290,8 @@
 
     if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0))
     {
-        char temp[512];
-        int drive = DRIVE_GetCurrentDrive();
-        strcpy( temp, "A:\\" );
-        temp[0] += drive;
-        lstrcpynA( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
+        char temp[MAX_PATH];
+        GetCurrentDirectoryA( sizeof(temp), temp );
         CharLowerA( temp );
         /* Can't use PostMessage() here, because the string is on the stack */
         SetDlgItemTextA( hDlg, idStatic, temp );
diff --git a/windows/mdi.c b/windows/mdi.c
index f6056d9..bd2e2df 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -77,10 +77,8 @@
 #include "win.h"
 #include "heap.h"
 #include "nonclient.h"
-#include "mdi.h"
+#include "controls.h"
 #include "user.h"
-#include "menu.h"
-#include "scroll.h"
 #include "struct32.h"
 #include "tweak.h"
 #include "debugtools.h"
@@ -88,8 +86,37 @@
 
 DEFAULT_DEBUG_CHANNEL(mdi);
 
+#define MDI_MAXLISTLENGTH       0x40
+#define MDI_MAXTITLELENGTH      0xa1
+
+#define MDI_NOFRAMEREPAINT      0
+#define MDI_REPAINTFRAMENOW     1
+#define MDI_REPAINTFRAME        2
+
+#define WM_MDICALCCHILDSCROLL   0x10ac /* this is exactly what Windows uses */
+
+/* "More Windows..." definitions */
+#define MDI_MOREWINDOWSLIMIT    9       /* after this number of windows, a "More Windows..." 
+                                           option will appear under the Windows menu */
+#define MDI_IDC_LISTBOX         100
+#define MDI_IDS_MOREWINDOWS     13
+
 #define MDIF_NEEDUPDATE		0x0001
 
+typedef struct
+{
+    UINT      nActiveChildren;
+    HWND      hwndChildMaximized;
+    HWND      hwndActiveChild;
+    HMENU     hWindowMenu;
+    UINT      idFirstChild;
+    LPWSTR    frameTitle;
+    UINT      nTotalCreated;
+    UINT      mdiFlags;
+    UINT      sbRecalc;   /* SB_xxx flags for scrollbar fixup */
+    HWND      self;
+} MDICLIENTINFO;
+
 static HBITMAP16 hBmpClose   = 0;
 static HBITMAP16 hBmpRestore = 0;
 
@@ -102,6 +129,7 @@
 
 static HWND MDI_MoreWindowsDialog(WND*);
 static void MDI_SwapMenuItems(WND *, UINT, UINT);
+static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
 /* -------- Miscellaneous service functions ----------
  *
  *			MDI_GetChildByID
@@ -124,6 +152,22 @@
     ci->sbRecalc = recalc;
 }
 
+
+/*********************************************************************
+ * MDIClient class descriptor
+ */
+const struct builtin_class_descr MDICLIENT_builtin_class =
+{
+    "MDIClient",            /* name */
+    CS_GLOBALCLASS,         /* style */
+    MDIClientWndProcA,      /* procA */
+    NULL,                   /* procW (FIXME) */
+    sizeof(MDICLIENTINFO),  /* extra */
+    IDC_ARROWA,             /* cursor */
+    COLOR_APPWORKSPACE+1    /* brush */
+};
+
+
 /**********************************************************************
  *			MDI_MenuModifyItem
  */
@@ -1190,12 +1234,11 @@
 
 
 /**********************************************************************
- *					MDIClientWndProc
+ *					MDIClientWndProcA
  *
  * This function handles all MDI requests.
  */
-LRESULT WINAPI MDIClientWndProc( HWND hwnd, UINT message, WPARAM wParam,
-                                 LPARAM lParam )
+static LRESULT WINAPI MDIClientWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
     LPCREATESTRUCTA	 cs;
     MDICLIENTINFO       *ci;
diff --git a/windows/message.c b/windows/message.c
index 49c0eed..ee656a0 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -26,7 +26,7 @@
 #include "selectors.h"
 #include "thread.h"
 #include "options.h"
-#include "menu.h"
+#include "controls.h"
 #include "struct32.h"
 #include "debugtools.h"
 
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 9cfc809..54be17c 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -14,12 +14,10 @@
 #include "user.h"
 #include "heap.h"
 #include "dce.h"
+#include "controls.h"
 #include "cursoricon.h"
-#include "dialog.h"
-#include "menu.h"
 #include "winpos.h"
 #include "hook.h"
-#include "scroll.h"
 #include "nonclient.h"
 #include "queue.h"
 #include "selectors.h"
diff --git a/windows/sysparams.c b/windows/sysparams.c
index aeebdb1..c36fa43 100644
--- a/windows/sysparams.c
+++ b/windows/sysparams.c
@@ -15,10 +15,10 @@
 #include "wine/winuser16.h"
 #include "winerror.h"
 
+#include "controls.h"
 #include "keyboard.h"
 #include "tweak.h"
 #include "user.h"
-#include "desktop.h"
 #include "debugtools.h"
 
 DEFAULT_DEBUG_CHANNEL(system);
diff --git a/windows/user.c b/windows/user.c
index 43f7f57..137d65f 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -16,7 +16,7 @@
 #include "queue.h"
 #include "win.h"
 #include "clipboard.h"
-#include "menu.h"
+#include "controls.h"
 #include "cursoricon.h"
 #include "hook.h"
 #include "toolhelp.h"
diff --git a/windows/win.c b/windows/win.c
index 5323615..c684504 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -15,16 +15,15 @@
 #include "heap.h"
 #include "user.h"
 #include "dce.h"
+#include "controls.h"
 #include "cursoricon.h"
 #include "hook.h"
-#include "menu.h"
 #include "message.h"
 #include "queue.h"
 #include "winpos.h"
 #include "task.h"
 #include "thread.h"
 #include "winerror.h"
-#include "mdi.h"
 #include "stackframe.h"
 #include "debugtools.h"
 
@@ -585,9 +584,8 @@
     TRACE("Creating desktop window\n");
 
 
-    if (!ICONTITLE_Init() ||
-	!WINPOS_CreateInternalPosAtom() ||
-        !(class = CLASS_AddWindow( DESKTOP_CLASS_ATOM, 0, WIN_PROC_32A,
+    if (!WINPOS_CreateInternalPosAtom() ||
+        !(class = CLASS_AddWindow( (ATOM)LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W,
                                    &wndExtra, &winproc, &clsStyle, &dce )))
         return FALSE;
 
@@ -632,11 +630,9 @@
     pWndDesktop->cbWndExtra        = wndExtra;
     pWndDesktop->irefCount         = 0;
 
-    /* FIXME: How do we know if it should be Unicode or not */
-    if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, FALSE))
-      return FALSE;
-    
-    SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 );
+    if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop)) return FALSE;
+
+    SendMessageW( hwndDesktop, WM_NCCREATE, 0, 0 );
     pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
     return TRUE;
 }
diff --git a/windows/winpos.c b/windows/winpos.c
index c080c32..3fa9a35 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -11,6 +11,7 @@
 #include "wingdi.h"
 #include "winerror.h"
 #include "wine/winuser16.h"
+#include "controls.h"
 #include "heap.h"
 #include "user.h"
 #include "region.h"
diff --git a/windows/winproc.c b/windows/winproc.c
index e374315..bd57cf7 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -15,6 +15,7 @@
 #include "wine/winuser16.h"
 #include "stackframe.h"
 #include "builtin16.h"
+#include "controls.h"
 #include "heap.h"
 #include "selectors.h"
 #include "struct32.h"
@@ -25,7 +26,6 @@
 #include "commctrl.h"
 #include "task.h"
 #include "thread.h"
-#include "menu.h"
 
 DECLARE_DEBUG_CHANNEL(msg);
 DECLARE_DEBUG_CHANNEL(relay);
diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c
index fc6379f..519ab37 100644
--- a/windows/x11drv/event.c
+++ b/windows/x11drv/event.c
@@ -28,7 +28,6 @@
 #include "clipboard.h"
 #include "dce.h"
 #include "debugtools.h"
-#include "drive.h"
 #include "heap.h"
 #include "input.h"
 #include "keyboard.h"
@@ -1576,9 +1575,6 @@
 	    {
 	      p_drop = p;
 	      if((u.i = *p) != -1 ) 
-		u.i = DRIVE_FindDriveRoot( (const char **)&p_drop );
-	      if( u.i == -1 ) *p = -1;	/* mark as "bad" */
-	      else
 		{
 		  INT len = GetShortPathNameA( p, NULL, 0 );
 		  if (len) aux_long += len + 1;
diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c
index e8ef341..56e8164 100644
--- a/windows/x11drv/wnd.c
+++ b/windows/x11drv/wnd.c
@@ -173,7 +173,7 @@
 /**********************************************************************
  *		X11DRV_WND_CreateDesktopWindow
  */
-BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, BOOL bUnicode)
+BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr)
 {
     if (wmProtocols == None)
         wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );