Release 960521

Tue May 21 14:06:07 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/button.c]
	Made ButtonWndProc a 32-bit window procedure.

	* [controls/desktop.c]
	Made DesktopWndProc a 32-bit window procedure.
	Added handling of WM_SETCURSOR.

	* [controls/menu.c]
	Allocate menu items and strings on the 32-bit system heap.
	Implemented Win32 versions for ChangeMenu, InsertMenu, ModifyMenu,
	AppendMenu and LoadMenuIndirect.

	* [controls/widgets.c]
	Added possibility to have 32-bit built-in classes.

	* [files/drive.c]
	Implemented GetLogicalDrive() and GetLogicalDriveStrings().

	* [misc/spy.c] [include/spy.h]
	Added support for spying Win32 messages.

	* [loader/builtin.c]
	Fixed bug in -dll option parsing.

	* [memory/local.c]
	Added back the change by Huw D. M. Davies to free the block in
	LocalRealloc() before allocating the new one.

	* [objects/bitmap.c] [objects/cursoricon.c] [objects/oembitmap.c]
	Fixed bug in bitmap size that caused memory corruption for 24bpp.

	* [windows/defwnd.c]
	Implemented Win32 version of DefWindowProc().

	* [windows/dialog.c]
	Implemented Win32 version of SendDlgItemMessage,
	Get/SetDlgItemText and Get/SetDlgItemInt.

	* [windows/mdi.c]
	Implemented Win32 version of DefFrameProc() and DefMDIChildProc().
	Don't make a copy of the OBM bitmaps for every MDI window.

	* [windows/message.c]
	Implemented Win32 version of SendMessage().
	
	* [windows/winproc.c] [windows/class.c] [windows/win.c]
	New scheme for 32-bit window procedures to replace aliases. All
	32-bit window procedure get a 16-bit address pointing to a
	WINDOWPROC structure.
	Implemented Ansi<->Unicode translation for CallWindowProc().
	Added translation of WM_DRAWITEM between Win16 and Win32.

	* [windows/win.c] [include/callback.h]
	Added ugly hack to build CREATESTRUCT on the stack when sending
	WM_NCCREATE.
	Implemented Win32 version of Get/SetWindowWord/Long and
	Get/SetWindowText.
	
Fri May 17 10:20:16 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [controls/button.c]
	Avoid gray text on gray background in disabled push buttons
	using a b/w raster and some raster operations (PatBlt,BitBlt).

	* [objects/text.c]
	DrawText(): don't draw an underbar anymore if DT_CALCRECT is set.
diff --git a/ANNOUNCE b/ANNOUNCE
index b9a0222..e675cea 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,13 @@
-This is release 960516 of Wine the MS Windows emulator.  This is still a
+This is release 960521 of Wine the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-960516: (see ChangeLog for details)
-	- Tons of Win32 support.
-	- Several local heap fixes.
-	- Window management improvements.
+WHAT'S NEW with Wine-960521: (see ChangeLog for details)
+	- Even more Win32 support.
+	- Winhelp clone should compile OK.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,10 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960516.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960516.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960516.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960516.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960521.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960521.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960521.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960521.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 237d319..2a032fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,74 @@
 ----------------------------------------------------------------------
+Tue May 21 14:06:07 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [controls/button.c]
+	Made ButtonWndProc a 32-bit window procedure.
+
+	* [controls/desktop.c]
+	Made DesktopWndProc a 32-bit window procedure.
+	Added handling of WM_SETCURSOR.
+
+	* [controls/menu.c]
+	Allocate menu items and strings on the 32-bit system heap.
+	Implemented Win32 versions for ChangeMenu, InsertMenu, ModifyMenu,
+	AppendMenu and LoadMenuIndirect.
+
+	* [controls/widgets.c]
+	Added possibility to have 32-bit built-in classes.
+
+	* [files/drive.c]
+	Implemented GetLogicalDrive() and GetLogicalDriveStrings().
+
+	* [misc/spy.c] [include/spy.h]
+	Added support for spying Win32 messages.
+
+	* [loader/builtin.c]
+	Fixed bug in -dll option parsing.
+
+	* [memory/local.c]
+	Added back the change by Huw D. M. Davies to free the block in
+	LocalRealloc() before allocating the new one.
+
+	* [objects/bitmap.c] [objects/cursoricon.c] [objects/oembitmap.c]
+	Fixed bug in bitmap size that caused memory corruption for 24bpp.
+
+	* [windows/defwnd.c]
+	Implemented Win32 version of DefWindowProc().
+
+	* [windows/dialog.c]
+	Implemented Win32 version of SendDlgItemMessage,
+	Get/SetDlgItemText and Get/SetDlgItemInt.
+
+	* [windows/mdi.c]
+	Implemented Win32 version of DefFrameProc() and DefMDIChildProc().
+	Don't make a copy of the OBM bitmaps for every MDI window.
+
+	* [windows/message.c]
+	Implemented Win32 version of SendMessage().
+	
+	* [windows/winproc.c] [windows/class.c] [windows/win.c]
+	New scheme for 32-bit window procedures to replace aliases. All
+	32-bit window procedure get a 16-bit address pointing to a
+	WINDOWPROC structure.
+	Implemented Ansi<->Unicode translation for CallWindowProc().
+	Added translation of WM_DRAWITEM between Win16 and Win32.
+
+	* [windows/win.c] [include/callback.h]
+	Added ugly hack to build CREATESTRUCT on the stack when sending
+	WM_NCCREATE.
+	Implemented Win32 version of Get/SetWindowWord/Long and
+	Get/SetWindowText.
+	
+Fri May 17 10:20:16 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [controls/button.c]
+	Avoid gray text on gray background in disabled push buttons
+	using a b/w raster and some raster operations (PatBlt,BitBlt).
+
+	* [objects/text.c]
+	DrawText(): don't draw an underbar anymore if DT_CALCRECT is set.
+
+----------------------------------------------------------------------
 Thu May 16 13:35:31 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [*/*.c]
diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS
index 8025e6f..a4be04e 100644
--- a/DEVELOPERS-HINTS
+++ b/DEVELOPERS-HINTS
@@ -43,6 +43,28 @@
 use it as a regular 32-bit pointer.
 
 
+STRUCTURE PACKING
+=================
+
+Under Windows, data structures are tightly packed, i.e. there is no
+padding between structure members. On the other hand, by default gcc
+aligns structure members (e.g. WORDs are on a WORD boundary, etc.).
+This means that a structure like
+
+struct { BYTE x; WORD y; };
+
+will take 3 bytes under Windows, but 4 with gcc, because gcc will add a
+dummy byte between x and y. To have the correct layout for structures
+used by Windows code, you need to use the WINE_PACKED attribute; so you
+would declare the above structure like this:
+
+struct { BYTE x; WORD y WINE_PACKED; };
+
+You have to do this every time a structure member is not aligned
+correctly under Windows (i.e. a WORD not on an even address, or a
+DWORD on a address that is not a multiple of 4).
+
+
 NAMING CONVENTIONS FOR API FUNCTIONS AND TYPES
 ==============================================
 
diff --git a/controls/button.c b/controls/button.c
index 60558ec..7e24f64 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -6,22 +6,18 @@
  */
 
 #include "win.h"
-#include "user.h"
 #include "syscolor.h"
 #include "graphics.h"
 #include "button.h"
-#include "heap.h"
-
-extern void DEFWND_SetText( WND *wndPtr, LPSTR text );  /* windows/defwnd.c */
 
 static void PB_Paint( WND *wndPtr, HDC hDC, WORD action );
+static void PB_PaintGrayOnGray(HDC hDC,HFONT hFont,RECT16 *rc,char *text);
 static void CB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void GB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void UB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void OB_Paint( WND *wndPtr, HDC hDC, WORD action );
 static void BUTTON_CheckAutoRadioButton( WND *wndPtr );
 
-
 #define MAX_BTN_TYPE  12
 
 static WORD maxCheckState[MAX_BTN_TYPE] =
@@ -64,213 +60,188 @@
          (btnPaintFunc[style])(wndPtr,hdc,action); \
          ReleaseDC( (wndPtr)->hwndSelf, hdc ); }
 
-#ifdef WINELIB32
 #define BUTTON_SEND_CTLCOLOR(wndPtr,hdc) \
-    SendMessage( GetParent((wndPtr)->hwndSelf), WM_CTLCOLORBTN, \
-                 (hdc), (wndPtr)->hwndSelf )
-#else
-#define BUTTON_SEND_CTLCOLOR(wndPtr,hdc) \
-    SendMessage( GetParent((wndPtr)->hwndSelf), WM_CTLCOLOR, (hdc), \
-                 MAKELPARAM((wndPtr)->hwndSelf, CTLCOLOR_BTN) )
-#endif
+    SendMessage32A( GetParent((wndPtr)->hwndSelf), WM_CTLCOLORBTN, \
+                    (hdc), (wndPtr)->hwndSelf )
 
 static HBITMAP hbitmapCheckBoxes = 0;
 static WORD checkBoxWidth = 0, checkBoxHeight = 0;
 
 
-LRESULT ButtonWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+/***********************************************************************
+ *           ButtonWndProc
+ */
+LRESULT ButtonWndProc(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
 {
-        RECT16 rect;
-	LONG lResult = 0;
-	WND *wndPtr = WIN_FindWndPtr(hWnd);
-	LONG style = wndPtr->dwStyle & 0x0000000F;
-        BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
+    RECT16 rect;
+    WND *wndPtr = WIN_FindWndPtr(hWnd);
+    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
+    LONG style = wndPtr->dwStyle & 0x0f;
 
-	switch (uMsg) {
-	case WM_GETDLGCODE:
-                switch(style)
-                {
-                case BS_PUSHBUTTON:
-                    return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON;
-                case BS_DEFPUSHBUTTON:
-                    return DLGC_BUTTON | DLGC_DEFPUSHBUTTON;
-                case BS_RADIOBUTTON:
-                case BS_AUTORADIOBUTTON:
-                    return DLGC_BUTTON | DLGC_RADIOBUTTON;
-                default:
-                    return DLGC_BUTTON;
-                }
+    switch (uMsg)
+    {
+    case WM_GETDLGCODE:
+        switch(style)
+        {
+        case BS_PUSHBUTTON:      return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON;
+        case BS_DEFPUSHBUTTON:   return DLGC_BUTTON | DLGC_DEFPUSHBUTTON;
+        case BS_RADIOBUTTON:
+        case BS_AUTORADIOBUTTON: return DLGC_BUTTON | DLGC_RADIOBUTTON;
+        default:                 return DLGC_BUTTON;
+        }
 
-	case WM_ENABLE:
-                PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
-		break;
+    case WM_ENABLE:
+        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+        break;
 
-	case WM_CREATE:
-		if (!hbitmapCheckBoxes)
-		{
-		    BITMAP bmp;
-		    hbitmapCheckBoxes = LoadBitmap( 0, MAKEINTRESOURCE(OBM_CHECKBOXES) );
-		    GetObject( hbitmapCheckBoxes, sizeof(bmp), (LPSTR)&bmp );
-		    checkBoxWidth  = bmp.bmWidth / 4;
-		    checkBoxHeight = bmp.bmHeight / 3;
-		}
-		
-		if (style < 0L || style >= MAX_BTN_TYPE)
-		    lResult = -1L;
-		else
-		{
-                    infoPtr->state = BUTTON_UNCHECKED;
-                    infoPtr->hFont = 0;
-		    lResult = 0L;
-		}
-		break;
+    case WM_CREATE:
+        if (!hbitmapCheckBoxes)
+        {
+            BITMAP bmp;
+            hbitmapCheckBoxes = LoadBitmap(0, MAKEINTRESOURCE(OBM_CHECKBOXES));
+            GetObject( hbitmapCheckBoxes, sizeof(bmp), (LPSTR)&bmp );
+            checkBoxWidth  = bmp.bmWidth / 4;
+            checkBoxHeight = bmp.bmHeight / 3;
+        }
+        if (style < 0L || style >= MAX_BTN_TYPE) return -1; /* abort */
+        infoPtr->state = BUTTON_UNCHECKED;
+        infoPtr->hFont = 0;
+        return 0;
 
-        case WM_ERASEBKGND:
+    case WM_ERASEBKGND:
+        break;
+
+    case WM_PAINT:
+        if (btnPaintFunc[style])
+        {
+            PAINTSTRUCT16 ps;
+            HDC hdc = BeginPaint16( hWnd, &ps );
+            (btnPaintFunc[style])( wndPtr, hdc, ODA_DRAWENTIRE );
+            EndPaint16( hWnd, &ps );
+        }
+        break;
+
+    case WM_LBUTTONDOWN:
+        SendMessage32A( hWnd, BM_SETSTATE32, TRUE, 0 );
+        SetFocus( hWnd );
+        SetCapture( hWnd );
+        break;
+
+    case WM_LBUTTONUP:
+        ReleaseCapture();
+        if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
+        SendMessage16( hWnd, BM_SETSTATE16, FALSE, 0 );
+        GetClientRect16( hWnd, &rect );
+        if (PtInRect16( &rect, MAKEPOINT16(lParam) ))
+        {
+            switch(style)
+            {
+            case BS_AUTOCHECKBOX:
+                SendMessage32A( hWnd, BM_SETCHECK32,
+                                !(infoPtr->state & BUTTON_CHECKED), 0 );
                 break;
-
-	case WM_PAINT:
-                if (btnPaintFunc[style])
-                {
-                    PAINTSTRUCT16 ps;
-                    HDC hdc = BeginPaint16( hWnd, &ps );
-                    (btnPaintFunc[style])( wndPtr, hdc, ODA_DRAWENTIRE );
-                    EndPaint16( hWnd, &ps );
-                }
-		break;
-
-	case WM_LBUTTONDOWN:
-                SendMessage( hWnd, BM_SETSTATE16, TRUE, 0 );
-                SetFocus( hWnd );
-                SetCapture( hWnd );
-		break;
-
-	case WM_LBUTTONUP:
-	        ReleaseCapture();
-	        if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
-                SendMessage( hWnd, BM_SETSTATE16, FALSE, 0 );
-                GetClientRect16( hWnd, &rect );
-                if (PtInRect16( &rect, MAKEPOINT16(lParam) ))
-                {
-                    switch(style)
-                    {
-                    case BS_AUTOCHECKBOX:
-                        SendMessage( hWnd, BM_SETCHECK16,
-                                    !(infoPtr->state & BUTTON_CHECKED), 0 );
-                        break;
-                    case BS_AUTORADIOBUTTON:
-                        SendMessage( hWnd, BM_SETCHECK16, TRUE, 0 );
-                        break;
-                    case BS_AUTO3STATE:
-                        SendMessage( hWnd, BM_SETCHECK16,
-                                     (infoPtr->state & BUTTON_3STATE) ? 0 :
-                                     ((infoPtr->state & 3) + 1), 0 );
-                        break;
-                    }
-#ifdef WINELIB32
-                    SendMessage( GetParent(hWnd), WM_COMMAND,
-                                 MAKEWPARAM(wndPtr->wIDmenu,BN_CLICKED), hWnd);
-#else
-                    SendMessage( GetParent(hWnd), WM_COMMAND,
-                                 wndPtr->wIDmenu, MAKELPARAM(hWnd,BN_CLICKED));
-#endif
-                }
-		break;
-
-        case WM_MOUSEMOVE:
-                if (GetCapture() == hWnd)
-                {
-                    GetClientRect16( hWnd, &rect );
-                    SendMessage(hWnd, BM_SETSTATE16,
-                                PtInRect16( &rect,MAKEPOINT16(lParam) ), 0 );
-                }
+            case BS_AUTORADIOBUTTON:
+                SendMessage32A( hWnd, BM_SETCHECK32, TRUE, 0 );
                 break;
-
-        case WM_NCHITTEST:
-                if(style == BS_GROUPBOX) return HTTRANSPARENT;
-                lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
+            case BS_AUTO3STATE:
+                SendMessage32A( hWnd, BM_SETCHECK32,
+                                (infoPtr->state & BUTTON_3STATE) ? 0 :
+                                ((infoPtr->state & 3) + 1), 0 );
                 break;
+            }
+            SendMessage32A( GetParent(hWnd), WM_COMMAND,
+                            MAKEWPARAM( wndPtr->wIDmenu, BN_CLICKED ), hWnd);
+        }
+        break;
 
-        case WM_SETTEXT:
-		DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
-                PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
-		return 0;
+    case WM_MOUSEMOVE:
+        if (GetCapture() == hWnd)
+        {
+            GetClientRect16( hWnd, &rect );
+            SendMessage32A( hWnd, BM_SETSTATE32,
+                            PtInRect16( &rect,MAKEPOINT16(lParam) ), 0 );
+        }
+        break;
 
-        case WM_SETFONT:
-                infoPtr->hFont = (HFONT) wParam;
-                if (lParam)
-                    PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
-                break;
+    case WM_NCHITTEST:
+        if(style == BS_GROUPBOX) return HTTRANSPARENT;
+        return DefWindowProc32A( hWnd, uMsg, wParam, lParam );
 
-        case WM_GETFONT:
-                return infoPtr->hFont;
+    case WM_SETTEXT:
+        DEFWND_SetText( wndPtr, (LPSTR)lParam );
+        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+        return 0;
 
-	case WM_SETFOCUS:
-                infoPtr->state |= BUTTON_HASFOCUS;
-                PAINT_BUTTON( wndPtr, style, ODA_FOCUS );
-		break;
+    case WM_SETFONT:
+        infoPtr->hFont = (HFONT) wParam;
+        if (lParam) PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+        break;
 
-	case WM_KILLFOCUS:
-                infoPtr->state &= ~BUTTON_HASFOCUS;
-                PAINT_BUTTON( wndPtr, style, ODA_FOCUS );
-		break;
+    case WM_GETFONT:
+        return infoPtr->hFont;
 
-	case WM_SYSCOLORCHANGE:
-		InvalidateRect32( hWnd, NULL, FALSE );
-		break;
+    case WM_SETFOCUS:
+        infoPtr->state |= BUTTON_HASFOCUS;
+        PAINT_BUTTON( wndPtr, style, ODA_FOCUS );
+        break;
 
-	case BM_SETSTYLE16:
-	case BM_SETSTYLE32:
-		if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
-		wndPtr->dwStyle = (wndPtr->dwStyle & 0xfffffff0) 
-		                   | (wParam & 0x0000000f);
-                style = wndPtr->dwStyle & 0x0000000f;
-                PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
-		break;
+    case WM_KILLFOCUS:
+        infoPtr->state &= ~BUTTON_HASFOCUS;
+        PAINT_BUTTON( wndPtr, style, ODA_FOCUS );
+        break;
 
-	case BM_GETCHECK16:
-	case BM_GETCHECK32:
-		lResult = infoPtr->state & 3;
-		break;
+    case WM_SYSCOLORCHANGE:
+        InvalidateRect32( hWnd, NULL, FALSE );
+        break;
 
-	case BM_SETCHECK16:
-	case BM_SETCHECK32:
-                if (wParam > maxCheckState[style])
-                    wParam = maxCheckState[style];
-		if ((infoPtr->state & 3) != wParam)
-                {
-                    infoPtr->state = (infoPtr->state & ~3) | wParam;
-                    PAINT_BUTTON( wndPtr, style, ODA_SELECT );
-                }
-		if(style == BS_AUTORADIOBUTTON && wParam==BUTTON_CHECKED)
-			BUTTON_CheckAutoRadioButton( wndPtr );
-                break;
+    case BM_SETSTYLE16:
+    case BM_SETSTYLE32:
+        if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
+        wndPtr->dwStyle = (wndPtr->dwStyle & 0xfffffff0) 
+                           | (wParam & 0x0000000f);
+        style = wndPtr->dwStyle & 0x0000000f;
+        PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE );
+        break;
 
-	case BM_GETSTATE16:
-	case BM_GETSTATE32:
-		lResult = infoPtr->state;
-		break;
+    case BM_GETCHECK16:
+    case BM_GETCHECK32:
+        return infoPtr->state & 3;
 
-	case BM_SETSTATE16:
-	case BM_SETSTATE32:
-                if (wParam)
-                {
-                    if (infoPtr->state & BUTTON_HIGHLIGHTED) break;
-                    infoPtr->state |= BUTTON_HIGHLIGHTED;
-                }
-                else
-                {
-                    if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
-                    infoPtr->state &= ~BUTTON_HIGHLIGHTED;
-                }
-                PAINT_BUTTON( wndPtr, style, ODA_SELECT );
-                break;
+    case BM_SETCHECK16:
+    case BM_SETCHECK32:
+        if (wParam > maxCheckState[style]) wParam = maxCheckState[style];
+        if ((infoPtr->state & 3) != wParam)
+        {
+            infoPtr->state = (infoPtr->state & ~3) | wParam;
+            PAINT_BUTTON( wndPtr, style, ODA_SELECT );
+        }
+        if ((style == BS_AUTORADIOBUTTON) && (wParam == BUTTON_CHECKED))
+            BUTTON_CheckAutoRadioButton( wndPtr );
+        break;
 
-	default:
-		lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
-		break;
-	}
+    case BM_GETSTATE16:
+    case BM_GETSTATE32:
+        return infoPtr->state;
 
-	return lResult;
+    case BM_SETSTATE16:
+    case BM_SETSTATE32:
+        if (wParam)
+        {
+            if (infoPtr->state & BUTTON_HIGHLIGHTED) break;
+            infoPtr->state |= BUTTON_HIGHLIGHTED;
+        }
+        else
+        {
+            if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
+            infoPtr->state &= ~BUTTON_HIGHLIGHTED;
+        }
+        PAINT_BUTTON( wndPtr, style, ODA_SELECT );
+        break;
+
+    default:
+        return DefWindowProc32A(hWnd, uMsg, wParam, lParam);
+    }
+    return 0;
 }
 
 
@@ -283,7 +254,6 @@
     RECT16 rc;
     HPEN16 hOldPen;
     HBRUSH hOldBrush;
-    char *text;
     DWORD dwTextSize;
     TEXTMETRIC tm;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
@@ -324,18 +294,25 @@
     else GRAPH_DrawReliefRect( hDC, &rc, 2, 2, FALSE );
     
     /* draw button label, if any: */
-    text = (char*) USER_HEAP_LIN_ADDR( wndPtr->hText );
-    if (text && text[0])
+    if (wndPtr->text && wndPtr->text[0])
     {
+     LOGBRUSH lb;
+     GetObject(sysColorObjects.hbrushBtnFace,sizeof(LOGBRUSH),(LPSTR)&lb);
+     if (wndPtr->dwStyle & WS_DISABLED &&
+         GetSysColor(COLOR_GRAYTEXT)==lb.lbColor)
+         /* don't write gray text on gray bkg */
+         PB_PaintGrayOnGray(hDC,infoPtr->hFont,&rc,wndPtr->text);
+     else
+     {
         SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
                      GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_BTNTEXT));
-        DrawText16( hDC, text, -1, &rc,
+        DrawText16( hDC, wndPtr->text, -1, &rc,
                     DT_SINGLELINE | DT_CENTER | DT_VCENTER );
         /* do we have the focus? */
         if (infoPtr->state & BUTTON_HASFOCUS)
         {
             short xdelta, ydelta;
-            dwTextSize = GetTextExtent( hDC, text, strlen(text) );
+            dwTextSize = GetTextExtent(hDC,wndPtr->text,strlen(wndPtr->text));
             GetTextMetrics( hDC, &tm );
             xdelta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) / 2;
             ydelta = ((rc.bottom - rc.top) - tm.tmHeight - 1) / 2;
@@ -344,6 +321,7 @@
             InflateRect16( &rc, -xdelta, -ydelta );
             DrawFocusRect16( hDC, &rc );
         }
+     }   
     }
 
     SelectObject( hDC, hOldPen );
@@ -352,6 +330,40 @@
 
 
 /**********************************************************************
+ *   Push Button sub function                               [internal]
+ *   using a raster brush to avoid gray text on gray background
+ */
+
+void PB_PaintGrayOnGray(HDC hDC,HFONT hFont,RECT16 *rc,char *text)
+{
+    static int Pattern[] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};
+    HBITMAP hbm  = CreateBitmap(8, 8, 1, 1, Pattern);
+    HDC hdcMem   = CreateCompatibleDC(hDC);
+    HBITMAP hbmMem;
+    HBRUSH hBr;
+    RECT16 rect,rc2;
+
+    rect=*rc;
+    DrawText16( hDC, text, -1, &rect, DT_SINGLELINE | DT_CALCRECT);
+    rc2=rect;
+    rect.left=(rc->right-rect.right)/2;       /* for centering text bitmap */
+    rect.top=(rc->bottom-rect.bottom)/2;
+    hbmMem = CreateCompatibleBitmap( hDC,rect.right,rect.bottom);
+    SelectObject( hdcMem, hbmMem);
+    hBr = SelectObject( hdcMem,CreatePatternBrush(hbm));
+    DeleteObject( hbm);
+    PatBlt( hdcMem,0,0,rect.right,rect.bottom,WHITENESS);
+    if (hFont) SelectObject( hdcMem, hFont);
+    DrawText16( hdcMem, text, -1, &rc2, DT_SINGLELINE);  
+    PatBlt( hdcMem,0,0,rect.right,rect.bottom,0xFA0089);
+    DeleteObject( SelectObject( hdcMem,hBr));
+    BitBlt( hDC,rect.left,rect.top,rect.right,rect.bottom,hdcMem,0,0,0x990000);
+    DeleteDC( hdcMem);
+    DeleteObject( hbmMem);
+}
+
+
+/**********************************************************************
  *       Check Box & Radio Button Functions
  */
 
@@ -360,7 +372,6 @@
     RECT16 rc;
     HBRUSH hBrush;
     int textlen, delta, x, y;
-    char *text;
     TEXTMETRIC tm;
     SIZE16 size;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
@@ -385,20 +396,21 @@
                       x, y, checkBoxWidth, checkBoxHeight );
     rc.left += checkBoxWidth + tm.tmAveCharWidth / 2;
 
-    if (!(text = (char*) USER_HEAP_LIN_ADDR( wndPtr->hText ))) return;
-    textlen = strlen( text );
+    if (!wndPtr->text) return;
+    textlen = strlen( wndPtr->text );
 
     if (action == ODA_DRAWENTIRE)
     {
         if (wndPtr->dwStyle & WS_DISABLED)
             SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
-        DrawText16( hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER );
+        DrawText16( hDC, wndPtr->text, textlen, &rc,
+                    DT_SINGLELINE | DT_VCENTER );
     }
     
     if ((action == ODA_FOCUS) ||
         ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
     {
-        GetTextExtentPoint16( hDC, text, textlen, &size );
+        GetTextExtentPoint16( hDC, wndPtr->text, textlen, &size );
         if (delta > 1)
         {
             rc.top += delta - 1;
@@ -424,7 +436,7 @@
     for(sibling = GetNextDlgGroupItem(parent,wndPtr->hwndSelf,FALSE);
         sibling != wndPtr->hwndSelf;
         sibling = GetNextDlgGroupItem(parent,sibling,FALSE))
-	    SendMessage( sibling, BM_SETCHECK16, BUTTON_UNCHECKED, 0 );
+	    SendMessage32A( sibling, BM_SETCHECK32, BUTTON_UNCHECKED, 0 );
 }
 
 
@@ -435,7 +447,6 @@
 static void GB_Paint( WND *wndPtr, HDC hDC, WORD action )
 {
     RECT16 rc;
-    char *text;
     SIZE16 size;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
@@ -453,14 +464,14 @@
     LineTo( hDC, rc.left, rc.bottom-1 );
     LineTo( hDC, rc.left, rc.top+2 );
 
-    if (!(text = (char*) USER_HEAP_LIN_ADDR( wndPtr->hText ))) return;
-    GetTextExtentPoint16( hDC, text, strlen(text), &size );
+    if (!wndPtr->text) return;
+    GetTextExtentPoint16( hDC, wndPtr->text, strlen(wndPtr->text), &size );
     rc.left  += 10;
     rc.right  = rc.left + size.cx + 1;
     rc.bottom = size.cy;
     if (wndPtr->dwStyle & WS_DISABLED)
         SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
-    DrawText16( hDC, text, -1, &rc, DT_SINGLELINE );
+    DrawText16( hDC, wndPtr->text, -1, &rc, DT_SINGLELINE );
 }
 
 
@@ -494,22 +505,19 @@
 
 static void OB_Paint( WND *wndPtr, HDC hDC, WORD action )
 {
-    DRAWITEMSTRUCT16 *dis;
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
+    DRAWITEMSTRUCT32 dis;
 
-    if (!(dis = SEGPTR_NEW(DRAWITEMSTRUCT16))) return;
-    dis->CtlType    = ODT_BUTTON;
-    dis->CtlID      = wndPtr->wIDmenu;
-    dis->itemID     = 0;
-    dis->itemAction = action;
-    dis->itemState  = (infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0 |
+    dis.CtlType    = ODT_BUTTON;
+    dis.CtlID      = wndPtr->wIDmenu;
+    dis.itemID     = 0;
+    dis.itemAction = action;
+    dis.itemState  = (infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0 |
                      (infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0 |
                      (wndPtr->dwStyle & WS_DISABLED) ? ODS_DISABLED : 0;
-    dis->hwndItem   = wndPtr->hwndSelf;
-    dis->hDC        = hDC;
-    GetClientRect16( wndPtr->hwndSelf, &dis->rcItem );
-    dis->itemData   = 0;
-    SendMessage( GetParent(wndPtr->hwndSelf), WM_DRAWITEM, 1,
-                 (LPARAM)SEGPTR_GET(dis) );
-    SEGPTR_FREE(dis);
+    dis.hwndItem   = wndPtr->hwndSelf;
+    dis.hDC        = hDC;
+    dis.itemData   = 0;
+    GetClientRect32( wndPtr->hwndSelf, &dis.rcItem );
+    SendMessage32A( GetParent(wndPtr->hwndSelf), WM_DRAWITEM, 1, (LPARAM)&dis);
 }
diff --git a/controls/combo.c b/controls/combo.c
index 46b4b9f..37e6718 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -73,7 +73,7 @@
   LPHEADCOMBO lphc;
 
   lphc = (LPHEADCOMBO)xmalloc(sizeof(HEADCOMBO));
-  SetWindowLong(hwnd,4,(LONG)lphc);
+  SetWindowLong32A(hwnd,4,(LONG)lphc);
   lphc->hWndEdit = 0;
   lphc->hWndLBox = 0;
   lphc->dwState = 0;
@@ -103,10 +103,10 @@
 
   createStruct = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
   createStruct->style |= WS_BORDER;
-  SetWindowLong(hwnd, GWL_STYLE, createStruct->style);
+  SetWindowLong32A(hwnd, GWL_STYLE, createStruct->style);
 
   dprintf_combo(stddeb,"ComboBox WM_NCCREATE!\n");
-  return DefWindowProc(hwnd, WM_NCCREATE, wParam, lParam);
+  return DefWindowProc16(hwnd, WM_NCCREATE, wParam, lParam);
 
 }
 
@@ -251,10 +251,10 @@
   hOldFont = SelectObject(hdc, lphl->hFont);
 
 #ifdef WINELIB32
-  hBrush = SendMessage(lphl->hParent, WM_CTLCOLORLISTBOX, hdc, hwnd);
+  hBrush = SendMessage32A(lphl->hParent, WM_CTLCOLORLISTBOX, hdc, hwnd);
 #else
-  hBrush = SendMessage(lphl->hParent, WM_CTLCOLOR, hdc,
-		       MAKELONG(hwnd, CTLCOLOR_LISTBOX));
+  hBrush = SendMessage16(lphl->hParent, WM_CTLCOLOR, hdc,
+                         MAKELONG(hwnd, CTLCOLOR_LISTBOX));
 #endif
   if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
 
@@ -290,7 +290,7 @@
 static LRESULT CBLButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
-  SendMessage(hwnd,CB_SHOWDROPDOWN,!lphc->DropDownVisible,0);
+  SendMessage16(hwnd,CB_SHOWDROPDOWN,!lphc->DropDownVisible,0);
   return 0;
 }
 
@@ -323,7 +323,7 @@
     newFocused = lphl->ItemsCount - 1;
   
   ListBoxSetCurSel(lphl, newFocused);
-  SendMessage(hwnd, WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
+  SendMessage16(hwnd, WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
   ListBoxSendNotification(lphl, CBN_SELCHANGE);
 
   lphl->ItemFocused = newFocused;
@@ -349,7 +349,7 @@
     newFocused = lphl->ItemsCount - 1;
   
   ListBoxSetCurSel(lphl, newFocused);
-  SendMessage(hwnd, WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
+  SendMessage16(hwnd, WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
   ListBoxSendNotification(lphl, CBN_SELCHANGE);
   lphl->ItemFocused = newFocused;
   ListBoxScrollToFocus(lphl);
@@ -555,7 +555,7 @@
   else
     lphl->hFont = (HFONT)wParam;
   if (lphc->hWndEdit)
-     SendMessage(lphc->hWndEdit,WM_SETFONT,lphl->hFont,0); 
+     SendMessage16(lphc->hWndEdit,WM_SETFONT,lphl->hFont,0); 
   return 0;
 }
 
@@ -691,14 +691,14 @@
                  { 
                   ListBoxGetText(lphl,lphl->ItemFocused, buffer);
                   dprintf_combo(stddeb,"CBCommand: update Edit: %s\n",buffer);
-                  SendMessage( lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(buffer));
+                  SetWindowText32A( lphc->hWndEdit, buffer );
                  }
                 break;
     case ID_EDIT:                                      /* update LISTBOX window */
                  id=GetWindowWord(hwnd,GWW_ID);
                  switch (HIWORD(lParam))
                  {
-                  case EN_UPDATE:GetWindowText(lphc->hWndEdit,buffer,255);
+                  case EN_UPDATE:GetWindowText32A(lphc->hWndEdit,buffer,255);
                                  if (*buffer)
                                  {
                                   newFocused=ListBoxFindString(lphl, -1, MAKE_SEGPTR(buffer));
@@ -711,13 +711,13 @@
                                    InvalidateRect32(hwnd, NULL, TRUE); 
                                   }
                                  }
-                                 SendMessage(GetParent(hwnd),WM_COMMAND,id,
+                                 SendMessage16(GetParent(hwnd),WM_COMMAND,id,
                                          MAKELONG(hwnd, CBN_EDITUPDATE));
                                  break;
-                  case EN_CHANGE:SendMessage(GetParent(hwnd),WM_COMMAND,id,
+                  case EN_CHANGE:SendMessage16(GetParent(hwnd),WM_COMMAND,id,
                                          MAKELONG(hwnd, CBN_EDITCHANGE));
                                  break;
-                  case EN_ERRSPACE:SendMessage(GetParent(hwnd),WM_COMMAND,id,
+                  case EN_ERRSPACE:SendMessage16(GetParent(hwnd),WM_COMMAND,id,
                                          MAKELONG(hwnd, CBN_ERRSPACE));
                                  break;
                 }
@@ -766,7 +766,7 @@
      case CB_SETITEMHEIGHT: return CBSetItemHeight(hwnd, wParam, lParam);
      case CB_SHOWDROPDOWN: return CBShowDropDown(hwnd, wParam, lParam);
     }
-    return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
 /*--------------------------------------------------------------------*/
@@ -848,7 +848,7 @@
   
   ListBoxSetCurSel(lphl, newFocused);
   ListBoxSendNotification(lphl, CBN_SELCHANGE);
-  SendMessage(GetParent(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
+  SendMessage16(GetParent(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
   lphl->ItemFocused = newFocused;
   ListBoxScrollToFocus(lphl);
   SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
@@ -946,7 +946,7 @@
  */
 static LRESULT CBLKillFocus( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
-/*  SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);*/
+/*  SendMessage16(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);*/
   return 0;
 }
 
@@ -956,7 +956,7 @@
 static LRESULT CBLActivate( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   if (wParam == WA_INACTIVE)
-    SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
+    SendMessage16(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
   return 0;
 }
 
@@ -1000,12 +1000,12 @@
      }
   else if (lphl->PrevFocused != lphl->ItemFocused) 
           {
-      		SendMessage(CLBoxGetCombo(hwnd),CB_SETCURSEL,lphl->ItemFocused,0);
-      		SendMessage(GetParent(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
+      		SendMessage16(CLBoxGetCombo(hwnd),CB_SETCURSEL,lphl->ItemFocused,0);
+      		SendMessage16(GetParent(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
       		ListBoxSendNotification(lphl, CBN_SELCHANGE);
      	  }
 
-  SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
+  SendMessage16(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
 
   return 0;
 }
@@ -1174,7 +1174,7 @@
      case WM_VSCROLL: return CBLVScroll(hwnd, wParam, lParam);
      case WM_SIZE: return CBLCheckSize(hwnd);
     }
-    return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
 /************************************************************************
@@ -1187,37 +1187,66 @@
 	return TRUE;
 }
 
-
-/************************************************************************
- * 					DlgDirListComboBox     [USER.195]
- */
-INT DlgDirListComboBox( HWND hDlg, SEGPTR path, INT idCBox,
-                        INT idStatic, UINT wType )
+static INT32 COMBO_DlgDirList( HWND32 hDlg, LPARAM path, INT32 idCBox,
+                               INT32 idStatic, UINT32 wType, BOOL32 unicode )
 {
-    INT ret = 0;
-
-    dprintf_combo( stddeb,"DlgDirListComboBox(%04x,%08lx,%d,%d,%04X) \n",
-                   hDlg, (DWORD)path, idCBox, idStatic, wType );
+    LRESULT res = 0;
 
     if (idCBox)
     {
-        SendDlgItemMessage( hDlg, idCBox, CB_RESETCONTENT, 0, 0 );
-        ret = (SendDlgItemMessage( hDlg, idCBox, CB_DIR,
-                                   wType, (LPARAM)path ) >= 0);
+        SendDlgItemMessage32A( hDlg, idCBox, CB_RESETCONTENT, 0, 0 );
+        if (unicode)
+            res = SendDlgItemMessage32W( hDlg, idCBox, CB_DIR, wType, path );
+        else
+            res = SendDlgItemMessage32A( hDlg, idCBox, CB_DIR, wType, path );
     }
     if (idStatic)
     {
+        char temp[512] = "A:\\";
         int drive = DRIVE_GetCurrentDrive();
-        const char *cwd = DRIVE_GetDosCwd(drive);
-        char *temp = SEGPTR_ALLOC( strlen(cwd) + 4 );
-        if (!temp) return FALSE;
-        strcpy( temp, "A:\\" );
         temp[0] += drive;
-        strcpy( temp + 3, cwd );
+        lstrcpyn( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
         AnsiLower( temp );
-        SendDlgItemMessage( hDlg, idStatic, WM_SETTEXT,
-                            0, (LPARAM)SEGPTR_GET(temp) );
-        SEGPTR_FREE(temp);
+        SetDlgItemText32A( hDlg, idStatic, temp );
     } 
-    return ret;
+    return (res >= 0);
+}
+
+
+/***********************************************************************
+ *           DlgDirListComboBox16   (USER.195)
+ */
+INT16 DlgDirListComboBox16( HWND16 hDlg, LPCSTR path, INT16 idCBox,
+                            INT16 idStatic, UINT16 wType )
+{
+    dprintf_combo( stddeb,"DlgDirListComboBox16(%04x,'%s',%d,%d,%04x)\n",
+                   hDlg, path, idCBox, idStatic, wType );
+    return COMBO_DlgDirList( hDlg, (LPARAM)path, idCBox,
+                             idStatic, wType, FALSE );
+}
+
+
+/***********************************************************************
+ *           DlgDirListComboBox32A   (USER32.143)
+ */
+INT32 DlgDirListComboBox32A( HWND32 hDlg, LPCSTR path, INT32 idCBox,
+                             INT32 idStatic, UINT32 wType )
+{
+    dprintf_combo( stddeb,"DlgDirListComboBox32A(%08x,'%s',%d,%d,%08X)\n",
+                   hDlg, path, idCBox, idStatic, wType );
+    return COMBO_DlgDirList( hDlg, (LPARAM)path, idCBox,
+                             idStatic, wType, FALSE );
+}
+
+
+/***********************************************************************
+ *           DlgDirListComboBox32W   (USER32.144)
+ */
+INT32 DlgDirListComboBox32W( HWND32 hDlg, LPCWSTR path, INT32 idCBox,
+                             INT32 idStatic, UINT32 wType )
+{
+    dprintf_combo( stddeb,"DlgDirListComboBox32W(%08x,%p,%d,%d,%08X)\n",
+                   hDlg, path, idCBox, idStatic, wType );
+    return COMBO_DlgDirList( hDlg, (LPARAM)path, idCBox,
+                             idStatic, wType, TRUE );
 }
diff --git a/controls/desktop.c b/controls/desktop.c
index 1e0c106..e70d85a 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -128,7 +128,8 @@
  *
  * Window procedure for the desktop window.
  */
-LRESULT DesktopWndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
+                        WPARAM32 wParam, LPARAM lParam )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
@@ -152,7 +153,10 @@
 
     case WM_SYSCOMMAND:
 	if ((wParam & 0xfff0) != SC_CLOSE) return 0;
-	ExitWindows( 0, 0 );
+	ExitWindows( 0, 0 ); 
+
+    case WM_SETCURSOR:
+        return (LRESULT)SetCursor( LoadCursor( 0, IDC_ARROW ) );
     }
     
     return 0;
diff --git a/controls/edit.c b/controls/edit.c
index 6bba8a3..4018290 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -84,10 +84,10 @@
 
 #ifdef WINELIB32
 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
-		SendMessage((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
+		SendMessage32A((wndPtr)->parent->hwndSelf, WM_CTLCOLOREDIT, \
 				(WPARAM)(hdc), (LPARAM)(wndPtr)->hwndSelf)
 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
-		SendMessage((wndPtr)->parent->hwndSelf, WM_COMMAND, \
+		SendMessage32A((wndPtr)->parent->hwndSelf, WM_COMMAND, \
 				MAKEWPARAM((wndPtr)->wIDmenu, wNotifyCode), \
 				(LPARAM)(wndPtr)->hwndSelf )
 #define DPRINTF_EDIT_MSG(str) \
@@ -96,10 +96,10 @@
 			(UINT)hwnd, (UINT)wParam, (DWORD)lParam)
 #else
 #define EDIT_SEND_CTLCOLOR(wndPtr,hdc) \
-		SendMessage((wndPtr)->parent->hwndSelf, WM_CTLCOLOR, \
+		SendMessage16((wndPtr)->parent->hwndSelf, WM_CTLCOLOR, \
 				(WPARAM)(hdc), MAKELPARAM((wndPtr)->hwndSelf, CTLCOLOR_EDIT))
 #define EDIT_NOTIFY_PARENT(wndPtr, wNotifyCode) \
-		SendMessage((wndPtr)->parent->hwndSelf, WM_COMMAND, \
+		SendMessage16((wndPtr)->parent->hwndSelf, WM_COMMAND, \
 				(wndPtr)->wIDmenu, \
 				MAKELPARAM((wndPtr)->hwndSelf, wNotifyCode))
 #define DPRINTF_EDIT_MSG(str) \
@@ -491,7 +491,7 @@
 	default:
 		if (msg >= WM_USER)
 			fprintf(stdnimp, "edit: undocumented message %d >= WM_USER, please report.\n", msg);
-		lResult = DefWindowProc(hwnd, msg, wParam, lParam);
+		lResult = DefWindowProc16(hwnd, msg, wParam, lParam);
 		break;
 	}
 	EDIT_ReleasePointer(wndPtr);
diff --git a/controls/listbox.c b/controls/listbox.c
index 9e40cba..25d4bfb 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -84,7 +84,7 @@
   HDC         hdc;
 
   lphl = (LPHEADLIST)xmalloc(sizeof(HEADLIST));
-  SetWindowLong(hwnd, 0, (LONG)lphl);
+  SetWindowLong32A(hwnd, 0, (LONG)lphl);
   ListBoxInitialize(lphl);
   lphl->DrawCtlType    = CtlType;
   lphl->CtlID          = GetWindowWord(hwnd,GWW_ID);
@@ -114,10 +114,10 @@
       ReleaseDC( 0, hdc );
   }
 
-  if (lphl->OwnerDrawn) {
+  if (lphl->OwnerDrawn)
+  {
     LISTSTRUCT dummyls;
     
-    lphl->hDrawItemStruct = USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT16));
     lphl->needMeasure = TRUE;
     dummyls.mis.CtlType    = lphl->DrawCtlType;
     dummyls.mis.CtlID      = lphl->CtlID;
@@ -126,8 +126,6 @@
     dummyls.mis.itemData   = 0;
 
     ListBoxAskMeasure(lphl,&dummyls);
-  } else {
-    lphl->hDrawItemStruct = 0;
   }
 
 /* WINELIBS list boxes do not operate on local heaps */
@@ -141,9 +139,6 @@
 
 void DestroyListBoxStruct(LPHEADLIST lphl)
 {
-  if (lphl->hDrawItemStruct)
-    USER_HEAP_FREE(lphl->hDrawItemStruct);
-
   /* XXX need to free lphl->Heap */
   GlobalFree16(lphl->HeapSel);
   free(lphl);
@@ -160,11 +155,11 @@
 {
   if (lphl->dwStyle & LBS_NOTIFY)
 #ifdef WINELIB32
-    SendMessage(lphl->hParent, WM_COMMAND,
-		MAKEWPARAM(lphl->CtlID,code), (LPARAM)lphl->hSelf);
+    SendMessage32A(lphl->hParent, WM_COMMAND,
+                   MAKEWPARAM(lphl->CtlID,code), (LPARAM)lphl->hSelf);
 #else
-    SendMessage(lphl->hParent, WM_COMMAND,
-		lphl->CtlID, MAKELONG(lphl->hSelf, code));
+    SendMessage16(lphl->hParent, WM_COMMAND,
+                  lphl->CtlID, MAKELONG(lphl->hSelf, code));
 #endif
 }
 
@@ -237,21 +232,22 @@
 void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, 
 		      RECT16 *rect, WORD itemAction, WORD itemState)
 {
-  if (lphl->OwnerDrawn) {
-    DRAWITEMSTRUCT16   *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct);
+    if (lphl->OwnerDrawn)
+    {
+        DRAWITEMSTRUCT32 dis;
 
-    dis->CtlID    = lpls->mis.CtlID;
-    dis->CtlType  = lpls->mis.CtlType;
-    dis->itemID   = lpls->mis.itemID;
-    dis->hDC      = hdc;
-    dis->hwndItem = hwnd;
-    dis->itemData = lpls->mis.itemData;
-    dis->itemAction = itemAction;
-    dis->itemState  = itemState;
-    dis->rcItem     = *rect;
-    SendMessage(lphl->hParent, WM_DRAWITEM,
-		0, (LPARAM)USER_HEAP_SEG_ADDR(lphl->hDrawItemStruct));
-  } else {
+        dis.CtlID      = lpls->mis.CtlID;
+        dis.CtlType    = lpls->mis.CtlType;
+        dis.itemID     = lpls->mis.itemID;
+        dis.hDC        = hdc;
+        dis.hwndItem   = hwnd;
+        dis.itemData   = lpls->mis.itemData;
+        dis.itemAction = itemAction;
+        dis.itemState  = itemState;
+        CONV_RECT16TO32( rect, &dis.rcItem );
+        SendMessage32A( lphl->hParent, WM_DRAWITEM, 0, (LPARAM)&dis );
+        return;
+    }
     if (itemAction == ODA_DRAWENTIRE || itemAction == ODA_SELECT) {
       int 	OldBkMode;
       DWORD 	dwOldTextColor = 0;
@@ -277,10 +273,8 @@
       }
       
       SetBkMode(hdc, OldBkMode);
-    } else DrawFocusRect16(hdc, rect);
-  }
-
-  return;
+    }
+    else DrawFocusRect16(hdc, rect);
 }
 
 
@@ -321,7 +315,7 @@
  
   *lpmeasure = lpls->mis;
   lpmeasure->itemHeight = lphl->StdItemHeight;
-  SendMessage(lphl->hParent, WM_MEASUREITEM, 0, (LPARAM)USER_HEAP_SEG_ADDR(hTemp));
+  SendMessage16(lphl->hParent, WM_MEASUREITEM, 0, (LPARAM)USER_HEAP_SEG_ADDR(hTemp));
 
   if (lphl->dwStyle & LBS_OWNERDRAWFIXED) {
     if (lpmeasure->itemHeight > lphl->StdItemHeight)
@@ -931,7 +925,7 @@
   if (y == -1) return 0;
 
   if (lphl->dwStyle & LBS_NOTIFY && y!= LB_ERR )
-     if( SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam) )
+     if( SendMessage16(lphl->hParent, WM_LBTRACKPOINT, y, lParam) )
          return 0;
 
 
@@ -986,7 +980,7 @@
 #ifndef WINELIB
   if (GetWindowLong(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT)
      if( DragDetect(lphl->hSelf,MAKEPOINT16(lParam)) )
-         SendMessage(lphl->hParent, WM_BEGINDRAG,0,0L);
+         SendMessage16(lphl->hParent, WM_BEGINDRAG,0,0L);
 #endif
   return 0;
 }
@@ -1014,11 +1008,11 @@
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
 #ifdef WINELIB32
-  SendMessage(lphl->hParent, WM_COMMAND, 
-	      MAKEWPARAM(GetWindowWord(hwnd,GWW_ID),LBN_DBLCLK),
-	      (LPARAM)hwnd);
+  SendMessage32A(lphl->hParent, WM_COMMAND, 
+                 MAKEWPARAM(GetWindowWord(hwnd,GWW_ID),LBN_DBLCLK),
+                 (LPARAM)hwnd);
 #else
-  SendMessage(lphl->hParent, WM_COMMAND, GetWindowWord(hwnd,GWW_ID),
+  SendMessage16(lphl->hParent, WM_COMMAND, GetWindowWord(hwnd,GWW_ID),
 		MAKELONG(hwnd, LBN_DBLCLK));
 #endif
 
@@ -1116,8 +1110,8 @@
 	case VK_NEXT:
 	     if ( lphl->dwStyle & LBS_WANTKEYBOARDINPUT )
 	        {
-		  newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_VKEYTOITEM,
-					              wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
+		  newFocused = (WORD)(INT)SendMessage16(lphl->hParent,WM_VKEYTOITEM,
+                                                        wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
 	          if ( newFocused == 0xFFFE ) return 0L;
                 }
 	     if ( newFocused == 0xFFFF ) 
@@ -1220,8 +1214,8 @@
 
   if ( (lphl->dwStyle & LBS_WANTKEYBOARDINPUT) && !(lphl->HasStrings))
        {
-        newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_CHARTOITEM,
-                                            wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
+        newFocused = (WORD)(INT)SendMessage16(lphl->hParent,WM_CHARTOITEM,
+                                              wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
         if ( newFocused == 0xFFFE ) return 0L;
        }
 
@@ -1320,11 +1314,11 @@
   hOldFont = SelectObject(hdc, lphl->hFont);
 
 #ifdef WINELIB32
-  hBrush = (HBRUSH) SendMessage(lphl->hParent, WM_CTLCOLORLISTBOX, (WPARAM)hdc,
-				(LPARAM)hwnd);
+  hBrush = (HBRUSH) SendMessage16(lphl->hParent, WM_CTLCOLORLISTBOX, (WPARAM)hdc,
+                                  (LPARAM)hwnd);
 #else
-  hBrush = SendMessage(lphl->hParent, WM_CTLCOLOR, hdc,
-		       MAKELONG(hwnd, CTLCOLOR_LISTBOX));
+  hBrush = SendMessage16(lphl->hParent, WM_CTLCOLOR, hdc,
+                         MAKELONG(hwnd, CTLCOLOR_LISTBOX));
 #endif
 
   if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
@@ -1948,7 +1942,7 @@
   if( ptrWnd )
       if( /* !(ptrWnd->dwExStyle & WS_EX_NOPARENTNOTIFY) && */ 
           ptrWnd->parent ) 
-          return SendMessage(ptrWnd->parent->hwndSelf,message,wParam,lParam);
+          return SendMessage16(ptrWnd->parent->hwndSelf,message,wParam,lParam);
   return 0;
 }
 
@@ -2032,7 +2026,7 @@
 		}
     }
     
-    return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
 
@@ -2045,10 +2039,10 @@
     INT i;
 
     dprintf_listbox( stddeb, "DlgDirSelect: %04x '%s' %d\n", hDlg, lpStr, id );
-    if ((i = SendDlgItemMessage( hDlg, id, LB_GETCURSEL, 0, 0 )) == LB_ERR)
+    if ((i = SendDlgItemMessage16( hDlg, id, LB_GETCURSEL, 0, 0 )) == LB_ERR)
         return FALSE;
     if (!(buffer = SEGPTR_ALLOC( 20 * sizeof(char) ))) return FALSE;
-    SendDlgItemMessage( hDlg, id, LB_GETTEXT, i, (LPARAM)SEGPTR_GET(buffer) );
+    SendDlgItemMessage16(hDlg, id, LB_GETTEXT, i, (LPARAM)SEGPTR_GET(buffer) );
     if (buffer[0] == '[')  /* drive or directory */
     {
         if (buffer[1] == '-')  /* drive */
@@ -2084,7 +2078,7 @@
 
 #define SENDMSG(msg,wparam,lparam) \
     ((attrib & DDL_POSTMSGS) ? PostMessage( hwnd, msg, wparam, lparam ) \
-                             : SendMessage( hwnd, msg, wparam, lparam ))
+                             : SendMessage16( hwnd, msg, wparam, lparam ))
 
     dprintf_listbox( stddeb, "DlgDirList: %04x '%s' %d %d %04x\n",
                      hDlg, filespec ? filespec : "NULL",
@@ -2135,6 +2129,8 @@
                          (LPARAM)spec ) == LB_ERR) return FALSE;
             if (!(temp = SEGPTR_ALLOC( 4*sizeof(char) ))) return FALSE;
             strcpy( temp, "*.*" );
+            /* FIXME: this won't work with PostMessage(), as temp will */
+            /* have been freed by the time we do a DispatchMessage().  */
             if (SENDMSG( LB_DIR, (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
                          (LPARAM)SEGPTR_GET(temp) ) == LB_ERR)
             {
@@ -2151,15 +2147,14 @@
 
     if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0))
     {
-        const char *cwd = DRIVE_GetDosCwd(drive);
-        char *temp = SEGPTR_ALLOC( strlen(cwd) + 4 );
-        if (!temp) return FALSE;
+        char temp[512];
+        int drive = DRIVE_GetCurrentDrive();
         strcpy( temp, "A:\\" );
         temp[0] += drive;
-        strcpy( temp + 3, cwd );
+        lstrcpyn( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
         AnsiLower( temp );
-        SENDMSG( WM_SETTEXT, 0, (LPARAM)SEGPTR_GET(temp) );
-        SEGPTR_FREE(temp);
+        /* Can't use PostMessage() here, because the string is on the stack */
+        SetDlgItemText32A( hDlg, idStatic, temp );
     }
     return TRUE;
 #undef SENDMSG
diff --git a/controls/menu.c b/controls/menu.c
index e36dea0..3372b74 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -28,9 +28,38 @@
 #include "message.h"
 #include "graphics.h"
 #include "resource.h"
+#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
+/* Menu item structure */
+typedef struct
+{
+    WORD	item_flags;    /* Item flags */
+    UINT	item_id;       /* Item or popup id */
+    RECT16      rect;          /* Item area (relative to menu window) */
+    WORD        xTab;          /* X position of text after Tab */
+    HBITMAP	hCheckBit;     /* Bitmap for checked item */
+    HBITMAP	hUnCheckBit;   /* Bitmap for unchecked item */
+    LPSTR       text;          /* Item text or bitmap handle */
+} MENUITEM;
+
+/* Popup menu structure */
+typedef struct
+{
+    WORD        wFlags;       /* Menu flags (MF_POPUP, MF_SYSMENU) */
+    WORD        wMagic;       /* Magic number */
+    HANDLE      hTaskQ;       /* Task queue for this menu */
+    WORD	Width;        /* Width of the whole menu */
+    WORD	Height;       /* Height of the whole menu */
+    WORD	nItems;       /* Number of items in the menu */
+    HWND	hWnd;	      /* Window containing the menu */
+    MENUITEM   *items;        /* Array of menu items */
+    UINT	FocusedItem;  /* Currently focused item */
+} POPUPMENU, *LPPOPUPMENU;
+
+#define MENU_MAGIC   0x554d  /* 'MU' */
+
   /* Dimension of the menu bitmaps */
 static WORD check_bitmap_width = 0, check_bitmap_height = 0;
 static WORD arrow_bitmap_width = 0, arrow_bitmap_height = 0;
@@ -55,16 +84,8 @@
 #define IS_STRING_ITEM(flags) (!((flags) & (MF_BITMAP | MF_OWNERDRAW | \
 			     MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR)))
 
-#define SET_OWNERDRAW_DATA(item,data)  \
-  ((item)->hText = LOWORD((DWORD)(data)), (item)->xTab = HIWORD((DWORD)(data)))
-
-#define GET_OWNERDRAW_DATA(item)  \
-  ((DWORD)MAKELONG( (WORD)(item)->hText, (item)->xTab ))
-
 extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down);  /* nonclient.c */
 
-HMENU MENU_CopySysMenu(void);
-
 static HBITMAP hStdCheck = 0;
 static HBITMAP hStdMnArrow = 0;
 static HMENU MENU_DefSysMenu = 0;  /* Default system menu */
@@ -77,6 +98,33 @@
 static WND* pTopPWnd   = 0;
 static UINT uSubPWndLevel = 0;
 
+
+/**********************************************************************
+ *           MENU_CopySysMenu
+ *
+ * Load a copy of the system menu.
+ */
+static HMENU MENU_CopySysMenu(void)
+{
+    HMENU hMenu;
+    HGLOBAL handle;
+    POPUPMENU *menu;
+
+    if (!(handle = SYSRES_LoadResource( SYSRES_MENU_SYSMENU ))) return 0;
+    hMenu = LoadMenuIndirect16( GlobalLock16( handle ) );
+    SYSRES_FreeResource( handle );
+    if (!hMenu)
+    {
+	dprintf_menu(stddeb,"No SYSMENU\n");
+	return 0;
+    }
+    menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hMenu);
+    menu->wFlags |= MF_SYSMENU | MF_POPUP;
+    dprintf_menu(stddeb,"CopySysMenu hMenu=%04x !\n", hMenu);
+    return hMenu;
+}
+
+
 /***********************************************************************
  *           MENU_Init
  *
@@ -134,30 +182,6 @@
 }
 
 
-/**********************************************************************
- *           MENU_CopySysMenu
- */
-HMENU MENU_CopySysMenu(void)
-{
-    HMENU hMenu;
-    HGLOBAL handle;
-    POPUPMENU *menu;
-
-    if (!(handle = SYSRES_LoadResource( SYSRES_MENU_SYSMENU ))) return 0;
-    hMenu = LoadMenuIndirect( WIN16_GlobalLock16( handle ) );
-    SYSRES_FreeResource( handle );
-    if (!hMenu)
-    {
-	dprintf_menu(stddeb,"No SYSMENU\n");
-	return 0;
-    }
-    menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hMenu);
-    menu->wFlags |= MF_SYSMENU | MF_POPUP;
-    dprintf_menu(stddeb,"CopySysMenu hMenu=%04x !\n", hMenu);
-    return hMenu;
-}
-
-
 /***********************************************************************
  *           MENU_IsInSysMenu
  *
@@ -190,18 +214,17 @@
 static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
 {
     POPUPMENU *menu;
-    MENUITEM *item;
     int i;
 
     if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(*hmenu))) return NULL;
-    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if (wFlags & MF_BYPOSITION)
     {
 	if (*nPos >= menu->nItems) return NULL;
-	return &item[*nPos];
+	return &menu->items[*nPos];
     }
     else
     {
+        MENUITEM *item = menu->items;
 	for (i = 0; i < menu->nItems; i++, item++)
 	{
 	    if (item->item_id == *nPos)
@@ -239,7 +262,7 @@
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return NULL;
     x -= wndPtr->rectWindow.left;
     y -= wndPtr->rectWindow.top;
-    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
+    item = menu->items;
     for (i = 0; i < menu->nItems; i++, item++)
     {
 	if ((x >= item->rect.left) && (x < item->rect.right) &&
@@ -262,7 +285,7 @@
 static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, UINT key )
 {
     POPUPMENU *menu;
-    LPMENUITEM lpitem;
+    MENUITEM *item;
     int i;
     LONG menuchar;
 
@@ -270,22 +293,22 @@
     if (!hmenu) return -1;
 
     menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
-    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
+    item = menu->items;
     key = toupper(key);
-    for (i = 0; i < menu->nItems; i++, lpitem++)
+    for (i = 0; i < menu->nItems; i++, item++)
     {
-	if (IS_STRING_ITEM(lpitem->item_flags))
+	if (IS_STRING_ITEM(item->item_flags))
 	{
-	    char *p = strchr( (char *)USER_HEAP_LIN_ADDR(lpitem->hText), '&' );
+	    char *p = strchr( item->text, '&' );
 	    if (p && (p[1] != '&') && (toupper(p[1]) == key)) return i;
 	}
     }
 #ifdef WINELIB32
-    menuchar = SendMessage( hwndOwner, WM_MENUCHAR, 
-			    MAKEWPARAM(key,menu->wFlags), hmenu );
+    menuchar = SendMessage32A( hwndOwner, WM_MENUCHAR, 
+                               MAKEWPARAM(key,menu->wFlags), hmenu );
 #else
-    menuchar = SendMessage( hwndOwner, WM_MENUCHAR, key,
-			    MAKELONG( menu->wFlags, hmenu ) );
+    menuchar = SendMessage16( hwndOwner, WM_MENUCHAR, key,
+                              MAKELONG( menu->wFlags, hmenu ) );
 #endif
     if (HIWORD(menuchar) == 2) return LOWORD(menuchar);
     if (HIWORD(menuchar) == 1) return -2;
@@ -298,7 +321,7 @@
  *
  * Calculate the size of the menu item and store it in lpitem->rect.
  */
-static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, HWND hwndOwner,
+static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
 			       int orgX, int orgY, BOOL menuBar )
 {
     DWORD dwSize;
@@ -312,10 +335,10 @@
         if (!(mis = SEGPTR_NEW(MEASUREITEMSTRUCT))) return;
         mis->CtlType    = ODT_MENU;
         mis->itemID     = lpitem->item_id;
-        mis->itemData   = GET_OWNERDRAW_DATA(lpitem);
+        mis->itemData   = (DWORD)lpitem->text;
         mis->itemHeight = 16;
         mis->itemWidth  = 30;
-        SendMessage( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)SEGPTR_GET(mis) );
+        SendMessage16( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)SEGPTR_GET(mis) );
         lpitem->rect.bottom += mis->itemHeight;
         lpitem->rect.right  += mis->itemWidth;
         dprintf_menu( stddeb, "DrawMenuItem: MeasureItem %04x %dx%d!\n",
@@ -340,7 +363,8 @@
     if (lpitem->item_flags & MF_BITMAP)
     {
 	BITMAP bm;
-        if (GetObject( (HBITMAP)lpitem->hText, sizeof(BITMAP), (LPSTR)&bm ))
+        if (GetObject( (HBITMAP16)(UINT32)lpitem->text,
+                       sizeof(BITMAP), (LPSTR)&bm ))
         {
             lpitem->rect.right  += bm.bmWidth;
             lpitem->rect.bottom += bm.bmHeight;
@@ -352,23 +376,24 @@
 
     if (IS_STRING_ITEM( lpitem->item_flags ))
     {
-        const char *text = (const char *)USER_HEAP_LIN_ADDR( lpitem->hText );
-        dwSize = GetTextExtent( hdc, text, strlen(text) );
+        dwSize = GetTextExtent( hdc, lpitem->text, strlen(lpitem->text) );
         lpitem->rect.right  += LOWORD(dwSize);
         lpitem->rect.bottom += MAX( HIWORD(dwSize), SYSMETRICS_CYMENU );
         lpitem->xTab = 0;
 
         if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE;
-        else if ((p = strchr( text, '\t' )) != NULL)
+        else if ((p = strchr( lpitem->text, '\t' )) != NULL)
         {
             /* Item contains a tab (only meaningful in popup menus) */
             lpitem->xTab = check_bitmap_width + MENU_TAB_SPACE + 
-                LOWORD( GetTextExtent( hdc, text, (int)(p - text) ));
+                LOWORD( GetTextExtent( hdc, lpitem->text,
+                                       (int)(p - lpitem->text) ));
             lpitem->rect.right += MENU_TAB_SPACE;
         }
         else
         {
-            if (strchr( text, '\b' )) lpitem->rect.right += MENU_TAB_SPACE;
+            if (strchr( lpitem->text, '\b' ))
+                lpitem->rect.right += MENU_TAB_SPACE;
             lpitem->xTab = lpitem->rect.right - check_bitmap_width 
                            - arrow_bitmap_width;
         }
@@ -383,19 +408,18 @@
  */
 static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner )
 {
-    LPMENUITEM  items, lpitem;
+    MENUITEM *lpitem;
     HDC hdc;
     int start, i;
     int orgX, orgY, maxX, maxTab, maxTabWidth;
 
     lppop->Width = lppop->Height = 0;
     if (lppop->nItems == 0) return;
-    items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems );
     hdc = GetDC( 0 );
     maxX = start = 0;
     while (start < lppop->nItems)
     {
-	lpitem = &items[start];
+	lpitem = &lppop->items[start];
 	orgX = maxX;
 	orgY = 0;
 	maxTab = maxTabWidth = 0;
@@ -418,7 +442,7 @@
 
 	  /* Finish the column (set all items to the largest width found) */
 	maxX = MAX( maxX, maxTab + maxTabWidth );
-	for (lpitem = &items[start]; start < i; start++, lpitem++)
+	for (lpitem = &lppop->items[start]; start < i; start++, lpitem++)
 	{
 	    lpitem->rect.right = maxX;
 	    if (IS_STRING_ITEM(lpitem->item_flags) && lpitem->xTab)
@@ -440,14 +464,13 @@
 static void MENU_MenuBarCalcSize( HDC hdc, LPRECT16 lprect, LPPOPUPMENU lppop,
 				  HWND hwndOwner )
 {
-    LPMENUITEM lpitem, items;
+    MENUITEM *lpitem;
     int start, i, orgX, orgY, maxY, helpPos;
 
     if ((lprect == NULL) || (lppop == NULL)) return;
     if (lppop->nItems == 0) return;
     dprintf_menu(stddeb,"MENU_MenuBarCalcSize left=%d top=%d right=%d bottom=%d\n", 
                  lprect->left, lprect->top, lprect->right, lprect->bottom);
-    items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems );
     lppop->Width  = lprect->right - lprect->left;
     lppop->Height = 0;
     maxY = lprect->top;
@@ -455,7 +478,7 @@
     helpPos = -1;
     while (start < lppop->nItems)
     {
-	lpitem = &items[start];
+	lpitem = &lppop->items[start];
 	orgX = lprect->left;
 	orgY = maxY;
 
@@ -476,7 +499,7 @@
 	}
 
 	  /* Finish the line (set all items to the largest height found) */
-	while (start < i) items[start++].rect.bottom = maxY;
+	while (start < i) lppop->items[start++].rect.bottom = maxY;
     }
 
     lprect->bottom = maxY;
@@ -486,7 +509,7 @@
       /* (if several lines, only move the last line) */
     if (helpPos != -1)
     {
-	lpitem = &items[lppop->nItems-1];
+	lpitem = &lppop->items[lppop->nItems-1];
 	orgY = lpitem->rect.top;
 	orgX = lprect->right;
 	for (i = lppop->nItems - 1; i >= helpPos; i--, lpitem--)
@@ -506,30 +529,28 @@
  *
  * Draw a single menu item.
  */
-static void MENU_DrawMenuItem( HWND hwnd, HDC hdc, LPMENUITEM lpitem,
+static void MENU_DrawMenuItem( HWND hwnd, HDC hdc, MENUITEM *lpitem,
 			       UINT height, BOOL menuBar )
 {
     RECT16 rect;
 
     if (lpitem->item_flags & MF_OWNERDRAW)
     {
-        DRAWITEMSTRUCT16 *dis;
+        DRAWITEMSTRUCT32 dis;
 
-        if (!(dis = SEGPTR_NEW(DRAWITEMSTRUCT16))) return;
         dprintf_menu( stddeb, "DrawMenuItem: Ownerdraw!\n" );
-        dis->CtlType   = ODT_MENU;
-        dis->itemID    = lpitem->item_id;
-        dis->itemData  = GET_OWNERDRAW_DATA(lpitem);
-        dis->itemState = 0;
-        if (lpitem->item_flags & MF_CHECKED) dis->itemState |= ODS_CHECKED;
-        if (lpitem->item_flags & MF_GRAYED)  dis->itemState |= ODS_GRAYED;
-        if (lpitem->item_flags & MF_HILITE)  dis->itemState |= ODS_SELECTED;
-        dis->itemAction = ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS;
-        dis->hwndItem   = hwnd;
-        dis->hDC        = hdc;
-        dis->rcItem     = lpitem->rect;
-        SendMessage( hwnd, WM_DRAWITEM, 0, (LPARAM)SEGPTR_GET(dis) );
-        SEGPTR_FREE(dis);
+        dis.CtlType   = ODT_MENU;
+        dis.itemID    = lpitem->item_id;
+        dis.itemData  = (DWORD)lpitem->text;
+        dis.itemState = 0;
+        if (lpitem->item_flags & MF_CHECKED) dis.itemState |= ODS_CHECKED;
+        if (lpitem->item_flags & MF_GRAYED)  dis.itemState |= ODS_GRAYED;
+        if (lpitem->item_flags & MF_HILITE)  dis.itemState |= ODS_SELECTED;
+        dis.itemAction = ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS;
+        dis.hwndItem   = hwnd;
+        dis.hDC        = hdc;
+        CONV_RECT16TO32( &lpitem->rect, &dis.rcItem );
+        SendMessage32A( hwnd, WM_DRAWITEM, 0, (LPARAM)&dis );
         return;
     }
 
@@ -614,39 +635,41 @@
 
     if (lpitem->item_flags & MF_BITMAP)
     {
-	GRAPH_DrawBitmap( hdc, (HBITMAP)lpitem->hText, rect.left, rect.top,
-                          0, 0, rect.right-rect.left, rect.bottom-rect.top );
+	GRAPH_DrawBitmap( hdc, (HBITMAP16)(UINT32)lpitem->text,
+                          rect.left, rect.top, 0, 0,
+                          rect.right-rect.left, rect.bottom-rect.top );
 	return;
     }
     /* No bitmap - process text if present */
     else if (IS_STRING_ITEM(lpitem->item_flags))
     {
 	register int i;
-        const char *text = (const char *)USER_HEAP_LIN_ADDR( lpitem->hText );
 
 	if (menuBar)
 	{
 	    rect.left += MENU_BAR_ITEMS_SPACE / 2;
 	    rect.right -= MENU_BAR_ITEMS_SPACE / 2;
-	    i = strlen( text );
+	    i = strlen( lpitem->text );
 	}
 	else
 	{
-	    for (i = 0; text[i]; i++)
-                if ((text[i] == '\t') || (text[i] == '\b')) break;
+	    for (i = 0; lpitem->text[i]; i++)
+                if ((lpitem->text[i] == '\t') || (lpitem->text[i] == '\b'))
+                    break;
 	}
 	
-	DrawText16( hdc, text, i, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+	DrawText16( hdc, lpitem->text, i, &rect,
+                    DT_LEFT | DT_VCENTER | DT_SINGLELINE );
 
-	if (text[i])  /* There's a tab or flush-right char */
+	if (lpitem->text[i])  /* There's a tab or flush-right char */
 	{
-	    if (text[i] == '\t')
+	    if (lpitem->text[i] == '\t')
 	    {
 		rect.left = lpitem->xTab;
-		DrawText16( hdc, text + i + 1, -1, &rect,
+		DrawText16( hdc, lpitem->text + i + 1, -1, &rect,
                             DT_LEFT | DT_VCENTER | DT_SINGLELINE );
 	    }
-	    else DrawText16( hdc, text + i + 1, -1, &rect,
+	    else DrawText16( hdc, lpitem->text + i + 1, -1, &rect,
                              DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
 	}
     }
@@ -669,8 +692,7 @@
     FillRect16( hdc, &rect, sysColorObjects.hbrushMenu );
     menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu || !menu->nItems) return;
-    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
-    for (i = menu->nItems; i > 0; i--, item++)
+    for (i = menu->nItems, item = menu->items; i > 0; i--, item++)
 	MENU_DrawMenuItem( hwnd, hdc, item, menu->Height, FALSE );
 }
 
@@ -683,7 +705,6 @@
 UINT MENU_DrawMenuBar(HDC hDC, LPRECT16 lprect, HWND hwnd, BOOL suppress_draw)
 {
     LPPOPUPMENU lppop;
-    LPMENUITEM lpitem;
     int i;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     
@@ -701,14 +722,14 @@
     LineTo( hDC, lprect->right, lprect->bottom );
 
     if (lppop->nItems == 0) return SYSMETRICS_CYMENU;
-    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
-    for (i = 0; i < lppop->nItems; i++, lpitem++)
+    for (i = 0; i < lppop->nItems; i++)
     {
-	MENU_DrawMenuItem( hwnd, hDC, lpitem, lppop->Height, TRUE );
+	MENU_DrawMenuItem( hwnd, hDC, &lppop->items[i], lppop->Height, TRUE );
     }
     return lppop->Height;
 } 
 
+
 /***********************************************************************
  *	     MENU_SwitchTPWndTo
  */
@@ -741,11 +762,10 @@
     if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
     {
-	MENUITEM *item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
-	item[menu->FocusedItem].item_flags &= ~(MF_HILITE | MF_MOUSESELECT);
+	menu->items[menu->FocusedItem].item_flags &= ~(MF_HILITE|MF_MOUSESELECT);
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
-    SendMessage( hwndOwner, WM_INITMENUPOPUP, (WPARAM)hmenu,
+    SendMessage16( hwndOwner, WM_INITMENUPOPUP, (WPARAM)hmenu,
 		 MAKELONG( id, (menu->wFlags & MF_SYSMENU) ? 1 : 0 ));
     MENU_PopupMenuCalcSize( menu, hwndOwner );
 
@@ -779,7 +799,7 @@
 	if( !skip_init )
 	  {
             MENU_SwitchTPWndTo(GetCurrentTask());
-	    SendMessage( pTopPWnd->hwndSelf, WM_USER, (WPARAM)hmenu, 0L);
+	    SendMessage16( pTopPWnd->hwndSelf, WM_USER, (WPARAM)hmenu, 0L);
 	  }
 	menu->hWnd = pTopPWnd->hwndSelf;
     }
@@ -805,16 +825,14 @@
 static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
                              BOOL sendMenuSelect )
 {
-    MENUITEM *items;
     LPPOPUPMENU lppop;
     HDC hdc;
 
     lppop = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!lppop->nItems) return;
-    items = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     if ((wIndex != NO_SELECTED_ITEM) && 
 	(wIndex != SYSMENU_SELECTED) &&
-	(items[wIndex].item_flags & MF_SEPARATOR))
+	(lppop->items[wIndex].item_flags & MF_SEPARATOR))
 	wIndex = NO_SELECTED_ITEM;
     if (lppop->FocusedItem == wIndex) return;
     if (lppop->wFlags & MF_POPUP) hdc = GetDC( lppop->hWnd );
@@ -827,9 +845,9 @@
 	    NC_DrawSysButton( lppop->hWnd, hdc, FALSE );
 	else
 	{
-	    items[lppop->FocusedItem].item_flags &=~(MF_HILITE|MF_MOUSESELECT);
-	    MENU_DrawMenuItem( lppop->hWnd, hdc, &items[lppop->FocusedItem], lppop->Height,
-			       !(lppop->wFlags & MF_POPUP) );
+	    lppop->items[lppop->FocusedItem].item_flags &=~(MF_HILITE|MF_MOUSESELECT);
+	    MENU_DrawMenuItem(lppop->hWnd,hdc,&lppop->items[lppop->FocusedItem],
+                              lppop->Height, !(lppop->wFlags & MF_POPUP) );
 	}
     }
 
@@ -843,44 +861,44 @@
             if (sendMenuSelect)
 #ifdef WINELIB32
 /* FIX: LostInfo */
-                SendMessage( hwndOwner, WM_MENUSELECT,
+                SendMessage32A( hwndOwner, WM_MENUSELECT,
                              MAKEWPARAM( WIN_FindWndPtr(lppop->hWnd)->hSysMenu,
                                          lppop->wFlags | MF_MOUSESELECT ),
                              (LPARAM)hmenu );
 #else
-                SendMessage( hwndOwner, WM_MENUSELECT,
+                SendMessage16( hwndOwner, WM_MENUSELECT,
                              WIN_FindWndPtr(lppop->hWnd)->hSysMenu,
                              MAKELONG(lppop->wFlags | MF_MOUSESELECT, hmenu));
 #endif
         }
 	else
 	{
-	    items[lppop->FocusedItem].item_flags |= MF_HILITE;
-	    MENU_DrawMenuItem( lppop->hWnd, hdc, &items[lppop->FocusedItem], lppop->Height,
-			       !(lppop->wFlags & MF_POPUP) );
+	    lppop->items[lppop->FocusedItem].item_flags |= MF_HILITE;
+	    MENU_DrawMenuItem( lppop->hWnd, hdc, &lppop->items[lppop->FocusedItem],
+                               lppop->Height, !(lppop->wFlags & MF_POPUP) );
             if (sendMenuSelect)
 #ifdef WINELIB32
-                SendMessage( hwndOwner, WM_MENUSELECT,
-                             MAKEWPARAM( items[lppop->FocusedItem].item_id,
-                                         items[lppop->FocusedItem].item_flags| 
+                SendMessage32A( hwndOwner, WM_MENUSELECT,
+                             MAKEWPARAM( lppop->items[lppop->FocusedItem].item_id,
+                                         lppop->items[lppop->FocusedItem].item_flags| 
                                          MF_MOUSESELECT ),
                              (LPARAM) hmenu );
 #else
-	        SendMessage( hwndOwner, WM_MENUSELECT,
-                             items[lppop->FocusedItem].item_id,
-                             MAKELONG( items[lppop->FocusedItem].item_flags | MF_MOUSESELECT, hmenu));
+	        SendMessage16( hwndOwner, WM_MENUSELECT,
+                             lppop->items[lppop->FocusedItem].item_id,
+                             MAKELONG( lppop->items[lppop->FocusedItem].item_flags | MF_MOUSESELECT, hmenu));
 #endif
 	}
     }
 #ifdef WINELIB32
 /* FIX: Lost Info */
     else if (sendMenuSelect)
-        SendMessage( hwndOwner, WM_MENUSELECT, 
+        SendMessage32A( hwndOwner, WM_MENUSELECT, 
                      MAKEWPARAM( (DWORD)hmenu, lppop->wFlags | MF_MOUSESELECT),
                      hmenu );
 #else
     else if (sendMenuSelect)
-        SendMessage( hwndOwner, WM_MENUSELECT, hmenu,
+        SendMessage16( hwndOwner, WM_MENUSELECT, hmenu,
                      MAKELONG( lppop->wFlags | MF_MOUSESELECT, hmenu ) );
 #endif
 
@@ -894,18 +912,16 @@
 static void MENU_SelectNextItem( HWND hwndOwner, HMENU hmenu )
 {
     int i;
-    MENUITEM *items;
     POPUPMENU *menu;
 
     menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
-    if (!menu->nItems) return;
-    items = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
+    if (!menu->items) return;
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
 	for (i = menu->FocusedItem+1; i < menu->nItems; i++)
 	{
-	    if (!(items[i].item_flags & MF_SEPARATOR))
+	    if (!(menu->items[i].item_flags & MF_SEPARATOR))
 	    {
 		MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
 		return;
@@ -919,7 +935,7 @@
     }
     for (i = 0; i < menu->nItems; i++)
     {
-	if (!(items[i].item_flags & MF_SEPARATOR))
+	if (!(menu->items[i].item_flags & MF_SEPARATOR))
 	{
 	    MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
 	    return;
@@ -936,18 +952,16 @@
 static void MENU_SelectPrevItem( HWND hwndOwner, HMENU hmenu )
 {
     int i;
-    MENUITEM *items;
     POPUPMENU *menu;
 
     menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
-    if (!menu->nItems) return;
-    items = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
+    if (!menu->items) return;
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
 	for (i = menu->FocusedItem - 1; i >= 0; i--)
 	{
-	    if (!(items[i].item_flags & MF_SEPARATOR))
+	    if (!(menu->items[i].item_flags & MF_SEPARATOR))
 	    {
 		MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
 		return;
@@ -961,7 +975,7 @@
     }
     for (i = menu->nItems - 1; i > 0; i--)
     {
-	if (!(items[i].item_flags & MF_SEPARATOR))
+	if (!(menu->items[i].item_flags & MF_SEPARATOR))
 	{
 	    MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
 	    return;
@@ -977,41 +991,38 @@
  *
  * Set an item flags, id and text ptr.
  */
-static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id, SEGPTR data)
+static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id, LPCSTR str )
 {
-    HANDLE hPrevText = IS_STRING_ITEM(item->item_flags) ? item->hText : 0;
+    LPSTR prevText = IS_STRING_ITEM(item->item_flags) ? item->text : NULL;
 
     if (IS_STRING_ITEM(flags))
     {
-        if (!data)
+        if (!str)
         {
             flags |= MF_SEPARATOR;
-            item->hText = 0;
+            item->text = NULL;
         }
         else
         {
-            char *str = (char *)PTR_SEG_TO_LIN(data);
-            HANDLE hText;
-            
+            LPSTR text;
             /* Item beginning with a backspace is a help item */
             if (*str == '\b')
             {
                 flags |= MF_HELP;
                 str++;
             }
-            if (!(hText = USER_HEAP_ALLOC( strlen(str)+1 ))) return FALSE;
-            item->hText = hText;
-            strcpy( (char *)USER_HEAP_LIN_ADDR( hText ), str );
+            if (!(text = HEAP_strdupA( SystemHeap, 0, str ))) return FALSE;
+            item->text = text;
         }
     }
-    else if (flags & MF_BITMAP) item->hText = (HANDLE)data;
-    else if (flags & MF_OWNERDRAW) SET_OWNERDRAW_DATA( item, data );
-    else item->hText = 0;
+    else if ((flags & MF_BITMAP) || (flags & MF_OWNERDRAW))
+        item->text = (LPSTR)str;
+    else item->text = NULL;
 
     item->item_flags = flags & ~(MF_HILITE | MF_MOUSESELECT);
     item->item_id    = id;
     SetRectEmpty16( &item->rect );
-    if (hPrevText) USER_HEAP_FREE( hPrevText );
+    if (prevText) HeapFree( SystemHeap, 0, prevText );
     return TRUE;
 }
 
@@ -1023,7 +1034,6 @@
  */
 static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags )
 {
-    HANDLE hNewItems;
     MENUITEM *newItems;
     POPUPMENU *menu;
 
@@ -1061,24 +1071,21 @@
 
     /* Create new items array */
 
-    hNewItems = USER_HEAP_ALLOC( sizeof(MENUITEM) * (menu->nItems+1) );
-    if (!hNewItems)
+    newItems = HeapAlloc( SystemHeap, 0, sizeof(MENUITEM) * (menu->nItems+1) );
+    if (!newItems)
     {
-        dprintf_menu( stddeb, "MENU_InsertMenu: allocation failed\n" );
+        dprintf_menu( stddeb, "MENU_InsertItem: allocation failed\n" );
         return NULL;
     }
-    newItems = (MENUITEM *) USER_HEAP_LIN_ADDR( hNewItems );
     if (menu->nItems > 0)
     {
 	  /* Copy the old array into the new */
-	MENUITEM *oldItems = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
-	if (pos > 0) memcpy( newItems, oldItems, pos * sizeof(MENUITEM) );
-	if (pos < menu->nItems) memcpy( &newItems[pos+1], &oldItems[pos],
+	if (pos > 0) memcpy( newItems, menu->items, pos * sizeof(MENUITEM) );
+	if (pos < menu->nItems) memcpy( &newItems[pos+1], &menu->items[pos],
 					(menu->nItems-pos)*sizeof(MENUITEM) );
-
-	USER_HEAP_FREE( menu->hItems );
+        HeapFree( SystemHeap, 0, menu->items );
     }
-    menu->hItems = hNewItems;
+    menu->items = newItems;
     menu->nItems++;
     memset( &newItems[pos], 0, sizeof(*newItems) );
     return &newItems[pos];
@@ -1088,39 +1095,43 @@
 /**********************************************************************
  *         MENU_ParseResource
  *
- * Parse a menu resource and add items to the menu.
+ * Parse a standard menu resource and add items to the menu.
  * Return a pointer to the end of the resource.
  */
-static SEGPTR MENU_ParseResource( SEGPTR res, HMENU hMenu )
+static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
 {
     WORD flags, id = 0;
-    SEGPTR data;
+    LPCSTR str;
 
     do
     {
-        flags = GET_WORD( PTR_SEG_TO_LIN( res ) );
+        flags = GET_WORD(res);
         res += sizeof(WORD);
         if (!(flags & MF_POPUP))
         {
-            id = GET_WORD( PTR_SEG_TO_LIN( res ) );
+            id = GET_WORD(res);
             res += sizeof(WORD);
         }
-        data = res;
-        res += strlen( (char *)PTR_SEG_TO_LIN(data) ) + 1;
         if (!IS_STRING_ITEM(flags))
             fprintf( stderr, "MENU_ParseResource: not a string item %04x\n",
                      flags );
+        str = res;
+        if (!unicode) res += strlen(str) + 1;
+        else res += (STRING32_lstrlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
         if (flags & MF_POPUP)
         {
             HMENU hSubMenu = CreatePopupMenu();
-            if (!hSubMenu) return (SEGPTR)0;
-            if (!(res = MENU_ParseResource( res, hSubMenu ))) return (SEGPTR)0;
-            AppendMenu( hMenu, flags, (UINT)hSubMenu, data );
+            if (!hSubMenu) return NULL;
+            if (!(res = MENU_ParseResource( res, hSubMenu, unicode )))
+                return NULL;
+            if (!unicode) AppendMenu32A( hMenu, flags, (UINT)hSubMenu, str );
+            else AppendMenu32W( hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str );
         }
-        else
+        else  /* Not a popup */
         {
-            if (!*(char *)PTR_SEG_TO_LIN(data)) data = 0;
-            AppendMenu( hMenu, flags, id, data );
+            if (!unicode) AppendMenu32A( hMenu, flags, id, *str ? str : NULL );
+            else AppendMenu32W( hMenu, flags, id,
+                                *(LPCWSTR)str ? (LPCWSTR)str : NULL );
         }
     } while (!(flags & MF_END));
     return res;
@@ -1142,7 +1153,7 @@
     else if (menu->FocusedItem == SYSMENU_SELECTED)
 	return WIN_FindWndPtr(menu->hWnd)->hSysMenu;
 
-    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
+    item = &menu->items[menu->FocusedItem];
     if (!(item->item_flags & MF_POPUP) || !(item->item_flags & MF_MOUSESELECT))
 	return 0;
     return (HMENU)item->item_id;
@@ -1169,7 +1180,7 @@
     }
     else
     {
-	item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
+	item = &menu->items[menu->FocusedItem];
 	if (!(item->item_flags & MF_POPUP) ||
 	    !(item->item_flags & MF_MOUSESELECT)) return;
 	item->item_flags &= ~MF_MOUSESELECT;
@@ -1213,7 +1224,7 @@
 	if (selectFirst) MENU_SelectNextItem( hwndOwner, wndPtr->hSysMenu );
 	return wndPtr->hSysMenu;
     }
-    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
+    item = &menu->items[menu->FocusedItem];
     if (!(item->item_flags & MF_POPUP) ||
 	(item->item_flags & (MF_GRAYED | MF_DISABLED))) return hmenu;
     item->item_flags |= MF_MOUSESELECT;
@@ -1284,7 +1295,7 @@
     POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu || !menu->nItems || (menu->FocusedItem == NO_SELECTED_ITEM) ||
 	(menu->FocusedItem == SYSMENU_SELECTED)) return TRUE;
-    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
+    item = &menu->items[menu->FocusedItem];
     if (!(item->item_flags & MF_POPUP))
     {
 	if (!(item->item_flags & (MF_GRAYED | MF_DISABLED)))
@@ -1693,7 +1704,7 @@
 	 uSubPWndLevel = 0;
     }
     MENU_SelectItem( hwnd, hmenu, NO_SELECTED_ITEM, FALSE );
-    SendMessage( hwnd, WM_MENUSELECT, 0, MAKELONG( 0xffff, 0 ) );
+    SendMessage16( hwnd, WM_MENUSELECT, 0, MAKELONG( 0xffff, 0 ) );
     fEndMenuCalled = FALSE;
     return TRUE;
 }
@@ -1708,11 +1719,11 @@
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     HideCaret(0);
-    SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 );
-    SendMessage( hwnd, WM_INITMENU, wndPtr->wIDmenu, 0 );
+    SendMessage16( hwnd, WM_ENTERMENULOOP, 0, 0 );
+    SendMessage16( hwnd, WM_INITMENU, wndPtr->wIDmenu, 0 );
     MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
 		    pt.x, pt.y, hwnd, NULL );
-    SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 );
+    SendMessage16( hwnd, WM_EXITMENULOOP, 0, 0 );
     ShowCaret(0);
 }
 
@@ -1748,8 +1759,8 @@
                                                 wndPtr->hSysMenu;
 
     HideCaret(0);
-    SendMessage( wndPtr->hwndSelf, WM_ENTERMENULOOP, 0, 0 );
-    SendMessage( wndPtr->hwndSelf, WM_INITMENU, wndPtr->wIDmenu, 0 );
+    SendMessage16( wndPtr->hwndSelf, WM_ENTERMENULOOP, 0, 0 );
+    SendMessage16( wndPtr->hwndSelf, WM_INITMENU, wndPtr->wIDmenu, 0 );
 
     /* find suitable menu entry 
      */
@@ -1763,7 +1774,7 @@
 	  {
 	    if( uItem == 0xFFFF ) 
                 MessageBeep(0);
-	    SendMessage( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
+	    SendMessage16( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
             ShowCaret(0);
 	    return;
 	  }
@@ -1778,7 +1789,7 @@
     MENU_TrackMenu( hTrackMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
 		    0, 0, wndPtr->hwndSelf, NULL );
 
-    SendMessage( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
+    SendMessage16( wndPtr->hwndSelf, WM_EXITMENULOOP, 0, 0 );
     ShowCaret(0);
 }
 
@@ -1869,7 +1880,7 @@
 #endif
         break;
     default:
-	return DefWindowProc(hwnd, message, wParam, lParam);
+	return DefWindowProc16(hwnd, message, wParam, lParam);
     }
     return 0;
 }
@@ -1899,34 +1910,68 @@
 
 
 /*******************************************************************
- *         ChangeMenu    (USER.153)
+ *         ChangeMenu16    (USER.153)
  */
-BOOL ChangeMenu( HMENU hMenu, UINT pos, SEGPTR data, UINT id, UINT flags )
+BOOL16 ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
+                     UINT16 id, UINT16 flags )
 {
-    dprintf_menu( stddeb,"ChangeMenu: menu=%04x pos=%d data=%08lx id=%04x flags=%04x\n",
+    dprintf_menu( stddeb,"ChangeMenu16: menu=%04x pos=%d data=%08lx id=%04x flags=%04x\n",
                   hMenu, pos, (DWORD)data, id, flags );
-    if (flags & MF_APPEND)
-    {
-        return AppendMenu( hMenu, flags & ~MF_APPEND, id, data );
-    }
-    if (flags & MF_DELETE)
-    {
-        /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
-        /* for MF_DELETE. We should check the parameters for all others */
-        /* MF_* actions also (anybody got a doc on ChangeMenu?). */
-        return DeleteMenu( hMenu, pos, flags & ~MF_DELETE );
-    }
-    if (flags & MF_CHANGE)
-    {
-        return ModifyMenu( hMenu, pos, flags & ~MF_CHANGE, id, data );
-    }
-    if (flags & MF_REMOVE)
-    {
-        return RemoveMenu( hMenu, flags & MF_BYPOSITION ? pos : id,
-                           flags & ~MF_REMOVE );
-    }
+    if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND,
+                                                id, data );
+    /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
+    /* for MF_DELETE. We should check the parameters for all others */
+    /* MF_* actions also (anybody got a doc on ChangeMenu?). */
+    if (flags & MF_DELETE) return DeleteMenu( hMenu, pos, flags & ~MF_DELETE );
+    if (flags & MF_CHANGE) return ModifyMenu16( hMenu, pos, flags & ~MF_CHANGE,
+                                                id, data );
+    if (flags & MF_REMOVE) return RemoveMenu( hMenu,
+                                              flags & MF_BYPOSITION ? pos : id,
+                                              flags & ~MF_REMOVE );
     /* Default: MF_INSERT */
-    return InsertMenu( hMenu, pos, flags, id, data );
+    return InsertMenu16( hMenu, pos, flags, id, data );
+}
+
+
+/*******************************************************************
+ *         ChangeMenu32A    (USER32.22)
+ */
+BOOL32 ChangeMenu32A( HMENU32 hMenu, UINT32 pos, LPCSTR data,
+                      UINT32 id, UINT32 flags )
+{
+    dprintf_menu( stddeb,"ChangeMenu32A: menu=%08x pos=%d data=%08lx id=%08x flags=%08x\n",
+                  hMenu, pos, (DWORD)data, id, flags );
+    if (flags & MF_APPEND) return AppendMenu32A( hMenu, flags & ~MF_APPEND,
+                                                 id, data );
+    if (flags & MF_DELETE) return DeleteMenu( hMenu, pos, flags & ~MF_DELETE );
+    if (flags & MF_CHANGE) return ModifyMenu32A(hMenu, pos, flags & ~MF_CHANGE,
+                                                id, data );
+    if (flags & MF_REMOVE) return RemoveMenu( hMenu,
+                                              flags & MF_BYPOSITION ? pos : id,
+                                              flags & ~MF_REMOVE );
+    /* Default: MF_INSERT */
+    return InsertMenu32A( hMenu, pos, flags, id, data );
+}
+
+
+/*******************************************************************
+ *         ChangeMenu32W    (USER32.23)
+ */
+BOOL32 ChangeMenu32W( HMENU32 hMenu, UINT32 pos, LPCWSTR data,
+                      UINT32 id, UINT32 flags )
+{
+    dprintf_menu( stddeb,"ChangeMenu32W: menu=%08x pos=%d data=%08lx id=%08x flags=%08x\n",
+                  hMenu, pos, (DWORD)data, id, flags );
+    if (flags & MF_APPEND) return AppendMenu32W( hMenu, flags & ~MF_APPEND,
+                                                 id, data );
+    if (flags & MF_DELETE) return DeleteMenu( hMenu, pos, flags & ~MF_DELETE );
+    if (flags & MF_CHANGE) return ModifyMenu32W(hMenu, pos, flags & ~MF_CHANGE,
+                                                id, data );
+    if (flags & MF_REMOVE) return RemoveMenu( hMenu,
+                                              flags & MF_BYPOSITION ? pos : id,
+                                              flags & ~MF_REMOVE );
+    /* Default: MF_INSERT */
+    return InsertMenu32W( hMenu, pos, flags, id, data );
 }
 
 
@@ -1952,23 +1997,23 @@
  */
 BOOL EnableMenuItem(HMENU hMenu, UINT wItemID, UINT wFlags)
 {
-    LPMENUITEM 	lpitem;
+    MENUITEM *item;
     dprintf_menu(stddeb,"EnableMenuItem (%04x, %04X, %04X) !\n", 
 		 hMenu, wItemID, wFlags);
-    if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return FALSE;
+    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return FALSE;
 
       /* We can't have MF_GRAYED and MF_DISABLED together */
     if (wFlags & MF_GRAYED)
     {
-	lpitem->item_flags = (lpitem->item_flags & ~MF_DISABLED) | MF_GRAYED;
+	item->item_flags = (item->item_flags & ~MF_DISABLED) | MF_GRAYED;
     }
     else if (wFlags & MF_DISABLED)
     {
-	lpitem->item_flags = (lpitem->item_flags & ~MF_GRAYED) | MF_DISABLED;
+	item->item_flags = (item->item_flags & ~MF_GRAYED) | MF_DISABLED;
     }
     else   /* MF_ENABLED */
     {
-	lpitem->item_flags &= ~(MF_GRAYED | MF_DISABLED);
+	item->item_flags &= ~(MF_GRAYED | MF_DISABLED);
     }
     return TRUE;
 }
@@ -1980,15 +2025,15 @@
 int GetMenuString( HMENU hMenu, UINT wItemID,
                    LPSTR str, short nMaxSiz, UINT wFlags )
 {
-    LPMENUITEM lpitem;
+    MENUITEM *item;
 
     dprintf_menu( stddeb, "GetMenuString: menu=%04x item=%04x ptr=%p len=%d flags=%04x\n",
                  hMenu, wItemID, str, nMaxSiz, wFlags );
     if (!str || !nMaxSiz) return 0;
     str[0] = '\0';
-    if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0;
-    if (!IS_STRING_ITEM(lpitem->item_flags)) return 0;
-    lstrcpyn( str, (char *)USER_HEAP_LIN_ADDR(lpitem->hText), nMaxSiz );
+    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0;
+    if (!IS_STRING_ITEM(item->item_flags)) return 0;
+    lstrcpyn( str, item->text, nMaxSiz );
     dprintf_menu( stddeb, "GetMenuString: returning '%s'\n", str );
     return strlen(str);
 }
@@ -2000,10 +2045,9 @@
 BOOL HiliteMenuItem(HWND hWnd, HMENU hMenu, UINT wItemID, UINT wHilite)
 {
     LPPOPUPMENU menu;
-    LPMENUITEM  lpitem;
     dprintf_menu(stddeb,"HiliteMenuItem(%04x, %04x, %04x, %04x);\n", 
                  hWnd, hMenu, wItemID, wHilite);
-    if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wHilite ))) return FALSE;
+    if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE;
     if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
     if (menu->FocusedItem == wItemID) return TRUE;
     MENU_HideSubPopups( hWnd, hMenu, FALSE );
@@ -2017,17 +2061,17 @@
  */
 UINT GetMenuState(HMENU hMenu, UINT wItemID, UINT wFlags)
 {
-    LPMENUITEM lpitem;
+    MENUITEM *item;
     dprintf_menu(stddeb,"GetMenuState(%04x, %04x, %04x);\n", 
 		 hMenu, wItemID, wFlags);
-    if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
-    if (lpitem->item_flags & MF_POPUP)
+    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
+    if (item->item_flags & MF_POPUP)
     {
-	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( (HMENU)lpitem->item_id );
+	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( (HMENU)item->item_id );
 	if (!menu) return -1;
 	else return (menu->nItems << 8) | (menu->wFlags & 0xff);
     }
-    else return lpitem->item_flags;
+    else return item->item_flags;
 }
 
 
@@ -2052,33 +2096,45 @@
 UINT GetMenuItemID(HMENU hMenu, int nPos)
 {
     LPPOPUPMENU	menu;
-    MENUITEM *item;
 
     dprintf_menu(stddeb,"GetMenuItemID(%04x, %d);\n", hMenu, nPos);
     if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1;
     if ((nPos < 0) || (nPos >= menu->nItems)) return -1;
-    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
-    if (item[nPos].item_flags & MF_POPUP) return -1;
-    return item[nPos].item_id;
+    if (menu->items[nPos].item_flags & MF_POPUP) return -1;
+    return menu->items[nPos].item_id;
 }
 
 
 /*******************************************************************
- *         InsertMenu    (USER.410)
+ *         InsertMenu16    (USER.410)
  */
-BOOL InsertMenu( HMENU hMenu, UINT pos, UINT flags, UINT id, SEGPTR data )
+BOOL16 InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
+                     UINT16 id, SEGPTR data )
+{
+    if (IS_STRING_ITEM(flags) && data)
+        return InsertMenu32A( hMenu, (INT32)(INT16)pos, flags, id,
+                              (LPSTR)PTR_SEG_TO_LIN(data) );
+    return InsertMenu32A( hMenu, (INT32)(INT16)pos, flags, id, (LPSTR)data );
+}
+
+
+/*******************************************************************
+ *         InsertMenu32A    (USER32.321)
+ */
+BOOL32 InsertMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                      UINT32 id, LPCSTR str )
 {
     MENUITEM *item;
 
-    if (IS_STRING_ITEM(flags) && data)
+    if (IS_STRING_ITEM(flags) && str)
         dprintf_menu( stddeb, "InsertMenu: %04x %d %04x %04x '%s'\n",
-                      hMenu, pos, flags, id, (char *)PTR_SEG_TO_LIN(data) );
+                      hMenu, pos, flags, id, str );
     else dprintf_menu( stddeb, "InsertMenu: %04x %d %04x %04x %08lx\n",
-                       hMenu, pos, flags, id, (DWORD)data );
+                       hMenu, pos, flags, id, (DWORD)str );
 
     if (!(item = MENU_InsertItem( hMenu, pos, flags ))) return FALSE;
 
-    if (!(MENU_SetItemData( item, flags, id, data )))
+    if (!(MENU_SetItemData( item, flags, id, str )))
     {
         RemoveMenu( hMenu, pos, flags );
         return FALSE;
@@ -2094,11 +2150,48 @@
 
 
 /*******************************************************************
- *         AppendMenu    (USER.411)
+ *         InsertMenu32W    (USER32.324)
  */
-BOOL AppendMenu( HMENU hMenu, UINT flags, UINT id, SEGPTR data )
+BOOL32 InsertMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                      UINT32 id, LPCWSTR str )
 {
-    return InsertMenu( hMenu, -1, flags | MF_BYPOSITION, id, data );
+    BOOL32 ret;
+
+    if (IS_STRING_ITEM(flags) && str)
+    {
+        LPSTR newstr = STRING32_DupUniToAnsi( str );
+        ret = InsertMenu32A( hMenu, pos, flags, id, newstr );
+        free( newstr );
+        return ret;
+    }
+    else return InsertMenu32A( hMenu, pos, flags, id, (LPCSTR)str );
+}
+
+
+/*******************************************************************
+ *         AppendMenu16    (USER.411)
+ */
+BOOL16 AppendMenu16( HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data )
+{
+    return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
+}
+
+
+/*******************************************************************
+ *         AppendMenu32A    (USER32.4)
+ */
+BOOL32 AppendMenu32A( HMENU32 hMenu, UINT32 flags, UINT32 id, LPCSTR data )
+{
+    return InsertMenu32A( hMenu, -1, flags | MF_BYPOSITION, id, data );
+}
+
+
+/*******************************************************************
+ *         AppendMenu32W    (USER32.5)
+ */
+BOOL32 AppendMenu32W( HMENU32 hMenu, UINT32 flags, UINT32 id, LPCWSTR data )
+{
+    return InsertMenu32W( hMenu, -1, flags | MF_BYPOSITION, id, data );
 }
 
 
@@ -2108,31 +2201,31 @@
 BOOL RemoveMenu(HMENU hMenu, UINT nPos, UINT wFlags)
 {
     LPPOPUPMENU	menu;
-    LPMENUITEM 	lpitem;
-	dprintf_menu(stddeb,"RemoveMenu (%04x, %04x, %04x) !\n", 
-		     hMenu, nPos, wFlags);
-    if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+    MENUITEM *item;
+
+    dprintf_menu(stddeb,"RemoveMenu (%04x, %04x, %04x)\n",hMenu, nPos, wFlags);
+    if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
     if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
     
       /* Remove item */
 
-    if (IS_STRING_ITEM(lpitem->item_flags) && lpitem->hText)
-	USER_HEAP_FREE(lpitem->hText);
+    if (IS_STRING_ITEM(item->item_flags) && item->text)
+        HeapFree( SystemHeap, 0, item->text );
     if (--menu->nItems == 0)
     {
-	USER_HEAP_FREE( menu->hItems );
-	menu->hItems = 0;
+        HeapFree( SystemHeap, 0, menu->items );
+        menu->items = NULL;
     }
     else
     {
 	while(nPos < menu->nItems)
 	{
-	    *lpitem = *(lpitem+1);
-	    lpitem++;
+	    *item = *(item+1);
+	    item++;
 	    nPos++;
 	}
-	menu->hItems = USER_HEAP_REALLOC( menu->hItems,
-					  menu->nItems * sizeof(MENUITEM) );
+        menu->items = HeapReAlloc( SystemHeap, 0, menu->items,
+                                   menu->nItems * sizeof(MENUITEM) );
     }
     return TRUE;
 }
@@ -2153,25 +2246,61 @@
 
 
 /*******************************************************************
- *         ModifyMenu    (USER.414)
+ *         ModifyMenu16    (USER.414)
  */
-BOOL ModifyMenu( HMENU hMenu, UINT pos, UINT flags, UINT id, SEGPTR data )
+BOOL16 ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
+                     UINT16 id, SEGPTR data )
+{
+    if (IS_STRING_ITEM(flags))
+        return ModifyMenu32A( hMenu, (INT32)(INT16)pos, flags, id,
+                              (LPSTR)PTR_SEG_TO_LIN(data) );
+    return ModifyMenu32A( hMenu, (INT32)(INT16)pos, flags, id, (LPSTR)data );
+}
+
+
+/*******************************************************************
+ *         ModifyMenu32A    (USER32.396)
+ */
+BOOL32 ModifyMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                      UINT32 id, LPCSTR str )
 {
     MENUITEM *item;
+    HMENU hMenu16 = hMenu;
+    UINT16 pos16 = pos;
 
     if (IS_STRING_ITEM(flags))
     {
 	dprintf_menu( stddeb, "ModifyMenu: %04x %d %04x %04x '%s'\n",
-                      hMenu, pos, flags, id,
-                      data ? (char *)PTR_SEG_TO_LIN(data) : "#NULL#");
-        if (!data) return FALSE;
+                      hMenu, pos, flags, id, str ? str : "#NULL#" );
+        if (!str) return FALSE;
     }
     else
+    {
 	dprintf_menu( stddeb, "ModifyMenu: %04x %d %04x %04x %08lx\n",
-                      hMenu, pos, flags, id, (DWORD)data );
-    if (!(item = MENU_FindItem( &hMenu, &pos, flags ))) return FALSE;
+                      hMenu, pos, flags, id, (DWORD)str );
+    }
 
-    return MENU_SetItemData( item, flags, id, data );
+    if (!(item = MENU_FindItem( &hMenu16, &pos16, flags ))) return FALSE;
+    return MENU_SetItemData( item, flags, id, str );
+}
+
+
+/*******************************************************************
+ *         ModifyMenu32W    (USER32.397)
+ */
+BOOL32 ModifyMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                      UINT32 id, LPCWSTR str )
+{
+    BOOL32 ret;
+
+    if (IS_STRING_ITEM(flags) && str)
+    {
+        LPSTR newstr = STRING32_DupUniToAnsi( str );
+        ret = ModifyMenu32A( hMenu, pos, flags, id, newstr );
+        free( newstr );
+        return ret;
+    }
+    else return ModifyMenu32A( hMenu, pos, flags, id, (LPCSTR)str );
 }
 
 
@@ -2205,23 +2334,23 @@
 BOOL SetMenuItemBitmaps(HMENU hMenu, UINT nPos, UINT wFlags,
                         HBITMAP hNewUnCheck, HBITMAP hNewCheck)
 {
-    LPMENUITEM lpitem;
-   dprintf_menu(stddeb,"SetMenuItemBitmaps(%04x, %04x, %04x, %04x, %04x)\n",
-                hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
-    if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+    MENUITEM *item;
+    dprintf_menu(stddeb,"SetMenuItemBitmaps(%04x, %04x, %04x, %04x, %04x)\n",
+                 hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
+    if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
 
     if (!hNewCheck && !hNewUnCheck)
     {
 	  /* If both are NULL, restore default bitmaps */
-	lpitem->hCheckBit   = hStdCheck;
-	lpitem->hUnCheckBit = 0;
-	lpitem->item_flags &= ~MF_USECHECKBITMAPS;
+	item->hCheckBit   = hStdCheck;
+	item->hUnCheckBit = 0;
+	item->item_flags &= ~MF_USECHECKBITMAPS;
     }
     else  /* Install new bitmaps */
     {
-	lpitem->hCheckBit   = hNewCheck;
-	lpitem->hUnCheckBit = hNewUnCheck;
-	lpitem->item_flags |= MF_USECHECKBITMAPS;
+	item->hCheckBit   = hNewCheck;
+	item->hUnCheckBit = hNewUnCheck;
+	item->item_flags |= MF_USECHECKBITMAPS;
     }
     return TRUE;
 }
@@ -2238,7 +2367,6 @@
     if (!(hMenu = USER_HEAP_ALLOC( sizeof(POPUPMENU) )))
 	return 0;
     menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
-    menu->hNext  = 0;
     menu->wFlags = 0;
     menu->wMagic = MENU_MAGIC;
     menu->hTaskQ = 0;
@@ -2246,7 +2374,7 @@
     menu->Height = 0;
     menu->nItems = 0;
     menu->hWnd   = 0;
-    menu->hItems = 0;
+    menu->items  = NULL;
     menu->FocusedItem = NO_SELECTED_ITEM;
     dprintf_menu(stddeb,"CreateMenu // return %04x\n", hMenu);
     return hMenu;
@@ -2270,18 +2398,18 @@
     if ((lppop->wFlags & MF_POPUP) && lppop->hWnd && lppop->hWnd != pTopPWnd->hwndSelf )
         DestroyWindow( lppop->hWnd );
 
-    if (lppop->hItems)
+    if (lppop->items)
     {
         int i;
-        MENUITEM *item = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
+        MENUITEM *item = lppop->items;
         for (i = lppop->nItems; i > 0; i--, item++)
         {
             if (item->item_flags & MF_POPUP)
                 DestroyMenu( (HMENU)item->item_id );
-	    if (IS_STRING_ITEM(item->item_flags) && item->hText)
-		USER_HEAP_FREE(item->hText);
+	    if (IS_STRING_ITEM(item->item_flags) && item->text)
+                HeapFree( SystemHeap, 0, item->text );
         }
-        USER_HEAP_FREE( lppop->hItems );
+        HeapFree( SystemHeap, 0, lppop->items );
     }
     USER_HEAP_FREE( hMenu );
     dprintf_menu(stddeb,"DestroyMenu (%04x) // End !\n", hMenu);
@@ -2375,13 +2503,12 @@
 HMENU GetSubMenu(HMENU hMenu, short nPos)
 {
     LPPOPUPMENU lppop;
-    LPMENUITEM 	lpitem;
+
     dprintf_menu(stddeb,"GetSubMenu (%04x, %04X) !\n", hMenu, nPos);
     if (!(lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return 0;
     if ((UINT)nPos >= lppop->nItems) return 0;
-    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
-    if (!(lpitem[nPos].item_flags & MF_POPUP)) return 0;
-    return (HMENU)lpitem[nPos].item_id;
+    if (!(lppop->items[nPos].item_flags & MF_POPUP)) return 0;
+    return (HMENU)lppop->items[nPos].item_id;
 }
 
 
@@ -2455,32 +2582,82 @@
 
     if (!(hRsrc = FindResource( instance, name, RT_MENU ))) return 0;
     if (!(handle = LoadResource( instance, hRsrc ))) return 0;
-    hMenu = LoadMenuIndirect( WIN16_LockResource(handle) );
+    hMenu = LoadMenuIndirect16( LockResource(handle) );
     FreeResource( handle );
     return hMenu;
 }
 
 
 /**********************************************************************
- *	    LoadMenuIndirect    (USER.220)
+ *	    LoadMenuIndirect16    (USER.220)
  */
-HMENU LoadMenuIndirect( SEGPTR template )
+HMENU16 LoadMenuIndirect16( LPCVOID template )
 {
     HMENU hMenu;
+    WORD version, offset;
+    LPCSTR p = (LPCSTR)template;
 
-    dprintf_menu(stddeb,"LoadMenuIndirect: %08lx\n", (DWORD)template );
-    if (!(hMenu = CreateMenu())) return (HMENU)0;
-    template += sizeof(MENU_HEADER);
-    if (!MENU_ParseResource( template, hMenu ))
+    dprintf_menu(stddeb,"LoadMenuIndirect32A: %p\n", template );
+    version = GET_WORD(p);
+    p += sizeof(WORD);
+    if (version)
+    {
+        fprintf( stderr, "LoadMenuIndirect16: version must be 0 for Win16\n" );
+        return 0;
+    }
+    offset = GET_WORD(p);
+    p += sizeof(WORD) + offset;
+    if (!(hMenu = CreateMenu())) return 0;
+    if (!MENU_ParseResource( p, hMenu, FALSE ))
     {
         DestroyMenu( hMenu );
-        return (HMENU)0;
+        return 0;
     }
     return hMenu;
 }
 
 
 /**********************************************************************
+ *	    LoadMenuIndirect32A    (USER32.370)
+ */
+HMENU32 LoadMenuIndirect32A( LPCVOID template )
+{
+    HMENU hMenu;
+    WORD version, offset;
+    LPCSTR p = (LPCSTR)template;
+
+    dprintf_menu(stddeb,"LoadMenuIndirect32A: %p\n", template );
+    version = GET_WORD(p);
+    p += sizeof(WORD);
+    if (version)
+    {
+        fprintf( stderr, "LoadMenuIndirect32A: version %d not supported.\n",
+                 version );
+        return 0;
+    }
+    offset = GET_WORD(p);
+    p += sizeof(WORD) + offset;
+    if (!(hMenu = CreateMenu())) return 0;
+    if (!MENU_ParseResource( p, hMenu, TRUE ))
+    {
+        DestroyMenu( hMenu );
+        return 0;
+    }
+    return hMenu;
+}
+
+
+/**********************************************************************
+ *	    LoadMenuIndirect32W    (USER32.371)
+ */
+HMENU32 LoadMenuIndirect32W( LPCVOID template )
+{
+    /* FIXME: is there anything different between A and W? */
+    return LoadMenuIndirect32A( template );
+}
+
+
+/**********************************************************************
  *		IsMenu    (USER.358)
  */
 BOOL IsMenu( HMENU hmenu )
diff --git a/controls/scroll.c b/controls/scroll.c
index 932f584..4bf9479 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -365,11 +365,11 @@
         if (nBar == SB_CTL)  /* Only scrollbar controls send WM_CTLCOLOR */
         {
 #ifdef WINELIB32
-            HBRUSH hbrush = SendMessage( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
+            HBRUSH hbrush = SendMessage32A( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
                                          hdc, hwnd );
 #else
-            HBRUSH hbrush = SendMessage( GetParent(hwnd), WM_CTLCOLOR, hdc,
-                                         MAKELONG(hwnd, CTLCOLOR_SCROLLBAR) );
+            HBRUSH hbrush = SendMessage16( GetParent(hwnd), WM_CTLCOLOR, hdc,
+                                          MAKELONG(hwnd, CTLCOLOR_SCROLLBAR) );
 #endif
             SelectObject( hdc, hbrush );
         }
@@ -525,11 +525,11 @@
         return;
     }
 #ifdef WINELIB32
-    SendMessage( GetParent(hwnd),
+    SendMessage32A( GetParent(hwnd),
                  (wndPtr->dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
                  msg, hwnd );
 #else
-    SendMessage( GetParent(hwnd),
+    SendMessage16( GetParent(hwnd),
                  (wndPtr->dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
                  msg, MAKELONG( 0, hwnd ));
 #endif
@@ -620,10 +620,10 @@
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
 #ifdef WINELIB32
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_LINEUP, hwndCtl );
 #else
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_LINEUP, MAKELONG( 0, hwndCtl ));
 #endif
                 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
@@ -643,10 +643,10 @@
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
 #ifdef WINELIB32
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_PAGEUP, hwndCtl );
 #else
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_PAGEUP, MAKELONG( 0, hwndCtl ));
 #endif
                 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
@@ -687,10 +687,10 @@
                 /* Save tracking info */
                 uTrackingPos = trackThumbPos + pos - lastClickPos;
 #ifdef WINELIB32
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              MAKEWPARAM(SB_THUMBTRACK,val), hwndCtl );
 #else
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_THUMBTRACK, MAKELONG( val, hwndCtl ));
 #endif
                 SCROLL_DrawMovingThumb( hdc, &rect, vertical,
@@ -708,10 +708,10 @@
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
 #ifdef WINELIB32
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_PAGEDOWN, hwndCtl );
 #else
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_PAGEDOWN, MAKELONG( 0, hwndCtl ));
 #endif
                 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
@@ -730,10 +730,10 @@
             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
             {
 #ifdef WINELIB32
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_LINEDOWN, hwndCtl );
 #else
-                SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+                SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_LINEDOWN, MAKELONG( 0, hwndCtl ));
 #endif
                 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
@@ -752,19 +752,19 @@
             UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
 #ifdef WINELIB32
-            SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+            SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                          MAKEWPARAM(SB_THUMBPOSITION,val), hwndCtl );
 #else
-            SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+            SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                          SB_THUMBPOSITION, MAKELONG( val, hwndCtl ) );
 #endif
         }
         else
 #ifdef WINELIB32
-            SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+            SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                          SB_ENDSCROLL, hwndCtl );
 #else
-            SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+            SendMessage16( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                          SB_ENDSCROLL, MAKELONG( 0, hwndCtl ) );
 #endif
         trackHitTest = SCROLL_NOWHERE;  /* Terminate tracking */
@@ -851,7 +851,7 @@
         fprintf(stdnimp,"ScrollBarWndProc: undocumented message %04x, please report\n", message );
 
     default:
-        return DefWindowProc( hwnd, message, wParam, lParam );
+        return DefWindowProc16( hwnd, message, wParam, lParam );
     }
     return 0;
 }
diff --git a/controls/static.c b/controls/static.c
index 7af526f..9384040 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -11,8 +11,6 @@
 #include "user.h"
 #include "static.h"
 
-extern void DEFWND_SetText( WND *wndPtr, LPSTR text );  /* windows/defwnd.c */
-
 static void STATIC_PaintTextfn( WND *wndPtr, HDC hdc );
 static void STATIC_PaintRectfn( WND *wndPtr, HDC hdc );
 static void STATIC_PaintIconfn( WND *wndPtr, HDC hdc );
@@ -70,14 +68,15 @@
 /***********************************************************************
  *           StaticWndProc
  */
-LONG StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+LRESULT StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-	LONG lResult = 0;
-	WND *wndPtr = WIN_FindWndPtr(hWnd);
-	LONG style = wndPtr->dwStyle & 0x0000000F;
-        STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
+    LRESULT lResult = 0;
+    WND *wndPtr = WIN_FindWndPtr(hWnd);
+    LONG style = wndPtr->dwStyle & 0x0000000F;
+    STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
-	switch (uMsg) {
+    switch (uMsg)
+    {
 	case WM_ENABLE:
 	    InvalidateRect32( hWnd, NULL, FALSE );
 	    break;
@@ -95,7 +94,7 @@
                 }
                 return 1;
             }
-            return DefWindowProc(hWnd, uMsg, wParam, lParam);
+            return DefWindowProc16(hWnd, uMsg, wParam, lParam);
 
 	case WM_CREATE:
 	    if (style < 0L || style > LAST_STATIC_TYPE)
@@ -114,7 +113,7 @@
             if (style == SS_ICON)
                 DestroyIcon( STATIC_SetIcon( wndPtr, 0 ) );
             else 
-                lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
+                lResult = DefWindowProc16(hWnd, uMsg, wParam, lParam);
             break;
 
 	case WM_PAINT:
@@ -174,7 +173,7 @@
 	    break;
 
 	default:
-		lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
+		lResult = DefWindowProc16(hWnd, uMsg, wParam, lParam);
 		break;
 	}
 
@@ -186,14 +185,12 @@
 {
     RECT16 rc;
     HBRUSH hBrush;
-    char *text;
     WORD wFormat;
 
     LONG style = wndPtr->dwStyle;
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
     GetClientRect16( wndPtr->hwndSelf, &rc);
-    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
 
     switch (style & 0x0000000F)
     {
@@ -226,15 +223,15 @@
 
     if (infoPtr->hFont) SelectObject( hdc, infoPtr->hFont );
 #ifdef WINELIB32
-    hBrush = SendMessage( GetParent(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
-                          hdc, wndPtr->hwndSelf );
+    hBrush = SendMessage32A( GetParent(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
+                             hdc, wndPtr->hwndSelf );
 #else
-    hBrush = SendMessage( GetParent(wndPtr->hwndSelf), WM_CTLCOLOR, (WORD)hdc,
-                          MAKELONG(wndPtr->hwndSelf, CTLCOLOR_STATIC));
+    hBrush = SendMessage16( GetParent(wndPtr->hwndSelf), WM_CTLCOLOR, (WORD)hdc,
+                            MAKELONG(wndPtr->hwndSelf, CTLCOLOR_STATIC));
 #endif
     if (!hBrush) hBrush = GetStockObject(WHITE_BRUSH);
     FillRect16(hdc, &rc, hBrush);
-    if (text) DrawText16( hdc, text, -1, &rc, wFormat );
+    if (wndPtr->text) DrawText16( hdc, wndPtr->text, -1, &rc, wFormat );
 }
 
 static void STATIC_PaintRectfn( WND *wndPtr, HDC hdc )
@@ -285,11 +282,11 @@
 
     GetClientRect16( wndPtr->hwndSelf, &rc);
 #ifdef WINELIB32
-    hbrush = SendMessage( GetParent(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
-                          hdc, wndPtr->hwndSelf );
+    hbrush = SendMessage32A( GetParent(wndPtr->hwndSelf), WM_CTLCOLORSTATIC,
+                             hdc, wndPtr->hwndSelf );
 #else
-    hbrush = SendMessage( GetParent(wndPtr->hwndSelf), WM_CTLCOLOR, hdc,
-                          MAKELONG(wndPtr->hwndSelf, CTLCOLOR_STATIC));
+    hbrush = SendMessage16( GetParent(wndPtr->hwndSelf), WM_CTLCOLOR, hdc,
+                            MAKELONG(wndPtr->hwndSelf, CTLCOLOR_STATIC));
 #endif
     FillRect16( hdc, &rc, hbrush );
     if (infoPtr->hIcon) DrawIcon( hdc, rc.left, rc.top, infoPtr->hIcon );
diff --git a/controls/widgets.c b/controls/widgets.c
index dc5a441..7205bc0 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -15,11 +15,8 @@
 #include "module.h"
 #include "heap.h"
 
-static WNDCLASS16 WIDGETS_BuiltinClasses[] =
+static WNDCLASS16 WIDGETS_BuiltinClasses16[] =
 {
-    { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
-          (WNDPROC16)"ButtonWndProc", 0, sizeof(BUTTONINFO),
-          0, 0, 0, 0, 0, (SEGPTR)"BUTTON" },
     { CS_GLOBALCLASS | CS_PARENTDC,
           (WNDPROC16)"StaticWndProc", 0, sizeof(STATICINFO),
           0, 0, 0, 0, 0, (SEGPTR)"STATIC" },
@@ -40,16 +37,25 @@
           0, 0, 0, 0, 0, (SEGPTR)"EDIT" },
     { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC16)"PopupMenuWndProc", 0, 8,
           0, 0, 0, 0, 0, (SEGPTR)POPUPMENU_CLASS_NAME },
-    { CS_GLOBALCLASS, (WNDPROC16)"DesktopWndProc", 0, sizeof(DESKTOPINFO),
-          0, 0, 0, 0, 0, (SEGPTR)DESKTOP_CLASS_NAME },
     { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC16)"DefDlgProc", 0, DLGWINDOWEXTRA,
           0, 0, 0, 0, 0, (SEGPTR)DIALOG_CLASS_NAME },
     { CS_GLOBALCLASS, (WNDPROC16)"MDIClientWndProc", 0, sizeof(MDICLIENTINFO),
           0, 0, 0, STOCK_LTGRAY_BRUSH, 0, (SEGPTR)"MDICLIENT" }
 };
 
-#define NB_BUILTIN_CLASSES \
-         (sizeof(WIDGETS_BuiltinClasses)/sizeof(WIDGETS_BuiltinClasses[0]))
+#define NB_BUILTIN_CLASSES16 \
+         (sizeof(WIDGETS_BuiltinClasses16)/sizeof(WIDGETS_BuiltinClasses16[0]))
+
+static WNDCLASS32A WIDGETS_BuiltinClasses32[] =
+{
+    { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
+          ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0, 0, 0, 0, "BUTTON" },
+    { CS_GLOBALCLASS, DesktopWndProc, 0, sizeof(DESKTOPINFO),
+          0, 0, 0, 0, 0, DESKTOP_CLASS_NAME }
+};
+
+#define NB_BUILTIN_CLASSES32 \
+         (sizeof(WIDGETS_BuiltinClasses32)/sizeof(WIDGETS_BuiltinClasses32[0]))
 
 
 /***********************************************************************
@@ -61,17 +67,33 @@
 {
     int i;
     char *name;
-    WNDCLASS16 *class = WIDGETS_BuiltinClasses;
+    WNDCLASS16 *class16  = WIDGETS_BuiltinClasses16;
+    WNDCLASS32A *class32 = WIDGETS_BuiltinClasses32;
 
     if (!(name = SEGPTR_ALLOC( 20 * sizeof(char) ))) return FALSE;
-    for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++)
+
+    /* Create 16-bit classes */
+
+    for (i = 0; i < NB_BUILTIN_CLASSES16; i++, class16++)
     {
-        strcpy( name, (char *)class->lpszClassName );
-        class->lpszClassName = SEGPTR_GET(name);
-        class->hCursor = LoadCursor( 0, IDC_ARROW );
-        class->lpfnWndProc = MODULE_GetWndProcEntry16( (char *)class->lpfnWndProc );
-        if (!RegisterClass16( class )) return FALSE;
+        strcpy( name, (char *)class16->lpszClassName );
+        class16->lpszClassName = SEGPTR_GET(name);
+        class16->hCursor = LoadCursor( 0, IDC_ARROW );
+        class16->lpfnWndProc = MODULE_GetWndProcEntry16( (char *)class16->lpfnWndProc );
+        if (!RegisterClass16( class16 )) return FALSE;
     }
+
+    /* Create 32-bit classes */
+
+    for (i = 0; i < NB_BUILTIN_CLASSES32; i++, class32++)
+    {
+        /* Just to make sure the string is > 0x10000 */
+        strcpy( name, (char *)class32->lpszClassName );
+        class32->lpszClassName = name;
+        class32->hCursor = LoadCursor( 0, IDC_ARROW );
+        if (!RegisterClass32A( class32 )) return FALSE;
+    }
+
     SEGPTR_FREE(name);
     return TRUE;
 }
diff --git a/files/drive.c b/files/drive.c
index c1b3e68..c51c2f5 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -5,6 +5,7 @@
  * Copyright 1996 Alexandre Julliard
  */
 
+#include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -477,6 +478,29 @@
 
 
 /***********************************************************************
+ *           GetDriveType32A   (KERNEL32.)
+ */
+WORD GetDriveType32A( LPCSTR root )
+{
+    dprintf_dosfs( stddeb, "GetDriveType32A(%s)\n", root );
+    if ((root[1] != ':') || (root[2] != '\\'))
+    {
+        fprintf( stderr, "GetDriveType32A: invalid root '%s'\n", root );
+        return DRIVE_DOESNOTEXIST;
+    }
+    switch(DRIVE_GetType(toupper(root[0]) - 'A'))
+    {
+    case TYPE_FLOPPY:  return DRIVE_REMOVABLE;
+    case TYPE_HD:      return DRIVE_FIXED;
+    case TYPE_CDROM:   return DRIVE_REMOVABLE;
+    case TYPE_NETWORK: return DRIVE_REMOTE;
+    case TYPE_INVALID:
+    default:           return DRIVE_CANNOTDETERMINE;
+    }
+}
+
+
+/***********************************************************************
  *           GetCurrentDirectory   (KERNEL.411)
  */
 UINT32 GetCurrentDirectory( UINT32 buflen, LPSTR buf )
@@ -499,3 +523,69 @@
 {
     return DRIVE_Chdir( DRIVE_GetCurrentDrive(), dir );
 }
+
+
+/***********************************************************************
+ *           GetLogicalDriveStrings32A   (KERNEL32.231)
+ */
+UINT32 GetLogicalDriveStrings32A( UINT32 len, LPSTR buffer )
+{
+    int drive, count;
+
+    for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
+        if (DRIVE_IsValid(drive)) count++;
+    if (count * 4 * sizeof(char) <= len)
+    {
+        LPSTR p = buffer;
+        for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
+            if (DRIVE_IsValid(drive))
+            {
+                *p++ = 'a' + drive;
+                *p++ = ':';
+                *p++ = '\\';
+                *p++ = '\0';
+            }
+        *p = '\0';
+    }
+    return count * 4 * sizeof(char);
+}
+
+
+/***********************************************************************
+ *           GetLogicalDriveStrings32W   (KERNEL32.232)
+ */
+UINT32 GetLogicalDriveStrings32W( UINT32 len, LPWSTR buffer )
+{
+    int drive, count;
+
+    for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
+        if (DRIVE_IsValid(drive)) count++;
+    if (count * 4 * sizeof(WCHAR) <= len)
+    {
+        LPWSTR p = buffer;
+        for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
+            if (DRIVE_IsValid(drive))
+            {
+                *p++ = (WCHAR)('a' + drive);
+                *p++ = (WCHAR)':';
+                *p++ = (WCHAR)'\\';
+                *p++ = (WCHAR)'\0';
+            }
+        *p = (WCHAR)'\0';
+    }
+    return count * 4 * sizeof(WCHAR);
+}
+
+
+/***********************************************************************
+ *           GetLogicalDrives   (KERNEL32.233)
+ */
+DWORD GetLogicalDrives(void)
+{
+    DWORD ret = 0;
+    int drive;
+
+    for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
+        if (DRIVE_IsValid(drive)) ret |= (1 << drive);
+    return ret;
+}
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index ae1834d..ea85539 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -48,7 +48,6 @@
 SPEC_FILES = $(DLLS:.spec=.S)
 
 C_SRCS = \
-	callback.c \
 	dummy.c \
 	relay.c
 
diff --git a/if1632/callback.c b/if1632/callback.c
index 313251c..1baeaa5 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -13,55 +13,6 @@
 #include "debug.h"
 
 
-/**********************************************************************
- *	     Catch    (KERNEL.55)
- */
-INT Catch( LPCATCHBUF lpbuf )
-{
-    STACK16FRAME *pFrame = CURRENT_STACK16;
-
-    dprintf_catch( stddeb, "Catch: buf=%p ss:sp=%04x:%04x\n",
-                   lpbuf, IF1632_Saved16_ss, IF1632_Saved16_sp );
-
-    /* Note: we don't save the current ss, as the catch buffer is */
-    /* only 9 words long. Hopefully no one will have the silly    */
-    /* idea to change the current stack before calling Throw()... */
-
-    lpbuf[0] = IF1632_Saved16_sp;
-    lpbuf[1] = LOWORD(IF1632_Saved32_esp);
-    lpbuf[2] = HIWORD(IF1632_Saved32_esp);
-    lpbuf[3] = pFrame->saved_ss;
-    lpbuf[4] = pFrame->saved_sp;
-    lpbuf[5] = pFrame->ds;
-    lpbuf[6] = pFrame->bp;
-    lpbuf[7] = pFrame->ip;
-    lpbuf[8] = pFrame->cs;
-    return 0;
-}
-
-
-/**********************************************************************
- *	     Throw    (KERNEL.56)
- */
-int Throw( LPCATCHBUF lpbuf, int retval )
-{
-    STACK16FRAME *pFrame;
-
-    dprintf_catch( stddeb, "Throw: buf=%p val=%04x ss:sp=%04x:%04x\n",
-                   lpbuf, retval, IF1632_Saved16_ss, IF1632_Saved16_sp );
-
-    IF1632_Saved16_sp  = lpbuf[0] - sizeof(WORD);
-    IF1632_Saved32_esp = MAKELONG( lpbuf[1], lpbuf[2] );
-    pFrame = CURRENT_STACK16;
-    pFrame->saved_ss   = lpbuf[3];
-    pFrame->saved_sp   = lpbuf[4];
-    pFrame->ds         = lpbuf[5];
-    pFrame->bp         = lpbuf[6];
-    pFrame->ip         = lpbuf[7];
-    pFrame->cs         = lpbuf[8];
-    pFrame->es         = 0;
-    return retval;
-}
 
 
 #endif /* !WINELIB */
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index ac1e982..fb441e5 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -36,7 +36,7 @@
 33  pascal16 LockCurrentTask(word) LockCurrentTask
 34  pascal SetTaskQueue(word word) SetTaskQueue
 35  pascal16 GetTaskQueue(word) GetTaskQueue
-36  pascal GetCurrentTask() GetCurrentTask
+36  pascal   GetCurrentTask() WIN16_GetCurrentTask
 37  pascal GetCurrentPDB() GetCurrentPDB
 38  stub SetTaskSignalProc
 41  return EnableDos 0 0
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 2582fac..5ff0b8c 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -210,7 +210,7 @@
 0205 stub GetDefaultCommConfigW
 0206 stub GetDiskFreeSpaceA
 0207 stub GetDiskFreeSpaceW
-0208 stub GetDriveTypeA
+0208 stdcall GetDriveTypeA(ptr) GetDriveType32A
 0209 stub GetDriveTypeW
 0210	stdcall GetEnvironmentStrings()	GetEnvironmentStrings
 0211 stub GetEnvironmentStringsA
@@ -233,9 +233,9 @@
 0228    stdcall GetLocalTime(ptr) GetLocalTime
 0229 stdcall GetLocaleInfoA(long long ptr long) GetLocaleInfoA
 0230 stub GetLocaleInfoW
-0231 stub GetLogicalDriveStringsA
-0232 stub GetLogicalDriveStringsW
-0233 stub GetLogicalDrives
+0231 stdcall GetLogicalDriveStringsA(long ptr) GetLogicalDriveStrings32A
+0232 stdcall GetLogicalDriveStringsW(long ptr) GetLogicalDriveStrings32W
+0233 stdcall GetLogicalDrives() GetLogicalDrives
 0234 stub GetMailslotInfo
 0235	stdcall GetModuleFileNameA(long ptr long) GetModuleFileNameA
 0236 stub GetModuleFileNameW
@@ -361,7 +361,7 @@
 0355 stub IsBadStringPtrA
 0356 stub IsBadStringPtrW
 0357 stdcall IsBadWritePtr(ptr long)	WIN32_IsBadWritePtr
-0358 stub IsDBCSLeadByte
+0358 return IsDBCSLeadByte 4 0
 0359 stub IsDBCSLeadByteEx
 0360 stub IsValidCodePage
 0361 stub IsValidLocale
diff --git a/if1632/relay.c b/if1632/relay.c
index 41ddc24..f14fd3b 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -286,3 +286,48 @@
         printf( ",%08x", *argptr );
     printf( ")\n" );
 }
+
+
+/**********************************************************************
+ *	     Catch    (KERNEL.55)
+ */
+INT Catch( LPCATCHBUF lpbuf )
+{
+    STACK16FRAME *pFrame = CURRENT_STACK16;
+
+    /* Note: we don't save the current ss, as the catch buffer is */
+    /* only 9 words long. Hopefully no one will have the silly    */
+    /* idea to change the current stack before calling Throw()... */
+
+    lpbuf[0] = IF1632_Saved16_sp;
+    lpbuf[1] = LOWORD(IF1632_Saved32_esp);
+    lpbuf[2] = HIWORD(IF1632_Saved32_esp);
+    lpbuf[3] = pFrame->saved_ss;
+    lpbuf[4] = pFrame->saved_sp;
+    lpbuf[5] = pFrame->ds;
+    lpbuf[6] = pFrame->bp;
+    lpbuf[7] = pFrame->ip;
+    lpbuf[8] = pFrame->cs;
+    return 0;
+}
+
+
+/**********************************************************************
+ *	     Throw    (KERNEL.56)
+ */
+int Throw( LPCATCHBUF lpbuf, int retval )
+{
+    STACK16FRAME *pFrame;
+
+    IF1632_Saved16_sp  = lpbuf[0] - sizeof(WORD);
+    IF1632_Saved32_esp = MAKELONG( lpbuf[1], lpbuf[2] );
+    pFrame = CURRENT_STACK16;
+    pFrame->saved_ss   = lpbuf[3];
+    pFrame->saved_sp   = lpbuf[4];
+    pFrame->ds         = lpbuf[5];
+    pFrame->bp         = lpbuf[6];
+    pFrame->ip         = lpbuf[7];
+    pFrame->cs         = lpbuf[8];
+    pFrame->es         = 0;
+    return retval;
+}
diff --git a/if1632/user.spec b/if1632/user.spec
index 9610bbe..e9b2b7c 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -35,8 +35,8 @@
 33  pascal16 GetClientRect(word ptr) GetClientRect16
 34  pascal16 EnableWindow(word word) EnableWindow
 35  pascal16 IsWindowEnabled(word) IsWindowEnabled
-36  pascal16 GetWindowText(word segptr word) WIN16_GetWindowText
-37  pascal16 SetWindowText(word segptr) WIN16_SetWindowText
+36  pascal16 GetWindowText(word segptr word) GetWindowText16
+37  pascal16 SetWindowText(word segptr) SetWindowText16
 38  pascal16 GetWindowTextLength(word) GetWindowTextLength
 39  pascal16 BeginPaint(word ptr) BeginPaint16
 40  pascal16 EndPaint(word ptr) EndPaint16
@@ -91,26 +91,26 @@
 89  pascal16 CreateDialog(word segptr word segptr) CreateDialog
 90  pascal16 IsDialogMessage(word ptr) IsDialogMessage
 91  pascal16 GetDlgItem(word word) GetDlgItem
-92  pascal16 SetDlgItemText(word word segptr) SetDlgItemText
-93  pascal16 GetDlgItemText(word word segptr word) GetDlgItemText
-94  pascal16 SetDlgItemInt(word word word word) SetDlgItemInt
+92  pascal16 SetDlgItemText(word word segptr) SetDlgItemText16
+93  pascal16 GetDlgItemText(word word segptr word) GetDlgItemText16
+94  pascal16 SetDlgItemInt(word word word word) SetDlgItemInt16
 95  pascal16 GetDlgItemInt(word word ptr word) GetDlgItemInt
 96  pascal16 CheckRadioButton(word word word word) CheckRadioButton
 97  pascal16 CheckDlgButton(word word word) CheckDlgButton
 98  pascal16 IsDlgButtonChecked(word word) IsDlgButtonChecked
 99  pascal16 DlgDirSelect(word ptr word) DlgDirSelect
 100 pascal16 DlgDirList(word segptr word word word) DlgDirList
-101 pascal   SendDlgItemMessage(word word word word long) SendDlgItemMessage
+101 pascal   SendDlgItemMessage(word word word word long) SendDlgItemMessage16
 102 pascal16 AdjustWindowRect(ptr long word) AdjustWindowRect16
 103 pascal16 MapDialogRect(word ptr) MapDialogRect16
 104 pascal16 MessageBeep(word) MessageBeep
 105 pascal16 FlashWindow(word word) FlashWindow
 106 pascal16 GetKeyState(word) GetKeyState
-107 pascal   DefWindowProc(word word word long) DefWindowProc
+107 pascal   DefWindowProc(word word word long) DefWindowProc16
 108 pascal16 GetMessage(segptr word word word) GetMessage
 109 pascal16 PeekMessage(ptr word word word word) PeekMessage
 110 pascal16 PostMessage(word word word long) PostMessage
-111 pascal   SendMessage(word word word long) SendMessage
+111 pascal   SendMessage(word word word long) SendMessage16
 112 pascal16 WaitMessage() WaitMessage
 113 pascal16 TranslateMessage(ptr) TranslateMessage
 114 pascal   DispatchMessage(ptr) DispatchMessage
@@ -135,7 +135,7 @@
 133 pascal16 GetWindowWord(word s_word) GetWindowWord
 134 pascal16 SetWindowWord(word s_word word) SetWindowWord
 135 pascal   GetWindowLong(word s_word) GetWindowLong
-136 pascal   SetWindowLong(word s_word long) SetWindowLong
+136 pascal   SetWindowLong(word s_word long) SetWindowLong16
 137 pascal16 OpenClipboard(word) OpenClipboard
 138 pascal16 CloseClipboard() CloseClipboard
 139 pascal16 EmptyClipboard() EmptyClipboard
@@ -152,7 +152,7 @@
 150 pascal16 LoadMenu(word segptr) LoadMenu
 151 pascal16 CreateMenu() CreateMenu
 152 pascal16 DestroyMenu(word) DestroyMenu
-153 pascal16 ChangeMenu(word word segptr word word) ChangeMenu
+153 pascal16 ChangeMenu(word word segptr word word) ChangeMenu16
 154 pascal16 CheckMenuItem(word word word) CheckMenuItem
 155 pascal16 EnableMenuItem(word word word) EnableMenuItem
 156 pascal16 GetSystemMenu(word word) GetSystemMenu
@@ -194,7 +194,7 @@
 192 pascal16 InSendMessage() InSendMessage
 193 pascal16 IsClipboardFormatAvailable(word) IsClipboardFormatAvailable
 194 pascal16 DlgDirSelectComboBox(word ptr word) DlgDirSelectComboBox
-195 pascal16 DlgDirListComboBox(word segptr word word word) DlgDirListComboBox
+195 pascal16 DlgDirListComboBox(word ptr word word word) DlgDirListComboBox16
 196 pascal   TabbedTextOut(word s_word s_word ptr s_word s_word ptr s_word)
              TabbedTextOut
 197 pascal   GetTabbedTextExtent(word ptr word word ptr) GetTabbedTextExtent
@@ -220,7 +220,7 @@
 217 pascal16 LookupMenuHandle(word s_word) LookupMenuHandle
 218 pascal16 DialogBoxIndirect(word word word segptr) DialogBoxIndirect
 219 pascal16 CreateDialogIndirect(word segptr word segptr) CreateDialogIndirect
-220 pascal16 LoadMenuIndirect(segptr) LoadMenuIndirect
+220 pascal16 LoadMenuIndirect(ptr) LoadMenuIndirect16
 221 pascal16 ScrollDC(word s_word s_word ptr ptr word ptr) ScrollDC
 222 pascal16 GetKeyboardState(ptr) GetKeyboardState
 223 pascal16 SetKeyboardState(ptr) SetKeyboardState
@@ -363,11 +363,11 @@
 408 pascal16 CreateCursorIconIndirect(word ptr ptr ptr)
 	     CreateCursorIconIndirect
 409 stub InitThreadInput
-410 pascal16 InsertMenu(word word word word segptr) InsertMenu
-411 pascal16 AppendMenu(word word word segptr) AppendMenu
+410 pascal16 InsertMenu(word word word word segptr) InsertMenu16
+411 pascal16 AppendMenu(word word word segptr) AppendMenu16
 412 pascal16 RemoveMenu(word word word) RemoveMenu
 413 pascal16 DeleteMenu(word word word) DeleteMenu
-414 pascal16 ModifyMenu(word word word word segptr) ModifyMenu
+414 pascal16 ModifyMenu(word word word word segptr) ModifyMenu16
 415 pascal16 CreatePopupMenu() CreatePopupMenu
 416 pascal16 TrackPopupMenu(word word s_word s_word s_word word ptr) TrackPopupMenu16
 417 pascal   GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions
@@ -390,9 +390,9 @@
 438 pascal16 AnsiLowerBuff(ptr word) AnsiLowerBuff
 441 stub InsertMenuItem
 443 stub GetMenuItemInfo
-445 pascal   DefFrameProc(word word word word long) DefFrameProc
+445 pascal   DefFrameProc(word word word word long) DefFrameProc16
 446 stub SetMenuItemInfo
-447 pascal   DefMDIChildProc(word word word long) DefMDIChildProc
+447 pascal   DefMDIChildProc(word word word long) DefMDIChildProc16
 448 stub DrawAnimatedRects
 449 stub DrawState
 450 stub CreateIconFromResourceEx
diff --git a/if1632/user32.spec b/if1632/user32.spec
index 4065b35..ecbbf4e 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -6,8 +6,8 @@
 0001 stdcall AdjustWindowRect(ptr long long) AdjustWindowRect32
 0002 stdcall AdjustWindowRectEx(ptr long long long) AdjustWindowRectEx32
 0003 stub AnyPopup
-0004 stub AppendMenuA
-0005 stub AppendMenuW
+0004 stdcall AppendMenuA(long long long ptr) AppendMenu32A
+0005 stdcall AppendMenuW(long long long ptr) AppendMenu32W
 0006 stub ArrangeIconicWindows
 0007 stub AttachThreadInput
 0008 stub BeginDeferWindowPos
@@ -24,8 +24,8 @@
 0019 stub CascadeChildWindows
 0020 stub CascadeWindows
 0021 stub ChangeClipboardChain
-0022 stub ChangeMenuA
-0023 stub ChangeMenuW
+0022 stdcall ChangeMenuA(long long ptr long long) ChangeMenu32A
+0023 stdcall ChangeMenuW(long long ptr long long) ChangeMenu32W
 0024 stub CharLowerA
 0025 stub CharLowerBuffA
 0026 stub CharLowerBuffW
@@ -90,7 +90,8 @@
 0081 stub CreatePopupMenu
 0082 stdcall CreateWindowExA(long ptr ptr long long long long long 
 				long long long ptr) CreateWindowEx32A
-0083 stub CreateWindowExW
+0083 stdcall CreateWindowExW(long ptr ptr long long long long long 
+				long long long ptr) CreateWindowEx32W
 0084 stub CreateWindowStationA
 0085 stub CreateWindowStationW
 0086 stub DdeAbandonTransaction
@@ -128,12 +129,12 @@
 0118 stub DdeUninitialize
 0119 stub DefDlgProcA
 0120 stub DefDlgProcW
-0121 stub DefFrameProcA
-0122 stub DefFrameProcW
-0123 stub DefMDIChildProcA
-0124 stub DefMDIChildProcW
-0125 stdcall DefWindowProcA(long long long long) USER32_DefWindowProcA
-0126 stub DefWindowProcW
+0121 stdcall DefFrameProcA(long long long long long) DefFrameProc32A
+0122 stdcall DefFrameProcW(long long long long long) DefFrameProc32W
+0123 stdcall DefMDIChildProcA(long long long long) DefMDIChildProc32A
+0124 stdcall DefMDIChildProcW(long long long long) DefMDIChildProc32W
+0125 stdcall DefWindowProcA(long long long long) DefWindowProc32A
+0126 stdcall DefWindowProcW(long long long long) DefWindowProc32W
 0127 stub DeferWindowPos
 0128 stub DeleteMenu
 0129 stub DestroyAcceleratorTable
@@ -152,8 +153,8 @@
 0140 stdcall DispatchMessageA(ptr) USER32_DispatchMessageA
 0141 stub DispatchMessageW
 0142 stub DlgDirListA
-0143 stub DlgDirListComboBoxA
-0144 stub DlgDirListComboBoxW
+0143 stdcall DlgDirListComboBoxA(long ptr long long long) DlgDirListComboBox32A
+0144 stdcall DlgDirListComboBoxW(long ptr long long long) DlgDirListComboBox32W
 0145 stub DlgDirListW
 0146 stub DlgDirSelectComboBoxExA
 0147 stub DlgDirSelectComboBoxExW
@@ -245,8 +246,8 @@
 0233 stub GetDlgCtrlID
 0234 stdcall GetDlgItem(long long) GetDlgItem
 0235 stdcall GetDlgItemInt(long long long long) GetDlgItemInt
-0236 stub GetDlgItemTextA
-0237 stub GetDlgItemTextW
+0236 stdcall GetDlgItemTextA(long long ptr long) GetDlgItemText32A
+0237 stdcall GetDlgItemTextW(long long ptr long) GetDlgItemText32W
 0238 stub GetDoubleClickTime
 0239 stub GetFocus
 0240 stub GetForegroundWindow
@@ -317,12 +318,12 @@
 0305 stub GetWindowLongW
 0306 stdcall GetWindowPlacement(long ptr) GetWindowPlacement32
 0307 stdcall GetWindowRect(long ptr) GetWindowRect32
-0308 stdcall GetWindowTextA(long segptr long) WIN16_GetWindowText
+0308 stdcall GetWindowTextA(long ptr long) GetWindowText32A
 0309 stub GetWindowTextLengthA
 0310 stub GetWindowTextLengthW
-0311 stub GetWindowTextW
+0311 stdcall GetWindowTextW(long ptr long) GetWindowText32W
 0312 stub GetWindowThreadProcessId
-0313 stub GetWindowWord
+0313 stdcall GetWindowWord(long long) GetWindowWord
 0314 stub GrayStringA
 0315 stub GrayStringW
 0316 stub HideCaret
@@ -330,10 +331,10 @@
 0318 stub ImpersonateDdeClientWindow
 0319 stub InSendMessage
 0320 stdcall InflateRect(ptr long long) InflateRect32
-0321 stub InsertMenuA
+0321 stdcall InsertMenuA(long long long long ptr) InsertMenu32A
 0322 stub InsertMenuItemA
 0323 stub InsertMenuItemW
-0324 stub InsertMenuW
+0324 stdcall InsertMenuW(long long long long ptr) InsertMenu32W
 0325 stub InternalGetWindowText
 0326 stdcall IntersectRect(ptr ptr ptr) IntersectRect32
 0327 stdcall InvalidateRect(long ptr long) InvalidateRect32
@@ -379,8 +380,8 @@
 0367 stub LoadKeyboardLayoutW
 0368 stub LoadLocalFonts
 0369 stdcall LoadMenuA(long ptr) WIN32_LoadMenuA
-0370 stdcall LoadMenuIndirectA(long ptr) WIN32_LoadMenuIndirectA
-0371 stdcall LoadMenuIndirectW(long ptr) WIN32_LoadMenuIndirectW
+0370 stdcall LoadMenuIndirectA(ptr) LoadMenuIndirect32A
+0371 stdcall LoadMenuIndirectW(ptr) LoadMenuIndirect32W
 0372 stdcall LoadMenuW(long ptr) WIN32_LoadMenuW
 0373 stub LoadRemoteFonts
 0374 	stdcall LoadStringA(long long ptr long) WIN32_LoadStringA
@@ -405,8 +406,8 @@
 0393 stub MessageBoxIndirectA
 0394 stub MessageBoxIndirectW
 0395 stub MessageBoxW
-0396 stub ModifyMenuA
-0397 stub ModifyMenuW
+0396 stdcall ModifyMenuA(long long long long ptr) ModifyMenu32A
+0397 stdcall ModifyMenuW(long long long long ptr) ModifyMenu32W
 0398 stdcall MoveWindow(long long long long long long) MoveWindow
 0399 stub MsgWaitForMultipleObjects
 0400 stub OemKeyScan
@@ -460,14 +461,14 @@
 0448 stub ScrollDC
 0449 stub ScrollWindow
 0450 stub ScrollWindowEx
-0451 stub SendDlgItemMessageA
-0452 stub SendDlgItemMessageW
-0453 stdcall SendMessageA(long long long long) SendMessage
+0451 stdcall SendDlgItemMessageA(long long long long long) SendDlgItemMessage32A
+0452 stdcall SendDlgItemMessageW(long long long long long) SendDlgItemMessage32W
+0453 stdcall SendMessageA(long long long long) SendMessage32A
 0454 stub SendMessageCallbackA
 0455 stub SendMessageCallbackW
 0456 stub SendMessageTimeoutA
 0457 stub SendMessageTimeoutW
-0458 stub SendMessageW
+0458 stdcall SendMessageW(long long long long) SendMessage32W
 0459 stub SendNotifyMessageA
 0460 stub SendNotifyMessageW
 0461 stub ServerSetFunctionPointers
@@ -485,9 +486,9 @@
 0473 stub SetCursorPos
 0474 stub SetDebugErrorLevel
 0475 stub SetDeskWallpaper
-0476 stdcall SetDlgItemInt(long long long long) SetDlgItemInt
-0477 stub SetDlgItemTextA
-0478 stub SetDlgItemTextW
+0476 stdcall SetDlgItemInt(long long long long) SetDlgItemInt32
+0477 stdcall SetDlgItemTextA(long long ptr) SetDlgItemText32A
+0478 stdcall SetDlgItemTextW(long long ptr) SetDlgItemText32W
 0479 stub SetDoubleClickTime
 0480 stub SetFocus
 0481 stub SetForegroundWindow
@@ -525,14 +526,14 @@
 0513 stub SetUserObjectSecurity
 0514 stub SetWindowContextHelpId
 0515 stub SetWindowFullScreenState
-0516 stub SetWindowLongA
-0517 stub SetWindowLongW
+0516 stdcall SetWindowLongA(long long long) SetWindowLong32A
+0517 stdcall SetWindowLongW(long long long) SetWindowLong32W
 0518 stdcall SetWindowPlacement(long ptr) SetWindowPlacement32
 0519 stub SetWindowPos
 0520 stub SetWindowStationUser
-0521 stdcall SetWindowTextA(long ptr)	SetWindowText
-0522 stub SetWindowTextW
-0523 stub SetWindowWord
+0521 stdcall SetWindowTextA(long ptr) SetWindowText32A
+0522 stdcall SetWindowTextW(long ptr) SetWindowText32W
+0523 stdcall SetWindowWord(long long long) SetWindowWord
 0524 stub SetWindowsHookA
 0525 stdcall SetWindowsHookExA(long long long long) SetWindowsHookEx32A
 0526 stub SetWindowsHookExW
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index fb7c614..00e6332 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -1,18 +1,14 @@
 name	wprocs
 type	win16
 
-1  pascal ButtonWndProc(word word word long) ButtonWndProc
 2  pascal StaticWndProc(word word word long) StaticWndProc
 3  pascal ScrollBarWndProc(word word word long) ScrollBarWndProc
 4  pascal ListBoxWndProc(word word word long) ListBoxWndProc
 5  pascal ComboBoxWndProc(word word word long) ComboBoxWndProc
 6  pascal EditWndProc(word word word long) EditWndProc
 7  pascal PopupMenuWndProc(word word word long) PopupMenuWndProc
-8  pascal DesktopWndProc(word word word long) DesktopWndProc
 9  pascal DefDlgProc(word word word long) DefDlgProc
 10 pascal MDIClientWndProc(word word word long) MDIClientWndProc
-11 pascal DefWindowProc(word word word long) DefWindowProc
-12 pascal DefMDIChildProc(word word word long) DefMDIChildProc
 13 pascal SystemMessageBoxProc(word word word long) SystemMessageBoxProc
 14 pascal FileOpenDlgProc(word word word long) FileOpenDlgProc
 15 pascal FileSaveDlgProc(word word word long) FileSaveDlgProc
diff --git a/if1632/wprocs32.spec b/if1632/wprocs32.spec
index 287a0a3..e49d04f 100644
--- a/if1632/wprocs32.spec
+++ b/if1632/wprocs32.spec
@@ -1,18 +1,15 @@
 name	wprocs32
 type	win32
 
-1  stdcall ButtonWndProc(long long long long) ButtonWndProc32
 2  stdcall StaticWndProc(long long long long) StaticWndProc32
 3  stdcall ScrollBarWndProc(long long long long) ScrollBarWndProc32
 4  stdcall ListBoxWndProc(long long long long) ListBoxWndProc32
 5  stdcall ComboBoxWndProc(long long long long) ComboBoxWndProc32
 6  stdcall EditWndProc(long long long long) EditWndProc32
 7  stdcall PopupMenuWndProc(long long long long) PopupMenuWndProc32
-8  stdcall DesktopWndProc(long long long long) DesktopWndProc32
 9  stdcall DefDlgProc(long long long long) DefDlgProc32
 10 stdcall MDIClientWndProc(long long long long) MDIClientWndProc32
-11 stdcall DefWindowProc(long long long long) DefWindowProc32
-12 stdcall DefMDIChildProc(long long long long) DefMDIChildProc32
+11 stdcall DefWindowProc(long long long long) DefWindowProc32A
 13 stdcall SystemMessageBoxProc(long long long long) SystemMessageBoxProc32
 14 stdcall FileOpenDlgProc(long long long long) FileOpenDlgProc32
 15 stdcall FileSaveDlgProc(long long long long) FileSaveDlgProc32
diff --git a/include/alias.h b/include/alias.h
deleted file mode 100644
index c6d93e3..0000000
--- a/include/alias.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * structure definitions for aliases
- *
- * Copyright 1995 Martin von Loewis
- *
- */
-
-#ifndef __WINE_ALIAS_H
-#define __WINE_ALIAS_H
-
-#include "wintypes.h"
-
-typedef struct
-{
-    DWORD  wine;
-    DWORD  win16;
-    DWORD  win32;
-} FUNCTIONALIAS;
-
-extern int ALIAS_UseAliases;
-
-typedef struct _ALIASHASH{
-	DWORD used;
-	int recno;
-} ALIASHASH;
-
-extern BOOL ALIAS_Init(void);
-extern void ALIAS_RegisterAlias( DWORD Wine, DWORD Win16Proc, DWORD Win32Proc);
-extern FUNCTIONALIAS* ALIAS_LookupAlias(DWORD);
-
-#endif  /* __WINE_ALIAS_H */
diff --git a/include/bitmap.h b/include/bitmap.h
index 5c3b763..db8db52 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -24,6 +24,9 @@
 #define BITMAP_GC(bmp) \
   (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC)
 
+#define BITMAP_WIDTH_BYTES(width,bpp) \
+    (((bpp) == 24) ? (width) * 4 : ((width) * (bpp) + 15) / 16 * 2)
+
 #define XCREATEIMAGE(image,width,height,bpp) \
 { \
     int width_bytes = DIB_GetImageWidthBytes( (width), (bpp) ); \
diff --git a/include/button.h b/include/button.h
index 28fdd82..b4f7ad7 100644
--- a/include/button.h
+++ b/include/button.h
@@ -28,7 +28,7 @@
 
 #define BUTTON_STATE(hwnd)     ((WIN_FindWndPtr(hwnd))->wExtra[0])
 
-extern LRESULT ButtonWndProc( HWND hWnd, UINT uMsg,
-                              WPARAM wParam, LPARAM lParam );
+extern LRESULT ButtonWndProc( HWND32 hWnd, UINT32 uMsg,
+                              WPARAM32 wParam, LPARAM lParam );
 
 #endif  /* BUTTON_H */
diff --git a/include/callback.h b/include/callback.h
index f252007..c636e60 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -36,6 +36,9 @@
 extern WORD CallTo16_word_lwww ( FARPROC, WORD, LONG, WORD, WORD, WORD );
 extern WORD CallTo16_word_wllwl( FARPROC, WORD, WORD, LONG, LONG, WORD, LONG );
 extern WORD CallTo16_word_wwlll( FARPROC, WORD, WORD, WORD, LONG, LONG, LONG );
+extern LONG CallTo16_long_lllllllwlwwwl( FARPROC, WORD, LONG, LONG, LONG,
+                                         LONG, LONG, LONG, LONG, WORD, LONG,
+                                         WORD, WORD, WORD, LONG );
 
 extern WORD CallTo16_regs_( FARPROC func, WORD ds, WORD es, WORD bp, WORD ax,
                             WORD bx, WORD cx, WORD dx, WORD si, WORD di );
@@ -68,7 +71,13 @@
     CallTo16_long_wwwl( func, ds, hwnd, msg, wParam, lParam )
 #define CallWordBreakProc( func, lpch, ichCurrent, cch, code ) \
     CallTo16_word_lwww( func, CURRENT_DS, lpch, ichCurrent, cch, code )
-
+#define CallWndProcNCCREATE16( func, ds, exStyle, clsName, winName, style, \
+                               x, y, cx, cy, hparent, hmenu, instance, \
+                               params, hwnd, msg, wParam, lParam ) \
+    CallTo16_long_lllllllwlwwwl( func, ds, exStyle, clsName, winName, style, \
+                                 MAKELONG(y,x), MAKELONG(cy,cx), \
+                                 MAKELONG(hmenu,hparent), instance, params, \
+                                 hwnd, msg, wParam, lParam )
 
 /* List of the 32-bit callback functions. This list is used  */
 /* by the build program to generate the file if1632/callto32.S */
diff --git a/include/class.h b/include/class.h
index 599fb23..b958529 100644
--- a/include/class.h
+++ b/include/class.h
@@ -17,8 +17,7 @@
     UINT32           magic;         /* Magic number */
     UINT32           cWindows;      /* Count of existing windows */
     UINT32           style;         /* Class style */
-    UINT32           flags;         /* Class flags (see below) */
-    WNDPROC16        lpfnWndProc;   /* 16-bit window procedure */ 
+    WNDPROC16        lpfnWndProc;   /* Window procedure */ 
     INT32            cbClsExtra;    /* Class extra bytes */
     INT32            cbWndExtra;    /* Window extra bytes */
     LPSTR            menuNameA;     /* Default menu name (ASCII string) */
@@ -33,9 +32,6 @@
     LONG             wExtra[1];     /* Class extra bytes */
 } CLASS;
 
-/* Class flags */
-#define CLASS_FLAG_UNICODE  0x0001  /* Window procedure expects Unicode */
-
 extern void CLASS_DumpClass( CLASS *class );
 extern void CLASS_WalkClasses(void);
 extern void CLASS_FreeModuleClasses( HMODULE hModule );
diff --git a/include/debug.h b/include/debug.h
index 0fe2002..0e0ab86 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -21,7 +21,6 @@
 #undef DEBUG_BITBLT
 #undef DEBUG_BITMAP
 #undef DEBUG_CARET
-#undef DEBUG_CATCH
 #undef DEBUG_CDAUDIO
 #undef DEBUG_CLASS
 #undef DEBUG_CLIPBOARD
@@ -88,7 +87,6 @@
 #undef DEBUG_TEXT
 #undef DEBUG_TIMER
 #undef DEBUG_TOOLHELP
-#undef DEBUG_UTILITY
 #undef DEBUG_VXD
 #undef DEBUG_WIN
 #undef DEBUG_WIN32
@@ -101,7 +99,6 @@
 #define DEBUG_BITBLT
 #define DEBUG_BITMAP
 #define DEBUG_CARET
-#define DEBUG_CATCH
 #define DEBUG_CDAUDIO
 #define DEBUG_CLASS
 #define DEBUG_CLIPBOARD
@@ -168,7 +165,6 @@
 #define DEBUG_TEXT
 #define DEBUG_TIMER
 #define DEBUG_TOOLHELP
-#define DEBUG_UTILITY
 #define DEBUG_VXD
 #define DEBUG_WIN
 #define DEBUG_WIN32
@@ -203,11 +199,6 @@
 #else
     0,
 #endif
-#ifdef DEBUG_CATCH
-    1,
-#else
-    0,
-#endif
 #ifdef DEBUG_CDAUDIO
     1,
 #else
@@ -538,11 +529,6 @@
 #else
     0,
 #endif
-#ifdef DEBUG_UTILITY
-    1,
-#else
-    0,
-#endif
 #ifdef DEBUG_VXD
     1,
 #else
@@ -636,21 +622,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_catch if(!debug_msg_enabled[5]) ; else fprintf
-#define debugging_catch debug_msg_enabled[5]
-#else
-#ifdef DEBUG_CATCH
-#define dprintf_catch fprintf
-#define debugging_catch 1
-#else
-#define dprintf_catch while(0) fprintf
-#define debugging_catch 0
-#endif
-#endif
-
-#ifdef DEBUG_RUNTIME
-#define dprintf_cdaudio if(!debug_msg_enabled[6]) ; else fprintf
-#define debugging_cdaudio debug_msg_enabled[6]
+#define dprintf_cdaudio if(!debug_msg_enabled[5]) ; else fprintf
+#define debugging_cdaudio debug_msg_enabled[5]
 #else
 #ifdef DEBUG_CDAUDIO
 #define dprintf_cdaudio fprintf
@@ -662,8 +635,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_class if(!debug_msg_enabled[7]) ; else fprintf
-#define debugging_class debug_msg_enabled[7]
+#define dprintf_class if(!debug_msg_enabled[6]) ; else fprintf
+#define debugging_class debug_msg_enabled[6]
 #else
 #ifdef DEBUG_CLASS
 #define dprintf_class fprintf
@@ -675,8 +648,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_clipboard if(!debug_msg_enabled[8]) ; else fprintf
-#define debugging_clipboard debug_msg_enabled[8]
+#define dprintf_clipboard if(!debug_msg_enabled[7]) ; else fprintf
+#define debugging_clipboard debug_msg_enabled[7]
 #else
 #ifdef DEBUG_CLIPBOARD
 #define dprintf_clipboard fprintf
@@ -688,8 +661,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_clipping if(!debug_msg_enabled[9]) ; else fprintf
-#define debugging_clipping debug_msg_enabled[9]
+#define dprintf_clipping if(!debug_msg_enabled[8]) ; else fprintf
+#define debugging_clipping debug_msg_enabled[8]
 #else
 #ifdef DEBUG_CLIPPING
 #define dprintf_clipping fprintf
@@ -701,8 +674,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_combo if(!debug_msg_enabled[10]) ; else fprintf
-#define debugging_combo debug_msg_enabled[10]
+#define dprintf_combo if(!debug_msg_enabled[9]) ; else fprintf
+#define debugging_combo debug_msg_enabled[9]
 #else
 #ifdef DEBUG_COMBO
 #define dprintf_combo fprintf
@@ -714,8 +687,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_comm if(!debug_msg_enabled[11]) ; else fprintf
-#define debugging_comm debug_msg_enabled[11]
+#define dprintf_comm if(!debug_msg_enabled[10]) ; else fprintf
+#define debugging_comm debug_msg_enabled[10]
 #else
 #ifdef DEBUG_COMM
 #define dprintf_comm fprintf
@@ -727,8 +700,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_commdlg if(!debug_msg_enabled[12]) ; else fprintf
-#define debugging_commdlg debug_msg_enabled[12]
+#define dprintf_commdlg if(!debug_msg_enabled[11]) ; else fprintf
+#define debugging_commdlg debug_msg_enabled[11]
 #else
 #ifdef DEBUG_COMMDLG
 #define dprintf_commdlg fprintf
@@ -740,8 +713,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_cursor if(!debug_msg_enabled[13]) ; else fprintf
-#define debugging_cursor debug_msg_enabled[13]
+#define dprintf_cursor if(!debug_msg_enabled[12]) ; else fprintf
+#define debugging_cursor debug_msg_enabled[12]
 #else
 #ifdef DEBUG_CURSOR
 #define dprintf_cursor fprintf
@@ -753,8 +726,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dc if(!debug_msg_enabled[14]) ; else fprintf
-#define debugging_dc debug_msg_enabled[14]
+#define dprintf_dc if(!debug_msg_enabled[13]) ; else fprintf
+#define debugging_dc debug_msg_enabled[13]
 #else
 #ifdef DEBUG_DC
 #define dprintf_dc fprintf
@@ -766,8 +739,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dde if(!debug_msg_enabled[15]) ; else fprintf
-#define debugging_dde debug_msg_enabled[15]
+#define dprintf_dde if(!debug_msg_enabled[14]) ; else fprintf
+#define debugging_dde debug_msg_enabled[14]
 #else
 #ifdef DEBUG_DDE
 #define dprintf_dde fprintf
@@ -779,8 +752,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dialog if(!debug_msg_enabled[16]) ; else fprintf
-#define debugging_dialog debug_msg_enabled[16]
+#define dprintf_dialog if(!debug_msg_enabled[15]) ; else fprintf
+#define debugging_dialog debug_msg_enabled[15]
 #else
 #ifdef DEBUG_DIALOG
 #define dprintf_dialog fprintf
@@ -792,8 +765,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dll if(!debug_msg_enabled[17]) ; else fprintf
-#define debugging_dll debug_msg_enabled[17]
+#define dprintf_dll if(!debug_msg_enabled[16]) ; else fprintf
+#define debugging_dll debug_msg_enabled[16]
 #else
 #ifdef DEBUG_DLL
 #define dprintf_dll fprintf
@@ -805,8 +778,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dosfs if(!debug_msg_enabled[18]) ; else fprintf
-#define debugging_dosfs debug_msg_enabled[18]
+#define dprintf_dosfs if(!debug_msg_enabled[17]) ; else fprintf
+#define debugging_dosfs debug_msg_enabled[17]
 #else
 #ifdef DEBUG_DOSFS
 #define dprintf_dosfs fprintf
@@ -818,8 +791,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_driver if(!debug_msg_enabled[19]) ; else fprintf
-#define debugging_driver debug_msg_enabled[19]
+#define dprintf_driver if(!debug_msg_enabled[18]) ; else fprintf
+#define debugging_driver debug_msg_enabled[18]
 #else
 #ifdef DEBUG_DRIVER
 #define dprintf_driver fprintf
@@ -831,8 +804,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_edit if(!debug_msg_enabled[20]) ; else fprintf
-#define debugging_edit debug_msg_enabled[20]
+#define dprintf_edit if(!debug_msg_enabled[19]) ; else fprintf
+#define debugging_edit debug_msg_enabled[19]
 #else
 #ifdef DEBUG_EDIT
 #define dprintf_edit fprintf
@@ -844,8 +817,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_enum if(!debug_msg_enabled[21]) ; else fprintf
-#define debugging_enum debug_msg_enabled[21]
+#define dprintf_enum if(!debug_msg_enabled[20]) ; else fprintf
+#define debugging_enum debug_msg_enabled[20]
 #else
 #ifdef DEBUG_ENUM
 #define dprintf_enum fprintf
@@ -857,8 +830,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_env if(!debug_msg_enabled[22]) ; else fprintf
-#define debugging_env debug_msg_enabled[22]
+#define dprintf_env if(!debug_msg_enabled[21]) ; else fprintf
+#define debugging_env debug_msg_enabled[21]
 #else
 #ifdef DEBUG_ENV
 #define dprintf_env fprintf
@@ -870,8 +843,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_event if(!debug_msg_enabled[23]) ; else fprintf
-#define debugging_event debug_msg_enabled[23]
+#define dprintf_event if(!debug_msg_enabled[22]) ; else fprintf
+#define debugging_event debug_msg_enabled[22]
 #else
 #ifdef DEBUG_EVENT
 #define dprintf_event fprintf
@@ -883,8 +856,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_exec if(!debug_msg_enabled[24]) ; else fprintf
-#define debugging_exec debug_msg_enabled[24]
+#define dprintf_exec if(!debug_msg_enabled[23]) ; else fprintf
+#define debugging_exec debug_msg_enabled[23]
 #else
 #ifdef DEBUG_EXEC
 #define dprintf_exec fprintf
@@ -896,8 +869,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_file if(!debug_msg_enabled[25]) ; else fprintf
-#define debugging_file debug_msg_enabled[25]
+#define dprintf_file if(!debug_msg_enabled[24]) ; else fprintf
+#define debugging_file debug_msg_enabled[24]
 #else
 #ifdef DEBUG_FILE
 #define dprintf_file fprintf
@@ -909,8 +882,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_fixup if(!debug_msg_enabled[26]) ; else fprintf
-#define debugging_fixup debug_msg_enabled[26]
+#define dprintf_fixup if(!debug_msg_enabled[25]) ; else fprintf
+#define debugging_fixup debug_msg_enabled[25]
 #else
 #ifdef DEBUG_FIXUP
 #define dprintf_fixup fprintf
@@ -922,8 +895,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_font if(!debug_msg_enabled[27]) ; else fprintf
-#define debugging_font debug_msg_enabled[27]
+#define dprintf_font if(!debug_msg_enabled[26]) ; else fprintf
+#define debugging_font debug_msg_enabled[26]
 #else
 #ifdef DEBUG_FONT
 #define dprintf_font fprintf
@@ -935,8 +908,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_gdi if(!debug_msg_enabled[28]) ; else fprintf
-#define debugging_gdi debug_msg_enabled[28]
+#define dprintf_gdi if(!debug_msg_enabled[27]) ; else fprintf
+#define debugging_gdi debug_msg_enabled[27]
 #else
 #ifdef DEBUG_GDI
 #define dprintf_gdi fprintf
@@ -948,8 +921,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_global if(!debug_msg_enabled[29]) ; else fprintf
-#define debugging_global debug_msg_enabled[29]
+#define dprintf_global if(!debug_msg_enabled[28]) ; else fprintf
+#define debugging_global debug_msg_enabled[28]
 #else
 #ifdef DEBUG_GLOBAL
 #define dprintf_global fprintf
@@ -961,8 +934,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_graphics if(!debug_msg_enabled[30]) ; else fprintf
-#define debugging_graphics debug_msg_enabled[30]
+#define dprintf_graphics if(!debug_msg_enabled[29]) ; else fprintf
+#define debugging_graphics debug_msg_enabled[29]
 #else
 #ifdef DEBUG_GRAPHICS
 #define dprintf_graphics fprintf
@@ -974,8 +947,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_heap if(!debug_msg_enabled[31]) ; else fprintf
-#define debugging_heap debug_msg_enabled[31]
+#define dprintf_heap if(!debug_msg_enabled[30]) ; else fprintf
+#define debugging_heap debug_msg_enabled[30]
 #else
 #ifdef DEBUG_HEAP
 #define dprintf_heap fprintf
@@ -987,8 +960,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_hook if(!debug_msg_enabled[32]) ; else fprintf
-#define debugging_hook debug_msg_enabled[32]
+#define dprintf_hook if(!debug_msg_enabled[31]) ; else fprintf
+#define debugging_hook debug_msg_enabled[31]
 #else
 #ifdef DEBUG_HOOK
 #define dprintf_hook fprintf
@@ -1000,8 +973,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_icon if(!debug_msg_enabled[33]) ; else fprintf
-#define debugging_icon debug_msg_enabled[33]
+#define dprintf_icon if(!debug_msg_enabled[32]) ; else fprintf
+#define debugging_icon debug_msg_enabled[32]
 #else
 #ifdef DEBUG_ICON
 #define dprintf_icon fprintf
@@ -1013,8 +986,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_int if(!debug_msg_enabled[34]) ; else fprintf
-#define debugging_int debug_msg_enabled[34]
+#define dprintf_int if(!debug_msg_enabled[33]) ; else fprintf
+#define debugging_int debug_msg_enabled[33]
 #else
 #ifdef DEBUG_INT
 #define dprintf_int fprintf
@@ -1026,8 +999,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_key if(!debug_msg_enabled[35]) ; else fprintf
-#define debugging_key debug_msg_enabled[35]
+#define dprintf_key if(!debug_msg_enabled[34]) ; else fprintf
+#define debugging_key debug_msg_enabled[34]
 #else
 #ifdef DEBUG_KEY
 #define dprintf_key fprintf
@@ -1039,8 +1012,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_keyboard if(!debug_msg_enabled[36]) ; else fprintf
-#define debugging_keyboard debug_msg_enabled[36]
+#define dprintf_keyboard if(!debug_msg_enabled[35]) ; else fprintf
+#define debugging_keyboard debug_msg_enabled[35]
 #else
 #ifdef DEBUG_KEYBOARD
 #define dprintf_keyboard fprintf
@@ -1052,8 +1025,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ldt if(!debug_msg_enabled[37]) ; else fprintf
-#define debugging_ldt debug_msg_enabled[37]
+#define dprintf_ldt if(!debug_msg_enabled[36]) ; else fprintf
+#define debugging_ldt debug_msg_enabled[36]
 #else
 #ifdef DEBUG_LDT
 #define dprintf_ldt fprintf
@@ -1065,8 +1038,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_listbox if(!debug_msg_enabled[38]) ; else fprintf
-#define debugging_listbox debug_msg_enabled[38]
+#define dprintf_listbox if(!debug_msg_enabled[37]) ; else fprintf
+#define debugging_listbox debug_msg_enabled[37]
 #else
 #ifdef DEBUG_LISTBOX
 #define dprintf_listbox fprintf
@@ -1078,8 +1051,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_local if(!debug_msg_enabled[39]) ; else fprintf
-#define debugging_local debug_msg_enabled[39]
+#define dprintf_local if(!debug_msg_enabled[38]) ; else fprintf
+#define debugging_local debug_msg_enabled[38]
 #else
 #ifdef DEBUG_LOCAL
 #define dprintf_local fprintf
@@ -1091,8 +1064,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mci if(!debug_msg_enabled[40]) ; else fprintf
-#define debugging_mci debug_msg_enabled[40]
+#define dprintf_mci if(!debug_msg_enabled[39]) ; else fprintf
+#define debugging_mci debug_msg_enabled[39]
 #else
 #ifdef DEBUG_MCI
 #define dprintf_mci fprintf
@@ -1104,8 +1077,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mcianim if(!debug_msg_enabled[41]) ; else fprintf
-#define debugging_mcianim debug_msg_enabled[41]
+#define dprintf_mcianim if(!debug_msg_enabled[40]) ; else fprintf
+#define debugging_mcianim debug_msg_enabled[40]
 #else
 #ifdef DEBUG_MCIANIM
 #define dprintf_mcianim fprintf
@@ -1117,8 +1090,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mciwave if(!debug_msg_enabled[42]) ; else fprintf
-#define debugging_mciwave debug_msg_enabled[42]
+#define dprintf_mciwave if(!debug_msg_enabled[41]) ; else fprintf
+#define debugging_mciwave debug_msg_enabled[41]
 #else
 #ifdef DEBUG_MCIWAVE
 #define dprintf_mciwave fprintf
@@ -1130,8 +1103,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mdi if(!debug_msg_enabled[43]) ; else fprintf
-#define debugging_mdi debug_msg_enabled[43]
+#define dprintf_mdi if(!debug_msg_enabled[42]) ; else fprintf
+#define debugging_mdi debug_msg_enabled[42]
 #else
 #ifdef DEBUG_MDI
 #define dprintf_mdi fprintf
@@ -1143,8 +1116,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_menu if(!debug_msg_enabled[44]) ; else fprintf
-#define debugging_menu debug_msg_enabled[44]
+#define dprintf_menu if(!debug_msg_enabled[43]) ; else fprintf
+#define debugging_menu debug_msg_enabled[43]
 #else
 #ifdef DEBUG_MENU
 #define dprintf_menu fprintf
@@ -1156,8 +1129,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_message if(!debug_msg_enabled[45]) ; else fprintf
-#define debugging_message debug_msg_enabled[45]
+#define dprintf_message if(!debug_msg_enabled[44]) ; else fprintf
+#define debugging_message debug_msg_enabled[44]
 #else
 #ifdef DEBUG_MESSAGE
 #define dprintf_message fprintf
@@ -1169,8 +1142,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_metafile if(!debug_msg_enabled[46]) ; else fprintf
-#define debugging_metafile debug_msg_enabled[46]
+#define dprintf_metafile if(!debug_msg_enabled[45]) ; else fprintf
+#define debugging_metafile debug_msg_enabled[45]
 #else
 #ifdef DEBUG_METAFILE
 #define dprintf_metafile fprintf
@@ -1182,8 +1155,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_midi if(!debug_msg_enabled[47]) ; else fprintf
-#define debugging_midi debug_msg_enabled[47]
+#define dprintf_midi if(!debug_msg_enabled[46]) ; else fprintf
+#define debugging_midi debug_msg_enabled[46]
 #else
 #ifdef DEBUG_MIDI
 #define dprintf_midi fprintf
@@ -1195,8 +1168,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmio if(!debug_msg_enabled[48]) ; else fprintf
-#define debugging_mmio debug_msg_enabled[48]
+#define dprintf_mmio if(!debug_msg_enabled[47]) ; else fprintf
+#define debugging_mmio debug_msg_enabled[47]
 #else
 #ifdef DEBUG_MMIO
 #define dprintf_mmio fprintf
@@ -1208,8 +1181,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmsys if(!debug_msg_enabled[49]) ; else fprintf
-#define debugging_mmsys debug_msg_enabled[49]
+#define dprintf_mmsys if(!debug_msg_enabled[48]) ; else fprintf
+#define debugging_mmsys debug_msg_enabled[48]
 #else
 #ifdef DEBUG_MMSYS
 #define dprintf_mmsys fprintf
@@ -1221,8 +1194,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmtime if(!debug_msg_enabled[50]) ; else fprintf
-#define debugging_mmtime debug_msg_enabled[50]
+#define dprintf_mmtime if(!debug_msg_enabled[49]) ; else fprintf
+#define debugging_mmtime debug_msg_enabled[49]
 #else
 #ifdef DEBUG_MMTIME
 #define dprintf_mmtime fprintf
@@ -1234,8 +1207,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_module if(!debug_msg_enabled[51]) ; else fprintf
-#define debugging_module debug_msg_enabled[51]
+#define dprintf_module if(!debug_msg_enabled[50]) ; else fprintf
+#define debugging_module debug_msg_enabled[50]
 #else
 #ifdef DEBUG_MODULE
 #define dprintf_module fprintf
@@ -1247,8 +1220,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_msg if(!debug_msg_enabled[52]) ; else fprintf
-#define debugging_msg debug_msg_enabled[52]
+#define dprintf_msg if(!debug_msg_enabled[51]) ; else fprintf
+#define debugging_msg debug_msg_enabled[51]
 #else
 #ifdef DEBUG_MSG
 #define dprintf_msg fprintf
@@ -1260,8 +1233,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_nonclient if(!debug_msg_enabled[53]) ; else fprintf
-#define debugging_nonclient debug_msg_enabled[53]
+#define dprintf_nonclient if(!debug_msg_enabled[52]) ; else fprintf
+#define debugging_nonclient debug_msg_enabled[52]
 #else
 #ifdef DEBUG_NONCLIENT
 #define dprintf_nonclient fprintf
@@ -1273,8 +1246,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ole if(!debug_msg_enabled[54]) ; else fprintf
-#define debugging_ole debug_msg_enabled[54]
+#define dprintf_ole if(!debug_msg_enabled[53]) ; else fprintf
+#define debugging_ole debug_msg_enabled[53]
 #else
 #ifdef DEBUG_OLE
 #define dprintf_ole fprintf
@@ -1286,8 +1259,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_palette if(!debug_msg_enabled[55]) ; else fprintf
-#define debugging_palette debug_msg_enabled[55]
+#define dprintf_palette if(!debug_msg_enabled[54]) ; else fprintf
+#define debugging_palette debug_msg_enabled[54]
 #else
 #ifdef DEBUG_PALETTE
 #define dprintf_palette fprintf
@@ -1299,8 +1272,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_profile if(!debug_msg_enabled[56]) ; else fprintf
-#define debugging_profile debug_msg_enabled[56]
+#define dprintf_profile if(!debug_msg_enabled[55]) ; else fprintf
+#define debugging_profile debug_msg_enabled[55]
 #else
 #ifdef DEBUG_PROFILE
 #define dprintf_profile fprintf
@@ -1312,8 +1285,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_prop if(!debug_msg_enabled[57]) ; else fprintf
-#define debugging_prop debug_msg_enabled[57]
+#define dprintf_prop if(!debug_msg_enabled[56]) ; else fprintf
+#define debugging_prop debug_msg_enabled[56]
 #else
 #ifdef DEBUG_PROP
 #define dprintf_prop fprintf
@@ -1325,8 +1298,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_reg if(!debug_msg_enabled[58]) ; else fprintf
-#define debugging_reg debug_msg_enabled[58]
+#define dprintf_reg if(!debug_msg_enabled[57]) ; else fprintf
+#define debugging_reg debug_msg_enabled[57]
 #else
 #ifdef DEBUG_REG
 #define dprintf_reg fprintf
@@ -1338,8 +1311,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_region if(!debug_msg_enabled[59]) ; else fprintf
-#define debugging_region debug_msg_enabled[59]
+#define dprintf_region if(!debug_msg_enabled[58]) ; else fprintf
+#define debugging_region debug_msg_enabled[58]
 #else
 #ifdef DEBUG_REGION
 #define dprintf_region fprintf
@@ -1351,8 +1324,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_relay if(!debug_msg_enabled[60]) ; else fprintf
-#define debugging_relay debug_msg_enabled[60]
+#define dprintf_relay if(!debug_msg_enabled[59]) ; else fprintf
+#define debugging_relay debug_msg_enabled[59]
 #else
 #ifdef DEBUG_RELAY
 #define dprintf_relay fprintf
@@ -1364,8 +1337,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_resource if(!debug_msg_enabled[61]) ; else fprintf
-#define debugging_resource debug_msg_enabled[61]
+#define dprintf_resource if(!debug_msg_enabled[60]) ; else fprintf
+#define debugging_resource debug_msg_enabled[60]
 #else
 #ifdef DEBUG_RESOURCE
 #define dprintf_resource fprintf
@@ -1377,8 +1350,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_scroll if(!debug_msg_enabled[62]) ; else fprintf
-#define debugging_scroll debug_msg_enabled[62]
+#define dprintf_scroll if(!debug_msg_enabled[61]) ; else fprintf
+#define debugging_scroll debug_msg_enabled[61]
 #else
 #ifdef DEBUG_SCROLL
 #define dprintf_scroll fprintf
@@ -1390,8 +1363,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_selector if(!debug_msg_enabled[63]) ; else fprintf
-#define debugging_selector debug_msg_enabled[63]
+#define dprintf_selector if(!debug_msg_enabled[62]) ; else fprintf
+#define debugging_selector debug_msg_enabled[62]
 #else
 #ifdef DEBUG_SELECTOR
 #define dprintf_selector fprintf
@@ -1403,8 +1376,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_sem if(!debug_msg_enabled[64]) ; else fprintf
-#define debugging_sem debug_msg_enabled[64]
+#define dprintf_sem if(!debug_msg_enabled[63]) ; else fprintf
+#define debugging_sem debug_msg_enabled[63]
 #else
 #ifdef DEBUG_SEM
 #define dprintf_sem fprintf
@@ -1416,8 +1389,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_shm if(!debug_msg_enabled[65]) ; else fprintf
-#define debugging_shm debug_msg_enabled[65]
+#define dprintf_shm if(!debug_msg_enabled[64]) ; else fprintf
+#define debugging_shm debug_msg_enabled[64]
 #else
 #ifdef DEBUG_SHM
 #define dprintf_shm fprintf
@@ -1429,8 +1402,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_stress if(!debug_msg_enabled[66]) ; else fprintf
-#define debugging_stress debug_msg_enabled[66]
+#define dprintf_stress if(!debug_msg_enabled[65]) ; else fprintf
+#define debugging_stress debug_msg_enabled[65]
 #else
 #ifdef DEBUG_STRESS
 #define dprintf_stress fprintf
@@ -1442,8 +1415,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_syscolor if(!debug_msg_enabled[67]) ; else fprintf
-#define debugging_syscolor debug_msg_enabled[67]
+#define dprintf_syscolor if(!debug_msg_enabled[66]) ; else fprintf
+#define debugging_syscolor debug_msg_enabled[66]
 #else
 #ifdef DEBUG_SYSCOLOR
 #define dprintf_syscolor fprintf
@@ -1455,8 +1428,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_task if(!debug_msg_enabled[68]) ; else fprintf
-#define debugging_task debug_msg_enabled[68]
+#define dprintf_task if(!debug_msg_enabled[67]) ; else fprintf
+#define debugging_task debug_msg_enabled[67]
 #else
 #ifdef DEBUG_TASK
 #define dprintf_task fprintf
@@ -1468,8 +1441,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_text if(!debug_msg_enabled[69]) ; else fprintf
-#define debugging_text debug_msg_enabled[69]
+#define dprintf_text if(!debug_msg_enabled[68]) ; else fprintf
+#define debugging_text debug_msg_enabled[68]
 #else
 #ifdef DEBUG_TEXT
 #define dprintf_text fprintf
@@ -1481,8 +1454,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_timer if(!debug_msg_enabled[70]) ; else fprintf
-#define debugging_timer debug_msg_enabled[70]
+#define dprintf_timer if(!debug_msg_enabled[69]) ; else fprintf
+#define debugging_timer debug_msg_enabled[69]
 #else
 #ifdef DEBUG_TIMER
 #define dprintf_timer fprintf
@@ -1494,8 +1467,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_toolhelp if(!debug_msg_enabled[71]) ; else fprintf
-#define debugging_toolhelp debug_msg_enabled[71]
+#define dprintf_toolhelp if(!debug_msg_enabled[70]) ; else fprintf
+#define debugging_toolhelp debug_msg_enabled[70]
 #else
 #ifdef DEBUG_TOOLHELP
 #define dprintf_toolhelp fprintf
@@ -1507,21 +1480,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_utility if(!debug_msg_enabled[72]) ; else fprintf
-#define debugging_utility debug_msg_enabled[72]
-#else
-#ifdef DEBUG_UTILITY
-#define dprintf_utility fprintf
-#define debugging_utility 1
-#else
-#define dprintf_utility while(0) fprintf
-#define debugging_utility 0
-#endif
-#endif
-
-#ifdef DEBUG_RUNTIME
-#define dprintf_vxd if(!debug_msg_enabled[73]) ; else fprintf
-#define debugging_vxd debug_msg_enabled[73]
+#define dprintf_vxd if(!debug_msg_enabled[71]) ; else fprintf
+#define debugging_vxd debug_msg_enabled[71]
 #else
 #ifdef DEBUG_VXD
 #define dprintf_vxd fprintf
@@ -1533,8 +1493,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win if(!debug_msg_enabled[74]) ; else fprintf
-#define debugging_win debug_msg_enabled[74]
+#define dprintf_win if(!debug_msg_enabled[72]) ; else fprintf
+#define debugging_win debug_msg_enabled[72]
 #else
 #ifdef DEBUG_WIN
 #define dprintf_win fprintf
@@ -1546,8 +1506,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win32 if(!debug_msg_enabled[75]) ; else fprintf
-#define debugging_win32 debug_msg_enabled[75]
+#define dprintf_win32 if(!debug_msg_enabled[73]) ; else fprintf
+#define debugging_win32 debug_msg_enabled[73]
 #else
 #ifdef DEBUG_WIN32
 #define dprintf_win32 fprintf
@@ -1559,8 +1519,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_winsock if(!debug_msg_enabled[76]) ; else fprintf
-#define debugging_winsock debug_msg_enabled[76]
+#define dprintf_winsock if(!debug_msg_enabled[74]) ; else fprintf
+#define debugging_winsock debug_msg_enabled[74]
 #else
 #ifdef DEBUG_WINSOCK
 #define dprintf_winsock fprintf
@@ -1580,7 +1540,6 @@
     "bitblt",
     "bitmap",
     "caret",
-    "catch",
     "cdaudio",
     "class",
     "clipboard",
@@ -1647,7 +1606,6 @@
     "text",
     "timer",
     "toolhelp",
-    "utility",
     "vxd",
     "win",
     "win32",
diff --git a/include/desktop.h b/include/desktop.h
index 5c06635..0de03fa 100644
--- a/include/desktop.h
+++ b/include/desktop.h
@@ -17,9 +17,8 @@
     BOOL     fTileWallPaper;
 } DESKTOPINFO;
 
-extern BOOL DESKTOP_Init();
 extern BOOL DESKTOP_SetPattern(char *pattern );
-
-extern LRESULT DesktopWndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
+extern LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
+                               WPARAM32 wParam, LPARAM lParam );
 
 #endif  /* DESKTOP_H */
diff --git a/include/handle32.h b/include/handle32.h
index 93162cd..c2b79cb 100644
--- a/include/handle32.h
+++ b/include/handle32.h
@@ -103,10 +103,6 @@
 #define KERNEL_OBJECT_HEAP      (KERNEL_OBJECT_UNUSED + 9)
 #define KERNEL_OBJECT_HEAPITEM  (KERNEL_OBJECT_UNUSED + 10)
 
-/* Define the invalid handle value
- */
-#define INVALID_HANDLE_VALUE    ((HANDLE32)-1)
-
 /* Functions for checking kernel objects.
  */
 int ValidateKernelObject(KERNEL_OBJECT *ptr);
diff --git a/include/hook.h b/include/hook.h
index 4d82514..23aa709 100644
--- a/include/hook.h
+++ b/include/hook.h
@@ -32,6 +32,7 @@
 
 #define HOOK_MAGIC  ((int)'H' | (int)'K' << 8)  /* 'HK' */
 
+extern HANDLE HOOK_GetHook( short id , HQUEUE hQueue );
 extern DWORD HOOK_CallHooks( short id, short code,
                              WPARAM wParam, LPARAM lParam );
 extern void HOOK_FreeModuleHooks( HMODULE hModule );
diff --git a/include/listbox.h b/include/listbox.h
index 179badd..8dfcf65 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -33,7 +33,6 @@
         BOOL    OwnerDrawn;
 	WORD    iNumStops;
 	LPINT16 TabStops;
-	HANDLE  hDrawItemStruct;
         BOOL    needMeasure;
 	HANDLE	HeapSel;
 /*	MDESC   *Heap; */
diff --git a/include/mdi.h b/include/mdi.h
index 2fac0d8..6f26824 100644
--- a/include/mdi.h
+++ b/include/mdi.h
@@ -37,11 +37,9 @@
     HMENU  	hWindowMenu;
     WORD   	idFirstChild;
     WORD	nTotalCreated;
-    HANDLE 	hFrameTitle;
+    LPSTR 	frameTitle;
     WORD   	sbNeedUpdate;
     WORD   	sbRecalc;
-    HBITMAP 	obmClose;
-    HBITMAP 	obmRestore;
     HWND   	self;
 } MDICLIENTINFO;
 
diff --git a/include/menu.h b/include/menu.h
index d2e90bf..4beed85 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -1,12 +1,9 @@
-/* $Id$
- *
+/*
  * Menu definitions
  */
 
-#ifndef MENU_H
-#define MENU_H
-
-#define MENU_MAGIC   0x554d  /* 'MU' */
+#ifndef __WINE_MENU_H
+#define __WINE_MENU_H
 
 extern BOOL MENU_Init(void);
 extern HMENU MENU_GetDefSysMenu(void);
@@ -18,49 +15,4 @@
 			      HWND hwnd, BOOL suppress_draw );
 extern LRESULT PopupMenuWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam );
 
-typedef struct tagMENUITEM
-{
-    WORD	item_flags;    /* Item flags */
-    UINT	item_id;       /* Item or popup id */
-    RECT16      rect;          /* Item area (relative to menu window) */
-    WORD        xTab;          /* X position of text after Tab */
-    HBITMAP	hCheckBit;     /* Bitmap for checked item */
-    HBITMAP	hUnCheckBit;   /* Bitmap for unchecked item */
-    HANDLE      hText;	       /* Handle to item string or bitmap */
-} MENUITEM, *LPMENUITEM;
-
-
-typedef struct tagPOPUPMENU
-{
-    HMENU       hNext;        /* Next menu (compatibility only, always 0) */
-    WORD        wFlags;       /* Menu flags (MF_POPUP, MF_SYSMENU) */
-    WORD        wMagic;       /* Magic number */
-    HANDLE      hTaskQ;       /* Task queue for this menu */
-    WORD	Width;        /* Width of the whole menu */
-    WORD	Height;       /* Height of the whole menu */
-    WORD	nItems;       /* Number of items in the menu */
-    HWND	hWnd;	      /* Window containing the menu */
-    HANDLE      hItems;       /* Handle to the items array */
-    UINT	FocusedItem;  /* Currently focused item */
-} POPUPMENU, *LPPOPUPMENU;
-
-typedef struct
-{
-    WORD	version;		/* Should be zero		  */
-    WORD	reserved;		/* Must be zero			  */
-} MENU_HEADER;
-
-typedef struct
-{
-    WORD	item_flags;		/* See windows.h		  */
-    char	item_text[1];		/* Text for menu item		  */
-} MENU_POPUPITEM;
-
-typedef struct
-{
-    WORD	item_flags;		/* See windows.h		  */
-    WORD	item_id;		/* Control Id for menu item	  */
-    char	item_text[1];		/* Text for menu item		  */
-} MENUITEMTEMPLATE;
-
-#endif /* MENU_H */
+#endif /* __WINE_MENU_H */
diff --git a/include/nonclient.h b/include/nonclient.h
index 6b4bff1..af2c8f9 100644
--- a/include/nonclient.h
+++ b/include/nonclient.h
@@ -14,7 +14,7 @@
 extern void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint );
 extern LONG NC_HandleNCPaint( HWND hwnd , HRGN clip);
 extern LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam );
-extern LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS16 *params );
+extern LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect );
 extern LONG NC_HandleNCHitTest( HWND hwnd, POINT16 pt );
 extern LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam );
 extern LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM wParam, LPARAM lParam);
diff --git a/include/spy.h b/include/spy.h
index c039241..ea1b6cc 100644
--- a/include/spy.h
+++ b/include/spy.h
@@ -1,20 +1,28 @@
 /*
- * 			     Message Logging functions
+ * Message Logging functions
  */
 
 #ifndef __WINE_SPY_H
 #define __WINE_SPY_H
 
-#define SPY_DISPATCHMESSAGE     0x0100
-#define SPY_SENDMESSAGE         0x0101
-#define SPY_DEFWNDPROC          0x0102
+#include "wintypes.h"
 
-#define SPY_RESULT_OK           0x0000
-#define SPY_RESULT_INVALIDHWND  0x0001
+#define SPY_DISPATCHMESSAGE16     0x0100
+#define SPY_DISPATCHMESSAGE32     0x0101
+#define SPY_SENDMESSAGE16         0x0102
+#define SPY_SENDMESSAGE32         0x0103
+#define SPY_DEFWNDPROC16          0x0104
+#define SPY_DEFWNDPROC32          0x0105
 
-extern void SPY_EnterMessage( int iFlag, HWND hwnd, UINT msg,
-                              WPARAM wParam, LPARAM lParam );
-extern void SPY_ExitMessage( int iFlag, HWND hwnd, UINT msg, LRESULT lReturn );
+#define SPY_RESULT_OK16           0x0000
+#define SPY_RESULT_OK32           0x0001
+#define SPY_RESULT_INVALIDHWND16  0x0002
+#define SPY_RESULT_INVALIDHWND32  0x0003
+
+extern void SPY_EnterMessage( INT32 iFlag, HWND32 hwnd, UINT32 msg,
+                              WPARAM32 wParam, LPARAM lParam );
+extern void SPY_ExitMessage( INT32 iFlag, HWND32 hwnd, UINT32 msg,
+                             LRESULT lReturn );
 extern int SPY_Init(void);
 
 #endif /* __WINE_SPY_H */
diff --git a/include/stddebug.h b/include/stddebug.h
index 7852551..eb1e0ec 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -81,7 +81,6 @@
 #undef DEBUG_BITBLT
 #undef DEBUG_BITMAP
 #undef DEBUG_CARET
-#undef DEBUG_CATCH
 #undef DEBUG_CDAUDIO
 #undef DEBUG_CLASS
 #undef DEBUG_CLIPBOARD
@@ -148,7 +147,6 @@
 #undef DEBUG_TEXT
 #undef DEBUG_TIMER
 #undef DEBUG_TOOLHELP
-#undef DEBUG_UTILITY
 #undef DEBUG_VXD
 #undef DEBUG_WIN
 #undef DEBUG_WIN32
@@ -161,7 +159,6 @@
 #define DEBUG_BITBLT
 #define DEBUG_BITMAP
 #define DEBUG_CARET
-#define DEBUG_CATCH
 #define DEBUG_CDAUDIO
 #define DEBUG_CLASS
 #define DEBUG_CLIPBOARD
@@ -228,7 +225,6 @@
 #define DEBUG_TEXT
 #define DEBUG_TIMER
 #define DEBUG_TOOLHELP
-#define DEBUG_UTILITY
 #define DEBUG_VXD
 #define DEBUG_WIN
 #define DEBUG_WIN32
diff --git a/include/win.h b/include/win.h
index 6e5ec44..b451832 100644
--- a/include/win.h
+++ b/include/win.h
@@ -37,22 +37,22 @@
     DWORD          dwMagic;       /* Magic number (must be WND_MAGIC) */
     HWND16         hwndSelf;      /* Handle of this window */
     HINSTANCE16    hInstance;     /* Window hInstance (from CreateWindow) */
+    WNDPROC16      lpfnWndProc;   /* Window procedure */
     RECT16         rectClient;    /* Client area rel. to parent client area */
     RECT16         rectWindow;    /* Whole window rel. to parent client area */
     RECT16         rectNormal;    /* Window rect. when in normal state */
     POINT16        ptIconPos;     /* Icon position */
     POINT16        ptMaxPos;      /* Maximized window position */
+    LPSTR          text;          /* Window text */
     HGLOBAL        hmemTaskQ;     /* Task queue global memory handle */
     HRGN           hrgnUpdate;    /* Update region */
     HWND           hwndLastActive;/* Last active popup hwnd */
-    WNDPROC        lpfnWndProc;   /* Window procedure */
     DWORD          dwStyle;       /* Window style (from CreateWindow) */
     DWORD          dwExStyle;     /* Extended style (from CreateWindowEx) */
     HANDLE         hdce;          /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
     HANDLE         hVScroll;      /* Vertical scroll-bar info */
     HANDLE         hHScroll;      /* Horizontal scroll-bar info */
     UINT           wIDmenu;       /* ID or hmenu (from CreateWindow) */
-    HANDLE         hText;         /* Handle of window text */
     WORD           flags;         /* Misc. flags (see below) */
     Window         window;        /* X window (only for top-level windows) */
     HMENU          hSysMenu;      /* window's copy of System Menu */
@@ -70,7 +70,6 @@
 #define WIN_NEED_SIZE          0x0040 /* Internal WM_SIZE is needed */
 #define WIN_NCACTIVATED        0x0080 /* last WM_NCACTIVATE was positive */
 #define WIN_MANAGED            0x0100 /* Window managed by the X wm */
-#define WIN_UNICODE            0x0200 /* Window procedure expects Unicode */
 
   /* Window functions */
 extern WND *WIN_FindWndPtr( HWND hwnd );
@@ -87,6 +86,8 @@
 extern HWND WIN_GetTopParent( HWND hwnd );
 extern HINSTANCE WIN_GetWindowInstance( HWND hwnd );
 
+extern void DEFWND_SetText( WND *wndPtr, LPCSTR text );  /* windows/defwnd.c */
+
 extern Display * display;
 extern Screen * screen;
 extern Window rootWindow;
diff --git a/include/winbase.h b/include/winbase.h
index 487eeee..27ef776 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -11,7 +11,7 @@
 #endif
 
 
-#define INVALID_HANDLE_VALUE ((HANDLE) -1)
+#define INVALID_HANDLE_VALUE    ((HANDLE32) -1)
 
 #define WAIT_FAILED		0xffffffff
 #define WAIT_OBJECT_0		0
diff --git a/include/windows.h b/include/windows.h
index a078710..5d64c15 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -194,11 +194,15 @@
 #define MDITILE_HORIZONTAL  1
 
   /* Offsets for GetWindowLong() and GetWindowWord() */
+#define GWL_USERDATA        (-21)
 #define GWL_EXSTYLE         (-20)
 #define GWL_STYLE           (-16)
 #define GWW_ID              (-12)
+#define GWL_ID              GWW_ID
 #define GWW_HWNDPARENT      (-8)
+#define GWL_HWNDPARENT      GWW_HWNDPARENT
 #define GWW_HINSTANCE       (-6)
+#define GWL_HINSTANCE       GWW_HINSTANCE
 #define GWL_WNDPROC         (-4)
 #define DWL_MSGRESULT	    0
 #define DWL_DLGPROC	    4
@@ -2814,7 +2818,6 @@
 LPSTR      AnsiUpper(LPSTR);
 UINT       AnsiUpperBuff(LPSTR,UINT);
 BOOL       AnyPopup(void);
-BOOL       AppendMenu(HMENU,UINT,UINT,SEGPTR);
 BOOL       Arc(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
 UINT       ArrangeIconicWindows(HWND);
 HDWP16     BeginDeferWindowPos(INT);
@@ -2826,7 +2829,6 @@
 LRESULT    CallNextHookEx(HHOOK,INT,WPARAM,LPARAM);
 INT        Catch(LPCATCHBUF);
 BOOL       ChangeClipboardChain(HWND,HWND);
-BOOL       ChangeMenu(HMENU,UINT,SEGPTR,UINT,UINT);
 WORD       ChangeSelector(WORD,WORD);
 BOOL       CheckDlgButton(HWND,INT,UINT);
 INT        CheckMenuItem(HMENU,UINT,UINT);
@@ -2884,10 +2886,7 @@
 HBRUSH     CreateSolidBrush(COLORREF);
 void       DebugBreak(void);
 LRESULT    DefDlgProc(HWND,UINT,WPARAM,LPARAM);
-LRESULT    DefFrameProc(HWND,HWND,UINT,WPARAM,LPARAM);
 DWORD      DefHookProc(short,WORD,DWORD,HHOOK*);
-LRESULT    DefMDIChildProc(HWND,UINT,WPARAM,LPARAM);
-LRESULT    DefWindowProc(HWND,UINT,WPARAM,LPARAM);
 HDWP16     DeferWindowPos(HDWP16,HWND,HWND,INT,INT,INT,INT,UINT);
 ATOM       DeleteAtom(ATOM);
 BOOL       DeleteDC(HDC);
@@ -2907,7 +2906,6 @@
 void       DirectedYield(HTASK);
 LONG       DispatchMessage(const MSG*);
 INT        DlgDirList(HWND,SEGPTR,INT,INT,UINT);
-INT        DlgDirListComboBox(HWND,SEGPTR,INT,INT,UINT);
 BOOL       DlgDirSelect(HWND,LPSTR,INT);
 BOOL       DlgDirSelectComboBox(HWND,LPSTR,INT);
 BOOL16     DragDetect(HWND16,POINT16);
@@ -2972,7 +2970,6 @@
 WORD       GetCaretBlinkTime(void);
 BOOL       GetCharABCWidths(HDC,UINT,UINT,LPABC);
 BOOL       GetCharWidth(HDC,WORD,WORD,LPINT16);
-WORD       GetClassWord(HWND,INT32);
 HRGN       GetClipRgn(HDC);
 HANDLE     GetClipboardData(WORD);
 int        GetClipboardFormatName(WORD,LPSTR,short);
@@ -3003,7 +3000,6 @@
 int        GetDlgCtrlID(HWND);
 HWND       GetDlgItem(HWND,WORD);
 WORD       GetDlgItemInt(HWND,WORD,BOOL*,BOOL);
-int        GetDlgItemText(HWND,WORD,SEGPTR,WORD);
 WORD       GetDoubleClickTime(void);
 WORD       GetDriveType(INT);
 int        GetEnvironment(LPSTR,LPSTR,WORD);
@@ -3099,12 +3095,9 @@
 HWND       GetWindow(HWND,WORD);
 HDC        GetWindowDC(HWND);
 DWORD      GetWindowExt(HDC);
-LONG       GetWindowLong(HWND,short);
 DWORD      GetWindowOrg(HDC);
 HANDLE     GetWindowTask(HWND);
-int        GetWindowText(HWND,LPSTR,int);
 int        GetWindowTextLength(HWND);
-WORD       GetWindowWord(HWND,short);
 UINT       GetWindowsDirectory(LPSTR,UINT);
 DWORD      GlobalDOSAlloc(DWORD);
 WORD       GlobalDOSFree(WORD);
@@ -3125,7 +3118,6 @@
 BOOL       InSendMessage(void);
 WORD       InitAtomTable(WORD);
 HRGN       InquireVisRgn(HDC);
-BOOL       InsertMenu(HMENU,UINT,UINT,UINT,SEGPTR);
 int        IntersectClipRect(HDC,short,short,short,short);
 int        IntersectVisRect(HDC,short,short,short,short);
 void       InvalidateRgn(HWND32,HRGN32,BOOL32);
@@ -3165,7 +3157,6 @@
 HICON      LoadIcon(HANDLE,SEGPTR);
 HANDLE     LoadLibrary(LPCSTR);
 HMENU      LoadMenu(HANDLE,SEGPTR);
-HMENU      LoadMenuIndirect(SEGPTR);
 HANDLE     LoadModule(LPCSTR,LPVOID);
 HGLOBAL    LoadResource(HINSTANCE,HRSRC);
 int        LoadString(HANDLE,WORD,LPSTR,int);
@@ -3178,7 +3169,6 @@
 WORD       MapVirtualKey(WORD,WORD);
 void       MessageBeep(WORD);
 int        MessageBox(HWND,LPCSTR,LPCSTR,WORD);
-BOOL       ModifyMenu(HMENU,UINT,UINT,UINT,SEGPTR);
 DWORD      MoveTo(HDC,short,short);
 BOOL       MoveWindow(HWND,short,short,short,short,BOOL);
 DWORD      OemKeyScan(WORD);
@@ -3238,8 +3228,6 @@
 HPALETTE16 SelectPalette(HDC,HPALETTE16,BOOL);
 int        SelectVisRgn(HDC,HRGN);
 WORD       SelectorAccessRights(WORD,WORD,WORD);
-LONG       SendDlgItemMessage(HWND,INT,UINT,WPARAM,LPARAM);
-LRESULT    SendMessage(HWND,UINT,WPARAM,LPARAM);
 HWND       SetActiveWindow(HWND);
 LONG       SetBitmapBits(HBITMAP,LONG,LPSTR);
 DWORD      SetBkColor(HDC,COLORREF);
@@ -3248,7 +3236,6 @@
 HWND       SetCapture(HWND);
 void       SetCaretBlinkTime(WORD);
 void       SetCaretPos(short,short);
-WORD       SetClassWord(HWND,INT32,WORD);
 HANDLE     SetClipboardData(WORD,HANDLE);
 HWND       SetClipboardViewer(HWND);
 int        SetCommBreak(int);
@@ -3264,8 +3251,6 @@
 int        SetDIBitsToDevice(HDC,short,short,WORD,WORD,WORD,WORD,WORD,WORD,LPSTR,LPBITMAPINFO,WORD);
 BOOL       SetDeskPattern(void);
 BOOL       SetDeskWallPaper(LPCSTR);
-void       SetDlgItemInt(HWND,WORD,WORD,BOOL);
-void       SetDlgItemText(HWND,WORD,SEGPTR);
 void       SetDoubleClickTime(WORD);
 int        SetEnvironment(LPSTR,LPSTR,WORD);
 UINT       SetErrorMode(UINT);
@@ -3311,10 +3296,7 @@
 int        SetVoiceSound(int,LONG,int);
 int        SetVoiceThreshold(int,int);
 BOOL       SetWinDebugInfo(LPWINDEBUGINFO);
-LONG       SetWindowLong(HWND,short,LONG);
 BOOL       SetWindowPos(HWND,HWND,INT,INT,INT,INT,WORD);
-void       SetWindowText(HWND,LPCSTR);
-WORD       SetWindowWord(HWND,short,WORD);
 FARPROC    SetWindowsHook(short,FARPROC);
 HHOOK      SetWindowsHookEx(short,HOOKPROC,HINSTANCE,HTASK);
 HINSTANCE  ShellExecute(HWND,LPCSTR,LPCSTR,LPSTR,LPCSTR,INT);
@@ -3389,7 +3371,11 @@
 INT16      ExcludeUpdateRgn(HDC32,HWND32);
 void       FillWindow(HWND16,HWND16,HDC16,HBRUSH16);
 DWORD      GetBitmapDimension(HBITMAP16);
+WORD       GetClassWord(HWND32,INT32);
+DWORD      GetLogicalDrives(void);
 INT16      GetUpdateRgn(HWND32,HRGN32,BOOL32);
+LONG       GetWindowLong(HWND32,INT32);
+WORD       GetWindowWord(HWND32,INT32);
 INT16      OffsetRgn(HRGN32,INT32,INT32);
 DWORD      OffsetViewportOrg(HDC16,INT16,INT16);
 DWORD      OffsetWindowOrg(HDC16,INT16,INT16);
@@ -3399,10 +3385,12 @@
 DWORD      ScaleViewportExt(HDC16,INT16,INT16,INT16,INT16);
 DWORD      ScaleWindowExt(HDC16,INT16,INT16,INT16,INT16);
 DWORD      SetBitmapDimension(HBITMAP16,INT16,INT16);
+WORD       SetClassWord(HWND32,INT32,WORD);
 DWORD      SetViewportExt(HDC16,INT16,INT16);
 DWORD      SetViewportOrg(HDC16,INT16,INT16);
 DWORD      SetWindowExt(HDC16,INT16,INT16);
 DWORD      SetWindowOrg(HDC16,INT16,INT16);
+WORD       SetWindowWord(HWND32,INT32,WORD);
 
 /* Declarations for functions that change between Win16 and Win32 */
 
@@ -3412,6 +3400,10 @@
 BOOL16     AdjustWindowRectEx16(LPRECT16,DWORD,BOOL16,DWORD);
 BOOL32     AdjustWindowRectEx32(LPRECT32,DWORD,BOOL32,DWORD);
 #define    AdjustWindowRectEx WINELIB_NAME(AdjustWindowRectEx)
+BOOL16     AppendMenu16(HMENU16,UINT16,UINT16,SEGPTR);
+BOOL32     AppendMenu32A(HMENU32,UINT32,UINT32,LPCSTR);
+BOOL32     AppendMenu32W(HMENU32,UINT32,UINT32,LPCWSTR);
+#define    AppendMenu WINELIB_NAME_AW(AppendMenu)
 HDC16      BeginPaint16(HWND16,LPPAINTSTRUCT16);
 HDC32      BeginPaint32(HWND32,LPPAINTSTRUCT32);
 #define    BeginPaint WINELIB_NAME(BeginPaint)
@@ -3419,6 +3411,10 @@
 LRESULT    CallWindowProc32A(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    CallWindowProc32W(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
 #define    CallWindowProc WINELIB_NAME_AW(CallWindowProc)
+BOOL16     ChangeMenu16(HMENU16,UINT16,SEGPTR,UINT16,UINT16);
+BOOL32     ChangeMenu32A(HMENU32,UINT32,LPCSTR,UINT32,UINT32);
+BOOL32     ChangeMenu32W(HMENU32,UINT32,LPCWSTR,UINT32,UINT32);
+#define    ChangeMenu WINELIB_NAME_AW(ChangeMenu)
 HWND16     ChildWindowFromPoint16(HWND16,POINT16);
 HWND32     ChildWindowFromPoint32(HWND32,POINT32);
 #define    ChildWindowFromPoint WINELIB_NAME(ChildWindowFromPoint)
@@ -3457,6 +3453,22 @@
 HWND32     CreateWindowEx32A(DWORD,LPCSTR,LPCSTR,DWORD,INT32,INT32,INT32,INT32,HWND32,HMENU32,HINSTANCE32,LPVOID);
 HWND32     CreateWindowEx32W(DWORD,LPCWSTR,LPCWSTR,DWORD,INT32,INT32,INT32,INT32,HWND32,HMENU32,HINSTANCE32,LPVOID);
 #define    CreateWindowEx WINELIB_NAME_AW(CreateWindowEx)
+LRESULT    DefFrameProc16(HWND16,HWND16,UINT16,WPARAM16,LPARAM);
+LRESULT    DefFrameProc32A(HWND32,HWND32,UINT32,WPARAM32,LPARAM);
+LRESULT    DefFrameProc32W(HWND32,HWND32,UINT32,WPARAM32,LPARAM);
+#define    DefFrameProc WINELIB_NAME_AW(DefFrameProc)
+LRESULT    DefMDIChildProc16(HWND16,UINT16,WPARAM16,LPARAM);
+LRESULT    DefMDIChildProc32A(HWND32,UINT32,WPARAM32,LPARAM);
+LRESULT    DefMDIChildProc32W(HWND32,UINT32,WPARAM32,LPARAM);
+#define    DefMDIChildProc WINELIB_NAME_AW(DefMDIChildProc)
+LRESULT    DefWindowProc16(HWND16,UINT16,WPARAM16,LPARAM);
+LRESULT    DefWindowProc32A(HWND32,UINT32,WPARAM32,LPARAM);
+LRESULT    DefWindowProc32W(HWND32,UINT32,WPARAM32,LPARAM);
+#define    DefWindowProc WINELIB_NAME_AW(DefWindowProc)
+INT16      DlgDirListComboBox16(HWND16,LPCSTR,INT16,INT16,UINT16);
+INT32      DlgDirListComboBox32A(HWND32,LPCSTR,INT32,INT32,UINT32);
+INT32      DlgDirListComboBox32W(HWND32,LPCWSTR,INT32,INT32,UINT32);
+#define    DlgDirListComboBox WINELIB_NAME_AW(DlgDirListComboBox)
 BOOL16     DPtoLP16(HDC16,LPPOINT16,INT16);
 BOOL32     DPtoLP32(HDC32,LPPOINT32,INT32);
 #define    DPtoLP WINELIB_NAME(DPtoLP)
@@ -3531,9 +3543,16 @@
 void       GetCursorPos16(LPPOINT16);
 void       GetCursorPos32(LPPOINT32);
 #define    GetCursorPos WINELIB_NAME(GetCursorPos)
+INT16      GetDlgItemText16(HWND16,INT16,SEGPTR,UINT16);
+INT32      GetDlgItemText32A(HWND32,INT32,LPSTR,UINT32);
+INT32      GetDlgItemText32W(HWND32,INT32,LPWSTR,UINT32);
+#define    GetDlgItemText WINELIB_NAME_AW(GetDlgItemText)
 UINT16     GetInternalWindowPos16(HWND16,LPRECT16,LPPOINT16);
 UINT32     GetInternalWindowPos32(HWND32,LPRECT32,LPPOINT32);
 #define    GetInternalWindowPos WINELIB_NAME(GetInternalWindowPos)
+UINT32     GetLogicalDriveStrings32A(UINT32,LPSTR);
+UINT32     GetLogicalDriveStrings32W(UINT32,LPWSTR);
+#define    GetLogicalDriveStrings WINELIB_NAME(GetLogicalDriveStrings)
 INT16      GetRgnBox16(HRGN16,LPRECT16);
 INT32      GetRgnBox32(HRGN32,LPRECT32);
 #define    GetRgnBox WINELIB_NAME(GetRgnBox)
@@ -3562,6 +3581,10 @@
 void       GetWindowRect16(HWND16,LPRECT16);
 void       GetWindowRect32(HWND32,LPRECT32);
 #define    GetWindowRect WINELIB_NAME(GetWindowRect)
+INT16      GetWindowText16(HWND16,SEGPTR,INT16);
+INT32      GetWindowText32A(HWND32,LPSTR,INT32);
+INT32      GetWindowText32W(HWND32,LPWSTR,INT32);
+#define    GetWindowText WINELIB_NAME_AW(GetWindowText)
 ATOM       GlobalAddAtom16(SEGPTR);
 ATOM       GlobalAddAtom32A(LPCSTR);
 ATOM       GlobalAddAtom32W(LPCWSTR);
@@ -3604,6 +3627,10 @@
 void       InflateRect16(LPRECT16,INT16,INT16);
 void       InflateRect32(LPRECT32,INT32,INT32);
 #define    InflateRect WINELIB_NAME(InflateRect)
+BOOL16     InsertMenu16(HMENU16,UINT16,UINT16,UINT16,SEGPTR);
+BOOL32     InsertMenu32A(HMENU32,UINT32,UINT32,UINT32,LPCSTR);
+BOOL32     InsertMenu32W(HMENU32,UINT32,UINT32,UINT32,LPCWSTR);
+#define    InsertMenu WINELIB_NAME_AW(InsertMenu)
 BOOL16     IntersectRect16(LPRECT16,const RECT16*,const RECT16*);
 BOOL32     IntersectRect32(LPRECT32,const RECT32*,const RECT32*);
 #define    IntersectRect WINELIB_NAME(IntersectRect)
@@ -3616,6 +3643,10 @@
 BOOL16     IsRectEmpty16(const RECT16*);
 BOOL32     IsRectEmpty32(const RECT32*);
 #define    IsRectEmpty WINELIB_NAME(IsRectEmpty)
+HMENU16    LoadMenuIndirect16(LPCVOID);
+HMENU32    LoadMenuIndirect32A(LPCVOID);
+HMENU32    LoadMenuIndirect32W(LPCVOID);
+#define    LoadMenuIndirect WINELIB_NAME_AW(LoadMenuIndirect)
 HLOCAL16   LocalAlloc16(UINT16,WORD);
 HLOCAL32   LocalAlloc32(UINT32,DWORD);
 #define    LocalAlloc WINELIB_NAME(LocalAlloc)
@@ -3655,6 +3686,10 @@
 void       MapWindowPoints16(HWND16,HWND16,LPPOINT16,UINT16);
 void       MapWindowPoints32(HWND32,HWND32,LPPOINT32,UINT32);
 #define    MapWindowPoints WINELIB_NAME(MapWindowPoints)
+BOOL16     ModifyMenu16(HMENU16,UINT16,UINT16,UINT16,SEGPTR);
+BOOL32     ModifyMenu32A(HMENU32,UINT32,UINT32,UINT32,LPCSTR);
+BOOL32     ModifyMenu32W(HMENU32,UINT32,UINT32,UINT32,LPCWSTR);
+#define    ModifyMenu WINELIB_NAME_AW(ModifyMenu)
 BOOL16     MoveToEx16(HDC16,INT16,INT16,LPPOINT16);
 BOOL32     MoveToEx32(HDC32,INT32,INT32,LPPOINT32);
 #define    MoveToEx WINELIB_NAME(MoveToEx)
@@ -3772,6 +3807,14 @@
 void       ScreenToClient16(HWND16,LPPOINT16);
 void       ScreenToClient32(HWND32,LPPOINT32);
 #define    ScreenToClient WINELIB_NAME(ScreenToClient)
+LRESULT    SendDlgItemMessage16(HWND16,INT16,UINT16,WPARAM16,LPARAM);
+LRESULT    SendDlgItemMessage32A(HWND32,INT32,UINT32,WPARAM32,LPARAM);
+LRESULT    SendDlgItemMessage32W(HWND32,INT32,UINT32,WPARAM32,LPARAM);
+#define    SendDlgItemMessage WINELIB_NAME_AW(SendDlgItemMessage)
+LRESULT    SendMessage16(HWND16,UINT16,WPARAM16,LPARAM);
+LRESULT    SendMessage32A(HWND32,UINT32,WPARAM32,LPARAM);
+LRESULT    SendMessage32W(HWND32,UINT32,WPARAM32,LPARAM);
+#define    SendMessage WINELIB_NAME_AW(SendMessage)
 BOOL16     SetBitmapDimensionEx16(HBITMAP16,INT16,INT16,LPSIZE16);
 BOOL32     SetBitmapDimensionEx32(HBITMAP32,INT32,INT32,LPSIZE32);
 #define    SetBitmapDimensionEx WINELIB_NAME(SetBitmapDimensionEx)
@@ -3779,6 +3822,13 @@
 LONG       SetClassLong32A(HWND,INT32,LONG);
 LONG       SetClassLong32W(HWND,INT32,LONG);
 #define    SetClassLong WINELIB_NAME_AW(SetClassLong)
+void       SetDlgItemInt16(HWND16,INT16,UINT16,BOOL16);
+void       SetDlgItemInt32(HWND32,INT32,UINT32,BOOL32);
+#define    SetDlgItemInt WINELIB_NAME(SetDlgItemInt)
+void       SetDlgItemText16(HWND16,INT16,SEGPTR);
+void       SetDlgItemText32A(HWND32,INT32,LPCSTR);
+void       SetDlgItemText32W(HWND32,INT32,LPCWSTR);
+#define    SetDlgItemText WINELIB_NAME_AW(SetDlgItemText)
 void       SetInternalWindowPos16(HWND16,UINT16,LPRECT16,LPPOINT16);
 void       SetInternalWindowPos32(HWND32,UINT32,LPRECT32,LPPOINT32);
 #define    SetInternalWindowPos WINELIB_NAME(SetInternalWindowPos)
@@ -3797,12 +3847,20 @@
 BOOL16     SetWindowExtEx16(HDC16,INT16,INT16,LPSIZE16);
 BOOL32     SetWindowExtEx32(HDC32,INT32,INT32,LPSIZE32);
 #define    SetWindowExtEx WINELIB_NAME(SetWindowExtEx)
+LONG       SetWindowLong16(HWND16,INT16,LONG);
+LONG       SetWindowLong32A(HWND32,INT32,LONG);
+LONG       SetWindowLong32W(HWND32,INT32,LONG);
+#define    SetWindowLong WINELIB_NAME_AW(SetWindowLong)
 BOOL16     SetWindowOrgEx16(HDC16,INT16,INT16,LPPOINT16);
 BOOL32     SetWindowOrgEx32(HDC32,INT32,INT32,LPPOINT32);
 #define    SetWindowOrgEx WINELIB_NAME(SetWindowOrgEx)
 BOOL16     SetWindowPlacement16(HWND16,const WINDOWPLACEMENT16*);
 BOOL32     SetWindowPlacement32(HWND32,const WINDOWPLACEMENT32*);
 #define    SetWindowPlacement WINELIB_NAME(SetWindowPlacement)
+void       SetWindowText16(HWND16,SEGPTR);
+void       SetWindowText32A(HWND32,LPCSTR);
+void       SetWindowText32W(HWND32,LPCWSTR);
+#define    SetWindowText WINELIB_NAME_AW(SetWindowText)
 BOOL16     SubtractRect16(LPRECT16,const RECT16*,const RECT16*);
 BOOL32     SubtractRect32(LPRECT32,const RECT32*,const RECT32*);
 #define    SubtractRect WINELIB_NAME(SubtractRect)
diff --git a/include/winpos.h b/include/winpos.h
index 654bf12..02b2a92 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -39,7 +39,8 @@
                                   RECT16 *newWindowRect, RECT16 *oldWindowRect,
 				  RECT16 *oldClientRect, SEGPTR winpos,
 				  RECT16 *newClientRect );
-extern LONG WINPOS_HandleWindowPosChanging( WINDOWPOS16 *winpos );
+extern LONG WINPOS_HandleWindowPosChanging16(WND *wndPtr, WINDOWPOS16 *winpos);
+extern LONG WINPOS_HandleWindowPosChanging32(WND *wndPtr, WINDOWPOS32 *winpos);
 extern INT16 WINPOS_WindowFromPoint( POINT16 pt, WND **ppWnd );
 
 #endif  /* __WINE_WINPOS_H */
diff --git a/include/winproc.h b/include/winproc.h
new file mode 100644
index 0000000..c26546c
--- /dev/null
+++ b/include/winproc.h
@@ -0,0 +1,25 @@
+/*
+ * Window procedure callbacks definitions
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#ifndef __WINE_WINPROC_H
+#define __WINE_WINPROC_H
+
+#include "wintypes.h"
+
+typedef enum
+{
+    WIN_PROC_INVALID,
+    WIN_PROC_16,
+    WIN_PROC_32A,
+    WIN_PROC_32W
+} WINDOWPROCTYPE;
+
+extern WNDPROC16 WINPROC_AllocWinProc( WNDPROC32 func, WINDOWPROCTYPE type );
+extern WINDOWPROCTYPE WINPROC_GetWinProcType( WNDPROC16 func );
+extern WNDPROC32 WINPROC_GetWinProcFunc( WNDPROC16 func );
+extern void WINPROC_FreeWinProc( WNDPROC16 func );
+
+#endif  /* __WINE_WINPROC_H */
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 5382c5a..0999340 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -45,12 +45,10 @@
 
 extern LRESULT ACTIVATEAPP_callback(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ButtonWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT CARET_Callback(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ColorDlgProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ComboBoxWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ComboLBoxWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT DesktopWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT EditWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT FileOpenDlgProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT FileSaveDlgProc(HWND,UINT,WPARAM,LPARAM);
@@ -82,13 +80,11 @@
 #define MAP_STR_TO_PROC(str,proc) if(!strcmp(name,str))return proc
   MAP_STR_TO_PROC("ActivateAppProc",ACTIVATEAPP_callback);
   MAP_STR_TO_PROC("AboutDlgProc",AboutDlgProc);
-  MAP_STR_TO_PROC("ButtonWndProc",ButtonWndProc);
   MAP_STR_TO_PROC("CARET_Callback",CARET_Callback);
   MAP_STR_TO_PROC("ColorDlgProc",ColorDlgProc);
   MAP_STR_TO_PROC("ComboBoxWndProc",ComboBoxWndProc);
   MAP_STR_TO_PROC("ComboLBoxWndProc",ComboLBoxWndProc);
   MAP_STR_TO_PROC("DefDlgProc",DefDlgProc);
-  MAP_STR_TO_PROC("DesktopWndProc",DesktopWndProc);
   MAP_STR_TO_PROC("EditWndProc",EditWndProc);
   MAP_STR_TO_PROC("FileOpenDlgProc",FileOpenDlgProc);
   MAP_STR_TO_PROC("FileSaveDlgProc",FileSaveDlgProc);
diff --git a/loader/builtin.c b/loader/builtin.c
index 33ea613..e261ab0 100644
--- a/loader/builtin.c
+++ b/loader/builtin.c
@@ -148,12 +148,12 @@
     { &OLE32_Descriptor,    0 },
     { &GDI32_Descriptor,    0 },
     { &KERNEL32_Descriptor, DLL_FLAG_ALWAYS_USED },
-    { &NTDLL_Descriptor,  0 },
+    { &NTDLL_Descriptor,    0 },
     { &SHELL32_Descriptor,  0 },
     { &USER32_Descriptor,   0 },
     { &WPROCS32_Descriptor, DLL_FLAG_ALWAYS_USED },
     { &WINSPOOL_Descriptor, 0 },
-    { &WSOCK32_Descriptor, 0 },
+    { &WSOCK32_Descriptor,  0 },
     /* Last entry */
     { NULL, 0 }
 };
@@ -404,6 +404,7 @@
         }
         if (!dll->descr) return FALSE;
         str = p;
+        while (*str && (isspace(*str) || (*str == ','))) str++;
     }
     return TRUE;
 }
diff --git a/loader/main.c b/loader/main.c
index 18ecdfe..bc3ac02 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -11,7 +11,6 @@
 #include <string.h>
 #include <errno.h>
 #include "windows.h"
-#include "alias.h"
 #include "module.h"
 #include "selectors.h"
 #include "comm.h"
@@ -112,9 +111,6 @@
       /* GDI initialisation */
     if (!GDI_Init()) return 0;
 
-    /* Initialise window procedures aliases */
-    if (!ALIAS_Init()) return 0;
-
       /* Initialize system colors and metrics*/
     SYSMETRICS_Init();
     SYSCOLOR_Init();
diff --git a/loader/module.c b/loader/module.c
index e047415..f6638fd 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -762,11 +762,14 @@
 FARPROC16 MODULE_GetWndProcEntry16( const char *name )
 {
     WORD ordinal;
+    FARPROC16 ret;
     static HMODULE hModule = 0;
 
     if (!hModule) hModule = GetModuleHandle( "WPROCS" );
     ordinal = MODULE_GetOrdinal( hModule, name );
-    return MODULE_GetEntryPoint( hModule, ordinal );
+    if (!(ret = MODULE_GetEntryPoint( hModule, ordinal )))
+        fprintf( stderr, "GetWndProc16: %s not found, please report\n", name );
+    return ret;
 }
 #endif
 
@@ -779,10 +782,13 @@
 #ifndef WINELIB
 FARPROC32 MODULE_GetWndProcEntry32( const char *name )
 {
+    FARPROC32 ret;
     static HMODULE hModule = 0;
 
     if (!hModule) hModule = GetModuleHandle( "WPROCS32" );
-    return PE_GetProcAddress( hModule, name );
+    if (!(ret = PE_GetProcAddress( hModule, name )))
+        fprintf( stderr, "GetWndProc32: %s not found, please report\n", name );
+    return ret;
 }
 #endif
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 04d57bb..fffff8a 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -24,7 +24,6 @@
 #include "peexe.h"
 #include "pe_image.h"
 #include "module.h"
-#include "alias.h"
 #include "global.h"
 #include "task.h"
 #include "ldt.h"
@@ -538,8 +537,6 @@
 	HINSTANCE hInstance;
         struct mz_header_s mz_header;
 
-	ALIAS_UseAliases=1;
-
 	lseek(fd,0,SEEK_SET);
 	read( fd, &mz_header, sizeof(mz_header) );
 
diff --git a/loader/resource.c b/loader/resource.c
index 6ebfd69..56de36f 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -330,7 +330,7 @@
 		if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
 		if(mask == (lpAccelTbl->tbl[i].type &
 			    (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) {
-		    SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
+		    SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
 				0x00010000L);
 		    GlobalUnlock16(hAccel);
 		    return 1;
@@ -342,7 +342,7 @@
 	else {
 	    if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
 		msg->message == WM_CHAR) {
-		SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
+		SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
 		GlobalUnlock16(hAccel);
 		return 1;
 		}
diff --git a/loader/task.c b/loader/task.c
index 52be7a7..44443f6 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -1064,12 +1064,14 @@
  */
 HTASK GetCurrentTask(void)
 {
-      /* Undocumented: first task is returned in high word */
-#ifdef WINELIB32
     return hCurrentTask;
-#else
+}
+
+DWORD WIN16_GetCurrentTask(void)
+{
+    /* This is the version used by relay code; the first task is */
+    /* returned in the high word of the result */
     return MAKELONG( hCurrentTask, hFirstTask );
-#endif
 }
 
 
diff --git a/memory/local.c b/memory/local.c
index d3aecfa..00c564d 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -16,6 +16,8 @@
 #include <string.h>
 #include "windows.h"
 #include "ldt.h"
+#include "global.h"
+#include "heap.h"
 #include "instance.h"
 #include "local.h"
 #include "module.h"
@@ -112,7 +114,7 @@
     LOCALHEAPINFO *pInfo;
     INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 );
     dprintf_local( stddeb, "Heap at %p, %04x\n", ptr, ptr->heap );
-    if (!ptr->heap) return NULL;
+    if (!ptr || !ptr->heap) return NULL;
     if (IsBadReadPtr((SEGPTR)MAKELONG( ptr->heap, ds ), sizeof(LOCALHEAPINFO)))
         return NULL;
     pInfo = (LOCALHEAPINFO*)((char*)ptr + ptr->heap);
@@ -1022,7 +1024,7 @@
     LOCALHEAPINFO *pInfo;
     LOCALARENA *pArena, *pNext;
     LOCALHANDLEENTRY *pEntry;
-    WORD arena, newhandle, blockhandle;
+    WORD arena, newhandle, blockhandle, oldsize;
     LONG nextarena;
 
     if (!handle) return LOCAL_Alloc( ds, size, flags );
@@ -1104,6 +1106,7 @@
     }
 
     size = LALIGN( size );
+    oldsize = pArena->next - arena - ARENA_HEADER_SIZE;
     nextarena = LALIGN(blockhandle + size);
 
       /* Check for size reduction */
@@ -1154,19 +1157,28 @@
     ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
     if (!newhandle)
     {
-        /* Check if previous block is free and large enough */
-        LOCALARENA *pPrev = ARENA_PTR( ptr, pArena->prev & 3 );
-        if (((pPrev->prev & 3) == LOCAL_ARENA_FREE) &&
-            (pPrev->size + pArena->next >= nextarena))
+        /* Remove the block from the heap and try again */
+        LPSTR buffer = HeapAlloc( SystemHeap, 0, oldsize );
+        if (!buffer) return 0;
+        memcpy( buffer, ptr + (arena + ARENA_HEADER_SIZE), oldsize );
+        LOCAL_FreeArena( ds, arena );
+        if (!(newhandle = LOCAL_GetBlock( ds, size, flags )))
         {
-            newhandle = (pArena->prev & ~3) + ARENA_HEADER_SIZE;
-            LOCAL_GrowArenaDownward( ds, arena, size + ARENA_HEADER_SIZE );
+            if (!(newhandle = LOCAL_GetBlock( ds, oldsize, flags )))
+            {
+                fprintf( stderr, "LocalRealloc: can't restore saved block\n" );
+                HeapFree( SystemHeap, 0, buffer );
+                return 0;
+            }
+            size = oldsize;
         }
-        else return 0;  /* Nothing to do, no space left for the block */
+        ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );  /* Reload ptr */
+        memcpy( ptr + newhandle, buffer, oldsize );
+        HeapFree( SystemHeap, 0, buffer );
     }
     else
     {
-        memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), size );
+        memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), oldsize );
         LOCAL_FreeArena( ds, arena );
     }
     if (HANDLE_MOVEABLE( handle ))
@@ -1177,6 +1189,7 @@
         pEntry->lock = 0;
 	newhandle = handle;
     }
+    if (size == oldsize) newhandle = 0;  /* Realloc failed */
     dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
     return newhandle;
 }
@@ -1541,7 +1554,7 @@
  */
 BOOL LocalFirst( LOCALENTRY *pLocalEntry, HGLOBAL handle )
 {
-    WORD ds = SELECTOROF( WIN16_GlobalLock16( handle ) );
+    WORD ds = GlobalHandleToSel( handle );
     char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
     LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
     if (!pInfo) return FALSE;
@@ -1564,7 +1577,7 @@
  */
 BOOL LocalNext( LOCALENTRY *pLocalEntry )
 {
-    WORD ds = SELECTOROF( pLocalEntry->hHeap );
+    WORD ds = GlobalHandleToSel( pLocalEntry->hHeap );
     char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
     LOCALARENA *pArena;
 
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 84143c5..a0569f7 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -148,7 +148,7 @@
 {
     char temp[512], *cp;
 
-    SendDlgItemMessage(hwnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(temp));
+    GetDlgItemText32A( hwnd, edt1, temp, sizeof(temp) );
     cp = strrchr(temp, '\\');
     if (cp != NULL) {
 	strcpy(temp, cp+1);
@@ -157,6 +157,7 @@
     if (cp != NULL) {
 	strcpy(temp, cp+1);
     }
+    /* FIXME: shouldn't we do something with the result here? ;-) */
 }
 
 /***********************************************************************
@@ -167,7 +168,7 @@
   char str[512],str2[512];
 
   strncpy(str,newPath,511); str[511]=0;
-  SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(str2));
+  GetDlgItemText32A( hWnd, edt1, str2, sizeof(str2) );
   strncat(str,str2,511-strlen(str)); str[511]=0;
   if (!DlgDirList(hWnd, MAKE_SEGPTR(str), lst1, 0, 0x0000)) return FALSE;
   strcpy( str, "*.*" );
@@ -219,8 +220,8 @@
 	hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 	SelectObject(lpdis->hDC, hBrush);
 	FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
-	SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
-		    (LPARAM)MAKE_SEGPTR(str));
+	SendMessage16(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
+                      (LPARAM)MAKE_SEGPTR(str));
 	TextOut16(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
                   str, strlen(str));
 	if (lpdis->itemState != 0) {
@@ -233,8 +234,8 @@
 	hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 	SelectObject(lpdis->hDC, hBrush);
 	FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
-	SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
-		    (LPARAM)MAKE_SEGPTR(str));
+	SendMessage16(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
+                      (LPARAM)MAKE_SEGPTR(str));
 
 	hBitmap = hFolder;
 	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
@@ -255,8 +256,8 @@
 	hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 	SelectObject(lpdis->hDC, hBrush);
 	FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
-	SendMessage(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, 
-		    (LPARAM)MAKE_SEGPTR(str));
+	SendMessage16(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, 
+                      (LPARAM)MAKE_SEGPTR(str));
         switch(DRIVE_GetType( str[2] - 'a' ))
         {
         case TYPE_FLOPPY:  hBitmap = hFloppy; break;
@@ -319,10 +320,9 @@
   LPOPENFILENAME lpofn;
   char tmpstr[512];
   LPSTR pstr;
-  SetWindowLong(hWnd, DWL_USER, lParam);
+  SetWindowLong32A(hWnd, DWL_USER, lParam);
   lpofn = (LPOPENFILENAME)lParam;
-  if (lpofn->lpstrTitle)
-      SendMessage( hWnd, WM_SETTEXT, 0, (LPARAM)lpofn->lpstrTitle );
+  if (lpofn->lpstrTitle) SetWindowText16( hWnd, lpofn->lpstrTitle );
   /* read custom filter information */
   if (lpofn->lpstrCustomFilter)
     {
@@ -333,11 +333,11 @@
 	  n = strlen(pstr);
 	  strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
 	  dprintf_commdlg(stddeb,"lpstrCustomFilter // add tmpstr='%s' ", tmpstr);
-          i = SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
+          i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
 	  pstr += n + 1;
 	  n = strlen(pstr);
 	  dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
-          SendDlgItemMessage(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
+          SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
 	  pstr += n + 1;
 	}
     }
@@ -348,26 +348,26 @@
       n = strlen(pstr);
       strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
       dprintf_commdlg(stddeb,"lpstrFilter // add tmpstr='%s' ", tmpstr);
-      i = SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
+      i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
       pstr += n + 1;
       n = strlen(pstr);
       dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
-      SendDlgItemMessage(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
+      SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
       pstr += n + 1;
     }
   /* set default filter */
   if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
   	lpofn->nFilterIndex = 1;
-  SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL, lpofn->nFilterIndex - 1, 0);    
+  SendDlgItemMessage16(hWnd, cmb1, CB_SETCURSEL, lpofn->nFilterIndex - 1, 0);    
   strncpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
 	     PTR_SEG_TO_LIN(lpofn->lpstrFilter), lpofn->nFilterIndex - 1),511);
   tmpstr[511]=0;
   dprintf_commdlg(stddeb,"nFilterIndex = %ld // SetText of edt1 to '%s'\n", 
   			lpofn->nFilterIndex, tmpstr);
-  SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
+  SetDlgItemText32A( hWnd, edt1, tmpstr );
   /* get drive list */
   *tmpstr = 0;
-  DlgDirListComboBox(hWnd, MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
+  DlgDirListComboBox16(hWnd, tmpstr, cmb2, 0, 0xC000);
   /* read initial directory */
   if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) 
     {
@@ -383,7 +383,7 @@
     fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
   /* select current drive in combo 2 */
   n = DRIVE_GetCurrentDrive();
-  SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n, 0);
+  SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL, n, 0);
   if (!(lpofn->Flags & OFN_SHOWHELP))
     ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
   if (lpofn->Flags & OFN_HIDEREADONLY)
@@ -423,11 +423,11 @@
       FILEDLG_StripEditControl(hWnd);
       if (notification == LBN_DBLCLK)
 	goto almost_ok;
-      lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
+      lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL, 0, 0);
       if (lRet == LB_ERR) return TRUE;
-      SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
+      SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
 			 (LPARAM)MAKE_SEGPTR(tmpstr));
-      SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
+      SetDlgItemText32A( hWnd, edt1, tmpstr );
 
       if (FILEDLG_HookCallChk(lpofn))
        CallWindowProc16(lpofn->lpfnHook, hWnd,
@@ -439,9 +439,9 @@
       FILEDLG_StripEditControl(hWnd);
       if (notification == LBN_DBLCLK)
 	{
-	  lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0);
+	  lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL, 0, 0);
 	  if (lRet == LB_ERR) return TRUE;
-	  SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet,
+	  SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT, lRet,
 			     (LPARAM)MAKE_SEGPTR(tmpstr));
 	  if (tmpstr[0] == '[')
 	    {
@@ -461,18 +461,17 @@
       return TRUE;
     case cmb2: /* disk drop list */
       FILEDLG_StripEditControl(hWnd);
-      lRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
+      lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
       if (lRet == LB_ERR) return 0;
-      SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, lRet, (LPARAM)MAKE_SEGPTR(tmpstr));
+      SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT, lRet, (LPARAM)MAKE_SEGPTR(tmpstr));
       sprintf(tmpstr, "%c:", tmpstr[2]);
     reset_scan:
-      lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
+      lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL, 0, 0);
       if (lRet == LB_ERR)
 	return TRUE;
-      pstr = (LPSTR)SendDlgItemMessage(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
+      pstr = (LPSTR)SendDlgItemMessage16(hWnd, cmb1, CB_GETITEMDATA, lRet, 0);
       dprintf_commdlg(stddeb,"Selected filter : %s\n", pstr);
-      strncpy(tmpstr2, pstr, 511); tmpstr2[511]=0;
-      SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
+      SetDlgItemText32A( hWnd, edt1, pstr );
       FILEDLG_ScanDir(hWnd, tmpstr);
       return TRUE;
     case chx1:
@@ -482,7 +481,7 @@
     case IDOK:
     almost_ok:
       ofn2=*lpofn; /* for later restoring */
-      SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, (LPARAM)MAKE_SEGPTR(tmpstr));
+      GetDlgItemText32A( hWnd, edt1, tmpstr, sizeof(tmpstr) );
       pstr = strrchr(tmpstr, '\\');
       if (pstr == NULL)
 	pstr = strrchr(tmpstr, ':');
@@ -500,7 +499,7 @@
 	      *tmpstr=0;
 	    }
 	  dprintf_commdlg(stddeb,"commdlg: %s, %s\n", tmpstr, tmpstr2);
-	  SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
+          SetDlgItemText32A( hWnd, edt1, tmpstr2 );
 	  FILEDLG_ScanDir(hWnd, tmpstr);
 	  return TRUE;
 	}
@@ -509,16 +508,15 @@
       pstr2 = tmpstr + strlen(tmpstr);
       if (pstr == NULL || *(pstr+1) != 0)
 	strcat(tmpstr, "\\");
-      lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
+      lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL, 0, 0);
       if (lRet == LB_ERR) return TRUE;
       lpofn->nFilterIndex = lRet + 1;
       dprintf_commdlg(stddeb,"commdlg: lpofn->nFilterIndex=%ld\n", lpofn->nFilterIndex);
-      strncpy(tmpstr2, 
+      lstrcpyn(tmpstr2, 
 	     FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
 				 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
-				 lRet), 511);
-      tmpstr2[511]=0;
-      SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
+				 lRet), sizeof(tmpstr2));
+      SetDlgItemText32A( hWnd, edt1, tmpstr2 );
       /* if ScanDir succeeds, we have changed the directory */
       if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
       /* if not, this must be a filename */
@@ -527,14 +525,13 @@
 	{
 	  /* strip off the pathname */
 	  *pstr = 0;
-	  strncpy(tmpstr2, pstr+1, 511); tmpstr2[511]=0;
-	  SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr2));
+          SetDlgItemText32A( hWnd, edt1, pstr + 1 );
+	  lstrcpyn(tmpstr2, pstr+1, sizeof(tmpstr2) );
 	  /* Should we MessageBox() if this fails? */
 	  if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
 	  strcpy(tmpstr, tmpstr2);
 	}
-      else 
-	SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
+      else SetDlgItemText32A( hWnd, edt1, tmpstr );
 #if 0
       ShowWindow(hWnd, SW_HIDE);   /* this should not be necessary ?! (%%%) */
 #endif
@@ -559,8 +556,8 @@
 	lpofn->nFileExtension++;
       if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) 
 	{
-	  lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
-	  SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
+	  lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL, 0, 0);
+	  SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
 			     (LPARAM)MAKE_SEGPTR(tmpstr));
           dprintf_commdlg(stddeb,"strcpy'ing '%s'\n",tmpstr); fflush(stdout);
 	  strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
@@ -762,7 +759,7 @@
 {
     LPFINDREPLACE lpfr;
 
-    SetWindowLong(hWnd, DWL_USER, lParam);
+    SetWindowLong32A(hWnd, DWL_USER, lParam);
     lpfr = (LPFINDREPLACE)lParam;
     lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
     /*
@@ -770,7 +767,7 @@
      * FindNext (IDOK) button.  Only after typing some text, the button should be
      * enabled.
      */
-    SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
+    SetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat);
     CheckRadioButton(hWnd, rad1, rad2, (lpfr->Flags & FR_DOWN) ? rad2 : rad1);
     if (lpfr->Flags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
 	EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
@@ -812,7 +809,7 @@
     lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
     switch (wParam) {
 	case IDOK:
-	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
 	    if (IsDlgButtonChecked(hWnd, rad2))
 		lpfr->Flags |= FR_DOWN;
 		else lpfr->Flags &= ~FR_DOWN;
@@ -824,17 +821,17 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_FINDNEXT;
-	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
 	    return TRUE;
 	case IDCANCEL:
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
 	    lpfr->Flags |= FR_DIALOGTERM;
-	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
 	    DestroyWindow(hWnd);
 	    return TRUE;
 	case pshHelp:
 	    /* FIXME : should lpfr structure be passed as an argument ??? */
-	    SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
+	    SendMessage16(lpfr->hwndOwner, uHelpMessage, 0, 0);
 	    return TRUE;
     }
     return FALSE;
@@ -863,7 +860,7 @@
 {
     LPFINDREPLACE lpfr;
 
-    SetWindowLong(hWnd, DWL_USER, lParam);
+    SetWindowLong32A(hWnd, DWL_USER, lParam);
     lpfr = (LPFINDREPLACE)lParam;
     lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
     /*
@@ -871,8 +868,8 @@
      * Replace / ReplaceAll buttons.  Only after typing some text, the buttons should be
      * enabled.
      */
-    SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
-    SetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith);
+    SetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat);
+    SetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith);
     CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
     if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
 	EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
@@ -904,8 +901,8 @@
     lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
     switch (wParam) {
 	case IDOK:
-	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
-	    GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
 	    if (IsDlgButtonChecked(hWnd, chx1))
 		lpfr->Flags |= FR_WHOLEWORD; 
 		else lpfr->Flags &= ~FR_WHOLEWORD;
@@ -914,17 +911,17 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_FINDNEXT;
-	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
 	    return TRUE;
 	case IDCANCEL:
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
 	    lpfr->Flags |= FR_DIALOGTERM;
-	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
 	    DestroyWindow(hWnd);
 	    return TRUE;
 	case psh1:
-	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
-	    GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
 	    if (IsDlgButtonChecked(hWnd, chx1))
 		lpfr->Flags |= FR_WHOLEWORD; 
 		else lpfr->Flags &= ~FR_WHOLEWORD;
@@ -933,11 +930,11 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_REPLACE;
-	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
 	    return TRUE;
 	case psh2:
-	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
-	    GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText16(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
 	    if (IsDlgButtonChecked(hWnd, chx1))
 		lpfr->Flags |= FR_WHOLEWORD; 
 		else lpfr->Flags &= ~FR_WHOLEWORD;
@@ -946,11 +943,11 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_REPLACEALL;
-	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
 	    return TRUE;
 	case pshHelp:
 	    /* FIXME : should lpfr structure be passed as an argument ??? */
-	    SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
+	    SendMessage16(lpfr->hwndOwner, uHelpMessage, 0, 0);
 	    return TRUE;
     }
     return FALSE;
@@ -1382,7 +1379,7 @@
  int i,k,m,result,value;
  long editpos;
  char buffer[30];
- GetWindowText(hwnd,buffer,30-1);
+ GetWindowText32A(hwnd,buffer,sizeof(buffer));
  m=lstrlen(buffer);
  result=0;
 
@@ -1406,9 +1403,9 @@
  }
  if (result)
  {
-  editpos=SendMessage(hwnd,EM_GETSEL,0,0);
-  SetWindowText(hwnd,buffer);
-  SendMessage(hwnd,EM_SETSEL,0,editpos);
+  editpos=SendMessage16(hwnd,EM_GETSEL,0,0);
+  SetWindowText32A(hwnd,buffer);
+  SendMessage16(hwnd,EM_SETSEL,0,editpos);
  }
  return value;
 }
@@ -1654,11 +1651,11 @@
  {
    lpp->updating=TRUE;
    sprintf(buffer,"%d",r);
-   SetWindowText(GetDlgItem(hDlg,0x2c2),buffer);
+   SetWindowText32A(GetDlgItem(hDlg,0x2c2),buffer);
    sprintf(buffer,"%d",g);
-   SetWindowText(GetDlgItem(hDlg,0x2c3),buffer);
+   SetWindowText32A(GetDlgItem(hDlg,0x2c3),buffer);
    sprintf(buffer,"%d",b);
-   SetWindowText(GetDlgItem(hDlg,0x2c4),buffer);
+   SetWindowText32A(GetDlgItem(hDlg,0x2c4),buffer);
    lpp->updating=FALSE;
  }
 }
@@ -1675,11 +1672,11 @@
  {
    lpp->updating=TRUE;
    sprintf(buffer,"%d",h);
-   SetWindowText(GetDlgItem(hDlg,0x2bf),buffer);
+   SetWindowText32A(GetDlgItem(hDlg,0x2bf),buffer);
    sprintf(buffer,"%d",s);
-   SetWindowText(GetDlgItem(hDlg,0x2c0),buffer);
+   SetWindowText32A(GetDlgItem(hDlg,0x2c0),buffer);
    sprintf(buffer,"%d",l);
-   SetWindowText(GetDlgItem(hDlg,0x2c1),buffer);
+   SetWindowText32A(GetDlgItem(hDlg,0x2c1),buffer);
    lpp->updating=FALSE;
  }
  CC_PaintLumBar(hDlg,h,s);
@@ -1828,7 +1825,7 @@
       EndDialog (hDlg, 0) ;
       return FALSE;
    }
-   SetWindowLong(hDlg, DWL_USER, (LONG)lpp); 
+   SetWindowLong32A(hDlg, DWL_USER, (LONG)lpp); 
 
    if (!(lpp->lpcc->Flags & CC_SHOWHELP))
       ShowWindow(GetDlgItem(hDlg,0x40e),SW_HIDE);
@@ -1873,7 +1870,7 @@
       CC_SwitchToFullSize(hDlg,lpp->lpcc->rgbResult,NULL);
    res=TRUE;
    for (i=0x2bf;i<0x2c5;i++)
-     SendMessage(GetDlgItem(hDlg,i),EM_LIMITTEXT,3,0);      /* max 3 digits:  xyz  */
+     SendMessage16(GetDlgItem(hDlg,i),EM_LIMITTEXT,3,0);      /* max 3 digits:  xyz  */
    if (CC_HookCallChk(lpp->lpcc))
       res=CallWindowProc16((FARPROC)lpp->lpcc->lpfnHook,hDlg,WM_INITDIALOG,wParam,lParam);
    return res;
@@ -1983,7 +1980,7 @@
 	  case 0x40e:           /* Help! */ /* The Beatles, 1965  ;-) */
 	       i=RegisterWindowMessage32A( HELPMSGSTRING );
 	       if (lpp->lpcc->hwndOwner)
-		   SendMessage(lpp->lpcc->hwndOwner,i,0,(LPARAM)lpp->lpcc);
+		   SendMessage16(lpp->lpcc->hwndOwner,i,0,(LPARAM)lpp->lpcc);
 	       if (CC_HookCallChk(lpp->lpcc))
 		   CallWindowProc16((FARPROC)lpp->lpcc->lpfnHook,hDlg,
 		      WM_COMMAND,psh15,(LPARAM)lpp->lpcc);
@@ -1992,7 +1989,7 @@
           case IDOK :
 		cokmsg=RegisterWindowMessage32A( COLOROKSTRING );
 		if (lpp->lpcc->hwndOwner)
-			if (SendMessage(lpp->lpcc->hwndOwner,cokmsg,0,(LPARAM)lpp->lpcc))
+			if (SendMessage16(lpp->lpcc->hwndOwner,cokmsg,0,(LPARAM)lpp->lpcc))
 			   break;    /* do NOT close */
 
 		EndDialog (hDlg, 1) ;
@@ -2113,7 +2110,7 @@
 	                DeleteDC(lpp->hdcMem); 
 	                DeleteObject(lpp->hbmMem); 
 	                free(lpp);
-	                SetWindowLong(hDlg, DWL_USER, 0L); /* we don't need it anymore */
+	                SetWindowLong32A(hDlg, DWL_USER, 0L); /* we don't need it anymore */
 	                break;
 	  case WM_COMMAND:
 	                if (CC_WMCommand(hDlg, wParam, lParam))
@@ -2192,11 +2189,11 @@
 
   dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s (nFontType=%d)\n",
      			lplf->lfFaceName,nFontType);
-  i=SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(lplf->lfFaceName));
+  i=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(lplf->lfFaceName));
   if (i!=CB_ERR)
   {
     w=(lplf->lfCharSet << 8) | lplf->lfPitchAndFamily;
-    SendMessage(hwnd, CB_SETITEMDATA,i,MAKELONG(nFontType,w));
+    SendMessage16(hwnd, CB_SETITEMDATA,i,MAKELONG(nFontType,w));
     return 1 ;
   }
   else
@@ -2225,14 +2222,14 @@
   {
     int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};  
     int i;
-    if (!SendMessage(hcmb3,CB_GETCOUNT,0,0)) 
+    if (!SendMessage16(hcmb3,CB_GETCOUNT,0,0)) 
     {
       i=0;
       while (sizes[i])
       {
         sprintf(buffer,"%d",sizes[i]);
-        j=SendMessage(hcmb3,CB_INSERTSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
-        SendMessage(hcmb3, CB_SETITEMDATA, j, MAKELONG(sizes[i],0));
+        j=SendMessage16(hcmb3,CB_INSERTSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
+        SendMessage16(hcmb3, CB_SETITEMDATA, j, MAKELONG(sizes[i],0));
         i++;
       }
     }
@@ -2245,11 +2242,11 @@
     if (lplf->lfHeight)
     {
       sprintf(buffer,"%3d",lplf->lfHeight);
-      j=SendMessage(hcmb3,CB_FINDSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
+      j=SendMessage16(hcmb3,CB_FINDSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
       if (j==CB_ERR)
       {
-       j=SendMessage(hcmb3,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
-       SendMessage(hcmb3, CB_SETITEMDATA, j, MAKELONG(lplf->lfHeight,lplf->lfWidth));
+       j=SendMessage16(hcmb3,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
+       SendMessage16(hcmb3, CB_SETITEMDATA, j, MAKELONG(lplf->lfHeight,lplf->lfWidth));
       } 
     } 
   }
@@ -2273,7 +2270,7 @@
   HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT));
   LPCHOOSEFONT lpcf;
 
-  SetWindowLong(hDlg, DWL_USER, lParam); 
+  SetWindowLong32A(hDlg, DWL_USER, lParam); 
   lpcf=(LPCHOOSEFONT)lParam;
   lpxx=PTR_SEG_TO_LIN(lpcf->lpLogFont);
   dprintf_commdlg(stddeb,"FormatCharDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
@@ -2296,11 +2293,11 @@
     for (res=1,i=0;res && i<TEXT_COLORS;i++)
     {
       /* FIXME: load color name from resource:  res=LoadString(...,i+....,buffer,.....); */
-      j=SendDlgItemMessage(hDlg,cmb4,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR("[color name]"));
-      SendDlgItemMessage(hDlg,cmb4, CB_SETITEMDATA,j,textcolors[j]);
+      j=SendDlgItemMessage16(hDlg,cmb4,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR("[color name]"));
+      SendDlgItemMessage16(hDlg,cmb4, CB_SETITEMDATA,j,textcolors[j]);
       /* look for a fitting value in color combobox */
       if (textcolors[j]==lpcf->rgbColors)
-        SendDlgItemMessage(hDlg,cmb4, CB_SETCURSEL,j,0);
+        SendDlgItemMessage16(hDlg,cmb4, CB_SETCURSEL,j,0);
     }
   }
   else
@@ -2314,17 +2311,17 @@
   
   /* perhaps this stuff should be moved to FontStyleEnumProc() ?? */
   strcpy(buffer,"Regular"); 	/* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
-  j=SendDlgItemMessage(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
-  SendDlgItemMessage(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_NORMAL,0));
+  j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
+  SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_NORMAL,0));
   strcpy(buffer,"Bold");       	/* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
-  j=SendDlgItemMessage(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
-  SendDlgItemMessage(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_BOLD,0));
+  j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
+  SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_BOLD,0));
   strcpy(buffer,"Italic");	/* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
-  j=SendDlgItemMessage(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
-  SendDlgItemMessage(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_NORMAL,1));
+  j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
+  SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_NORMAL,1));
   strcpy(buffer,"Bold Italic");	/* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
-  j=SendDlgItemMessage(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
-  SendDlgItemMessage(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_BOLD,1));
+  j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
+  SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_BOLD,1));
   
   hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
   if (hdc)
@@ -2334,41 +2331,41 @@
     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
     {
       /* look for fitting font name in combobox1 */
-      j=SendDlgItemMessage(hDlg,cmb1,CB_FINDSTRING,-1,(LONG)lpxx->lfFaceName);
+      j=SendDlgItemMessage16(hDlg,cmb1,CB_FINDSTRING,-1,(LONG)lpxx->lfFaceName);
       if (j!=CB_ERR)
       {
-        SendDlgItemMessage(hDlg,cmb1,CB_SETCURSEL,j,0);
-	SendMessage(hDlg,WM_COMMAND,cmb1,MAKELONG(GetDlgItem(hDlg,cmb1),CBN_SELCHANGE));
+        SendDlgItemMessage16(hDlg,cmb1,CB_SETCURSEL,j,0);
+	SendMessage16(hDlg,WM_COMMAND,cmb1,MAKELONG(GetDlgItem(hDlg,cmb1),CBN_SELCHANGE));
         init=1;
         /* look for fitting font style in combobox2 */
         l=MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:FW_NORMAL,lpxx->lfItalic !=0);
         for (i=0;i<TEXT_EXTRAS;i++)
         {
-          if (l==SendDlgItemMessage(hDlg,cmb2, CB_GETITEMDATA,i,0))
-            SendDlgItemMessage(hDlg,cmb2,CB_SETCURSEL,i,0);
+          if (l==SendDlgItemMessage16(hDlg,cmb2, CB_GETITEMDATA,i,0))
+            SendDlgItemMessage16(hDlg,cmb2,CB_SETCURSEL,i,0);
         }
       
         /* look for fitting font size in combobox3 */
-        j=SendDlgItemMessage(hDlg,cmb3,CB_GETCOUNT,0,0);
+        j=SendDlgItemMessage16(hDlg,cmb3,CB_GETCOUNT,0,0);
         for (i=0;i<j;i++)
         {
-          if (lpxx->lfHeight==(int)SendDlgItemMessage(hDlg,cmb3, CB_GETITEMDATA,i,0))
-            SendDlgItemMessage(hDlg,cmb3,CB_SETCURSEL,i,0);
+          if (lpxx->lfHeight==(int)SendDlgItemMessage16(hDlg,cmb3, CB_GETITEMDATA,i,0))
+            SendDlgItemMessage16(hDlg,cmb3,CB_SETCURSEL,i,0);
         }
       }
       if (!init)
       {
-        SendDlgItemMessage(hDlg,cmb1,CB_SETCURSEL,0,0);
-	SendMessage(hDlg,WM_COMMAND,cmb1,MAKELONG(GetDlgItem(hDlg,cmb1),CBN_SELCHANGE));      
+        SendDlgItemMessage16(hDlg,cmb1,CB_SETCURSEL,0,0);
+	SendMessage16(hDlg,WM_COMMAND,cmb1,MAKELONG(GetDlgItem(hDlg,cmb1),CBN_SELCHANGE));      
       }
     }
     if (lpcf->Flags & CF_USESTYLE && lpcf->lpszStyle)
     {
-      j=SendDlgItemMessage(hDlg,cmb2,CB_FINDSTRING,-1,(LONG)lpcf->lpszStyle);
+      j=SendDlgItemMessage16(hDlg,cmb2,CB_FINDSTRING,-1,(LONG)lpcf->lpszStyle);
       if (j!=CB_ERR)
       {
-        j=SendDlgItemMessage(hDlg,cmb2,CB_SETCURSEL,j,0);
-        SendMessage(hDlg,WM_COMMAND,cmb2,MAKELONG(GetDlgItem(hDlg,cmb2),CBN_SELCHANGE));
+        j=SendDlgItemMessage16(hDlg,cmb2,CB_SETCURSEL,j,0);
+        SendMessage16(hDlg,WM_COMMAND,cmb2,MAKELONG(GetDlgItem(hDlg,cmb2),CBN_SELCHANGE));
       }
     }
   }
@@ -2439,13 +2436,13 @@
    switch (lpdi->CtlID)
    {
     case cmb1:	/* dprintf_commdlg(stddeb,"WM_Drawitem cmb1\n"); */
-		SendMessage(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
+		SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
 			(LPARAM)MAKE_SEGPTR(buffer));	          
 		GetObject(hBitmapTT, sizeof(BITMAP), (LPSTR)&bm);
 		TextOut16(lpdi->hDC, lpdi->rcItem.left + bm.bmWidth + 10,
                           lpdi->rcItem.top, buffer, lstrlen(buffer));
 #if 0
-		nFontType = SendMessage(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
+		nFontType = SendMessage16(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
 		  /* FIXME: draw bitmap if truetype usage */
 		if (nFontType&TRUETYPE_FONTTYPE)
 		{
@@ -2460,18 +2457,18 @@
 		break;
     case cmb2:
     case cmb3:	/* dprintf_commdlg(stddeb,"WM_DRAWITEN cmb2,cmb3\n"); */
-		SendMessage(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
+		SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
 			(LPARAM)MAKE_SEGPTR(buffer));
 		TextOut16(lpdi->hDC, lpdi->rcItem.left,
                           lpdi->rcItem.top, buffer, lstrlen(buffer));
 		break;
 
     case cmb4:	/* dprintf_commdlg(stddeb,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
-		SendMessage(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
+		SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
     		    (LPARAM)MAKE_SEGPTR(buffer));
 		TextOut16(lpdi->hDC, lpdi->rcItem.left +  25+5,
                           lpdi->rcItem.top, buffer, lstrlen(buffer));
-		cr = SendMessage(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
+		cr = SendMessage16(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
 		hBrush = CreateSolidBrush(cr);
 		if (hBrush)
 		{
@@ -2536,12 +2533,12 @@
 		      /* only if cmb2 is refilled in  FontStyleEnumProc():
        		                 SendDlgItemMessage(hDlg,cmb2,CB_RESETCONTENT,0,0); 
 		       */
-		      SendDlgItemMessage(hDlg,cmb3,CB_RESETCONTENT,0,0);
-		      i=SendDlgItemMessage(hDlg,cmb1,CB_GETCURSEL,0,0);
+		      SendDlgItemMessage16(hDlg,cmb3,CB_RESETCONTENT,0,0);
+		      i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL,0,0);
 		      if (i!=CB_ERR)
 		      {
 		        HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT));
-                        SendDlgItemMessage(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
+                        SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
 	                dprintf_commdlg(stddeb,"WM_COMMAND/cmb1 =>%s\n",buffer);
 		        enumCallback = MODULE_GetWndProcEntry16("FontStyleEnumProc");
        		        EnumFontFamilies(hdc,buffer,enumCallback,
@@ -2564,13 +2561,13 @@
 	case cmb3:if (HIWORD(lParam)==CBN_SELCHANGE || HIWORD(lParam)== BN_CLICKED )
 	          {
                     dprintf_commdlg(stddeb,"WM_COMMAND/cmb2,3 =%08lX\n", lParam);
-		    i=SendDlgItemMessage(hDlg,cmb1,CB_GETCURSEL,0,0);
+		    i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL,0,0);
 		    if (i==CB_ERR)
-                      i=SendDlgItemMessage(hDlg,cmb1,WM_GETTEXT,20,(LPARAM)MAKE_SEGPTR(buffer));
+                      i=GetDlgItemText32A( hDlg, cmb1, buffer, sizeof(buffer) );
                     else
                     {
-		      SendDlgItemMessage(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
-		      l=SendDlgItemMessage(hDlg,cmb1,CB_GETITEMDATA,i,0);
+		      SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
+		      l=SendDlgItemMessage16(hDlg,cmb1,CB_GETITEMDATA,i,0);
 		      j=HIWORD(l);
 		      lpcf->nFontType = LOWORD(l);
 		      /* FIXME:   lpcf->nFontType |= ....  SIMULATED_FONTTYPE and so */
@@ -2580,19 +2577,19 @@
 		      lpxx->lfCharSet=j>>8;
                     }
                     strcpy(lpxx->lfFaceName,buffer);
-		    i=SendDlgItemMessage(hDlg,cmb2,CB_GETCURSEL,0,0);
+		    i=SendDlgItemMessage16(hDlg,cmb2,CB_GETCURSEL,0,0);
 		    if (i!=CB_ERR)
 		    {
-		      l=SendDlgItemMessage(hDlg,cmb2,CB_GETITEMDATA,i,0);
+		      l=SendDlgItemMessage16(hDlg,cmb2,CB_GETITEMDATA,i,0);
 		      if (0!=(lpxx->lfItalic=HIWORD(l)))
 		        lpcf->nFontType |= ITALIC_FONTTYPE;
 		      if ((lpxx->lfWeight=LOWORD(l)) > FW_MEDIUM)
 		        lpcf->nFontType |= BOLD_FONTTYPE;
 		    }
-		    i=SendDlgItemMessage(hDlg,cmb3,CB_GETCURSEL,0,0);
+		    i=SendDlgItemMessage16(hDlg,cmb3,CB_GETCURSEL,0,0);
 		    if (i!=CB_ERR)
 		    {
-		      l=SendDlgItemMessage(hDlg,cmb3,CB_GETITEMDATA,i,0);
+		      l=SendDlgItemMessage16(hDlg,cmb3,CB_GETITEMDATA,i,0);
 		      lpxx->lfHeight=-LOWORD(l);
 		      lpxx->lfWidth = 0;  /* FYI: lfWidth is in HIWORD(l); */
 		    }
@@ -2605,12 +2602,12 @@
 
 		    hFont=CreateFontIndirect(lpxx);
 		    if (hFont)
-		      SendDlgItemMessage(hDlg,stc6,WM_SETFONT,hFont,TRUE);
+		      SendDlgItemMessage16(hDlg,stc6,WM_SETFONT,hFont,TRUE);
 		    /* FIXME: Delete old font ...? */  
                   }
                   break;
 
-	case cmb4:i=SendDlgItemMessage(hDlg,cmb4,CB_GETCURSEL,0,0);
+	case cmb4:i=SendDlgItemMessage16(hDlg,cmb4,CB_GETCURSEL,0,0);
 		  if (i!=CB_ERR)
 		  {
 		   lpcf->rgbColors=textcolors[i];
@@ -2620,7 +2617,7 @@
 	
 	case psh15:i=RegisterWindowMessage32A( HELPMSGSTRING );
 		  if (lpcf->hwndOwner)
-		    SendMessage(lpcf->hwndOwner,i,0,(LPARAM)lpcf);
+		    SendMessage16(lpcf->hwndOwner,i,0,(LPARAM)lpcf);
 		  if (CFn_HookCallChk(lpcf))
 		    CallWindowProc16(lpcf->lpfnHook,hDlg,WM_COMMAND,psh15,(LPARAM)lpcf);
 		  break;
diff --git a/misc/exec.c b/misc/exec.c
index a1982ce..d863e16 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -86,7 +86,7 @@
     {
           /* Make sure that window still exists */
         if (!IsWindow(*pWnd)) continue;
-	if (!SendMessage( *pWnd, WM_QUERYENDSESSION, 0, 0 )) break;
+	if (!SendMessage16( *pWnd, WM_QUERYENDSESSION, 0, 0 )) break;
     }
     result = (i == count);
 
@@ -95,7 +95,7 @@
     for (pWnd = list; i > 0; i--, pWnd++)
     {
 	if (!IsWindow(*pWnd)) continue;
-	SendMessage( *pWnd, WM_ENDSESSION, result, 0 );
+	SendMessage16( *pWnd, WM_ENDSESSION, result, 0 );
     }
     free( list );
 
@@ -176,5 +176,5 @@
 	} else
 		lpwh->ofsData = 0;
 	GlobalUnlock16(hwh);
-	return SendMessage(hDest,WM_WINHELP,hWnd,hwh);
+	return SendMessage16(hDest,WM_WINHELP,hWnd,hwh);
 }
diff --git a/misc/shell.c b/misc/shell.c
index ff63653..0aff5cb 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -336,14 +336,14 @@
   switch(msg) {
    case WM_INITDIALOG:
 #ifdef WINELIB32
-    SendDlgItemMessage(hWnd,stc1,STM_SETICON,lParam,0);
+    SendDlgItemMessage32A(hWnd,stc1,STM_SETICON,lParam,0);
 #else
-    SendDlgItemMessage(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
+    SendDlgItemMessage16(hWnd,stc1,STM_SETICON,LOWORD(lParam),0);
 #endif
-    GetWindowText(hWnd, Template, 511);
+    GetWindowText32A(hWnd, Template, sizeof(Template));
     sprintf(AppTitle, Template, AppName);
-    SetWindowText(hWnd, AppTitle);
-    SetWindowText(GetDlgItem(hWnd,100), AppMisc);
+    SetWindowText32A(hWnd, AppTitle);
+    SetWindowText32A(GetDlgItem(hWnd,100), AppMisc);
     return 1;
     
    case WM_COMMAND:
diff --git a/misc/spy.c b/misc/spy.c
index 791326b..072f62e 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -430,21 +430,28 @@
 /***********************************************************************
  *           SPY_EnterMessage
  */
-void SPY_EnterMessage( int iFlag, HWND hWnd, UINT msg,
-                       WPARAM wParam, LPARAM lParam )
+void SPY_EnterMessage( INT32 iFlag, HWND32 hWnd, UINT32 msg,
+                       WPARAM32 wParam, LPARAM lParam )
 {
     if (!debugging_message || SPY_EXCLUDE(msg)) return;
 
-    /* each SPY_SENDMESSAGE must be complemented by call to ExitSpyMessage */
+    /* each SPY_SENDMESSAGE must be complemented by call to SPY_ExitMessage */
     switch(iFlag)
     {
-    case SPY_DISPATCHMESSAGE:
-        dprintf_message(stddeb,"(%04x) message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
-                        hWnd, msg, SPY_GetMsgName( msg ),
+    case SPY_DISPATCHMESSAGE16:
+        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
+                        SPY_IndentLevel, "", hWnd, msg, SPY_GetMsgName( msg ),
                         wParam, lParam);
         break;
 
-    case SPY_SENDMESSAGE:
+    case SPY_DISPATCHMESSAGE32:
+        dprintf_message(stddeb,"%*s(%08x) message [%04x] %s dispatched  wp=%08x lp=%08lx\n",
+                        SPY_IndentLevel, "", hWnd, msg, SPY_GetMsgName( msg ),
+                        wParam, lParam);
+        break;
+
+    case SPY_SENDMESSAGE16:
+    case SPY_SENDMESSAGE32:
         {
             char taskName[30];
             HTASK hTask = GetWindowTask(hWnd);
@@ -453,43 +460,66 @@
             else sprintf( taskName, "task %04x %s",
                           hTask, MODULE_GetModuleName( GetExePtr(hTask) ) );
 
-            dprintf_message(stddeb,"%*s(%04x) message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
-                            SPY_IndentLevel, "", hWnd, msg,
-                            SPY_GetMsgName( msg ), taskName, wParam, lParam );
-            SPY_IndentLevel += SPY_INDENT_UNIT;
+            if (iFlag == SPY_SENDMESSAGE16)
+                dprintf_message(stddeb,"%*s(%04x) message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
+                                SPY_IndentLevel, "", hWnd, msg,
+                                SPY_GetMsgName( msg ), taskName, wParam,
+                                lParam );
+            else
+                dprintf_message(stddeb,"%*s(%08x) message [%04x] %s sent from %s wp=%08x lp=%08lx\n",
+                                SPY_IndentLevel, "", hWnd, msg,
+                                SPY_GetMsgName( msg ), taskName, wParam,
+                                lParam );
         }
         break;   
 
-    case SPY_DEFWNDPROC:
+    case SPY_DEFWNDPROC16:
         dprintf_message(stddeb, "%*s(%04x) DefWindowProc: %s [%04x]  wp=%04x lp=%08lx\n",
                         SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ),
                         msg, wParam, lParam );
         break;
+
+    case SPY_DEFWNDPROC32:
+        dprintf_message(stddeb, "%*s(%08x) DefWindowProc: %s [%04x]  wp=%08x lp=%08lx\n",
+                        SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ),
+                        msg, wParam, lParam );
+        break;
     }  
+    SPY_IndentLevel += SPY_INDENT_UNIT;
 }
 
 
 /***********************************************************************
  *           SPY_ExitMessage
  */
-void SPY_ExitMessage( int iFlag, HWND hWnd, UINT msg, LRESULT lReturn )
+void SPY_ExitMessage( INT32 iFlag, HWND32 hWnd, UINT32 msg, LRESULT lReturn )
 {
     if (!debugging_message || SPY_EXCLUDE(msg)) return;
     if (SPY_IndentLevel) SPY_IndentLevel -= SPY_INDENT_UNIT;
 
     switch(iFlag)
     {
-    case SPY_RESULT_INVALIDHWND: 
-        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s HAS INVALID HWND\n",
-                        SPY_IndentLevel, "", hWnd, msg,
-                        SPY_GetMsgName( msg ) );
-        break;
-    case SPY_RESULT_OK:
+    case SPY_RESULT_OK16:
         dprintf_message(stddeb,"%*s(%04x) message [%04x] %s returned %08lx\n",
                         SPY_IndentLevel, "", hWnd, msg,
                         SPY_GetMsgName( msg ), lReturn );
         break;
-    }
+    case SPY_RESULT_OK32:
+        dprintf_message(stddeb,"%*s(%08x) message [%04x] %s returned %08lx\n",
+                        SPY_IndentLevel, "", hWnd, msg,
+                        SPY_GetMsgName( msg ), lReturn );
+        break; 
+    case SPY_RESULT_INVALIDHWND16:
+        dprintf_message(stddeb,"%*s(%04x) message [%04x] %s HAS INVALID HWND\n",
+                        SPY_IndentLevel, "", hWnd, msg,
+                        SPY_GetMsgName( msg ) );
+        break;
+    case SPY_RESULT_INVALIDHWND32:
+        dprintf_message(stddeb,"%*s(%08x) message [%04x] %s HAS INVALID HWND\n",
+                        SPY_IndentLevel, "", hWnd, msg,
+                        SPY_GetMsgName( msg ) );
+        break;
+   }
 }
 
 
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 9efed12..a028713 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -101,7 +101,7 @@
     bmpObjPtr->bitmap.bmHeight = height;
     bmpObjPtr->bitmap.bmPlanes = planes;
     bmpObjPtr->bitmap.bmBitsPixel = bpp;
-    bmpObjPtr->bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2;
+    bmpObjPtr->bitmap.bmWidthBytes = BITMAP_WIDTH_BYTES( width, bpp );
     bmpObjPtr->bitmap.bmBits = NULL;
 
       /* Create the pixmap */
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index 700b53b..223c0c3 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -536,9 +536,9 @@
 
     hInstance = GetExePtr( hInstance );  /* Make it a module handle */
     if (!hInstance || !lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
-    info->nWidthBytes = (info->nWidth * info->bBitsPerPixel + 15) / 16 * 2;
+    info->nWidthBytes = BITMAP_WIDTH_BYTES(info->nWidth,info->bBitsPerPixel);
     sizeXor = info->nHeight * info->nWidthBytes;
-    sizeAnd = info->nHeight * ((info->nWidth + 15) / 16 * 2);
+    sizeAnd = info->nHeight * BITMAP_WIDTH_BYTES( info->nWidth, 1 );
     if (!(handle = DirectResAlloc(hInstance, 0x10,
                                   sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
         return 0;
@@ -624,7 +624,7 @@
     hAndBits = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, (char *)(ptr+1));
     hXorBits = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes,
                              ptr->bBitsPerPixel, (char *)(ptr + 1)
-                              + ptr->nHeight * ((ptr->nWidth + 15) / 16 * 2) );
+                         + ptr->nHeight * BITMAP_WIDTH_BYTES(ptr->nWidth,1) );
     oldFg = SetTextColor( hdc, RGB(0,0,0) );
     oldBg = SetBkColor( hdc, RGB(255,255,255) );
 
@@ -657,7 +657,7 @@
 
     if (!info) return 0;
     sizeXor = info->nHeight * info->nWidthBytes;
-    sizeAnd = info->nHeight * ((info->nWidth + 15) / 16 * 2);
+    sizeAnd = info->nHeight * BITMAP_WIDTH_BYTES( info->nWidth, 1 );
     if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO);
     if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd;
     if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor;
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index bdb6de9..13f4627 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -317,7 +317,7 @@
     bmpObjPtr->bitmap.bmType       = 0;
     bmpObjPtr->bitmap.bmWidth      = width;
     bmpObjPtr->bitmap.bmHeight     = height;
-    bmpObjPtr->bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2;
+    bmpObjPtr->bitmap.bmWidthBytes = BITMAP_WIDTH_BYTES( width, bpp );
     bmpObjPtr->bitmap.bmPlanes     = 1;
     bmpObjPtr->bitmap.bmBitsPixel  = bpp;
     bmpObjPtr->bitmap.bmBits       = NULL;
@@ -440,7 +440,7 @@
     bmpXor = (BITMAPOBJ *) GDI_GetObjPtr( hXorBits, BITMAP_MAGIC );
     bmpAnd = (BITMAPOBJ *) GDI_GetObjPtr( hAndBits, BITMAP_MAGIC );
     sizeXor = bmpXor->bitmap.bmHeight * bmpXor->bitmap.bmWidthBytes;
-    sizeAnd = bmpXor->bitmap.bmHeight * ((bmpXor->bitmap.bmWidth+15) / 16 * 2);
+    sizeAnd = bmpXor->bitmap.bmHeight * BITMAP_WIDTH_BYTES( bmpXor->bitmap.bmWidth, 1 );
 
     if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
                                   sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
diff --git a/objects/text.c b/objects/text.c
index cd3676e..10ef8b4 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -250,20 +250,19 @@
 	{
 	    if (!ExtTextOut16(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED,
                               rect, line, len, NULL )) return 0;
+            if (prefix_offset != -1)
+            {
+                HPEN16 hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
+                HPEN16 oldPen = SelectObject( hdc, hpen );
+                MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
+                LineTo(hdc, x + prefix_end, y + tm.tmAscent + 1 );
+                SelectObject( hdc, oldPen );
+                DeleteObject( hpen );
+            }
 	}
 	else if (size.cx > max_width)
 	    max_width = size.cx;
 
-	if (prefix_offset != -1)
-	{
-	    HPEN16 hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
-	    HPEN16 oldPen = SelectObject( hdc, hpen );
-	    MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
-	    LineTo(hdc, x + prefix_end, y + tm.tmAscent + 1 );
-	    SelectObject( hdc, oldPen );
-	    DeleteObject( hpen );
-	}
-
 	y += lh;
 	if (strPtr)
 	{
diff --git a/programs/winhelp/ChangeLog b/programs/winhelp/ChangeLog
index 9ba2f94..9af4b05 100644
--- a/programs/winhelp/ChangeLog
+++ b/programs/winhelp/ChangeLog
@@ -1,3 +1,13 @@
+Sat May 18 11:06:02 1996  Pablo Saratxaga <srtxg@f2219.n293.z2.fidonet.org>
+
+	* [Fr.rc] (new)
+ 	Added French language support.
+
+Thu May 16 19:24:19 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>
+
+	* [macro.lex.l] [macro.yacc.y]
+	Support older versions of Flex.
+
 Mon Apr 29 19:48:15 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>
 
 	* [winhelp.c] [winhelp.h] [hlpfile.c] [hlpfile.h]
diff --git a/programs/winhelp/Fr.rc b/programs/winhelp/Fr.rc
new file mode 100644
index 0000000..d7c2259
--- /dev/null
+++ b/programs/winhelp/Fr.rc
@@ -0,0 +1,55 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * French language by Pablo Saratxaga <srtxg@f2219.n293.z2.fidonet.org>
+ */
+
+/* This file is not yet complete !! */
+/* Alors peut-être ceci aidera (so maybe this will help) :) */
+/* #include ../progman/Fr.rc */
+
+#define LANGUAGE_ID                  Fr
+#define LANGUAGE_NUMBER              4
+
+/* Menu */
+
+#define MENU_FILE                    "&Fichier"
+#define MENU_FILE_OPEN               "O&uvrir..."
+#define MENU_FILE_PRINT              "&Imprimer la rubrique"
+#define MENU_FILE_PRINTER_SETUP      "&Configuration de l'impression..."
+#define MENU_FILE_EXIT               "&Quitter"
+
+#define MENU_EDIT                    "&Edition"
+#define MENU_EDIT_COPY_DIALOG        "&Copier..."
+#define MENU_EDIT_ANNOTATE           "&Annotation..."
+
+#define MENU_BOOKMARK                "&Signet"
+#define MENU_BOOKMARK_DEFINE         "&Définir..."
+
+#define MENU_HELP                    "&?"
+#define MENU_HELP_ON_HELP            "&Utiliser l'aide"
+#define MENU_HELP_ON_TOP             "&Toujours visible"
+#define MENU_HELP_INFO               "&Info..."
+#define MENU_HELP_ABOUT_WINE         "&A propos de WINE"
+
+/*
+	Configuration de l'imprimante
+*/
+
+/* Strings */
+
+#define STRING_WINE_HELP             "Aide de WINE"
+#define STRING_ERROR                 "ERREUR"
+#define STRING_WARNING               "WARNING"
+#define STRING_INFO                  "Information"
+#define STRING_NOT_IMPLEMENTED       "Non implementé"
+#define STRING_HLPFILE_ERROR_s       "Une erreur est survenue en lisant le fichier d'aide `%s'"
+#define STRING_CONTENTS              "&Index"
+#define STRING_SEARCH                "&Rechercher"
+#define STRING_BACK                  "&Précédent"
+#define STRING_HISTORY               "&Historique"
+#define STRING_ALL_FILES             "Tout fichier (*.*)"
+#define STRING_HELP_FILES_HLP        "Fichiers d'aide (*.hlp)"
+
+#include "Xx.rc"
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 96a5fcb..0499f9f 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -3,7 +3,7 @@
 PROGRAMS = winhelp hlp2sgml
 ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 
-LANGUAGES   = En De
+LANGUAGES   = En De Fr
 
 # Installation infos
 
@@ -54,7 +54,7 @@
 	$(YACC) -d -t macro.yacc.y
 
 lex.yy.c: macro.lex.l
-	$(LEX) -8 -I macro.lex.l
+	$(LEX) -8 -i macro.lex.l
 
 $(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h): $(WINERC) Xx.rc
 
diff --git a/programs/winhelp/hlp2sgml.c b/programs/winhelp/hlp2sgml.c
index 7df0184..717b876 100644
--- a/programs/winhelp/hlp2sgml.c
+++ b/programs/winhelp/hlp2sgml.c
@@ -250,29 +250,26 @@
  *           Substitutions for some WINELIB functions
  */
 
+static FILE *file = 0;
+
 HFILE OpenFile( LPCSTR path, OFSTRUCT *ofs, UINT mode )
 {
-  FILE *file;
-
-  if (!*path) return (HFILE) stdin;
-
-  file = fopen(path, "r");
-  if (!file) return HFILE_ERROR;
-  return (HFILE) file;
+  file = *path ? fopen(path, "r") : stdin;
+  return file ? 1 : HFILE_ERROR;
 }
 
 HFILE _lclose( HFILE hFile )
 {
-  fclose((FILE*) hFile);
+  fclose(file);
   return 0;
 }
 
 LONG _hread( HFILE hFile, SEGPTR buffer, LONG count )
 {
-  return fread(buffer, 1, count, (FILE*) hFile);
+  return fread(buffer, 1, count, file);
 }
 
-HGLOBAL GlobalAlloc( WORD flags, DWORD size )
+HGLOBAL GlobalAlloc( UINT flags, DWORD size )
 {
   return (HGLOBAL) malloc(size);
 }
diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c
index 80232d9..0c7bcd8 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -968,8 +968,8 @@
 
   HLPFILE_DeletePage(hlpfile->first_page);
   HLPFILE_DeleteMacro(hlpfile->first_macro);
-  GlobalFree(hlpfile->hContext);
-  GlobalFree(hlpfile->hTitle);
+  if (hlpfile->hContext) GlobalFree(hlpfile->hContext);
+  if (hlpfile->hTitle) GlobalFree(hlpfile->hTitle);
   GlobalFree(hlpfile->hSelf);
 }
 
diff --git a/programs/winhelp/macro.h b/programs/winhelp/macro.h
index b09e8dd..f1b403b 100644
--- a/programs/winhelp/macro.h
+++ b/programs/winhelp/macro.h
@@ -11,7 +11,6 @@
 INT  yyparse(VOID);
 INT  yylex(VOID);
 VOID yyerror(LPCSTR);
-extern CHAR MACRO_extra_separator;
 
 VOID MACRO_About(VOID);
 VOID MACRO_AddAccelerator(LONG, LONG, LPCSTR);
diff --git a/programs/winhelp/macro.lex.l b/programs/winhelp/macro.lex.l
index 146c8ea..ef246e1 100644
--- a/programs/winhelp/macro.lex.l
+++ b/programs/winhelp/macro.lex.l
@@ -6,25 +6,19 @@
  */
 %}
 %x quote dquote
-%x null_string
 %{
 #include "macro.h"
 #include "y.tab.h"
 
-static LPCSTR  macroptr, firsttoken, thistoken, nexttoken, current_string;
+static LPCSTR  macroptr;
 static LPSTR   strptr;
 static HGLOBAL hStringBuffer = 0;
-
-CHAR MACRO_extra_separator = 0;
+static INT     nested_quotes = 0;
 
 #define YY_INPUT(buf,result,max_size)\
   if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++;
 
-#define YY_USER_ACTION\
-  if (YY_START == INITIAL) thistoken = nexttoken, nexttoken = macroptr;
-
 #define YY_NO_UNPUT
-#define YY_NO_TOP_STATE
 %}
 %%
 About			yylval = MACRO_About;			return VOID_FUNCTION_VOID;
@@ -130,56 +124,35 @@
 			      hStringBuffer = GlobalAlloc(GMEM_FIXED, strlen(macroptr));
 			      strptr = GlobalLock(hStringBuffer);
 			    }
-			  current_string = strptr;
-			  yy_push_state(yytext[0] == '`' ? quote : dquote);
+			  yylval = strptr;
+			  BEGIN (yytext[0] == '`' ? quote : dquote);
 			}
 
 <quote>\`		{
 			  *strptr++ = yytext[0];
-			  yy_push_state(quote);
+			  nested_quotes++;
 			}
 
 <quote>\'		|
 <dquote>\"		{
-			  yy_pop_state();
-			  if (YY_START == INITIAL)
+			  if (nested_quotes)
 			    {
+			      nested_quotes--;
+			      *strptr++ = yytext[0];
+			    }
+			  else
+			    {
+			      BEGIN INITIAL;
 			      *strptr++ = '\0';
-			      if (MACRO_extra_separator)
-				{
-				  yy_push_state(null_string);
-				  MACRO_extra_separator = 0;
-				}
-			      yylval = current_string;
 			      return STRING;
 			    }
-			  else *strptr++ = yytext[0];
 			}
 
-<quote,dquote>{
+<quote,dquote>.		*strptr++ = yytext[0];
+<quote,dquote>\\.	*strptr++ = yytext[1];
 
-.			{
-			  if (MACRO_extra_separator == (CHAR) yytext[0])
-			    {
-			      *strptr++ = '\0';
-			      MACRO_extra_separator = 0;
-			      yylval = current_string;
-			      current_string = strptr;
-			      return STRING;
-			    }
-			  else *strptr++ = yytext[0];
-			}
+<quote,dquote><<EOF>>	return 0;
 
-\\.			*strptr++ = yytext[1];
-
-<<EOF>>			return 0;
-}
-
-<null_string>""		{
-			  yy_pop_state();
-			  yylval = (LPCSTR) 0;
-			  return STRING;
-			}
 
 " "
 
@@ -193,7 +166,7 @@
   if (msg == WM_COMMAND && wParam == IDOK)
     {
       GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro));
-      EndDialog(hDlg, IDCANCEL);
+      EndDialog(hDlg, IDOK);
       return TRUE;
     }
   return FALSE;
@@ -201,16 +174,6 @@
 
 VOID MACRO_ExecuteMacro(LPCSTR macro)
 {
-  static BOOL init = TRUE;
-
-  if (init) init = FALSE;
-  else
-    {
-      YY_FLUSH_BUFFER;
-      while (YY_START != INITIAL)
-	yy_pop_state();
-    }
-
   if (!lstrcmpi(macro, "MacroTest"))
     {
       WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance);
@@ -219,7 +182,7 @@
       macro = szTestMacro;
     }
 
-  macroptr = firsttoken = thistoken = nexttoken = macro;
+  macroptr = macro;
 
   yyparse();
 
@@ -229,7 +192,12 @@
 
 void yyerror (const char *s)
 {
-  fprintf(stderr, "%s\n%.*s\n%*s%s\n", s,
-	  thistoken - firsttoken, firsttoken,
-	  thistoken - firsttoken, "", thistoken);
+  fprintf(stderr, "%s\n", s);
+  nested_quotes = 0;
+  BEGIN INITIAL;
+  yyrestart(yyin);
 }
+
+#ifndef yywrap
+int yywrap(void) { return 1; }
+#endif
diff --git a/programs/winhelp/macro.yacc.y b/programs/winhelp/macro.yacc.y
index 66bce6e..c88983c 100644
--- a/programs/winhelp/macro.yacc.y
+++ b/programs/winhelp/macro.yacc.y
@@ -6,75 +6,73 @@
  */
 
 #include "macro.h"
-static int skip = 0;
+
+static int   skip = 0;
+static LPSTR filename;
+static LPSTR windowname;
+
 %}
 %union
   {
     BOOL    bool;
-    LPCSTR  string;
     LONG    integer;
-    VOID    (*void_function_void)(VOID);
+    LPSTR   string;
     BOOL    (*bool_function_void)(VOID);
-    VOID    (*void_function_string)(LPCSTR);
     BOOL    (*bool_function_string)(LPCSTR);
-
-    BOOL    (*bool_funktion_string)(LPCSTR);
-    BOOL    (*bool_funktion_void)(VOID);
-    VOID    (*void_funktion_2int_3uint_string)(LONG,LONG,LONG,LONG,LONG,LPCSTR);
-    VOID    (*void_funktion_2string)(LPCSTR,LPCSTR);
-    VOID    (*void_funktion_2string_2uint_2string)(LPCSTR,LPCSTR,LONG,LONG,LPCSTR,LPCSTR);
-    VOID    (*void_funktion_2string_uint)(LPCSTR,LPCSTR,LONG);
-    VOID    (*void_funktion_2string_uint_string)(LPCSTR,LPCSTR,LONG,LPCSTR);
-    VOID    (*void_funktion_2string_wparam_lparam_string)(LPCSTR,LPCSTR,WPARAM,LPARAM,LPCSTR);
-    VOID    (*void_funktion_2uint)(LONG,LONG);
-    VOID    (*void_funktion_2uint_string)(LONG,LONG,LPCSTR);
-    VOID    (*void_funktion_3string)(LPCSTR,LPCSTR,LPCSTR);
-    VOID    (*void_funktion_3string_2uint)(LPCSTR,LPCSTR,LPCSTR,LONG,LONG);
-    VOID    (*void_funktion_3uint)(LONG,LONG,LONG);
-    VOID    (*void_funktion_4string)(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
-    VOID    (*void_funktion_4string_2uint)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LONG,LONG);
-    VOID    (*void_funktion_4string_uint)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LONG);
-    VOID    (*void_funktion_string)(LPCSTR);
-    VOID    (*void_funktion_string_uint)(LPCSTR,LONG);
-    VOID    (*void_funktion_string_uint_2string)(LPCSTR,LONG,LPCSTR,LPCSTR);
-    VOID    (*void_funktion_string_uint_string)(LPCSTR,LONG,LPCSTR);
-    VOID    (*void_funktion_string_wparam_lparam)(LPCSTR,WPARAM,LPARAM);
-    VOID    (*void_funktion_uint)(LONG);
-    VOID    (*void_funktion_void)(VOID);
+    VOID    (*void_function_void)(VOID);
+    VOID    (*void_function_uint)(LONG);
+    VOID    (*void_function_string)(LPCSTR);
+    VOID    (*void_function_2int_3uint_string)(LONG,LONG,LONG,LONG,LONG,LPCSTR);
+    VOID    (*void_function_2string)(LPCSTR,LPCSTR);
+    VOID    (*void_function_2string_2uint_2string)(LPCSTR,LPCSTR,LONG,LONG,LPCSTR,LPCSTR);
+    VOID    (*void_function_2string_uint)(LPCSTR,LPCSTR,LONG);
+    VOID    (*void_function_2string_uint_string)(LPCSTR,LPCSTR,LONG,LPCSTR);
+    VOID    (*void_function_2string_wparam_lparam_string)(LPCSTR,LPCSTR,WPARAM,LPARAM,LPCSTR);
+    VOID    (*void_function_2uint)(LONG,LONG);
+    VOID    (*void_function_2uint_string)(LONG,LONG,LPCSTR);
+    VOID    (*void_function_3string)(LPCSTR,LPCSTR,LPCSTR);
+    VOID    (*void_function_3string_2uint)(LPCSTR,LPCSTR,LPCSTR,LONG,LONG);
+    VOID    (*void_function_3uint)(LONG,LONG,LONG);
+    VOID    (*void_function_4string)(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
+    VOID    (*void_function_4string_2uint)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LONG,LONG);
+    VOID    (*void_function_4string_uint)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LONG);
+    VOID    (*void_function_string_uint)(LPCSTR,LONG);
+    VOID    (*void_function_string_uint_2string)(LPCSTR,LONG,LPCSTR,LPCSTR);
+    VOID    (*void_function_string_uint_string)(LPCSTR,LONG,LPCSTR);
+    VOID    (*void_function_string_wparam_lparam)(LPCSTR,WPARAM,LPARAM);
   }
 %token							NOT
 %token 							IF_THEN
 %token 							IF_THEN_ELSE
 %token <string>	 					STRING
 %token <integer> 					INTEGER
-%token <bool_funktion_string>				BOOL_FUNCTION_STRING
-%token <bool_funktion_void>				BOOL_FUNCTION_VOID
-%token <void_funktion_2int_3uint_string>		VOID_FUNCTION_2INT_3UINT_STRING
-%token <void_funktion_2string>				VOID_FUNCTION_2STRING
-%token <void_funktion_2string_2uint_2string>		VOID_FUNCTION_2STRING_2UINT_2STRING
-%token <void_funktion_2string_uint>			VOID_FUNCTION_2STRING_UINT
-%token <void_funktion_2string_uint_string>		VOID_FUNCTION_2STRING_UINT_STRING
-%token <void_funktion_2string_wparam_lparam_string>	VOID_FUNCTION_2STRING_WPARAM_LPARAM_STRING
-%token <void_funktion_2uint>				VOID_FUNCTION_2UINT
-%token <void_funktion_2uint_string>			VOID_FUNCTION_2UINT_STRING
-%token <void_funktion_3string>				VOID_FUNCTION_3STRING
-%token <void_funktion_3string_2uint>			VOID_FUNCTION_3STRING_2UINT
-%token <void_funktion_3uint>				VOID_FUNCTION_3UINT
-%token <void_funktion_4string>				VOID_FUNCTION_4STRING
-%token <void_funktion_4string_2uint>			VOID_FUNCTION_4STRING_2UINT
-%token <void_funktion_4string_uint>			VOID_FUNCTION_4STRING_UINT
-%token <void_funktion_string>				VOID_FUNCTION_STRING
-%token <void_funktion_string_uint>			VOID_FUNCTION_STRING_UINT
-%token <void_funktion_string_uint_2string>		VOID_FUNCTION_STRING_UINT_2STRING
-%token <void_funktion_string_uint_string>		VOID_FUNCTION_STRING_UINT_STRING
-%token <void_funktion_string_wparam_lparam>		VOID_FUNCTION_STRING_WPARAM_LPARAM
-%token <void_funktion_uint>				VOID_FUNCTION_UINT
-%token <void_funktion_void>				VOID_FUNCTION_VOID
-%token <void_funktion_2string>				VOID_FUNCTION_FILE_WIN
-%token <void_funktion_3string>				VOID_FUNCTION_FILE_WIN_STRING
-%token <void_funktion_2string_uint>			VOID_FUNCTION_FILE_WIN_UINT
+%token <bool_function_string>				BOOL_FUNCTION_STRING
+%token <bool_function_void>				BOOL_FUNCTION_VOID
+%token <void_function_2int_3uint_string>		VOID_FUNCTION_2INT_3UINT_STRING
+%token <void_function_2string>				VOID_FUNCTION_2STRING
+%token <void_function_2string_2uint_2string>		VOID_FUNCTION_2STRING_2UINT_2STRING
+%token <void_function_2string_uint>			VOID_FUNCTION_2STRING_UINT
+%token <void_function_2string_uint_string>		VOID_FUNCTION_2STRING_UINT_STRING
+%token <void_function_2string_wparam_lparam_string>	VOID_FUNCTION_2STRING_WPARAM_LPARAM_STRING
+%token <void_function_2uint>				VOID_FUNCTION_2UINT
+%token <void_function_2uint_string>			VOID_FUNCTION_2UINT_STRING
+%token <void_function_3string>				VOID_FUNCTION_3STRING
+%token <void_function_3string_2uint>			VOID_FUNCTION_3STRING_2UINT
+%token <void_function_3uint>				VOID_FUNCTION_3UINT
+%token <void_function_4string>				VOID_FUNCTION_4STRING
+%token <void_function_4string_2uint>			VOID_FUNCTION_4STRING_2UINT
+%token <void_function_4string_uint>			VOID_FUNCTION_4STRING_UINT
+%token <void_function_string>				VOID_FUNCTION_STRING
+%token <void_function_string_uint>			VOID_FUNCTION_STRING_UINT
+%token <void_function_string_uint_2string>		VOID_FUNCTION_STRING_UINT_2STRING
+%token <void_function_string_uint_string>		VOID_FUNCTION_STRING_UINT_STRING
+%token <void_function_string_wparam_lparam>		VOID_FUNCTION_STRING_WPARAM_LPARAM
+%token <void_function_uint>				VOID_FUNCTION_UINT
+%token <void_function_void>				VOID_FUNCTION_VOID
+%token <void_function_2string>				VOID_FUNCTION_FILE_WIN
+%token <void_function_3string>				VOID_FUNCTION_FILE_WIN_STRING
+%token <void_function_2string_uint>			VOID_FUNCTION_FILE_WIN_UINT
 %type  <bool> bool_macro
-%type  <string> filename
 %%
 
 macrostring:	macro |
@@ -153,16 +151,21 @@
 			'(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ',' STRING ')'
 			{if (! skip) (*$1)($3, $5, $7, $9, $11, $13);} |
 		VOID_FUNCTION_FILE_WIN
-			'(' filename STRING ')'
-			{if (! skip) (*$1)($3, $4);} |
+			'(' file_win ')'
+			{if (! skip) (*$1)(filename, windowname);} |
 		VOID_FUNCTION_FILE_WIN_STRING
-			'(' filename STRING ',' STRING ')'
-			{if (! skip) (*$1)($3, $4, $6);} |
+			'(' file_win ',' STRING ')'
+			{if (! skip) (*$1)(filename, windowname, $5);} |
 		VOID_FUNCTION_FILE_WIN_UINT
-			'(' filename STRING ',' INTEGER ')'
-			{if (! skip) (*$1)($3, $4, $6);} ;
+			'(' file_win ',' INTEGER ')'
+			{if (! skip) (*$1)(filename, windowname, $5);} ;
 
-filename:	{MACRO_extra_separator = '>'} STRING {$$ = $2;} ;
+file_win:	STRING
+                {
+		  filename = windowname = $1;
+		  while (*windowname && *windowname != '>') windowname++;
+		  if (*windowname) *windowname++ = 0;
+		} ;
 
 bool_macro:     NOT '(' bool_macro ')' {$$ = ! $3;} |
 		STRING {$$ = MACRO_IsMark($1);} |
diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c
index c7244b0..a709473 100644
--- a/programs/winhelp/winhelp.c
+++ b/programs/winhelp/winhelp.c
@@ -16,6 +16,7 @@
 
 VOID LIBWINE_Register_De(void);
 VOID LIBWINE_Register_En(void);
+VOID LIBWINE_Register_Fr(void);
 
 static BOOL    WINHELP_RegisterWinClasses();
 static LRESULT WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM);
@@ -52,6 +53,7 @@
   /* Register resources */
   LIBWINE_Register_De();
   LIBWINE_Register_En();
+  LIBWINE_Register_Fr();
 #endif
 
   Globals.hInstance = hInstance;
@@ -196,7 +198,7 @@
 
   if (bPopup)
     lpszWindow = NULL;
-  else if (!lpszWindow)
+  else if (!lpszWindow || !lpszWindow[0])
     lpszWindow = Globals.active_win->lpszName;
   bPrimary = lpszWindow && !lstrcmpi(lpszWindow, "main");
 
@@ -586,10 +588,10 @@
 
     case WM_VSCROLL:
       {
-	BOOL update = TRUE;
-	RECT rect;
-	INT  Min, Max;
-	INT  CurPos = GetScrollPos(hWnd, SB_VERT);
+	BOOL  update = TRUE;
+	RECT  rect;
+	INT16 Min, Max;
+	INT   CurPos = GetScrollPos(hWnd, SB_VERT);
 	GetScrollRange(hWnd, SB_VERT, &Min, &Max);
 	GetClientRect(hWnd, &rect);
 
@@ -775,7 +777,7 @@
       while (len)
 	{
 	  INT free_width = rect.right - (part ? (*line)->rect.right : rect.left) - space.cx;
-	  UINT low = 0, curr = len, high = len, textlen;
+	  UINT low = 0, curr = len, high = len, textlen = 0;
 
 	  if (free_width > 0)
 	    {
@@ -789,7 +791,7 @@
 		  if (high <= low + 1) break;
 
 		  if (textsize.cx) curr = (curr * free_width) / textsize.cx;
-		  if (curr <= low)  curr = low + 1;
+		  if (curr <= low) curr = low + 1;
 		  else if (curr >= high) curr = high - 1;
 		}
 	      textlen = low;
diff --git a/win32/file.c b/win32/file.c
index ab33853..ed65650 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -14,6 +14,7 @@
 #include <string.h>
 #include <time.h>
 #include "windows.h"
+#include "winbase.h"
 #include "winerror.h"
 #include "kernel32.h"
 #include "handle32.h"
diff --git a/win32/resource.c b/win32/resource.c
index 74ff0af..4b4598d 100644
--- a/win32/resource.c
+++ b/win32/resource.c
@@ -381,60 +381,6 @@
     return res;
 }
 
-/**********************************************************************
- *      WIN32_ParseMenu
- *      LoadMenu helper function
- */
-BYTE* WIN32_ParseMenu(HMENU hMenu,BYTE *it)
-{
-    char entry[200]; /* buffer for ANSI names */
-	int bufsize=100;
-	int len;
-	WORD flags;
-	WORD wMenuID;
-	WCHAR *utext;
-	do{
-		flags=*(WORD*)it;
-		it+=sizeof(WORD);
-		/* POPUP entries have no ID, but a sub menu */
-		if(flags & MF_POPUP)
-		{
-			wMenuID = CreatePopupMenu();
-			len = STRING32_lstrlenW((LPWSTR)it);
-			utext = (WCHAR*)it;
-			it += sizeof(WCHAR)*(len+1);
-			it = WIN32_ParseMenu(wMenuID,it);
-		} else {
-			wMenuID=*(WORD*)it;
-			it+=sizeof(WORD);
-			utext = (LPWSTR)it;
-			len = STRING32_lstrlenW((LPWSTR)it);
-			it += sizeof(WCHAR)*(len+1);
-			if(!wMenuID && !*utext)
-				flags |= MF_SEPARATOR;
-		}
-		if(len>=bufsize) continue;  /* hack hack */
-		STRING32_UniToAnsi(entry,utext);
-		AppendMenu(hMenu,flags,wMenuID,MAKE_SEGPTR(entry));
-	}while(!(flags & MF_END));
-	return it;
-}
-
-/*****************************************************************
- *        LoadMenuIndirectW         (USER32.371)
- */
-HMENU WIN32_LoadMenuIndirectW(void *menu)
-{
-	BYTE *it=menu;
-	HMENU hMenu = CreateMenu();
-	/*skip menu header*/
-	if(*(DWORD*)it)
-		fprintf(stderr,"Unknown menu header\n");
-	it+=2*sizeof(WORD);
-	WIN32_ParseMenu(hMenu,it);
-	return hMenu;
-}
-
 /*****************************************************************
  *        LoadMenuW                 (USER32.372)
  */
@@ -443,16 +389,7 @@
 	HANDLE32 hrsrc;
 	hrsrc=FindResource32(instance,name,(LPWSTR)RT_MENU);
 	if(!hrsrc)return 0;
-	return WIN32_LoadMenuIndirectW(LoadResource32(instance, hrsrc));
-}
-
-/*****************************************************************
- *        LoadMenuIndirectA         (USER32.370)
- */
-HMENU WIN32_LoadMenuIndirectA(void *menu)
-{
-	fprintf(stderr,"WIN32_LoadMenuIndirectA not implemented\n");
-	return 0;
+        return LoadMenuIndirect32W( LoadResource32(instance, hrsrc) );
 }
 
 /*****************************************************************
diff --git a/win32/user32.c b/win32/user32.c
index 0168040..7572b7e 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -12,7 +12,6 @@
 #include <stdarg.h>
 #include "windows.h"
 #include "winerror.h"
-#include "alias.h"
 #include "stackframe.h"
 #include "xmalloc.h"
 #include "handle32.h"
@@ -21,6 +20,7 @@
 #include "string32.h"
 #include "dialog.h"
 #include "win.h"
+#include "winproc.h"
 #include "debug.h"
 #include "stddebug.h"
 
@@ -59,73 +59,6 @@
 	return TranslateMessage(&msg);
 }
 
-#if 0
-/***********************************************************************
- *         CreateWindowEx32A        (USER32.82)
- */
-HWND32 CreateWindowEx32A( DWORD flags, LPCSTR class, LPCSTR title,
-                          DWORD style, INT32 x, INT32 y, INT32 width,
-                          INT32 height, HWND32 parent, HMENU32 menu,
-                          HINSTANCE32 instance, LPVOID param )
-{
-    HWND32 retval;
-    HANDLE classh=0, titleh=0;
-    SEGPTR classsegp=0, titlesegp=0;
-    char *classbuf, *titlebuf;
-	int usec,uset;
-
-    /*Have to translate CW_USEDEFAULT */
-    if(x==CW_USEDEFAULT32)x=CW_USEDEFAULT16;
-    if(y==CW_USEDEFAULT32)y=CW_USEDEFAULT16;
-    if(width==CW_USEDEFAULT32)width=CW_USEDEFAULT16;
-    if(height==CW_USEDEFAULT32)height=CW_USEDEFAULT16;
-
-    /* FIXME: There has to be a better way of doing this - but neither
-    malloc nor alloca will work */
-	usec = HIWORD(class);
-	uset = HIWORD(title);
-
-	if(usec){
-    	classh = GlobalAlloc16(0, strlen(class)+1);
-    	classsegp = WIN16_GlobalLock16(classh);
-    	classbuf = PTR_SEG_TO_LIN(classsegp);
-    	strcpy( classbuf, class );
-	}
-	if(uset){
-    	titleh = GlobalAlloc16(0, strlen(title)+1);
-    	titlesegp = WIN16_GlobalLock16(titleh);
-    	titlebuf = PTR_SEG_TO_LIN(titlesegp);
-    	strcpy( titlebuf, title );
-	}
-    
-    retval = (HWND32)CreateWindowEx16(flags,(usec ? classsegp : (SEGPTR)class),
-				  (uset ? titlesegp : (SEGPTR)title),style,x,y,width,height,
-				  (HWND)parent,(HMENU)menu,(HINSTANCE)instance,
-				  (DWORD)param);
-    if(usec)GlobalFree16(classh);
-    if(uset)GlobalFree16(titleh);
-    return retval;
-}
-
-#endif
-HWND32 CreateWindowEx32W( DWORD flags, LPCWSTR class, LPCWSTR title,
-                          DWORD style, INT32 x, INT32 y, INT32 width,
-                          INT32 height, HWND32 parent, HMENU32 menu,
-                          HINSTANCE32 instance, LPVOID param )
-{
-        HWND32 hwnd;
-	LPSTR c,t;
-	int usec,uset;
-	usec=HIWORD(class);
-	uset=HIWORD(title);
-	c = usec ? STRING32_DupUniToAnsi(class) : (LPSTR)class;
-	t = uset ? STRING32_DupUniToAnsi(title) : (LPSTR)title;
-	hwnd=CreateWindowEx32A(flags,c,t,style,x,y,width,height,parent,menu,
-		instance,param);
-	if(usec)free(c);
-	if(uset)free(t);
-	return hwnd;
-}
 
 UINT USER32_SetTimer(HWND hwnd, UINT id, UINT timeout, void *proc)
 
@@ -296,13 +229,13 @@
 		SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
 			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
 		/* Send initialisation messages to the control */
-		if (hFont) SendMessage( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
-		if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
+		if (hFont) SendMessage32A( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
+		if (SendMessage32A( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
 		{
 			/* If there's already a default push-button, set it back */
 			/* to normal and use this one instead. */
 			if (hwndDefButton)
-				SendMessage( hwndDefButton, BM_SETSTYLE32, BS_PUSHBUTTON, FALSE);
+				SendMessage32A( hwndDefButton, BM_SETSTYLE32, BS_PUSHBUTTON, FALSE);
 			hwndDefButton = hwndCtrl;
 			dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
 		}
@@ -310,8 +243,7 @@
 	dprintf_dialog(stddeb, " END\n" );
 
 	 /* Initialise dialog extra data */
-	ALIAS_RegisterAlias(0,0,lpDialogFunc);
-	dlgInfo->dlgProc   = lpDialogFunc;
+	dlgInfo->dlgProc   = WINPROC_AllocWinProc(lpDialogFunc,WIN_PROC_32A);
 	dlgInfo->hUserFont = hFont;
 	dlgInfo->hMenu     = hMenu;
 	dlgInfo->xBaseUnit = xUnit;
@@ -320,8 +252,8 @@
 
 	/* Send initialisation messages and set focus */
 	if (dlgInfo->hUserFont)
-		SendMessage( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
-	if (SendMessage( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, dwInitParam ))
+		SendMessage32A( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
+	if (SendMessage32A( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, dwInitParam ))
 		SetFocus( dlgInfo->hwndFocus );
 	if (dlgTempl->style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
 		return hwnd;
diff --git a/win32/winprocs.c b/win32/winprocs.c
index 4d6105f..428b5ab 100644
--- a/win32/winprocs.c
+++ b/win32/winprocs.c
@@ -102,10 +102,8 @@
 
 
 extern LRESULT AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT ButtonWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ColorDlgProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ComboBoxWndProc(HWND,UINT,WPARAM,LPARAM);
-extern LRESULT DesktopWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT EditWndProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT FileOpenDlgProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT FileSaveDlgProc(HWND,UINT,WPARAM,LPARAM);
@@ -121,18 +119,6 @@
 extern LRESULT SystemMessageBoxProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ComboLBoxWndProc(HWND,UINT,WPARAM,LPARAM);
 
-LRESULT USER32_DefWindowProcA(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(DefWindowProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT ButtonWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(ButtonWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
 LRESULT StaticWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
 
 {
@@ -169,12 +155,6 @@
 	return WIN32_CallWindowProcTo16(PopupMenuWndProc,(HWND)hwnd, msg, wParam, lParam);
 }
 
-LRESULT DesktopWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(DesktopWndProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
 LRESULT DefDlgProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
 
 {
@@ -187,18 +167,6 @@
 	return WIN32_CallWindowProcTo16(MDIClientWndProc,(HWND)hwnd, msg, wParam, lParam);
 }
 
-LRESULT DefWindowProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(DefWindowProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
-LRESULT DefMDIChildProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
-
-{
-	return WIN32_CallWindowProcTo16(DefMDIChildProc,(HWND)hwnd, msg, wParam, lParam);
-}
-
 LRESULT SystemMessageBoxProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam)
 
 {
diff --git a/windows/Makefile.in b/windows/Makefile.in
index 4284cdf..9cb6607 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -2,7 +2,6 @@
 MODULE = windows
 
 C_SRCS = \
-	alias.c \
 	caret.c \
 	class.c \
 	dce.c \
diff --git a/windows/alias.c b/windows/alias.c
deleted file mode 100644
index 5716094..0000000
--- a/windows/alias.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Function alias support
- * 
- * Copyright 1995 Martin von Loewis
- * 
- */
-
-#include "windows.h"
-#include "alias.h"
-#include "module.h"
-
-#include "stddebug.h"
-#include "debug.h"
-
-/* some large prime */
-#define TABLESIZE	2677
-
-static ALIASHASH AliasTable[TABLESIZE];
-/* this could be a bit smaller */
-static FUNCTIONALIAS AliasRecord[TABLESIZE];
-/* record 0 is always empty */
-static int LastRecord;
-
-int ALIAS_UseAliases;
-
-/* Aliased window procedures */
-extern LRESULT ButtonWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT StaticWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT ScrollBarWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT ListBoxWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT ComboBoxWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT ComboLBoxWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT EditWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT PopupMenuWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT DesktopWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT DefDlgProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT MDIClientWndProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT AboutDlgProc( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT CARET_Callback( HWND, UINT, WPARAM, LPARAM );
-extern LRESULT SystemMessageBoxProc( HWND, UINT, WPARAM, LPARAM );
-
-/* closed hashing */
-static int ALIAS_LocateHash(DWORD value)
-{
-	int hash,start;
-	start=hash=value%TABLESIZE;
-	while(AliasTable[hash].used && AliasTable[hash].used!=value)
-	{
-		hash++;
-		if(hash==TABLESIZE)
-			hash=0;
-		if(hash==start)
-		{
-			fprintf(stderr,"Hash table full, increase size in alias.c\n");
-			exit(0);
-		}
-	}
-	return hash;
-}
-
-
-/***********************************************************************
- *           ALIAS_RegisterWndProcAlias
- */
-static void ALIAS_RegisterWndProcAlias( DWORD Wine, const char *name )
-{
-    FARPROC Win16Proc, Win32Proc;
-
-    Win16Proc = MODULE_GetWndProcEntry16( name );
-    Win32Proc = MODULE_GetWndProcEntry32( name );
-    ALIAS_RegisterAlias( Wine, (DWORD)Win16Proc, (DWORD)Win32Proc );
-}
-
-
-/***********************************************************************
- *           ALIAS_Init
- *
- * Create aliases for the standard window procedures.
- */
-BOOL ALIAS_Init(void)
-{
-    ALIAS_RegisterWndProcAlias( (DWORD)ButtonWndProc, "ButtonWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)StaticWndProc, "StaticWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)ScrollBarWndProc, "ScrollBarWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)ListBoxWndProc, "ListBoxWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)ComboBoxWndProc, "ComboBoxWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)ComboLBoxWndProc, "ComboLBoxWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)EditWndProc, "EditWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)PopupMenuWndProc, "PopupMenuWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)DesktopWndProc, "DesktopWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)DefDlgProc, "DefDlgProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)MDIClientWndProc, "MDIClientWndProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)AboutDlgProc, "AboutDlgProc" );
-    ALIAS_RegisterWndProcAlias( (DWORD)CARET_Callback, "CARET_Callback" );
-    ALIAS_RegisterWndProcAlias( (DWORD)SystemMessageBoxProc, "SystemMessageBoxProc" );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           ALIAS_RegisterAlias
- */
-void ALIAS_RegisterAlias(DWORD Wine,DWORD Win16, DWORD Win32)
-{
-    int whash = 0, w16hash = 0, w32hash = 0, recno=0;
-    if (!Wine && !Win16 && !Win32) return;
-    if (Wine)
-    {
-        whash=ALIAS_LocateHash(Wine);
-	recno=AliasTable[whash].used?AliasTable[whash].recno:0;
-    }
-    if (Win16)
-    {
-        w16hash=ALIAS_LocateHash(Win16);
-	recno=AliasTable[w16hash].used?AliasTable[w16hash].recno:0;
-    }
-    if (Win32)
-    {
-        w32hash=ALIAS_LocateHash(Win32);
-        recno=AliasTable[w32hash].used?AliasTable[w32hash].recno:0;
-    }
-    if (!recno)
-    {
-        recno=LastRecord;
-        LastRecord++;
-    }
-    if (Wine)
-    {
-        AliasTable[whash].used=Wine;
-        AliasTable[whash].recno=recno;
-        AliasRecord[recno].wine=Wine;
-    }
-    if (Win16)
-    {
-        AliasTable[w16hash].used=Win16;
-	AliasTable[w16hash].recno=recno;
-        AliasRecord[recno].win16=Win16;
-    }
-    if (Win32)
-    {
-        AliasTable[w32hash].used=Win32;
-        AliasTable[w32hash].recno=recno;
-        AliasRecord[recno].win32=Win32;
-    }
-}
-
-FUNCTIONALIAS* ALIAS_LookupAlias(DWORD fn)
-{
-	int index;
-	index=ALIAS_LocateHash(fn);
-	if(AliasTable[index].used==fn)
-		return &AliasRecord[AliasTable[index].recno];
-	return 0;
-}
diff --git a/windows/class.c b/windows/class.c
index 4db7797..4a3f6eb 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -15,6 +15,7 @@
 #include "ldt.h"
 #include "string32.h"
 #include "toolhelp.h"
+#include "winproc.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -155,6 +156,22 @@
 
 
 /***********************************************************************
+ *           CLASS_SetWndProc
+ *
+ * Set the window procedure and return the old one.
+ */
+static WNDPROC16 CLASS_SetWndProc( CLASS *classPtr, WNDPROC16 proc,
+                                   WINDOWPROCTYPE type )
+{
+    WNDPROC16 oldProc = classPtr->lpfnWndProc;
+    if (type == WIN_PROC_16) classPtr->lpfnWndProc = proc;
+    else classPtr->lpfnWndProc = WINPROC_AllocWinProc( (WNDPROC32)proc, type );
+    WINPROC_FreeWinProc( oldProc );
+    return oldProc;
+}
+
+
+/***********************************************************************
  *           CLASS_FreeClass
  *
  * Free a class structure.
@@ -184,6 +201,7 @@
     if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
     GlobalDeleteAtom( classPtr->atomName );
     CLASS_SetMenuNameA( classPtr, NULL );
+    CLASS_SetWndProc( classPtr, (WNDPROC16)0, WIN_PROC_16 );
     HeapFree( SystemHeap, 0, classPtr );
     return TRUE;
 }
@@ -256,7 +274,8 @@
  */
 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE32 hInstance,
                                    DWORD style, INT32 classExtra,
-                                   INT32 winExtra )
+                                   INT32 winExtra, WNDPROC16 wndProc,
+                                   WINDOWPROCTYPE wndProcType )
 {
     CLASS *classPtr;
 
@@ -286,17 +305,19 @@
     classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
                                        classExtra - sizeof(classPtr->wExtra) );
     if (!classPtr) return NULL;
-    classPtr->next       = firstClass;
-    classPtr->magic      = CLASS_MAGIC;
-    classPtr->cWindows   = 0;  
-    classPtr->style      = style;
-    classPtr->cbWndExtra = winExtra;
-    classPtr->cbClsExtra = classExtra;
-    classPtr->hInstance  = hInstance;
-    classPtr->atomName   = atom;
-    classPtr->menuNameA  = 0;
-    classPtr->menuNameW  = 0;
-    classPtr->hdce       = (style&CS_CLASSDC) ? DCE_AllocDCE(DCE_CLASS_DC) : 0;
+    classPtr->next        = firstClass;
+    classPtr->magic       = CLASS_MAGIC;
+    classPtr->cWindows    = 0;  
+    classPtr->style       = style;
+    classPtr->lpfnWndProc = 0;
+    classPtr->cbWndExtra  = winExtra;
+    classPtr->cbClsExtra  = classExtra;
+    classPtr->hInstance   = hInstance;
+    classPtr->atomName    = atom;
+    classPtr->menuNameA   = 0;
+    classPtr->menuNameW   = 0;
+    classPtr->hdce        = (style&CS_CLASSDC) ? DCE_AllocDCE(DCE_CLASS_DC): 0;
+    CLASS_SetWndProc( classPtr, wndProc, wndProcType );
     /* Other values must be set by caller */
 
     if (classExtra) memset( classPtr->wExtra, 0, classExtra );
@@ -317,7 +338,8 @@
 
     if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
-                                          wc->cbClsExtra, wc->cbWndExtra )))
+                                          wc->cbClsExtra, wc->cbWndExtra,
+                                          wc->lpfnWndProc, WIN_PROC_16 )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -328,8 +350,6 @@
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
 
-    classPtr->flags         = 0;
-    classPtr->lpfnWndProc   = wc->lpfnWndProc;
     classPtr->hIcon         = wc->hIcon;
     classPtr->hIconSm       = 0;
     classPtr->hCursor       = wc->hCursor;
@@ -354,7 +374,9 @@
 
     if (!(atom = GlobalAddAtom32A( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
-                                          wc->cbClsExtra, wc->cbWndExtra )))
+                                          wc->cbClsExtra, wc->cbWndExtra,
+                                          (WNDPROC16)wc->lpfnWndProc,
+                                          WIN_PROC_32A )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -365,13 +387,10 @@
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
-    classPtr->flags         = 0;
-    classPtr->lpfnWndProc   = (WNDPROC16)wc->lpfnWndProc;
     classPtr->hIcon         = (HICON16)wc->hIcon;
     classPtr->hIconSm       = 0;
     classPtr->hCursor       = (HCURSOR16)wc->hCursor;
     classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
-    ALIAS_RegisterAlias( 0, 0, (DWORD)wc->lpfnWndProc );
     CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
     return atom;
 }
@@ -390,7 +409,9 @@
 
     if (!(atom = GlobalAddAtom32W( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
-                                          wc->cbClsExtra, wc->cbWndExtra )))
+                                          wc->cbClsExtra, wc->cbWndExtra,
+                                          (WNDPROC16)wc->lpfnWndProc,
+                                          WIN_PROC_32W )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -401,14 +422,10 @@
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
-    classPtr->flags         = CLASS_FLAG_UNICODE;
-    classPtr->lpfnWndProc   = (WNDPROC16)wc->lpfnWndProc;
     classPtr->hIcon         = (HICON16)wc->hIcon;
     classPtr->hIconSm       = 0;
     classPtr->hCursor       = (HCURSOR16)wc->hCursor;
     classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
-
-    ALIAS_RegisterAlias( 0, 0, (DWORD)wc->lpfnWndProc );
     CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
     return atom;
 }
@@ -426,7 +443,8 @@
 
     if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
-                                          wc->cbClsExtra, wc->cbWndExtra )))
+                                          wc->cbClsExtra, wc->cbWndExtra,
+                                          wc->lpfnWndProc, WIN_PROC_16 )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -437,7 +455,6 @@
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
-    classPtr->lpfnWndProc   = wc->lpfnWndProc;
     classPtr->hIcon         = wc->hIcon;
     classPtr->hIconSm       = wc->hIconSm;
     classPtr->hCursor       = wc->hCursor;
@@ -462,7 +479,9 @@
 
     if (!(atom = GlobalAddAtom32A( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
-                                          wc->cbClsExtra, wc->cbWndExtra )))
+                                          wc->cbClsExtra, wc->cbWndExtra,
+                                          (WNDPROC16)wc->lpfnWndProc,
+                                          WIN_PROC_32A )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -473,13 +492,10 @@
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
-    classPtr->lpfnWndProc   = (WNDPROC16)wc->lpfnWndProc;
     classPtr->hIcon         = (HICON16)wc->hIcon;
     classPtr->hIconSm       = (HICON16)wc->hIconSm;
     classPtr->hCursor       = (HCURSOR16)wc->hCursor;
     classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
-
-    ALIAS_RegisterAlias( 0, 0, (DWORD)wc->lpfnWndProc );
     CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
     return atom;
 }
@@ -498,7 +514,9 @@
 
     if (!(atom = GlobalAddAtom32W( wc->lpszClassName ))) return 0;
     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
-                                          wc->cbClsExtra, wc->cbWndExtra )))
+                                          wc->cbClsExtra, wc->cbWndExtra,
+                                          (WNDPROC16)wc->lpfnWndProc,
+                                          WIN_PROC_32W )))
     {
         GlobalDeleteAtom( atom );
         return 0;
@@ -509,13 +527,10 @@
                    wc->hbrBackground, wc->style, wc->cbClsExtra,
                    wc->cbWndExtra, classPtr );
     
-    classPtr->lpfnWndProc   = (WNDPROC16)wc->lpfnWndProc;
     classPtr->hIcon         = (HICON16)wc->hIcon;
     classPtr->hIconSm       = (HICON16)wc->hIconSm;
     classPtr->hCursor       = (HCURSOR16)wc->hCursor;
     classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
-
-    ALIAS_RegisterAlias( 0, 0, (DWORD)wc->lpfnWndProc );
     CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
     return atom;
 }
@@ -572,7 +587,7 @@
 /***********************************************************************
  *           GetClassWord    (USER.129) (USER32.218)
  */
-WORD GetClassWord( HWND hwnd, INT32 offset )
+WORD GetClassWord( HWND32 hwnd, INT32 offset )
 {
     WND * wndPtr;
     
@@ -661,7 +676,7 @@
 /***********************************************************************
  *           SetClassWord    (USER.130) (USER32.468)
  */
-WORD SetClassWord( HWND hwnd, INT32 offset, WORD newval )
+WORD SetClassWord( HWND32 hwnd, INT32 offset, WORD newval )
 {
     WND * wndPtr;
     WORD retval = 0;
@@ -706,9 +721,19 @@
  */
 LONG SetClassLong16( HWND hwnd, INT16 offset, LONG newval )
 {
-    if ((offset == GCL_MENUNAME) && HIWORD(newval))
-        newval = (LONG)PTR_SEG_TO_LIN(newval);
-    return SetClassLong32A( hwnd, offset, newval );
+    WND *wndPtr;
+
+    switch(offset)
+    {
+    case GCL_WNDPROC:
+        if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+        return (LONG)CLASS_SetWndProc( wndPtr->class, (WNDPROC16)newval,
+                                       WIN_PROC_16 );
+    case GCL_MENUNAME:
+        return SetClassLong32A( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
+    default:
+        return SetClassLong32A( hwnd, offset, newval );
+    }
 }
 
 
@@ -738,6 +763,9 @@
         case GCL_MENUNAME:
             CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
             return 0;  /* Old value is now meaningless anyway */
+        case GCL_WNDPROC:
+            return (LONG)CLASS_SetWndProc( wndPtr->class, (WNDPROC16)newval,
+                                           WIN_PROC_32A );
         case GCL_HBRBACKGROUND:
         case GCL_HCURSOR:
         case GCL_HICON:
@@ -746,7 +774,6 @@
         case GCL_STYLE:      ptr = &wndPtr->class->style; break;
         case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
         case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
-        case GCL_WNDPROC:    ptr = &wndPtr->class->lpfnWndProc; break;
         case GCL_HMODULE:    ptr = &wndPtr->class->hInstance; break;
         default:
             fprintf( stderr, "Warning: invalid offset %d for SetClassLong()\n",
@@ -765,10 +792,19 @@
 LONG SetClassLong32W( HWND hwnd, INT32 offset, LONG newval )
 {
     WND *wndPtr;
-    if (offset != GCL_MENUNAME) return SetClassLong32A( hwnd, offset, newval );
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
-    CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
-    return 0;  /* Old value is now meaningless anyway */
+
+    switch(offset)
+    {
+    case GCL_WNDPROC:
+        return (LONG)CLASS_SetWndProc( wndPtr->class, (WNDPROC16)newval,
+                                       WIN_PROC_32W );
+    case GCL_MENUNAME:
+        CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
+        return 0;  /* Old value is now meaningless anyway */
+    default:
+        return SetClassLong32A( hwnd, offset, newval );
+    }
 }
 
 
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 6fcfe39..39e77e0 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -24,11 +24,11 @@
 
     if (IsChild( hwndDlg, hwndPrev ))
     {
-        if (SendMessage( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
-            SendMessage( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
+        if (SendMessage16( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
+            SendMessage16( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
     }
-    if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
-        SendMessage( hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
+    if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
+        SendMessage16( hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
     SetFocus( hwndCtrl );
 }
 
@@ -72,7 +72,7 @@
     HWND hwndChild = GetWindow( hwndDlg, GW_CHILD );
     while (hwndChild)
     {
-        if (SendMessage( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
+        if (SendMessage16( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
             break;
         hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
     }
@@ -90,18 +90,18 @@
                                  HWND hwndNew )
 {
     if (hwndNew &&
-        !(SendMessage( hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
+        !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
         return FALSE;  /* Destination is not a push button */
     
     if (dlgInfo->msgResult)  /* There's already a default pushbutton */
     {
         HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->msgResult );
-        if (SendMessage( hwndOld, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
-            SendMessage( hwndOld, BM_SETSTYLE16, BS_PUSHBUTTON, TRUE );
+        if (SendMessage32A( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
+            SendMessage32A( hwndOld, BM_SETSTYLE32, BS_PUSHBUTTON, TRUE );
     }
     if (hwndNew)
     {
-        SendMessage( hwndNew, BM_SETSTYLE16, BS_DEFPUSHBUTTON, TRUE );
+        SendMessage32A( hwndNew, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
         dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
     }
     else dlgInfo->msgResult = 0;
@@ -167,12 +167,12 @@
 	    }
 
 	      /* Window clean-up */
-	    DefWindowProc( hwnd, msg, wParam, lParam );
+	    DefWindowProc16( hwnd, msg, wParam, lParam );
 	    break;
 
 	case WM_SHOWWINDOW:
 	    if (!wParam) DEFDLG_SaveFocus( hwnd, dlgInfo );
-	    return DefWindowProc( hwnd, msg, wParam, lParam );
+	    return DefWindowProc16( hwnd, msg, wParam, lParam );
 
 	case WM_ACTIVATE:
 	    if (wParam) DEFDLG_RestoreFocus( hwnd, dlgInfo );
@@ -215,7 +215,7 @@
             return 0;
 
 	default:
-	    return DefWindowProc( hwnd, msg, wParam, lParam );
+	    return DefWindowProc16( hwnd, msg, wParam, lParam );
     }
         
     return result;
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 9ec8104..d3eb72a 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -9,8 +9,10 @@
 #include <stdio.h>
 #include "win.h"
 #include "user.h"
+#include "heap.h"
 #include "nonclient.h"
 #include "winpos.h"
+#include "string32.h"
 #include "syscolor.h"
 #include "stddebug.h"
 /* #define DEBUG_MESSAGE */
@@ -27,6 +29,7 @@
 static short iF10Key = 0;
 static short iMenuSysKey = 0;
 
+
 /***********************************************************************
  *           DEFWND_InitSysMenuPopup
  *
@@ -52,49 +55,55 @@
 
 
 /***********************************************************************
- *           DEFWND_SetText
+ *           DEFWND_HandleWindowPosChanged
  *
- * Set the window text.
+ * Handle the WM_WINDOWPOSCHANGED message.
  */
-void DEFWND_SetText( WND *wndPtr, LPSTR text )
+static void DEFWND_HandleWindowPosChanged( WND *wndPtr, UINT32 flags )
 {
-    LPSTR textPtr;
+    WPARAM16 wp = SIZE_RESTORED;
 
-    if (!text) text = "";
-    if (wndPtr->hText) USER_HEAP_FREE( wndPtr->hText );
-    wndPtr->hText = USER_HEAP_ALLOC( strlen(text) + 1 );
-    textPtr = (LPSTR) USER_HEAP_LIN_ADDR( wndPtr->hText );
-    strcpy( textPtr, text );
-    if (wndPtr->window)
-        XStoreName( display, wndPtr->window, text );
+    if (!(flags & SWP_NOCLIENTMOVE))
+        SendMessage16( wndPtr->hwndSelf, WM_MOVE, 0,
+                    MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top));
+    if (!(flags & SWP_NOCLIENTSIZE))
+    {
+        if (wndPtr->dwStyle & WS_MAXIMIZE) wp = SIZE_MAXIMIZED;
+        else if (wndPtr->dwStyle & WS_MINIMIZE) wp = SIZE_MINIMIZED;
+
+        SendMessage16( wndPtr->hwndSelf, WM_SIZE, wp, 
+                     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+    }
 }
 
 
 /***********************************************************************
- *           DefWindowProc   (USER.107)
+ *           DEFWND_SetText
+ *
+ * Set the window text.
  */
-LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+void DEFWND_SetText( WND *wndPtr, LPCSTR text )
 {
-    LPSTR textPtr;
-    int len;
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!text) text = "";
+    if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
+    wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );
+    if (wndPtr->window) XStoreName( display, wndPtr->window, wndPtr->text );
+}
 
-    SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
+
+/***********************************************************************
+ *           DEFWND_DefWinProc
+ *
+ * Default window procedure for messages that are the same in Win16 and Win32.
+ */
+static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam,
+                                  LPARAM lParam )
+{
+    HWND16 hwnd = wndPtr->hwndSelf;
 
     switch(msg)
     {
-    case WM_NCCREATE:
-	{
-	    CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
-	    if (cs->lpszName)
-		DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(cs->lpszName) );
-	    return 1;
-	}
-
-    case WM_NCCALCSIZE:
-	return NC_HandleNCCalcSize( hwnd,
-                               (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam) );
-
     case WM_PAINTICON: 
     case WM_NCPAINT:
 	return NC_HandleNCPaint( hwnd, (HRGN)wParam );
@@ -113,10 +122,11 @@
 	return NC_HandleNCActivate( hwnd, wParam );
 
     case WM_NCDESTROY:
-	if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText);
+	if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
+	wndPtr->text = NULL;
 	if (wndPtr->hVScroll) USER_HEAP_FREE(wndPtr->hVScroll);
 	if (wndPtr->hHScroll) USER_HEAP_FREE(wndPtr->hHScroll);
-	wndPtr->hText = wndPtr->hVScroll = wndPtr->hHScroll = 0;
+        wndPtr->hVScroll = wndPtr->hHScroll = 0;
 	return 0;
 	
     case WM_PAINT:
@@ -143,42 +153,16 @@
     case WM_MOUSEACTIVATE:
 	if (wndPtr->dwStyle & WS_CHILD)
 	{
-	    LONG ret = SendMessage( wndPtr->parent->hwndSelf, WM_MOUSEACTIVATE,
+	    LONG ret = SendMessage16( wndPtr->parent->hwndSelf, WM_MOUSEACTIVATE,
 				    wParam, lParam );
 	    if (ret) return ret;
 	}
 	return MA_ACTIVATE;
 
     case WM_ACTIVATE:
-      /* LOWORD() needed for WINELIB32 implementation.  Should be fine. */
-	if (LOWORD(wParam)!=WA_INACTIVE) SetFocus( hwnd );
+	if (LOWORD(wParam) != WA_INACTIVE) SetFocus( hwnd );
 	break;
 
-    case WM_WINDOWPOSCHANGING:
-	return WINPOS_HandleWindowPosChanging( (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam) );
-
-    case WM_WINDOWPOSCHANGED:
-	{
-	    WINDOWPOS16 * winPos = (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam);
-	    WPARAM16 wp = SIZE_RESTORED;
-
-	    if (!(winPos->flags & SWP_NOCLIENTMOVE))
-		SendMessage( hwnd, WM_MOVE, 0,
-		             MAKELONG( wndPtr->rectClient.left,
-				       wndPtr->rectClient.top ));
-	    if (!(winPos->flags & SWP_NOCLIENTSIZE))
-		 {
-	       	   if( wndPtr->dwStyle & WS_MAXIMIZE ) wp = SIZE_MAXIMIZED;
-		   else if(wndPtr->dwStyle & WS_MINIMIZE ) wp = SIZE_MINIMIZED;
-
-		   SendMessage( hwnd, WM_SIZE, wp, 
-			        MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-			                 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-
-                 }
-	    return 0;
-	}
-
     case WM_ERASEBKGND:
     case WM_ICONERASEBKGND:
 	{
@@ -208,13 +192,13 @@
     case WM_CTLCOLORSTATIC:
         SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
         SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
-        return (LONG)sysColorObjects.hbrushWindow;
+        return (LRESULT)sysColorObjects.hbrushWindow;
 
     case WM_CTLCOLORSCROLLBAR:
         SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
         SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
         UnrealizeObject( sysColorObjects.hbrushScrollbar );
-        return (LONG)sysColorObjects.hbrushScrollbar;
+        return (LRESULT)sysColorObjects.hbrushScrollbar;
 
     case WM_CTLCOLOR:
 	{
@@ -223,51 +207,23 @@
 		SetBkColor( (HDC)wParam, RGB(255, 255, 255) );
 		SetTextColor( (HDC)wParam, RGB(0, 0, 0) );
 		UnrealizeObject( sysColorObjects.hbrushScrollbar );
-		return (LONG)sysColorObjects.hbrushScrollbar;
+		return (LRESULT)sysColorObjects.hbrushScrollbar;
 	    }
 	    else
 	    {
 		SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW) );
 		SetTextColor( (HDC)wParam, GetSysColor(COLOR_WINDOWTEXT) );
-		return (LONG)sysColorObjects.hbrushWindow;
+		return (LRESULT)sysColorObjects.hbrushWindow;
 	    }
 	}
 	
-    case WM_GETTEXT:
-	{
-	    if (wParam)
-	    {
-		if (wndPtr->hText)
-		{
-		    textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
-		    if ((int)wParam > (len = strlen(textPtr)))
-		    {
-			strcpy((char *)PTR_SEG_TO_LIN(lParam), textPtr);
-			return (DWORD)len;
-		    }
-		}
-	    }
-	    return 0;
-	}
-
     case WM_GETTEXTLENGTH:
-	{
-	    if (wndPtr->hText)
-	    {
-		textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
-		return (DWORD)strlen(textPtr);
-	    }
-	    return 0;
-	}
-
-    case WM_SETTEXT:
-	DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
-	NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
-	return 0;
+        if (wndPtr->text) return (LRESULT)strlen(wndPtr->text);
+        return 0;
 
     case WM_SETCURSOR:
 	if (wndPtr->dwStyle & WS_CHILD)
-	    if (SendMessage(wndPtr->parent->hwndSelf, WM_SETCURSOR,
+	    if (SendMessage16(wndPtr->parent->hwndSelf, WM_SETCURSOR,
                             wParam, lParam))
 		return TRUE;
 	return NC_HandleSetCursor( hwnd, wParam, lParam );
@@ -276,12 +232,10 @@
         return NC_HandleSysCommand( hwnd, wParam, MAKEPOINT16(lParam) );
 
     case WM_KEYDOWN:
-
 	if(wParam == VK_F10) iF10Key = VK_F10;
 	break;
 
     case WM_SYSKEYDOWN:
-
 	if( HIWORD(lParam) & KEYDATA_ALT )
 	  {
 	    /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
@@ -297,63 +251,45 @@
 	         iF10Key = 1;
 	     else
 	         if( wParam == VK_ESCAPE && GetKeyState(VK_SHIFT) < 0 )
-		     SendMessage( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, 
+		     SendMessage16( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, 
  						       (LPARAM)VK_SPACE);
 	break;
 
     case WM_KEYUP:
     case WM_SYSKEYUP:
-
 	/* Press and release F10 or ALT */
-
-	if( ( wParam == VK_MENU && iMenuSysKey ) 
-	      || ( wParam == VK_F10 && iF10Key ) )
-
-	      SendMessage( WIN_GetTopParent(hwnd), WM_SYSCOMMAND,
+	if (((wParam == VK_MENU) && iMenuSysKey) ||
+            ((wParam == VK_F10) && iF10Key))
+	      SendMessage16( WIN_GetTopParent(hwnd), WM_SYSCOMMAND,
 			   SC_KEYMENU, 0L );
-
 	iMenuSysKey = iF10Key = 0;
         break;
 
     case WM_SYSCHAR:
-
 	iMenuSysKey = 0;
-
-	if( wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE) )
-	  {
+	if (wParam == VK_RETURN && (wndPtr->dwStyle & WS_MINIMIZE))
+        {
 	    PostMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0L ); 
 	    break;
-	  }  
-
-	if( (HIWORD(lParam) & KEYDATA_ALT) && wParam )
-	  {
-	    if( wParam == VK_TAB || wParam == VK_ESCAPE )
-	      break;
-
-	    if( wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD) )
-	      SendMessage( wndPtr->parent->hwndSelf, msg, wParam, lParam );
+        } 
+	if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
+        {
+	    if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
+	    if (wParam == VK_SPACE && (wndPtr->dwStyle & WS_CHILD))
+                SendMessage16( wndPtr->parent->hwndSelf, msg, wParam, lParam );
 	    else
-	      SendMessage(hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
-	  } 
-	else
-	  /* check for Ctrl-Esc */
-	  if( wParam != VK_ESCAPE )   
-	      MessageBeep(0);
-	  
+                SendMessage16( hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)(DWORD)wParam );
+        } 
+	else /* check for Ctrl-Esc */
+            if (wParam != VK_ESCAPE) MessageBeep(0);
 	break;
 
     case WM_SHOWWINDOW:
-	if( !lParam ) return 0; /* sent from ShowWindow */
-
-	if( !(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner ) 
-	      return 0;
-
-	if( wndPtr->dwStyle & WS_VISIBLE )
-	    { if( wParam ) return 0; }
-	else
-	      if(!wParam ) return 0;
-  
-	ShowWindow(hwnd,(wParam)? SW_SHOWNOACTIVATE: SW_HIDE);
+        if (!lParam) return 0; /* sent from ShowWindow */
+        if (!(wndPtr->dwStyle & WS_POPUP) || !wndPtr->owner) return 0;
+        if ((wndPtr->dwStyle & WS_VISIBLE) && wParam) return 0;
+	else if (!(wndPtr->dwStyle & WS_VISIBLE) && !wParam) return 0;
+        ShowWindow( hwnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE );
 	break; 
 
     case WM_INITMENUPOPUP:
@@ -364,13 +300,9 @@
         break;
 
     case WM_CANCELMODE:
-
 	/* EndMenu() should be called if in menu state but currently it's
 	   impossible to detect - menu code should be updated*/
-
-	if( GetCapture() == hwnd )
-	    ReleaseCapture();
-
+	if (GetCapture() == hwnd) ReleaseCapture();
 	break;
 
     case WM_VKEYTOITEM:
@@ -381,25 +313,197 @@
 	return DRAG_FILE;  
 
     case WM_QUERYDROPOBJECT:
-	if(wndPtr->dwExStyle & WS_EX_ACCEPTFILES)
-	   return 1;
+	if (wndPtr->dwExStyle & WS_EX_ACCEPTFILES) return 1;
 	break;
 
     case WM_QUERYDRAGICON:
-	{
-	 HICON hI = 0;
-
-	 len = 1;
-	 while(len < 64)
+        {
+            HICON hI = 0;
+            UINT16 len = 1;
+            while(len < 64)
 		if( (hI = LoadIcon(wndPtr->hInstance,MAKEINTRESOURCE(len))) )
-		     return (LRESULT)hI;
-	}
+                    return (LRESULT)hI;
+        }
         break;
 
     case WM_QUERYOPEN:
     case WM_QUERYENDSESSION:
 	return 1;
-
     }
     return 0;
 }
+
+
+
+/***********************************************************************
+ *           DefWindowProc16   (USER.107)
+ */
+LRESULT DefWindowProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
+                         LPARAM lParam )
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    LRESULT result = 0;
+
+    SPY_EnterMessage( SPY_DEFWNDPROC16, hwnd, msg, wParam, lParam );
+
+    switch(msg)
+    {
+    case WM_NCCREATE:
+	{
+	    CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
+	    if (cs->lpszName)
+		DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(cs->lpszName) );
+	    result = 1;
+	}
+        break;
+
+    case WM_NCCALCSIZE:
+	result = NC_HandleNCCalcSize(wndPtr, (RECT16 *)PTR_SEG_TO_LIN(lParam));
+        break;
+
+    case WM_WINDOWPOSCHANGING:
+	result = WINPOS_HandleWindowPosChanging16( wndPtr,
+                                       (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam) );
+        break;
+
+    case WM_WINDOWPOSCHANGED:
+	{
+	    WINDOWPOS16 * winPos = (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam);
+            DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
+	}
+        break;
+
+    case WM_GETTEXT:
+        if (wParam && wndPtr->text)
+        {
+            lstrcpyn( (LPSTR)PTR_SEG_TO_LIN(lParam), wndPtr->text, wParam );
+            return (LRESULT)strlen( (LPSTR)PTR_SEG_TO_LIN(lParam) ) + 1;
+        }
+        break;
+
+    case WM_SETTEXT:
+	DEFWND_SetText( wndPtr, (LPSTR)PTR_SEG_TO_LIN(lParam) );
+	NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
+        break;
+
+    default:
+        result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam );
+        break;
+    }
+
+    SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result );
+    return result;
+}
+
+
+/***********************************************************************
+ *           DefWindowProc32A   (USER32.125)
+ */
+LRESULT DefWindowProc32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
+                          LPARAM lParam )
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    LRESULT result = 0;
+
+    SPY_EnterMessage( SPY_DEFWNDPROC32, hwnd, msg, wParam, lParam );
+
+    switch(msg)
+    {
+    case WM_NCCREATE:
+	{
+	    CREATESTRUCT32A *cs = (CREATESTRUCT32A *)lParam;
+	    if (cs->lpszName) DEFWND_SetText( wndPtr, cs->lpszName );
+	    result = 1;
+	}
+        break;
+
+    case WM_NCCALCSIZE:
+        {
+            RECT16 rect16;
+            CONV_RECT32TO16( (RECT32 *)lParam, &rect16 );
+            result = NC_HandleNCCalcSize( wndPtr, &rect16 );
+            CONV_RECT16TO32( &rect16, (RECT32 *)lParam );
+        }
+        break;
+
+    case WM_WINDOWPOSCHANGING:
+	result = WINPOS_HandleWindowPosChanging32( wndPtr,
+                                                   (WINDOWPOS32 *)lParam );
+        break;
+
+    case WM_WINDOWPOSCHANGED:
+	{
+	    WINDOWPOS32 * winPos = (WINDOWPOS32 *)lParam;
+            DEFWND_HandleWindowPosChanged( wndPtr, winPos->flags );
+	}
+        break;
+
+    case WM_GETTEXT:
+        if (wParam && wndPtr->text)
+        {
+            lstrcpyn( (LPSTR)lParam, wndPtr->text, wParam );
+            return (LRESULT)strlen( (LPSTR)lParam ) + 1;
+        }
+        break;
+
+    case WM_SETTEXT:
+	DEFWND_SetText( wndPtr, (LPSTR)lParam );
+	NC_HandleNCPaint( hwnd , (HRGN)1 );  /* Repaint caption */
+        break;
+
+    default:
+        result = DEFWND_DefWinProc( wndPtr, msg, wParam, lParam );
+        break;
+    }
+
+    SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, result );
+    return result;
+}
+
+
+/***********************************************************************
+ *           DefWindowProc32W   (USER32.126)
+ */
+LRESULT DefWindowProc32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
+                          LPARAM lParam )
+{
+    LRESULT result;
+
+    switch(msg)
+    {
+    case WM_NCCREATE:
+	{
+	    CREATESTRUCT32W *cs = (CREATESTRUCT32W *)lParam;
+	    if (cs->lpszName)
+            {
+                WND *wndPtr = WIN_FindWndPtr( hwnd );
+                LPSTR str = STRING32_DupUniToAnsi( cs->lpszName );
+                DEFWND_SetText( wndPtr, str );
+                free( str );
+            }
+	    result = 1;
+	}
+
+    case WM_GETTEXT:
+        {
+            LPSTR str = malloc( wParam );
+            result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
+            STRING32_AnsiToUni( (LPWSTR)lParam, str );
+            free( str );
+        }
+        break;
+
+    case WM_SETTEXT:
+        {
+            LPSTR str = STRING32_DupUniToAnsi( (LPWSTR)lParam );
+            result = DefWindowProc32A( hwnd, msg, wParam, (LPARAM)str );
+            free( str );
+        }
+        break;
+
+    default:
+        result = DefWindowProc32A( hwnd, msg, wParam, lParam );
+        break;
+    }
+    return result;
+}
diff --git a/windows/dialog.c b/windows/dialog.c
index f8913b0..edf4623 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -420,13 +420,14 @@
                       SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
 
             /* Send initialisation messages to the control */
-        if (hFont) SendMessage( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
-        if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
+        if (hFont) SendMessage16( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
+        if (SendMessage16( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
         {
               /* If there's already a default push-button, set it back */
               /* to normal and use this one instead. */
             if (hwndDefButton)
-                SendMessage(hwndDefButton, BM_SETSTYLE16, BS_PUSHBUTTON,FALSE);
+                SendMessage32A( hwndDefButton, BM_SETSTYLE32,
+                                BS_PUSHBUTTON,FALSE );
             hwndDefButton = hwndCtrl;
             dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
         }
@@ -446,8 +447,8 @@
       /* Send initialisation messages and set focus */
 
     if (dlgInfo->hUserFont)
-	SendMessage( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
-    if (SendMessage( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param ))
+	SendMessage16( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
+    if (SendMessage16( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param ))
 	SetFocus( dlgInfo->hwndFocus );
     if (template.style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
     return hwnd;
@@ -577,7 +578,7 @@
 	(msg->message != WM_CHAR))
         return FALSE;
 
-    dlgCode = SendMessage( msg->hwnd, WM_GETDLGCODE, 0, 0 );
+    dlgCode = SendMessage16( msg->hwnd, WM_GETDLGCODE, 0, 0 );
     if (dlgCode & DLGC_WANTMESSAGE)
     {
         DispatchMessage( msg );
@@ -593,7 +594,7 @@
         case VK_TAB:
             if (!(dlgCode & DLGC_WANTTAB))
             {
-                SendMessage( hwndDlg, WM_NEXTDLGCTL,
+                SendMessage16( hwndDlg, WM_NEXTDLGCTL,
                              (GetKeyState(VK_SHIFT) & 0x80), 0 );
                 return TRUE;
             }
@@ -619,33 +620,33 @@
 
         case VK_ESCAPE:
 #ifdef WINELIB32
-            SendMessage( hwndDlg, WM_COMMAND, 
-			 MAKEWPARAM( IDCANCEL, 0 ),
-                         (LPARAM)GetDlgItem(hwndDlg,IDCANCEL) );
+            SendMessage32A( hwndDlg, WM_COMMAND, 
+                            MAKEWPARAM( IDCANCEL, 0 ),
+                            (LPARAM)GetDlgItem(hwndDlg,IDCANCEL) );
 #else
-            SendMessage( hwndDlg, WM_COMMAND, IDCANCEL,
-                         MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
+            SendMessage16( hwndDlg, WM_COMMAND, IDCANCEL,
+                           MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
 #endif
             break;
 
         case VK_RETURN:
             {
-                DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 );
+                DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 );
                 if (HIWORD(dw) == DC_HASDEFID)
 #ifdef WINELIB32
-                    SendMessage( hwndDlg, WM_COMMAND, 
-				 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
-                                 (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) ) );
+                    SendMessage32A( hwndDlg, WM_COMMAND, 
+                                    MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
+                                   (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) ) );
                 else
-                    SendMessage( hwndDlg, WM_COMMAND, 
-				 MAKEWPARAM( IDOK, 0 ),
-                                 (LPARAM)GetDlgItem(hwndDlg,IDOK) );
+                    SendMessage32A( hwndDlg, WM_COMMAND, 
+                                    MAKEWPARAM( IDOK, 0 ),
+                                    (LPARAM)GetDlgItem(hwndDlg,IDOK) );
 #else
-                    SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw),
+                    SendMessage16( hwndDlg, WM_COMMAND, LOWORD(dw),
                                  MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ),
                                              BN_CLICKED ));
                 else
-                    SendMessage( hwndDlg, WM_COMMAND, IDOK,
+                    SendMessage16( hwndDlg, WM_COMMAND, IDOK,
                                  MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 ));
 #endif
             }
@@ -699,49 +700,126 @@
 
 
 /*******************************************************************
- *           SendDlgItemMessage   (USER.101)
+ *           SendDlgItemMessage16   (USER.101)
  */
-LRESULT SendDlgItemMessage(HWND hwnd, INT id, UINT msg, WPARAM wParam, LPARAM lParam)
+LRESULT SendDlgItemMessage16( HWND16 hwnd, INT16 id, UINT16 msg,
+                              WPARAM16 wParam, LPARAM lParam )
 {
-    HWND hwndCtrl = GetDlgItem( hwnd, id );
-    if (hwndCtrl) return SendMessage( hwndCtrl, msg, wParam, lParam );
+    HWND16 hwndCtrl = GetDlgItem( hwnd, id );
+    if (hwndCtrl) return SendMessage16( hwndCtrl, msg, wParam, lParam );
     else return 0;
 }
 
 
 /*******************************************************************
- *           SetDlgItemText   (USER.92)
+ *           SendDlgItemMessage32A   (USER32.451)
  */
-void SetDlgItemText( HWND hwnd, WORD id, SEGPTR lpString )
+LRESULT SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg,
+                               WPARAM32 wParam, LPARAM lParam )
 {
-    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString );
-}
-
-
-/***********************************************************************
- *           GetDlgItemText   (USER.93)
- */
-int GetDlgItemText( HWND hwnd, WORD id, SEGPTR str, WORD max )
-{
-    return (int)SendDlgItemMessage( hwnd, id, WM_GETTEXT, max, (DWORD)str );
+    HWND hwndCtrl = GetDlgItem( (HWND16)hwnd, (INT16)id );
+    if (hwndCtrl) return SendMessage32A( hwndCtrl, msg, wParam, lParam );
+    else return 0;
 }
 
 
 /*******************************************************************
- *           SetDlgItemInt   (USER.94)
+ *           SendDlgItemMessage32W   (USER32.452)
  */
-void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned )
+LRESULT SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg,
+                               WPARAM32 wParam, LPARAM lParam )
+{
+    HWND hwndCtrl = GetDlgItem( (HWND16)hwnd, (INT16)id );
+    if (hwndCtrl) return SendMessage32W( hwndCtrl, msg, wParam, lParam );
+    else return 0;
+}
+
+
+/*******************************************************************
+ *           SetDlgItemText16   (USER.92)
+ */
+void SetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR lpString )
+{
+    SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ *           SetDlgItemText32A   (USER32.477)
+ */
+void SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString )
+{
+    SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ *           SetDlgItemText32W   (USER32.478)
+ */
+void SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString )
+{
+    SendDlgItemMessage32W( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/***********************************************************************
+ *           GetDlgItemText16   (USER.93)
+ */
+INT16 GetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR str, UINT16 len )
+{
+    return (INT16)SendDlgItemMessage16( hwnd, id, WM_GETTEXT,
+                                        len, (LPARAM)str );
+}
+
+
+/***********************************************************************
+ *           GetDlgItemText32A   (USER32.236)
+ */
+INT32 GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len )
+{
+    return (INT32)SendDlgItemMessage32A( hwnd, id, WM_GETTEXT,
+                                         len, (LPARAM)str );
+}
+
+
+/***********************************************************************
+ *           GetDlgItemText32W   (USER32.237)
+ */
+INT32 GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len )
+{
+    return (INT32)SendDlgItemMessage32W( hwnd, id, WM_GETTEXT,
+                                         len, (LPARAM)str );
+}
+
+
+/*******************************************************************
+ *           SetDlgItemInt16   (USER.94)
+ */
+void SetDlgItemInt16( HWND16 hwnd, INT16 id, UINT16 value, BOOL16 fSigned )
 {
     char *str = (char *)SEGPTR_ALLOC( 20 * sizeof(char) );
 
     if (!str) return;
-    if (fSigned) sprintf( str, "%d", (int)value );
+    if (fSigned) sprintf( str, "%d", (INT32)(INT16)value );
     else sprintf( str, "%u", value );
-    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (LPARAM)SEGPTR_GET(str) );
+    SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)SEGPTR_GET(str) );
     SEGPTR_FREE(str);
 }
 
 
+/*******************************************************************
+ *           SetDlgItemInt32   (USER32.476)
+ */
+void SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value, BOOL32 fSigned )
+{
+    char str[20];
+
+    if (fSigned) sprintf( str, "%d", (INT32)value );
+    else sprintf( str, "%u", value );
+    SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)str );
+}
+
+
 /***********************************************************************
  *           GetDlgItemInt   (USER.95)
  */
@@ -752,7 +830,7 @@
     
     if (translated) *translated = FALSE;
     if (!(str = (char *)SEGPTR_ALLOC( 30 * sizeof(char) ))) return 0;
-    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, 30, (LPARAM)SEGPTR_GET(str)))
+    if (SendDlgItemMessage16( hwnd, id, WM_GETTEXT, 30, (LPARAM)SEGPTR_GET(str)))
     {
 	char * endptr;
 	result = strtol( str, &endptr, 10 );
@@ -780,7 +858,7 @@
  */
 BOOL CheckDlgButton( HWND hwnd, INT id, UINT check )
 {
-    SendDlgItemMessage( hwnd, id, BM_SETCHECK16, check, 0 );
+    SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 );
     return TRUE;
 }
 
@@ -790,7 +868,7 @@
  */
 WORD IsDlgButtonChecked( HWND hwnd, WORD id )
 {
-    return (WORD)SendDlgItemMessage( hwnd, id, BM_GETCHECK16, 0, 0 );
+    return (WORD)SendDlgItemMessage16( hwnd, id, BM_GETCHECK16, 0, 0 );
 }
 
 
@@ -810,7 +888,8 @@
         lastID = firstID;  /* Buttons are in reverse order */
     while (pWnd)
     {
-	SendMessage(pWnd->hwndSelf,BM_SETCHECK16,(pWnd->wIDmenu == checkID),0);
+	SendMessage32A( pWnd->hwndSelf, BM_SETCHECK32,
+                        (pWnd->wIDmenu == checkID), 0 );
         if (pWnd->wIDmenu == lastID) break;
 	pWnd = pWnd->next;
     }
diff --git a/windows/event.c b/windows/event.c
index ce5d41e..be015bf 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -564,8 +564,8 @@
         if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
 
         /* Artificial messages - what is this for? */
-	SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0);
-	SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
+	SendMessage16(hwnd, WM_ENTERSIZEMOVE, 0, 0);
+	SendMessage16(hwnd, WM_EXITSIZEMOVE, 0, 0);
 
 	/* Fill WINDOWPOS struct */
 	winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
@@ -584,7 +584,7 @@
 	    winpos->flags |= SWP_NOSIZE;
 
 	/* Send WM_WINDOWPOSCHANGING */
-	SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)SEGPTR_GET(winpos));
+	SendMessage16(hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)SEGPTR_GET(winpos));
 
 	/* Calculate new position and size */
 	newWindowRect.left = event->x;
@@ -603,7 +603,7 @@
 	/* Set new size and position */
 	wndPtr->rectWindow = newWindowRect;
 	wndPtr->rectClient = newClientRect;
-	SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)SEGPTR_GET(winpos));
+	SendMessage16( hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)SEGPTR_GET(winpos));
         SEGPTR_FREE(winpos);
 
         /* full window drag leaves unrepainted garbage without this */
@@ -697,7 +697,7 @@
 	dprintf_event( stddeb, "unrecognized ClientMessage\n" );
 	return;
     }
-    SendMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+    SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
 }
 
 
diff --git a/windows/focus.c b/windows/focus.c
index 12f3cc9..f31f73e 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -54,11 +54,11 @@
 {
     hwndFocus = hFocusTo;
 
-    if (hFocusFrom) SendMessage( hFocusFrom, WM_KILLFOCUS, (WPARAM)hFocusTo, 0L);
+    if (hFocusFrom) SendMessage16( hFocusFrom, WM_KILLFOCUS, (WPARAM)hFocusTo, 0L);
     if( !hFocusTo || hFocusTo != hwndFocus )
 	return;
 
-    SendMessage( hFocusTo, WM_SETFOCUS, (WPARAM)hFocusFrom, 0L);
+    SendMessage16( hFocusTo, WM_SETFOCUS, (WPARAM)hFocusFrom, 0L);
     FOCUS_SetXFocus( hFocusTo );
 }
 
diff --git a/windows/hook.c b/windows/hook.c
index 3b46e9f..74c2259 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -45,7 +45,7 @@
  *
  * Get the first hook for a given type.
  */
-static HANDLE HOOK_GetHook( short id , HQUEUE hQueue )
+HANDLE HOOK_GetHook( short id , HQUEUE hQueue )
 {
     MESSAGEQUEUE *queue;
     HANDLE hook = 0;
diff --git a/windows/mdi.c b/windows/mdi.c
index d6488eb..22efc97 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -19,18 +19,23 @@
 #include "xmalloc.h"
 #include "windows.h"
 #include "win.h"
+#include "heap.h"
 #include "nonclient.h"
 #include "mdi.h"
 #include "user.h"
 #include "menu.h"
+#include "resource.h"
 #include "stackframe.h"
+#include "struct32.h"
 #include "sysmetrics.h"
 #include "stddebug.h"
 #include "debug.h"
 
 #define MDIS_ALLCHILDSTYLES	0x1
 
-HMENU MENU_CopySysMenu();
+static HBITMAP hBmpClose   = 0;
+static HBITMAP hBmpRestore = 0;
+
 DWORD SCROLL_SetNCSbState(WND*,int,int,int,int,int,int);
 
 /* ----------------- declarations ----------------- */
@@ -74,16 +79,14 @@
  char buffer[128];
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
  WND		*wndPtr     = WIN_FindWndPtr(hWndChild);
- LPSTR		 lpWndText  = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText);
  int 		 n          = sprintf(buffer, "%d ", 
 				      clientInfo->nActiveChildren);
 
  if( !clientInfo->hWindowMenu ) return 0; 
     
- if( lpWndText )
-     strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1);
- return AppendMenu(clientInfo->hWindowMenu,MF_STRING,
-                       wndPtr->wIDmenu, MAKE_SEGPTR(buffer) );
+ if (wndPtr->text) strncpy(buffer + n, wndPtr->text, sizeof(buffer) - n - 1);
+ return AppendMenu32A( clientInfo->hWindowMenu, MF_STRING,
+                       wndPtr->wIDmenu, buffer );
 }
 #endif
 
@@ -95,19 +98,17 @@
  char            buffer[128];
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
  WND            *wndPtr     = WIN_FindWndPtr(hWndChild);
- LPSTR           lpWndText  = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText);
  UINT		 n          = sprintf(buffer, "%d ",
                               wndPtr->wIDmenu - clientInfo->idFirstChild + 1);
  BOOL		 bRet	    = 0;
 
  if( !clientInfo->hWindowMenu ) return 0;
 
- if( lpWndText ) lstrcpyn(buffer + n, lpWndText, sizeof(buffer) - n );
+ if (wndPtr->text) lstrcpyn(buffer + n, wndPtr->text, sizeof(buffer) - n );
 
  n    = GetMenuState(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); 
- bRet = ModifyMenu(clientInfo->hWindowMenu , wndPtr->wIDmenu , 
-                   MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu ,
-                   MAKE_SEGPTR(buffer) );
+ bRet = ModifyMenu32A(clientInfo->hWindowMenu , wndPtr->wIDmenu, 
+                      MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu, buffer );
  CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED);
  return bRet;
 }
@@ -120,7 +121,6 @@
  char    	 buffer[128];
  MDICLIENTINFO  *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra;
  WND    	*wndPtr     = WIN_FindWndPtr(hWndChild);
- LPSTR		 lpWndText;
  UINT		 index      = 0,id,n;
 
  if( !clientInfo->nActiveChildren ||
@@ -146,15 +146,13 @@
 	/* set correct id */
 	wndPtr->wIDmenu--;
 
-	n          = sprintf(buffer, "%d ",index - clientInfo->idFirstChild);
-	lpWndText  = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText);
-
-	if( lpWndText )
-	    strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1);	
+	n = sprintf(buffer, "%d ",index - clientInfo->idFirstChild);
+	if (wndPtr->text)
+            lstrcpyn(buffer + n, wndPtr->text, sizeof(buffer) - n );	
 
 	/* change menu */
-	ModifyMenu(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
-		   index - 1 , MAKE_SEGPTR(buffer) ); 
+	ModifyMenu32A(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING,
+                      index - 1 , buffer ); 
     }
  return 1;
 }
@@ -246,7 +244,7 @@
             INT		i = GetMenuItemCount(ci->hWindowMenu) - 1;
 	    INT 	pos = GetMenuItemCount(hmenuWindow) + 1;
 
-            AppendMenu(hmenuWindow,MF_SEPARATOR,0,(SEGPTR)0);
+            AppendMenu32A( hmenuWindow, MF_SEPARATOR, 0, NULL);
 
 	    if( ci->nActiveChildren )
 	      {
@@ -262,8 +260,8 @@
 		     GetMenuString(ci->hWindowMenu, i, buffer, 100, MF_BYPOSITION);
 
 		     DeleteMenu(ci->hWindowMenu, i , MF_BYPOSITION);
-		     InsertMenu(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
-					     id, MAKE_SEGPTR(buffer));
+		     InsertMenu32A(hmenuWindow, pos, MF_BYPOSITION | MF_STRING,
+					     id, buffer);
 		     CheckMenuItem(hmenuWindow ,pos , MF_BYPOSITION | (state & MF_CHECKED));
 		   }
 	      }
@@ -311,7 +309,7 @@
     DWORD	     style = cs->style | (WS_CHILD | WS_CLIPSIBLINGS);
     HWND 	     hwnd, hwndMax = 0;
     WORD	     wIDmenu = ci->idFirstChild + ci->nActiveChildren;
-    char*	     lpstrDef="junk!";
+    char	     lpstrDef[]="junk!";
 
     /*
      * Create child window
@@ -338,15 +336,15 @@
     if( style & WS_VISIBLE && ci->hwndChildMaximized )
       {
 	if( style & WS_MAXIMIZE )
-	  SendMessage(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
+	  SendMessage16(w->hwndSelf, WM_SETREDRAW, FALSE, 0L );
 	hwndMax = ci->hwndChildMaximized;
 	ShowWindow( hwndMax, SW_SHOWNOACTIVATE );
 	if( style & WS_MAXIMIZE )
-	  SendMessage(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
+	  SendMessage16(w->hwndSelf, WM_SETREDRAW, TRUE, 0L );
       }
 
     /* this menu is needed to set a check mark in MDI_ChildActivate */
-    AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(lpstrDef) );
+    AppendMenu32A(ci->hWindowMenu ,MF_STRING ,wIDmenu, lpstrDef );
 
     ci->nActiveChildren++;
 
@@ -518,13 +516,13 @@
     /* deactivate prev. active child */
     if( wndPrev )
     {
-	SendMessage( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
+	SendMessage16( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L );
 #ifdef WINELIB32
-        SendMessage( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, 
-		     (LPARAM)hWndChild);
+        SendMessage32A( prevActiveWnd, WM_MDIACTIVATE, (WPARAM)prevActiveWnd, 
+                        (LPARAM)hWndChild);
 #else
-        SendMessage( prevActiveWnd, WM_MDIACTIVATE, FALSE,
-					    MAKELONG(hWndChild,prevActiveWnd));
+        SendMessage16( prevActiveWnd, WM_MDIACTIVATE, FALSE,
+                       MAKELONG(hWndChild,prevActiveWnd));
 #endif
         /* uncheck menu item */
        	if( clientInfo->hWindowMenu )
@@ -564,20 +562,20 @@
 
     if( isActiveFrameWnd )
 	  {
-	    SendMessage( hWndChild, WM_NCACTIVATE, TRUE, 0L);
+	    SendMessage16( hWndChild, WM_NCACTIVATE, TRUE, 0L);
 	    if( GetFocus() == clientInfo->self )
-		SendMessage( clientInfo->self, WM_SETFOCUS, 
+		SendMessage16( clientInfo->self, WM_SETFOCUS, 
 			    (WPARAM)clientInfo->self, 0L );
 	    else
 		SetFocus( clientInfo->self );
     }
 
 #ifdef WINELIB32
-    SendMessage( hWndChild, WM_MDIACTIVATE, (WPARAM)hWndChild,
-		 (LPARAM)prevActiveWnd );
+    SendMessage32A( hWndChild, WM_MDIACTIVATE, (WPARAM)hWndChild,
+                    (LPARAM)prevActiveWnd );
 #else
-    SendMessage( hWndChild, WM_MDIACTIVATE, TRUE,
-				       MAKELONG(prevActiveWnd,hWndChild) );
+    SendMessage16( hWndChild, WM_MDIACTIVATE, TRUE,
+                   MAKELONG(prevActiveWnd,hWndChild) );
 #endif
 
     return 1;
@@ -588,7 +586,7 @@
  *
  *  iTotal returns number of children available for tiling or cascading
  */
-MDIWCL* MDI_BuildWCL(WND* clientWnd, INT* iTotal)
+MDIWCL* MDI_BuildWCL(WND* clientWnd, INT16* iTotal)
 {
     MDIWCL *listTop,*listNext;
     WND    *childWnd;
@@ -720,7 +718,7 @@
     int		  rows, columns;
     int           r, c;
     int           i;
-    INT		  iToPosition = 0;
+    INT16	  iToPosition = 0;
 
     if (ci->hwndChildMaximized)
 	ShowWindow(ci->hwndChildMaximized, SW_NORMAL);
@@ -812,7 +810,7 @@
 BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild)
 {
  WND*		child = WIN_FindWndPtr(hChild);
- POPUPMENU*	pmenu = NULL;
+ HGLOBAL        handle;
  HMENU  	hSysPopup = 0;
 
  dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame %p,child %04x\n",frame,hChild);
@@ -820,19 +818,19 @@
  if( !frame->wIDmenu || !child->hSysMenu ) return 0; 
 
  /* create a copy of sysmenu popup and insert it into frame menu bar */
- 
- hSysPopup = MENU_CopySysMenu();
- pmenu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hSysPopup);
- pmenu->wFlags &= ~MF_SYSMENU;
 
+ if (!(handle = SYSRES_LoadResource( SYSRES_MENU_SYSMENU ))) return 0;
+ hSysPopup = LoadMenuIndirect16( GlobalLock16( handle ) );
+ SYSRES_FreeResource( handle );
+ 
  dprintf_mdi(stddeb,"\t\tgot popup %04x\n in sysmenu %04x",hSysPopup,child->hSysMenu);
  
- if( !InsertMenu(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
-                 hSysPopup, (SEGPTR)(DWORD)ci->obmClose) )
+ if( !InsertMenu32A(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP,
+                    hSysPopup, (LPSTR)(DWORD)hBmpClose ))
    {  DestroyMenu(hSysPopup); return 0; }
 
- if( !AppendMenu(frame->wIDmenu,MF_HELP | MF_BITMAP,
-                 SC_RESTORE, (SEGPTR)(DWORD)ci->obmRestore) )
+ if( !AppendMenu32A(frame->wIDmenu,MF_HELP | MF_BITMAP,
+                    SC_RESTORE, (LPSTR)(DWORD)hBmpRestore ))
    {
       RemoveMenu(frame->wIDmenu,0,MF_BYPOSITION);
       return 0;
@@ -883,7 +881,6 @@
 void MDI_UpdateFrameText(WND *frameWnd, HWND hClient, BOOL repaint, LPCSTR lpTitle)
 {
  char   lpBuffer[MDI_MAXTITLELENGTH+1];
- LPSTR	lpText    = NULL;
  WND* 	clientWnd = WIN_FindWndPtr(hClient);
 
  MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra;
@@ -891,71 +888,54 @@
  dprintf_mdi(stddeb, "MDI: repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL");
 
  /* store new "default" title if lpTitle is not NULL */
- if( lpTitle )
-   {
-	if( ci->hFrameTitle )
-	    USER_HEAP_FREE( ci->hFrameTitle );
-	ci->hFrameTitle = USER_HEAP_ALLOC( strlen(lpTitle) + 1 );
-	lpText = (LPSTR) USER_HEAP_LIN_ADDR( ci->hFrameTitle );
-	strcpy( lpText, lpTitle );
-   }
- else
-  lpText = (LPSTR) USER_HEAP_LIN_ADDR(ci->hFrameTitle);
+ if (lpTitle) 
+ {
+     if (ci->frameTitle) HeapFree( SystemHeap, 0, ci->frameTitle );
+     ci->frameTitle = HEAP_strdupA( SystemHeap, 0, lpTitle );
+ }
 
- if( ci->hFrameTitle )
+ if (ci->frameTitle)
    {
      WND* childWnd = WIN_FindWndPtr( ci->hwndChildMaximized );     
 
-     if( childWnd && childWnd->hText )
+     if( childWnd && childWnd->text )
        {
 	 /* combine frame title and child title if possible */
 
 	 LPCSTR lpBracket  = " - [";
-	 LPCSTR lpChildText = (LPCSTR) USER_HEAP_LIN_ADDR( childWnd->hText );
- 
-	 int	i_frame_text_length = strlen(lpText);
-	 int    i_child_text_length = strlen(lpChildText);
+	 int	i_frame_text_length = strlen(ci->frameTitle);
+	 int    i_child_text_length = strlen(childWnd->text);
 
-	 strncpy( lpBuffer, lpText, MDI_MAXTITLELENGTH);
-	 lpBuffer[MDI_MAXTITLELENGTH] = '\0';
+	 lstrcpyn( lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH);
 
-	 if( i_frame_text_length + 5 < MDI_MAXTITLELENGTH )
-	   {
+	 if( i_frame_text_length + 6 < MDI_MAXTITLELENGTH )
+         {
 	     strcat( lpBuffer, lpBracket );
 
-	     if( i_frame_text_length + i_child_text_length + 5 < MDI_MAXTITLELENGTH )
-		{
-		   strcat( lpBuffer, lpChildText );
-	         *(short*)(lpBuffer + i_frame_text_length + i_child_text_length + 4) = (short)']';
-		}
+	     if( i_frame_text_length + i_child_text_length + 6 < MDI_MAXTITLELENGTH )
+             {
+                 strcat( lpBuffer, childWnd->text );
+                 strcat( lpBuffer, "]" );
+             }
 	     else
-		{
-		   memcpy( lpBuffer + i_frame_text_length + 4, 
-		           lpChildText, 
-			   MDI_MAXTITLELENGTH - i_frame_text_length - 4);
-		 *(short*)(lpBuffer + MDI_MAXTITLELENGTH - 1) = (short)']';
+             {
+                 lstrcpyn( lpBuffer + i_frame_text_length + 4, 
+                           childWnd->text,
+                           MDI_MAXTITLELENGTH - i_frame_text_length - 5 );
+                 strcat( lpBuffer, "]" );
 		}
 	   }
        }
      else
        {
-         strncpy(lpBuffer, lpText, MDI_MAXTITLELENGTH );
+         strncpy(lpBuffer, ci->frameTitle, MDI_MAXTITLELENGTH );
 	 lpBuffer[MDI_MAXTITLELENGTH]='\0';
        }
    }
  else
    lpBuffer[0] = '\0';
 
- if( frameWnd->hText )
-     USER_HEAP_FREE( frameWnd->hText );
- 
- frameWnd->hText = USER_HEAP_ALLOC( strlen(lpBuffer) + 1 );
- lpText = (LPSTR) USER_HEAP_LIN_ADDR( frameWnd->hText );
- strcpy( lpText, lpBuffer );
-
- if( frameWnd->window )
-     XStoreName( display, frameWnd->window, lpBuffer );
-
+ DEFWND_SetText( frameWnd, lpBuffer );
  if( repaint == MDI_REPAINTFRAME)
      SetWindowPos(frameWnd->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED |
                   SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
@@ -992,20 +972,22 @@
 	ci->hwndChildMaximized  = 0;
 	ci->nActiveChildren	= 0;
 	ci->nTotalCreated	= 0;
-	ci->hFrameTitle		= frameWnd->hText;
+	ci->frameTitle		= NULL;
 	ci->sbNeedUpdate	= 0;
 	ci->self		= hwnd;
-	ci->obmClose		= CreateMDIMenuBitmap();
-	ci->obmRestore		= LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
 	w->dwStyle             |= WS_CLIPCHILDREN;
-	frameWnd->hText		= 0;	/* will be restored in UpdateFrameText */
 
-	MDI_UpdateFrameText( frameWnd, hwnd, MDI_NOFRAMEREPAINT, NULL);
+	if (!hBmpClose)
+        {
+            hBmpClose = CreateMDIMenuBitmap();
+            hBmpRestore = LoadBitmap( 0, MAKEINTRESOURCE(OBM_RESTORE) );
+        }
+	MDI_UpdateFrameText(frameWnd, hwnd, MDI_NOFRAMEREPAINT,frameWnd->text);
 
-	AppendMenu(ccs->hWindowMenu,MF_SEPARATOR,0,(SEGPTR)0);
+	AppendMenu32A( ccs->hWindowMenu, MF_SEPARATOR, 0, NULL );
 
 	GetClientRect16(frameWnd->hwndSelf, &rect);
-	NC_HandleNCCalcSize(hwnd, (NCCALCSIZE_PARAMS16*) &rect);
+	NC_HandleNCCalcSize( w, &rect );
 	w->rectClient = rect;
 
 	dprintf_mdi(stddeb,"MDI: Client created - hwnd = %04x, idFirst = %u\n",hwnd,ci->idFirstChild);
@@ -1014,10 +996,6 @@
       
       case WM_DESTROY:
 	if( ci->hwndChildMaximized ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf);
-
-	if(ci->obmClose)   DeleteObject(ci->obmClose);
-	if(ci->obmRestore) DeleteObject(ci->obmRestore);
-
 	ci->idFirstChild = GetMenuItemCount(ci->hWindowMenu) - 1;
 	ci->nActiveChildren++; 			/* to delete a separator */
 
@@ -1048,7 +1026,7 @@
 	ci->sbNeedUpdate = TRUE;
 	MDIIconArrange(hwnd);
 	ci->sbRecalc = SB_BOTH+1;
-	SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
+	SendMessage16(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
 	return 0;
 	
       case WM_MDIMAXIMIZE:
@@ -1095,7 +1073,7 @@
 	
       case WM_NCACTIVATE:
         if( ci->hwndActiveChild )
-	     SendMessage(ci->hwndActiveChild, message, wParam, lParam);
+	     SendMessage16(ci->hwndActiveChild, message, wParam, lParam);
 	break;
 	
       case WM_PARENTNOTIFY:
@@ -1144,15 +1122,15 @@
 	return 0;
     }
     
-    return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
-/**********************************************************************
- *					DefFrameProc (USER.445)
- *
+
+/***********************************************************************
+ *           DefFrameProc16   (USER.445)
  */
-LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message, 
-		     WPARAM wParam, LPARAM lParam)
+LRESULT DefFrameProc16( HWND16 hwnd, HWND16 hwndMDIClient, UINT16 message, 
+                        WPARAM16 wParam, LPARAM lParam )
 {
     HWND	         childHwnd;
     MDICLIENTINFO*       ci;
@@ -1183,7 +1161,7 @@
 		    case SC_CLOSE:
 		    case SC_RESTORE:
 		       if( ci->hwndChildMaximized )
-			   return SendMessage( ci->hwndChildMaximized, WM_SYSCOMMAND,
+			   return SendMessage16( ci->hwndChildMaximized, WM_SYSCOMMAND,
 					       wParam, lParam);
 		  }
 	      }
@@ -1192,12 +1170,12 @@
 	    	childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient),
                                           wParam );
  	    	if( childHwnd )
-	            SendMessage(hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd , 0L);
+	            SendMessage16(hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd , 0L);
 	      }
 	    break;
 
 	  case WM_NCACTIVATE:
-	    SendMessage(hwndMDIClient, message, wParam, lParam);
+	    SendMessage16(hwndMDIClient, message, wParam, lParam);
 	    break;
 
 	  case WM_SETTEXT:
@@ -1217,14 +1195,84 @@
 	}
     }
     
-    return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
-/**********************************************************************
- *					DefMDIChildProc (USER.447)
- *
+
+/***********************************************************************
+ *           DefFrameProc32A   (USER32.121)
  */
-LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT DefFrameProc32A( HWND32 hwnd, HWND32 hwndMDIClient, UINT32 message, 
+                         WPARAM32 wParam, LPARAM lParam )
+{
+    if (hwndMDIClient)
+    {
+	switch (message)
+	{
+	  case WM_COMMAND:
+              return DefFrameProc16( hwnd, hwndMDIClient, message,
+                                     (WPARAM16)wParam,
+                              MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );
+
+	  case WM_NCACTIVATE:
+	    SendMessage32A(hwndMDIClient, message, wParam, lParam);
+	    break;
+
+	  case WM_SETTEXT:
+              return DefFrameProc16( hwnd, hwndMDIClient, message,
+                                     wParam, (LPARAM)PTR_SEG_TO_LIN(lParam) );
+	
+	  case WM_SETFOCUS:
+	  case WM_SIZE:
+              return DefFrameProc16( hwnd, hwndMDIClient, message,
+                                     wParam, lParam );
+	}
+    }
+    
+    return DefWindowProc32A(hwnd, message, wParam, lParam);
+}
+
+
+/***********************************************************************
+ *           DefFrameProc32W   (USER32.122)
+ */
+LRESULT DefFrameProc32W( HWND32 hwnd, HWND32 hwndMDIClient, UINT32 message, 
+                         WPARAM32 wParam, LPARAM lParam )
+{
+    if (hwndMDIClient)
+    {
+	switch (message)
+	{
+	  case WM_COMMAND:
+              return DefFrameProc16( hwnd, hwndMDIClient, message,
+                                     (WPARAM16)wParam,
+                              MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );
+
+	  case WM_NCACTIVATE:
+	    SendMessage32W(hwndMDIClient, message, wParam, lParam);
+	    break;
+
+	  case WM_SETTEXT:
+              /* FIXME: Unicode */
+              return DefFrameProc32A( hwnd, hwndMDIClient, message,
+                                     wParam, lParam );
+	
+	  case WM_SETFOCUS:
+	  case WM_SIZE:
+              return DefFrameProc32A( hwnd, hwndMDIClient, message,
+                                      wParam, lParam );
+	}
+    }
+    
+    return DefWindowProc32W( hwnd, message, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           DefMDIChildProc16   (USER.447)
+ */
+LRESULT DefMDIChildProc16( HWND16 hwnd, UINT16 message,
+                           WPARAM16 wParam, LPARAM lParam )
 {
     MDICLIENTINFO       *ci;
     WND                 *clientWnd;
@@ -1235,7 +1283,7 @@
     switch (message)
     {
       case WM_SETTEXT:
-	DefWindowProc(hwnd, message, wParam, lParam);
+	DefWindowProc16(hwnd, message, wParam, lParam);
 	MDI_MenuModifyItem(clientWnd,hwnd);
 	if( ci->hwndChildMaximized == hwnd )
 	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
@@ -1243,7 +1291,7 @@
         return 0;
 
       case WM_CLOSE:
-	SendMessage(ci->self,WM_MDIDESTROY,(WPARAM)hwnd,0L);
+	SendMessage16(ci->self,WM_MDIDESTROY,(WPARAM)hwnd,0L);
 	return 0;
 
       case WM_SETFOCUS:
@@ -1268,14 +1316,14 @@
 		     break;
 		case SC_MAXIMIZE:
 		     if( ci->hwndChildMaximized == hwnd) 
-			 return SendMessage( clientWnd->parent->hwndSelf,
+			 return SendMessage16( clientWnd->parent->hwndSelf,
                                              message, wParam, lParam);
 		     break;
 		case SC_NEXTWINDOW:
-		     SendMessage( ci->self, WM_MDINEXT, 0, 0);
+		     SendMessage16( ci->self, WM_MDINEXT, 0, 0);
 		     return 0;
 		case SC_PREVWINDOW:
-		     SendMessage( ci->self, WM_MDINEXT, 0, 1);
+		     SendMessage16( ci->self, WM_MDINEXT, 0, 1);
 		     return 0;
 	  }
 	break;
@@ -1311,12 +1359,12 @@
 
 	    if( hMaxChild)
 	      {	    
-	       SendMessage( hMaxChild, WM_SETREDRAW, FALSE, 0L );
+	       SendMessage16( hMaxChild, WM_SETREDRAW, FALSE, 0L );
 
 	       MDI_RestoreFrameMenu( clientWnd->parent, hMaxChild);
 	       ShowWindow( hMaxChild, SW_SHOWNOACTIVATE);
 
-	       SendMessage( hMaxChild, WM_SETREDRAW, TRUE, 0L );
+	       SendMessage16( hMaxChild, WM_SETREDRAW, TRUE, 0L );
 	      }
 
 	    ci->hwndChildMaximized = hwnd; /* !!! */
@@ -1331,7 +1379,7 @@
 	    HWND switchTo = MDI_GetWindow(clientWnd, hwnd, 0);
 
 	    if( switchTo )
-	        SendMessage( switchTo, WM_CHILDACTIVATE, 0, 0L);
+	        SendMessage16( switchTo, WM_CHILDACTIVATE, 0, 0L);
 	  }
 	  
 	MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
@@ -1350,9 +1398,100 @@
 	break;	
     }
 	
-    return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc16(hwnd, message, wParam, lParam);
 }
 
+
+/***********************************************************************
+ *           DefMDIChildProc32A   (USER32.123)
+ */
+LRESULT DefMDIChildProc32A( HWND32 hwnd, UINT32 message,
+                            WPARAM32 wParam, LPARAM lParam )
+{
+    MDICLIENTINFO       *ci;
+    WND                 *clientWnd;
+
+    clientWnd  = WIN_FindWndPtr(GetParent(hwnd));
+    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
+
+    switch (message)
+    {
+      case WM_SETTEXT:
+	DefWindowProc32A(hwnd, message, wParam, lParam);
+	MDI_MenuModifyItem(clientWnd,hwnd);
+	if( ci->hwndChildMaximized == hwnd )
+	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
+				 MDI_REPAINTFRAME, NULL );
+        return 0;
+
+      case WM_GETMINMAXINFO:
+        {
+            MINMAXINFO16 mmi;
+            STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)lParam, &mmi );
+            MDI_ChildGetMinMaxInfo( clientWnd, hwnd, &mmi );
+            STRUCT32_MINMAXINFO16to32( &mmi, (MINMAXINFO32 *)lParam );
+        }
+	return 0;
+
+      case WM_MENUCHAR:
+
+	/* MDI children don't have menus */
+	PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, 
+                     (WPARAM)SC_KEYMENU, (LPARAM)LOWORD(wParam) );
+	return 0x00010000L;
+
+      case WM_CLOSE:
+      case WM_SETFOCUS:
+      case WM_CHILDACTIVATE:
+      case WM_NCPAINT:
+      case WM_SYSCOMMAND:
+      case WM_SETVISIBLE:
+      case WM_SIZE:
+      case WM_NEXTMENU:
+          return DefMDIChildProc16( hwnd, message, (WPARAM16)wParam, lParam );
+    }
+    return DefWindowProc32A(hwnd, message, wParam, lParam);
+}
+
+
+/***********************************************************************
+ *           DefMDIChildProc32W   (USER32.124)
+ */
+LRESULT DefMDIChildProc32W( HWND32 hwnd, UINT32 message,
+                            WPARAM32 wParam, LPARAM lParam )
+{
+    MDICLIENTINFO       *ci;
+    WND                 *clientWnd;
+
+    clientWnd  = WIN_FindWndPtr(GetParent(hwnd));
+    ci         = (MDICLIENTINFO *) clientWnd->wExtra;
+
+    switch (message)
+    {
+      case WM_SETTEXT:
+	DefWindowProc32W(hwnd, message, wParam, lParam);
+	MDI_MenuModifyItem(clientWnd,hwnd);
+	if( ci->hwndChildMaximized == hwnd )
+	    MDI_UpdateFrameText( clientWnd->parent, ci->self,
+				 MDI_REPAINTFRAME, NULL );
+        return 0;
+
+      case WM_GETMINMAXINFO:
+      case WM_MENUCHAR:
+      case WM_CLOSE:
+      case WM_SETFOCUS:
+      case WM_CHILDACTIVATE:
+      case WM_NCPAINT:
+      case WM_SYSCOMMAND:
+      case WM_SETVISIBLE:
+      case WM_SIZE:
+      case WM_NEXTMENU:
+          return DefMDIChildProc32A( hwnd, message, (WPARAM16)wParam, lParam );
+    }
+    return DefWindowProc32W(hwnd, message, wParam, lParam);
+}
+
+
 /**********************************************************************
  *					TranslateMDISysAccel (USER.451)
  *
@@ -1392,7 +1531,7 @@
 
   dprintf_mdi(stddeb,"TranslateMDISysAccel: wParam = %04x\n", wParam);
 
-  SendMessage(ci->hwndActiveChild,WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
+  SendMessage16(ci->hwndActiveChild,WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam);
   return 1;
 }
 
diff --git a/windows/message.c b/windows/message.c
index f86d585..7e1799b 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -25,7 +25,8 @@
 /* #define DEBUG_MSG */
 #include "debug.h"
 
-#define HWND_BROADCAST  ((HWND)0xffff)
+#define HWND_BROADCAST16  ((HWND16)0xffff)
+#define HWND_BROADCAST32  ((HWND32)0xffffffff)
 
 extern BYTE* 	KeyStateTable;				 /* event.c */
 extern WPARAM	lastEventChar;				 /* event.c */
@@ -95,7 +96,7 @@
 
         if (msg->hwnd != GetActiveWindow() && msg->hwnd != GetDesktopWindow())
         {
-            LONG ret = SendMessage( msg->hwnd, WM_MOUSEACTIVATE, hwndTop,
+            LONG ret = SendMessage16( msg->hwnd, WM_MOUSEACTIVATE, hwndTop,
                                     MAKELONG( hittest, msg->message ) );
 
             if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
@@ -109,8 +110,8 @@
 
       /* Send the WM_SETCURSOR message */
 
-    SendMessage( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
-                 MAKELONG( hittest, msg->message ));
+    SendMessage16( msg->hwnd, WM_SETCURSOR, (WPARAM)msg->hwnd,
+                   MAKELONG( hittest, msg->message ));
     if (eatMsg) return FALSE;
 
       /* Check for double-click */
@@ -533,7 +534,7 @@
                                   0, 0, 0, flags, TRUE ))
 	    {
 		  /* No message present -> send ENTERIDLE and wait */
-		SendMessage( hwndOwner, WM_ENTERIDLE, code, (LPARAM)hwnd );
+		SendMessage16( hwndOwner, WM_ENTERIDLE, code, (LPARAM)hwnd );
 		MSG_PeekMessage( (MSG *)PTR_SEG_TO_LIN(msg),
                                  0, 0, 0, flags, FALSE );
 	    }
@@ -579,7 +580,6 @@
 }
 
 
-
 /***********************************************************************
  *           PostMessage   (USER.110)
  */
@@ -601,7 +601,7 @@
        return TRUE;
 #endif  /* CONFIG_IPC */
     
-    if (hwnd == HWND_BROADCAST)
+    if (hwnd == HWND_BROADCAST16)
     {
         dprintf_msg(stddeb,"PostMessage // HWND_BROADCAST !\n");
         for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
@@ -644,18 +644,18 @@
 
 
 /***********************************************************************
- *           SendMessage   (USER.111)
+ *           SendMessage16   (USER.111)
  */
-LRESULT SendMessage( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+LRESULT SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPARAM lParam)
 {
     WND * wndPtr;
-    LONG ret;
+    LRESULT ret;
     struct
     {
-	LPARAM lParam;
-	WPARAM wParam;
-	UINT wMsg;
-	HWND hWnd;
+	LPARAM   lParam;
+	WPARAM16 wParam;
+	UINT16   wMsg;
+	HWND16   hWnd;
     } msgstruct = { lParam, wParam, msg, hwnd };
 
 #ifdef CONFIG_IPC
@@ -663,7 +663,7 @@
     if (DDE_SendMessage(&DDE_msg)) return TRUE;
 #endif  /* CONFIG_IPC */
 
-    if (hwnd == HWND_BROADCAST)
+    if (hwnd == HWND_BROADCAST16)
     {
         dprintf_msg(stddeb,"SendMessage // HWND_BROADCAST !\n");
         for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
@@ -672,24 +672,96 @@
             {
                 dprintf_msg(stddeb,"BROADCAST Message to hWnd=%04x m=%04X w=%04lX l=%08lX !\n",
                             wndPtr->hwndSelf, msg, (DWORD)wParam, lParam);
-                ret |= SendMessage( wndPtr->hwndSelf, msg, wParam, lParam );
+                SendMessage16( wndPtr->hwndSelf, msg, wParam, lParam );
 	    }
         }
         dprintf_msg(stddeb,"SendMessage // End of HWND_BROADCAST !\n");
         return TRUE;
     }
 
-    SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wParam, lParam );
+    HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
+                    (LPARAM)MAKE_SEGPTR(&msgstruct) );
+    hwnd   = msgstruct.hWnd;
+    msg    = msgstruct.wMsg;
+    wParam = msgstruct.wParam;
+    lParam = msgstruct.lParam;
 
-    HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)MAKE_SEGPTR(&msgstruct) );
+    SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) 
     {
-        SPY_ExitMessage( SPY_RESULT_INVALIDHWND, hwnd, msg, 0 );
+        SPY_ExitMessage( SPY_RESULT_INVALIDHWND16, hwnd, msg, 0 );
         return 0;
     }
-    ret = CallWindowProc16(wndPtr->lpfnWndProc, msgstruct.hWnd, msgstruct.wMsg,
-                           msgstruct.wParam, msgstruct.lParam );
-    SPY_ExitMessage( SPY_RESULT_OK, hwnd, msg, ret );
+    ret = CallWindowProc16( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam );
+    SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, ret );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SendMessage32A   (USER32.453)
+ */
+LRESULT SendMessage32A(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+{
+    WND * wndPtr;
+    LRESULT ret;
+
+    if (hwnd == HWND_BROADCAST32)
+    {
+        for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+        {
+            /* FIXME: should use something like EnumWindows here */
+            if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
+                SendMessage32A( wndPtr->hwndSelf, msg, wParam, lParam );
+        }
+        return TRUE;
+    }
+
+    /* FIXME: call hooks */
+
+    SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) 
+    {
+        SPY_ExitMessage( SPY_RESULT_INVALIDHWND32, hwnd, msg, 0 );
+        return 0;
+    }
+    ret = CallWindowProc32A( (WNDPROC32)wndPtr->lpfnWndProc,
+                             hwnd, msg, wParam, lParam );
+    SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SendMessage32W   (USER32.458)
+ */
+LRESULT SendMessage32W(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+{
+    WND * wndPtr;
+    LRESULT ret;
+
+    if (hwnd == HWND_BROADCAST32)
+    {
+        for (wndPtr = WIN_GetDesktop()->child; wndPtr; wndPtr = wndPtr->next)
+        {
+            /* FIXME: should use something like EnumWindows here */
+            if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
+                SendMessage32W( wndPtr->hwndSelf, msg, wParam, lParam );
+        }
+        return TRUE;
+    }
+
+    /* FIXME: call hooks */
+
+    SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) 
+    {
+        SPY_ExitMessage( SPY_RESULT_INVALIDHWND32, hwnd, msg, 0 );
+        return 0;
+    }
+    ret = CallWindowProc32W( (WNDPROC32)wndPtr->lpfnWndProc,
+                             hwnd, msg, wParam, lParam );
+    SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
     return ret;
 }
 
@@ -765,9 +837,6 @@
     LONG retval;
     int painting;
     
-    SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
-                      msg->wParam, msg->lParam );
-
       /* Process timer messages */
     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
     {
@@ -785,8 +854,13 @@
     painting = (msg->message == WM_PAINT);
     if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
 /*    HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+
+    SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message,
+                      msg->wParam, msg->lParam );
     retval = CallWindowProc16( wndPtr->lpfnWndProc, msg->hwnd, msg->message,
                                msg->wParam, msg->lParam );
+    SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval );
+
     if (painting && (wndPtr = WIN_FindWndPtr( msg->hwnd )) &&
         (wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
     {
diff --git a/windows/msgbox.c b/windows/msgbox.c
index d1bbae4..dc33193 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -31,10 +31,8 @@
   switch(message) {
    case WM_INITDIALOG:
     lpmb = (LPMSGBOX)lParam;
-    if (lpmb->title != NULL) {
-      SetWindowText(hwnd, lpmb->title);
-    }
-    SetWindowText(GetDlgItem(hwnd, 100), lpmb->text);
+    if (lpmb->title) SetWindowText32A(hwnd, lpmb->title);
+    SetWindowText32A(GetDlgItem(hwnd, 100), lpmb->text);
     /* Hide not selected buttons */
     switch(lpmb->type & MB_TYPEMASK) {
      case MB_OK:
@@ -66,21 +64,21 @@
     /* Set the icon */
     switch(lpmb->type & MB_ICONMASK) {
      case MB_ICONEXCLAMATION:
-      SendDlgItemMessage(hwnd, stc1, STM_SETICON, 
-			 (WPARAM)LoadIcon(0, IDI_EXCLAMATION), 0);
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+                           (WPARAM)LoadIcon(0, IDI_EXCLAMATION), 0);
       break;
      case MB_ICONQUESTION:
-      SendDlgItemMessage(hwnd, stc1, STM_SETICON, 
-			 (WPARAM)LoadIcon(0, IDI_QUESTION), 0);
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+                           (WPARAM)LoadIcon(0, IDI_QUESTION), 0);
       break;
      case MB_ICONASTERISK:
-      SendDlgItemMessage(hwnd, stc1, STM_SETICON, 
-			 (WPARAM)LoadIcon(0, IDI_ASTERISK), 0);
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+                           (WPARAM)LoadIcon(0, IDI_ASTERISK), 0);
       break;
      case MB_ICONHAND:
      default:
-      SendDlgItemMessage(hwnd, stc1, STM_SETICON, 
-			 (WPARAM)LoadIcon(0, IDI_HAND), 0);
+      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
+                           (WPARAM)LoadIcon(0, IDI_HAND), 0);
       break;
     }
     
@@ -146,7 +144,7 @@
       if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
 	if (buttons++ == ((lpmb->type & MB_DEFMASK) >> 8)) {
 	  SetFocus(hItem);
-	  SendMessage(hItem, BM_SETSTYLE16, BS_DEFPUSHBUTTON, TRUE);
+	  SendMessage32A( hItem, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
 	}
 	SetWindowPos(hItem, 0, bpos, tiheight, 0, 0,
 		     SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 0be13a8..37a916f 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -202,7 +202,7 @@
         MinMax->ptMaxPosition.y = -yinc;
     }
 
-    SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)SEGPTR_GET(MinMax) );
+    SendMessage16( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)SEGPTR_GET(MinMax) );
 
       /* Some sanity checks */
 
@@ -230,23 +230,21 @@
  *
  * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
  */
-LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS16 *params )
+LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect )
 {
     RECT16 tmpRect = { 0, 0, 0, 0 };
-    WND *wndPtr = WIN_FindWndPtr( hwnd );    
 
-    if (!wndPtr) return 0;
-    NC_AdjustRect( &tmpRect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle );
-    params->rgrc[0].left   -= tmpRect.left;
-    params->rgrc[0].top    -= tmpRect.top;
-    params->rgrc[0].right  -= tmpRect.right;
-    params->rgrc[0].bottom -= tmpRect.bottom;
+    NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
+    winRect->left   -= tmpRect.left;
+    winRect->top    -= tmpRect.top;
+    winRect->right  -= tmpRect.right;
+    winRect->bottom -= tmpRect.bottom;
 
-    if (HAS_MENU(wndPtr))
+    if (HAS_MENU(pWnd))
     {
-	params->rgrc[0].top += MENU_GetMenuBarHeight( hwnd,
-				  params->rgrc[0].right - params->rgrc[0].left,
-				  -tmpRect.left, -tmpRect.top ) + 1;
+	winRect->top += MENU_GetMenuBarHeight( pWnd->hwndSelf,
+                                               winRect->right - winRect->left,
+                                             -tmpRect.left, -tmpRect.top ) + 1;
     }
     return 0;
 }
@@ -635,7 +633,7 @@
     FillRect16( hdc, &r, active ? sysColorObjects.hbrushActiveCaption : 
 	                          sysColorObjects.hbrushInactiveCaption );
 
-    if (GetWindowText( hwnd, buffer, 256 ))
+    if (GetWindowText32A( hwnd, buffer, sizeof(buffer) ))
     {
 	if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
 	else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
@@ -676,7 +674,7 @@
     {
         if (wndPtr->class->hIcon)
         {
-            SendMessage(hwnd, WM_ICONERASEBKGND, (WPARAM)hdc, 0);
+            SendMessage16(hwnd, WM_ICONERASEBKGND, (WPARAM)hdc, 0);
             DrawIcon( hdc, 0, 0, wndPtr->class->hIcon );
         }
         ReleaseDC(hwnd, hdc);
@@ -1028,7 +1026,7 @@
 	mouseRect.top    = MAX( mouseRect.top, sizingRect.top+minTrack.y );
 	mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
     }
-    SendMessage( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
+    SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
 
     if (GetCapture() != hwnd) SetCapture( hwnd );    
 
@@ -1108,8 +1106,8 @@
 	ReleaseDC( 0, hdc );
 	if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display );
     }
-    SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 );
-    SendMessage( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
+    SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
+    SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
 
     /* Single click brings up the system menu when iconized */
 
@@ -1168,9 +1166,9 @@
     if (!pressed) return;
 
     if (wParam == HTMINBUTTON) 
-	SendMessage( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&msg.pt );
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&msg.pt );
     else
-	SendMessage( hwnd, WM_SYSCOMMAND, 
+	SendMessage16( hwnd, WM_SYSCOMMAND, 
 		  IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, *(LONG*)&msg.pt );
 }
 
@@ -1243,7 +1241,7 @@
     switch(wParam)  /* Hit test */
     {
     case HTCAPTION:
-	SendMessage( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
 	break;
 
     case HTSYSMENU:
@@ -1251,15 +1249,15 @@
 	break;
 
     case HTMENU:
-	SendMessage( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
 	break;
 
     case HTHSCROLL:
-	SendMessage( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
 	break;
 
     case HTVSCROLL:
-	SendMessage( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
 	break;
 
     case HTMINBUTTON:
@@ -1275,7 +1273,7 @@
     case HTBOTTOM:
     case HTBOTTOMLEFT:
     case HTBOTTOMRIGHT:
-	SendMessage( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - HTLEFT+1, lParam);
+	SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - HTLEFT+1, lParam);
 	break;
 
     case HTBORDER:
@@ -1300,7 +1298,7 @@
      */
     if (pWnd->dwStyle & WS_MINIMIZE)
     {
-        SendMessage( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
+        SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
         return 0;
     } 
 
@@ -1309,14 +1307,14 @@
     case HTCAPTION:
         /* stop processing if WS_MAXIMIZEBOX is missing */
         if (pWnd->dwStyle & WS_MAXIMIZEBOX)
-            SendMessage( pWnd->hwndSelf, WM_SYSCOMMAND,
+            SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
                       (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
                       lParam );
 	break;
 
     case HTSYSMENU:
         if (!(pWnd->class->style & CS_NOCLOSE))
-            SendMessage( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
+            SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
 	break;
     }
     return 0;
@@ -1362,7 +1360,7 @@
 	break;
 
     case SC_CLOSE:
-	return SendMessage( hwnd, WM_CLOSE, 0, 0 );
+	return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
 
     case SC_VSCROLL:
     case SC_HSCROLL:
diff --git a/windows/painting.c b/windows/painting.c
index 15eb8ad..10bdb97 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -76,7 +76,7 @@
         hClip = 1;
     }
 
-    if (hClip) SendMessage( wnd->hwndSelf, WM_NCPAINT, hClip, 0L );
+    if (hClip) SendMessage16( wnd->hwndSelf, WM_NCPAINT, hClip, 0L );
 
     if (hClip > 1) DeleteObject( hClip );
 }
@@ -119,7 +119,7 @@
     if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
     {
         wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
-        lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, (WPARAM)lps->hdc, 0 );
+        lps->fErase = !SendMessage16(hwnd, WM_ERASEBKGND, (WPARAM)lps->hdc, 0);
     }
     else lps->fErase = TRUE;
 
@@ -193,12 +193,12 @@
     {
 	if (!hwndParent) return;
 #ifdef WINELIB32
-	hbrush = (HBRUSH)SendMessage( hwndParent, 
-				      WM_CTLCOLORMSGBOX+(DWORD)hbrush,
-				      (WPARAM)hdc, (LPARAM)hwnd );
+	hbrush = (HBRUSH)SendMessage32A( hwndParent, 
+                                         WM_CTLCOLORMSGBOX+(DWORD)hbrush,
+                                         (WPARAM)hdc, (LPARAM)hwnd );
 #else
-	hbrush = (HBRUSH)SendMessage( hwndParent, WM_CTLCOLOR,
-				      hdc, MAKELONG( hwnd, hbrush ) );
+	hbrush = (HBRUSH)SendMessage16( hwndParent, WM_CTLCOLOR,
+                                        hdc, MAKELONG( hwnd, hbrush ) );
 #endif
     }
     if (hbrush) FillRect16( hdc, rect, hbrush );
@@ -211,11 +211,11 @@
 HBRUSH GetControlBrush( HWND hwnd, HDC hdc, WORD control )
 {
 #ifdef WINELIB32
-    return (HBRUSH)SendMessage( GetParent(hwnd), WM_CTLCOLOR+control,
-                                (WPARAM)hdc, (LPARAM)hwnd );
+    return (HBRUSH)SendMessage32A( GetParent(hwnd), WM_CTLCOLOR+control,
+                                   (WPARAM)hdc, (LPARAM)hwnd );
 #else
-    return (HBRUSH)SendMessage( GetParent(hwnd), WM_CTLCOLOR,
-                                hdc, MAKELONG( hwnd, control ) );
+    return (HBRUSH)SendMessage16( GetParent(hwnd), WM_CTLCOLOR,
+                                  hdc, MAKELONG( hwnd, control ) );
 #endif
 }
 
@@ -338,7 +338,7 @@
 
     if (flags & RDW_UPDATENOW)
     {
-        if (wndPtr->hrgnUpdate) SendMessage( hwnd, WM_PAINT, 0, 0 );
+        if (wndPtr->hrgnUpdate) SendMessage16( hwnd, WM_PAINT, 0, 0 );
     }
     else if (flags & RDW_ERASENOW)
     {
@@ -356,7 +356,7 @@
                 if (!(wndPtr->dwStyle & WS_MINIMIZE) ||
                     !wndPtr->class->hIcon)
                 {
-                    if (SendMessage( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 ))
+                    if (SendMessage16( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 ))
                         wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
                 }
                 ReleaseDC( hwnd, hdc );
diff --git a/windows/win.c b/windows/win.c
index 5dfb105..51e419c 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -27,6 +27,7 @@
 #include "shm_main_blk.h"
 #include "dde_proc.h"
 #include "callback.h"
+#include "winproc.h"
 #include "stddebug.h"
 /* #define DEBUG_WIN  */ 
 /* #define DEBUG_MENU */
@@ -89,14 +90,14 @@
     fprintf( stderr,
              "next=%p  child=%p  parent=%p  owner=%p  class=%p '%s'\n"
              "inst=%04x  taskQ=%04x  updRgn=%04x  active=%04x hdce=%04x  idmenu=%04x\n"
-             "style=%08lx  exstyle=%08lx  wndproc=%08lx  text=%04x '%s'\n"
+             "style=%08lx  exstyle=%08lx  wndproc=%08lx  text='%s'\n"
              "client=%d,%d-%d,%d  window=%d,%d-%d,%d  iconpos=%d,%d  maxpos=%d,%d\n"
              "sysmenu=%04x  flags=%04x  props=%04x  vscroll=%04x  hscroll=%04x\n",
              ptr->next, ptr->child, ptr->parent, ptr->owner,
              ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
              ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
-             ptr->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc, ptr->hText,
-             ptr->hText ? (char*)USER_HEAP_LIN_ADDR(ptr->hText) : "",
+             ptr->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc,
+             ptr->text ? ptr->text : "",
              ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
              ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
              ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
@@ -292,16 +293,31 @@
 
         wndPtr = wndPtr->parent;
 #ifdef WINELIB32
-	SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY, 
-		     MAKEWPARAM( event, idChild ), lValue );
+	SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY, 
+                        MAKEWPARAM( event, idChild ), lValue );
 #else
-	SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue);
+	SendMessage16( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue);
 #endif
     }
 }
 
 
 /***********************************************************************
+ *           WIN_SetWndProc
+ *
+ * Set the window procedure and return the old one.
+ */
+static WNDPROC16 WIN_SetWndProc(WND *pWnd, WNDPROC16 proc, WINDOWPROCTYPE type)
+{
+    WNDPROC16 oldProc = pWnd->lpfnWndProc;
+    if (type == WIN_PROC_16) pWnd->lpfnWndProc = proc;
+    else pWnd->lpfnWndProc = WINPROC_AllocWinProc( (WNDPROC32)proc, type );
+    WINPROC_FreeWinProc( oldProc );
+    return oldProc;
+}
+
+
+/***********************************************************************
  *           WIN_DestroyWindow
  *
  * Destroy storage associated to a window
@@ -331,6 +347,7 @@
     if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
     if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
     if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
+    WIN_SetWndProc( wndPtr, (WNDPROC16)0, WIN_PROC_16 );
     wndPtr->class->cWindows--;
     USER_HEAP_FREE( hwnd );
 }
@@ -389,10 +406,11 @@
     pWndDesktop->ptIconPos.y       = -1;
     pWndDesktop->ptMaxPos.x        = -1;
     pWndDesktop->ptMaxPos.y        = -1;
+    pWndDesktop->text              = NULL;
     pWndDesktop->hmemTaskQ         = 0; /* Desktop does not belong to a task */
     pWndDesktop->hrgnUpdate        = 0;
     pWndDesktop->hwndLastActive    = hwndDesktop;
-    pWndDesktop->lpfnWndProc       = class->lpfnWndProc;
+    pWndDesktop->lpfnWndProc       = (WNDPROC16)0;
     pWndDesktop->dwStyle           = WS_VISIBLE | WS_CLIPCHILDREN |
                                      WS_CLIPSIBLINGS;
     pWndDesktop->dwExStyle         = 0;
@@ -400,16 +418,17 @@
     pWndDesktop->hVScroll          = 0;
     pWndDesktop->hHScroll          = 0;
     pWndDesktop->wIDmenu           = 0;
-    pWndDesktop->hText             = 0;
     pWndDesktop->flags             = 0;
     pWndDesktop->window            = rootWindow;
     pWndDesktop->hSysMenu          = 0;
     pWndDesktop->hProp             = 0;
+    WIN_SetWndProc( pWndDesktop, class->lpfnWndProc,
+                    WINPROC_GetWinProcType(class->lpfnWndProc) );
     EVENT_RegisterWindow( pWndDesktop->window, hwndDesktop );
-    SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
+    SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
     if ((hdc = GetDC( hwndDesktop )) != 0)
     {
-        SendMessage( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
+        SendMessage32A( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
         ReleaseDC( hwndDesktop, hdc );
     }
     return TRUE;
@@ -421,11 +440,9 @@
  *
  * Implementation of CreateWindowEx().
  */
-static HWND WIN_CreateWindowEx( DWORD exStyle, ATOM classAtom,
-                                SEGPTR windowName, DWORD style, INT16 x,
-                                INT16 y, INT16 width, INT16 height,
-                                HWND parent, HMENU menu, HINSTANCE16 instance,
-                                SEGPTR data ) 
+static HWND WIN_CreateWindowEx( DWORD exStyle, ATOM classAtom, DWORD style,
+                                INT16 x, INT16 y, INT16 width, INT16 height,
+                                HWND parent, HMENU menu, HINSTANCE16 instance )
 {
     CLASS *classPtr;
     WND *wndPtr;
@@ -497,14 +514,14 @@
     wndPtr->ptIconPos.y    = -1;
     wndPtr->ptMaxPos.x     = -1;
     wndPtr->ptMaxPos.y     = -1;
+    wndPtr->text           = NULL;
     wndPtr->hmemTaskQ      = GetTaskQueue(0);
     wndPtr->hrgnUpdate     = 0;
     wndPtr->hwndLastActive = hwnd;
-    wndPtr->lpfnWndProc    = classPtr->lpfnWndProc;
+    wndPtr->lpfnWndProc    = (WNDPROC16)0;
     wndPtr->dwStyle        = style & ~WS_VISIBLE;
     wndPtr->dwExStyle      = exStyle;
     wndPtr->wIDmenu        = 0;
-    wndPtr->hText          = 0;
     wndPtr->flags          = 0;
     wndPtr->hVScroll       = 0;
     wndPtr->hHScroll       = 0;
@@ -512,7 +529,6 @@
     wndPtr->hProp          = 0;
 
     if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
-    if (classPtr->flags & CLASS_FLAG_UNICODE) wndPtr->flags |= WIN_UNICODE;
     classPtr->cWindows++;
 
     /* Correct the window style */
@@ -530,6 +546,11 @@
     else if (classPtr->style & CS_CLASSDC) wndPtr->hdce = classPtr->hdce;
     else wndPtr->hdce = 0;
 
+    /* Set the window procedure */
+
+    WIN_SetWndProc( wndPtr, classPtr->lpfnWndProc,
+                    WINPROC_GetWinProcType(classPtr->lpfnWndProc) );
+
     /* Insert the window in the linked list */
 
     WIN_LinkWindow( hwnd, HWND_TOP );
@@ -625,6 +646,56 @@
 
 
 /***********************************************************************
+ *           WIN_FinalWindowInit
+ */
+static HWND WIN_FinalWindowInit( WND *wndPtr, DWORD style )
+{
+    if (!(wndPtr->flags & WIN_NEED_SIZE))
+    {
+	/* send it anyway */
+	SendMessage16( wndPtr->hwndSelf, WM_SIZE, SIZE_RESTORED,
+		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
+                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
+        SendMessage16( wndPtr->hwndSelf, WM_MOVE, 0,
+                   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
+    } 
+
+    WIN_SendParentNotify( wndPtr->hwndSelf, WM_CREATE, wndPtr->wIDmenu,
+                          (LONG)wndPtr->hwndSelf );
+    if (!IsWindow(wndPtr->hwndSelf)) return 0;
+
+    /* Show the window, maximizing or minimizing if needed */
+
+    if (wndPtr->dwStyle & WS_MINIMIZE)
+    {
+        wndPtr->dwStyle &= ~WS_MAXIMIZE;
+        WINPOS_FindIconPos( wndPtr->hwndSelf );
+        SetWindowPos(wndPtr->hwndSelf, 0, wndPtr->ptIconPos.x,
+                     wndPtr->ptIconPos.y, SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+                     SWP_FRAMECHANGED |
+                     (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
+    }
+    else if (wndPtr->dwStyle & WS_MAXIMIZE)
+    {
+        POINT16 maxSize, maxPos, minTrack, maxTrack;
+        NC_GetMinMaxInfo( wndPtr->hwndSelf, &maxSize, &maxPos,
+                          &minTrack, &maxTrack );
+        SetWindowPos( wndPtr->hwndSelf, 0, maxPos.x, maxPos.y, maxSize.x,
+                      maxSize.y, SWP_FRAMECHANGED |
+                      (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
+    }
+    else if (style & WS_VISIBLE) ShowWindow( wndPtr->hwndSelf, SW_SHOW );
+
+    /* Call WH_SHELL hook */
+
+    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
+        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, wndPtr->hwndSelf, 0 );
+
+    return wndPtr->hwndSelf;
+}
+
+
+/***********************************************************************
  *           CreateWindow16   (USER.41)
  */
 HWND16 CreateWindow16( SEGPTR className, SEGPTR windowName,
@@ -649,7 +720,6 @@
     HWND16 hwnd;
     WND *wndPtr;
     LRESULT wmcreate;
-    CREATESTRUCT16 *cs;
 
     dprintf_win( stddeb, "CreateWindowEx: " );
     if (HIWORD(windowName))
@@ -675,54 +745,69 @@
         return 0;
     }
 
-    hwnd = WIN_CreateWindowEx( exStyle, classAtom, windowName, style, x, y,
-                               width, height, parent, menu, instance, data );
+    hwnd = WIN_CreateWindowEx( exStyle, classAtom, style, x, y, width, height,
+                               parent, menu, instance );
     if (!hwnd) return 0;
     wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
 
       /* Send the WM_CREATE message */
 
-    if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) wmcreate = -1;  /* abort */
-    else
+#ifndef WINELIB
+    if (WINPROC_GetWinProcType( wndPtr->lpfnWndProc ) == WIN_PROC_16)
     {
-        cs->lpCreateParams = (LPSTR)data;
-        cs->hInstance      = wndPtr->hInstance;
-        cs->hMenu          = wndPtr->wIDmenu;
-        cs->hwndParent     = parent;
-        cs->cx             = wndPtr->rectWindow.right-wndPtr->rectWindow.left;
-        cs->cy             = wndPtr->rectWindow.bottom-wndPtr->rectWindow.top;
-        cs->x              = wndPtr->rectWindow.left;
-        cs->y              = wndPtr->rectWindow.top;
-        cs->style          = wndPtr->dwStyle | (style & WS_VISIBLE);
-        cs->lpszName       = windowName;
-        cs->lpszClass      = className;
-        cs->dwExStyle      = wndPtr->dwExStyle;
-
-        wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LPARAM)SEGPTR_GET(cs) );
-        if (!wmcreate)
-        {
-            dprintf_win(stddeb,"CreateWindowEx: WM_NCCREATE return 0\n");
+        /* Build the CREATESTRUCT on the 16-bit stack. */
+        /* This is really ugly, but some programs (notably the */
+        /* "Undocumented Windows" examples) want it that way.  */
+        if (!CallWndProcNCCREATE16( wndPtr->lpfnWndProc, wndPtr->hInstance,
+                  wndPtr->dwExStyle, className, windowName, wndPtr->dwStyle,
+                  wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+                  wndPtr->rectWindow.right - wndPtr->rectWindow.left,
+                  wndPtr->rectWindow.bottom - wndPtr->rectWindow.top,
+                  parent, menu, wndPtr->hInstance, data, hwnd, WM_NCCREATE, 0,
+                  MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
+                            IF1632_Saved16_ss ) ))
             wmcreate = -1;
-        }
         else
         {
             WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
                                    NULL, NULL, 0, &wndPtr->rectClient );
-            wmcreate = SendMessage(hwnd, WM_CREATE, 0, (LPARAM)SEGPTR_GET(cs));
+            wmcreate = CallWndProcNCCREATE16( wndPtr->lpfnWndProc,
+                   wndPtr->hInstance, wndPtr->dwExStyle, className,
+                   windowName, wndPtr->dwStyle,
+                   wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+                   wndPtr->rectWindow.right - wndPtr->rectWindow.left,
+                   wndPtr->rectWindow.bottom - wndPtr->rectWindow.top,
+                   parent, menu, wndPtr->hInstance, data, hwnd, WM_CREATE, 0,
+                   MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
+                             IF1632_Saved16_ss ) );
         }
-        SEGPTR_FREE(cs);
+    }
+    else  /* We have a 32-bit window procedure */
+#endif  /* WINELIB */
+    {
+        CREATESTRUCT32A cs;
+        cs.lpCreateParams = (LPVOID)data;
+        cs.hInstance      = wndPtr->hInstance;
+        cs.hMenu          = wndPtr->wIDmenu;
+        cs.hwndParent     = parent;
+        cs.cx             = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+        cs.cy             = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+        cs.x              = wndPtr->rectWindow.left;
+        cs.y              = wndPtr->rectWindow.top;
+        cs.style          = wndPtr->dwStyle | (style & WS_VISIBLE);
+        cs.lpszName       = PTR_SEG_TO_LIN(windowName);
+        cs.lpszClass      = PTR_SEG_TO_LIN(className);
+        cs.dwExStyle      = wndPtr->dwExStyle;
+
+        if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)&cs)) wmcreate = -1;
+        else
+        {
+            WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
+                                   NULL, NULL, 0, &wndPtr->rectClient );
+            wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)&cs );
+        }
     }
     
-    if (!(wndPtr->flags & WIN_NEED_SIZE))
-    {
-	/* send it anyway */
-	SendMessage( hwnd, WM_SIZE, SIZE_RESTORED,                      
-		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-        SendMessage( hwnd, WM_MOVE, 0,
-                   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
-    } 
-
     if (wmcreate == -1)
     {
 	  /* Abort window creation */
@@ -731,42 +816,13 @@
 	return 0;
     }
 
-    WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
-    if (!IsWindow(hwnd)) return 0;
-
-    /* Show the window, maximizing or minimizing if needed */
-
-    if (wndPtr->dwStyle & WS_MINIMIZE)
-    {
-        wndPtr->dwStyle &= ~WS_MAXIMIZE;
-        WINPOS_FindIconPos( hwnd );
-        SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
-                      SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                      SWP_FRAMECHANGED |
-                      (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
-    }
-    else if (wndPtr->dwStyle & WS_MAXIMIZE)
-    {
-        POINT16 maxSize, maxPos, minTrack, maxTrack;
-        NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
-        SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
-                      SWP_FRAMECHANGED |
-                      (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
-    }
-    else if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
-
-    /* Call WH_SHELL hook */
-
-    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
-        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
-
-    dprintf_win(stddeb, "CreateWindowEx: return %04x\n", hwnd);
-    return hwnd;
+    dprintf_win(stddeb, "CreateWindowEx16: return %04x\n", hwnd);
+    return WIN_FinalWindowInit( wndPtr, style );
 }
 
 
 /***********************************************************************
- *           CreateWindowEx32A   (USER.452)
+ *           CreateWindowEx32A   (USER32.82)
  */
 HWND32 CreateWindowEx32A( DWORD exStyle, LPCSTR className, LPCSTR windowName,
                           DWORD style, INT32 x, INT32 y, INT32 width,
@@ -777,8 +833,7 @@
     HWND16 hwnd;
     WND *wndPtr;
     LRESULT wmcreate;
-    CREATESTRUCT16 *cs;
-    char *clsName, *winName;
+    CREATESTRUCT32A cs;
 
     /* Find the class atom */
 
@@ -786,7 +841,7 @@
     {
         fprintf( stderr, "CreateWindowEx32A: bad class name " );
         if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
-        else fprintf( stderr, "'%s'\n", (char *)PTR_SEG_TO_LIN(className) );
+        else fprintf( stderr, "'%s'\n", className );
         return 0;
     }
 
@@ -795,100 +850,116 @@
     if (x == CW_USEDEFAULT32) x = y = (UINT32)CW_USEDEFAULT16;
     if (width == CW_USEDEFAULT32) width = height = (UINT32)CW_USEDEFAULT16;
 
-    clsName = SEGPTR_STRDUP( className );
-    winName = SEGPTR_STRDUP( windowName );
-
     /* Create the window structure */
 
-    hwnd = WIN_CreateWindowEx( exStyle, classAtom, SEGPTR_GET(winName), style,
-                           x, y, width, height, parent, menu, instance, data );
+    hwnd = WIN_CreateWindowEx( exStyle, classAtom, style, x, y, width, height,
+                               parent, menu, instance );
     if (!hwnd) return 0;
     wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
 
-      /* Send the WM_CREATE message */
+    /* Send the WM_CREATE message */
 
-    if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) wmcreate = -1;  /* abort */
+    cs.lpCreateParams = data;
+    cs.hInstance      = wndPtr->hInstance;
+    cs.hMenu          = wndPtr->wIDmenu;
+    cs.hwndParent     = parent;
+    cs.cx             = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+    cs.cy             = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+    cs.x              = wndPtr->rectWindow.left;
+    cs.y              = wndPtr->rectWindow.top;
+    cs.style          = wndPtr->dwStyle | (style & WS_VISIBLE);
+    cs.lpszName       = windowName;
+    cs.lpszClass      = className;
+    cs.dwExStyle      = wndPtr->dwExStyle;
+
+    if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)&cs )) wmcreate = -1;
     else
     {
-        cs->lpCreateParams = (LPSTR)data;
-        cs->hInstance      = wndPtr->hInstance;
-        cs->hMenu          = wndPtr->wIDmenu;
-        cs->hwndParent     = parent;
-        cs->cx             = wndPtr->rectWindow.right-wndPtr->rectWindow.left;
-        cs->cy             = wndPtr->rectWindow.bottom-wndPtr->rectWindow.top;
-        cs->x              = wndPtr->rectWindow.left;
-        cs->y              = wndPtr->rectWindow.top;
-        cs->style          = wndPtr->dwStyle | (style & WS_VISIBLE);
-        cs->lpszName       = SEGPTR_GET(winName);
-        cs->lpszClass      = SEGPTR_GET(clsName);
-        cs->dwExStyle      = wndPtr->dwExStyle;
-
-        wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LPARAM)SEGPTR_GET(cs) );
-        if (!wmcreate)
-        {
-            dprintf_win(stddeb,"CreateWindowEx: WM_NCCREATE return 0\n");
-            wmcreate = -1;
-        }
-        else
-        {
-            WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
-                                   NULL, NULL, 0, &wndPtr->rectClient );
-            wmcreate = SendMessage(hwnd, WM_CREATE, 0, (LPARAM)SEGPTR_GET(cs));
-        }
-        SEGPTR_FREE(cs);
-        SEGPTR_FREE(clsName);
-        SEGPTR_FREE(winName);
+        WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
+                               NULL, NULL, 0, &wndPtr->rectClient );
+        wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)&cs );
     }
 
-    if (!(wndPtr->flags & WIN_NEED_SIZE))
-    {
-	/* send it anyway */
-	SendMessage( hwnd, WM_SIZE, SIZE_RESTORED,                      
-		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-                            wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-        SendMessage( hwnd, WM_MOVE, 0,
-                   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
-    } 
-
     if (wmcreate == -1)
     {
 	  /* Abort window creation */
-	dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
+	dprintf_win(stddeb,"CreateWindowEx32A: wmcreate==-1, aborting\n");
         WIN_DestroyWindow( hwnd );
 	return 0;
     }
 
-    WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
-    if (!IsWindow(hwnd)) return 0;
+    dprintf_win(stddeb, "CreateWindowEx32A: return %04x\n", hwnd);
+    return WIN_FinalWindowInit( wndPtr, style );
+}
 
-    /* Show the window, maximizing or minimizing if needed */
 
-    if (wndPtr->dwStyle & WS_MINIMIZE)
+/***********************************************************************
+ *           CreateWindowEx32W   (USER32.83)
+ */
+HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
+                          DWORD style, INT32 x, INT32 y, INT32 width,
+                          INT32 height, HWND32 parent, HMENU32 menu,
+                          HINSTANCE32 instance, LPVOID data )
+{
+    ATOM classAtom;
+    HWND16 hwnd;
+    WND *wndPtr;
+    LRESULT wmcreate;
+    CREATESTRUCT32W cs;
+
+    /* Find the class atom */
+
+    if (!(classAtom = GlobalFindAtom32W( className )))
     {
-        wndPtr->dwStyle &= ~WS_MAXIMIZE;
-        WINPOS_FindIconPos( hwnd );
-        SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
-                      SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                      SWP_FRAMECHANGED |
-                      (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
+        fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
+        return 0;
     }
-    else if (wndPtr->dwStyle & WS_MAXIMIZE)
+
+    /* Fix the coordinates */
+
+    if (x == CW_USEDEFAULT32) x = y = (UINT32)CW_USEDEFAULT16;
+    if (width == CW_USEDEFAULT32) width = height = (UINT32)CW_USEDEFAULT16;
+
+    /* Create the window structure */
+
+    hwnd = WIN_CreateWindowEx( exStyle, classAtom, style, x, y, width, height,
+                               parent, menu, instance );
+    if (!hwnd) return 0;
+    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
+
+    /* Send the WM_CREATE message */
+
+    cs.lpCreateParams = data;
+    cs.hInstance      = wndPtr->hInstance;
+    cs.hMenu          = wndPtr->wIDmenu;
+    cs.hwndParent     = parent;
+    cs.cx             = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+    cs.cy             = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+    cs.x              = wndPtr->rectWindow.left;
+    cs.y              = wndPtr->rectWindow.top;
+    cs.style          = wndPtr->dwStyle | (style & WS_VISIBLE);
+    cs.lpszName       = windowName;
+    cs.lpszClass      = className;
+    cs.dwExStyle      = wndPtr->dwExStyle;
+
+    if (!SendMessage32W( hwnd, WM_NCCREATE, 0, (LPARAM)&cs )) wmcreate = -1;
+    else
     {
-        POINT16 maxSize, maxPos, minTrack, maxTrack;
-        NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
-        SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
-                      SWP_FRAMECHANGED |
-                      (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
+        WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
+                               NULL, NULL, 0, &wndPtr->rectClient );
+        wmcreate = SendMessage32W( hwnd, WM_CREATE, 0, (LPARAM)&cs );
     }
-    else if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
 
-    /* Call WH_SHELL hook */
+    if (wmcreate == -1)
+    {
+	  /* Abort window creation */
+	dprintf_win(stddeb,"CreateWindowEx32W: wmcreate==-1, aborting\n");
+        WIN_DestroyWindow( hwnd );
+	return 0;
+    }
 
-    if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
-        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
-
-    dprintf_win(stddeb, "CreateWindowEx: return %04x\n", hwnd);
-    return hwnd;
+    dprintf_win(stddeb, "CreateWindowEx32W: return %04x\n", hwnd);
+    return WIN_FinalWindowInit( wndPtr, style );
 }
 
 
@@ -940,10 +1011,10 @@
 
       /* Send destroy messages and destroy children */
 
-    SendMessage( hwnd, WM_DESTROY, 0, 0 );
+    SendMessage16( hwnd, WM_DESTROY, 0, 0 );
     while (wndPtr->child)  /* The child removes itself from the list */
 	DestroyWindow( wndPtr->child->hwndSelf );
-    SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
+    SendMessage16( hwnd, WM_NCDESTROY, 0, 0 );
 
       /* Destroy the window */
 
@@ -1001,6 +1072,7 @@
         if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
         pWnd = pWnd->child;
     }
+    if (!pWnd) return 0;
 
     /* For a child window, all siblings will have the same hInstance, */
     /* so we can look for the class once and for all. */
@@ -1024,11 +1096,7 @@
         /* Now check the title */
 
         if (!title) return pWnd->hwndSelf;
-        if (pWnd->hText)
-        {
-            char *textPtr = (char *) USER_HEAP_LIN_ADDR( pWnd->hText );
-            if (!strcmp( textPtr, title )) return pWnd->hwndSelf;
-        }
+        if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
     }
     return 0;
 }
@@ -1145,7 +1213,7 @@
     {
 	  /* Enable window */
 	wndPtr->dwStyle &= ~WS_DISABLED;
-	SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
+	SendMessage16( hwnd, WM_ENABLE, TRUE, 0 );
 	return TRUE;
     }
     else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
@@ -1156,7 +1224,7 @@
 	    SetFocus( 0 );  /* A disabled window can't have the focus */
 	if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
 	    ReleaseCapture();  /* A disabled window can't capture the mouse */
-	SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
+	SendMessage16( hwnd, WM_ENABLE, FALSE, 0 );
 	return FALSE;
     }
     return ((wndPtr->dwStyle & WS_DISABLED) != 0);
@@ -1183,32 +1251,27 @@
     WND * wndPtr; 
 
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
-    return (wndPtr->flags & WIN_UNICODE) != 0;
+    return (WINPROC_GetWinProcType( wndPtr->lpfnWndProc ) == WIN_PROC_32W);
 }
 
 
 /**********************************************************************
- *	     GetWindowWord    (USER.133)
+ *	     GetWindowWord    (USER.133) (USER32.313)
  */
-WORD GetWindowWord( HWND hwnd, short offset )
+WORD GetWindowWord( HWND32 hwnd, INT32 offset )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
     switch(offset)
     {
-	case GWW_ID:         return wndPtr->wIDmenu;
-#ifdef WINELIB32
-        case GWW_HWNDPARENT:
-        case GWW_HINSTANCE: 
-            fprintf(stderr,"GetWindowWord called with offset %d.\n",offset);
-            return 0;
-#else
-	case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
-	case GWW_HINSTANCE:  return (WORD)wndPtr->hInstance;
-#endif
+    case GWW_ID:         return wndPtr->wIDmenu;
+    case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
+    case GWW_HINSTANCE:  return (WORD)wndPtr->hInstance;
+    default:
+        fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
+        return 0;
     }
-    return 0;
 }
 
 
@@ -1224,9 +1287,9 @@
 
 
 /**********************************************************************
- *	     SetWindowWord    (USER.134)
+ *	     SetWindowWord    (USER.134) (USER32.523)
  */
-WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
+WORD SetWindowWord( HWND32 hwnd, INT32 offset, WORD newval )
 {
     WORD *ptr, retval;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
@@ -1234,16 +1297,11 @@
     if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
     else switch(offset)
     {
-#ifdef WINELIB32
-	case GWW_ID:
-	case GWW_HINSTANCE:
-            fprintf(stderr,"SetWindowWord called with offset %d.\n",offset);
+	case GWW_ID:        ptr = (WORD *)&wndPtr->wIDmenu; break;
+	case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
+	default:
+            fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
             return 0;
-#else
-	case GWW_ID:        ptr = &wndPtr->wIDmenu;   break;
-	case GWW_HINSTANCE: ptr = (WORD*)&wndPtr->hInstance; break;
-#endif
-	default: return 0;
     }
     retval = *ptr;
     *ptr = newval;
@@ -1254,29 +1312,49 @@
 /**********************************************************************
  *	     GetWindowLong    (USER.135)
  */
-LONG GetWindowLong( HWND hwnd, short offset )
+LONG GetWindowLong( HWND32 hwnd, INT32 offset )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
     switch(offset)
     {
-	case GWL_STYLE:   return wndPtr->dwStyle;
-        case GWL_EXSTYLE: return wndPtr->dwExStyle;
-	case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
-#ifdef WINELIB32
-	case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
-	case GWW_HINSTANCE:  return wndPtr->hInstance;
-#endif
+        case GWL_USERDATA:   return 0;
+        case GWL_STYLE:      return wndPtr->dwStyle;
+        case GWL_EXSTYLE:    return wndPtr->dwExStyle;
+        case GWL_ID:         return wndPtr->wIDmenu;
+        case GWL_WNDPROC:    return (LONG)wndPtr->lpfnWndProc;
+        case GWL_HWNDPARENT: return wndPtr->parent ?
+                                        (HWND32)wndPtr->parent->hwndSelf : 0;
+        case GWL_HINSTANCE:  return (HINSTANCE32)wndPtr->hInstance;
+        default:
+            fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
     }
     return 0;
 }
 
 
 /**********************************************************************
- *	     SetWindowLong    (USER.136)
+ *	     SetWindowLong16    (USER.136)
  */
-LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
+LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
+{
+    WND *wndPtr;
+    switch(offset)
+    {
+    case GWL_WNDPROC:
+        wndPtr = WIN_FindWndPtr( hwnd );
+        return (LONG)WIN_SetWndProc( wndPtr, (WNDPROC16)newval, WIN_PROC_16 );
+    default:
+        return SetWindowLong32A( hwnd, offset, newval );
+    }
+}
+
+
+/**********************************************************************
+ *	     SetWindowLong32A    (USER32.516)
+ */
+LONG SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
 {
     LONG *ptr, retval;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
@@ -1284,10 +1362,18 @@
     if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
     else switch(offset)
     {
+        case GWL_ID:
+        case GWL_HINSTANCE:
+            return SetWindowWord( hwnd, offset, (WORD)newval );
+	case GWL_WNDPROC:
+            return (LONG)WIN_SetWndProc( wndPtr, (WNDPROC16)newval,
+                                         WIN_PROC_32A );
+        case GWL_USERDATA: return 0;
 	case GWL_STYLE:   ptr = &wndPtr->dwStyle; break;
         case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
-	case GWL_WNDPROC: ptr = (LONG *)&wndPtr->lpfnWndProc; break;
-	default: return 0;
+	default:
+            fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
+            return 0;
     }
     retval = *ptr;
     *ptr = newval;
@@ -1295,48 +1381,76 @@
 }
 
 
-/*******************************************************************
- *         GetWindowText          (USER.36)
+/**********************************************************************
+ *	     SetWindowLong32W    (USER32.517)
  */
-int WIN16_GetWindowText( HWND hwnd, SEGPTR lpString, INT nMaxCount )
+LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
 {
-    return (int)SendMessage(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
-}
-
-int GetWindowText( HWND hwnd, LPSTR lpString, int nMaxCount )
-{
-    int len;
-    HANDLE handle;
-
-      /* We have to allocate a buffer on the USER heap */
-      /* to be able to pass its address to 16-bit code */
-    if (!(handle = USER_HEAP_ALLOC( nMaxCount ))) return 0;
-    len = (int)SendMessage( hwnd, WM_GETTEXT, (WPARAM)nMaxCount, 
-                            (LPARAM)USER_HEAP_SEG_ADDR(handle) );
-    strncpy( lpString, USER_HEAP_LIN_ADDR(handle), nMaxCount );
-    USER_HEAP_FREE( handle );
-    return len;
+    WND *wndPtr;
+    switch(offset)
+    {
+    case GWL_WNDPROC:
+        wndPtr = WIN_FindWndPtr( hwnd );
+        return (LONG)WIN_SetWndProc( wndPtr, (WNDPROC16)newval, WIN_PROC_32W );
+    default:
+        return SetWindowLong32A( hwnd, offset, newval );
+    }
 }
 
 
 /*******************************************************************
- *         SetWindowText          (USER.37)
+ *	     GetWindowText16    (USER.36)
  */
-void WIN16_SetWindowText( HWND hwnd, SEGPTR lpString )
+INT16 GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
 {
-    SendMessage( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
+    return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
 }
 
-void SetWindowText( HWND hwnd, LPCSTR lpString )
-{
-    HANDLE handle;
 
-      /* We have to allocate a buffer on the USER heap */
-      /* to be able to pass its address to 16-bit code */
-    if (!(handle = USER_HEAP_ALLOC( strlen(lpString)+1 ))) return;
-    strcpy( USER_HEAP_LIN_ADDR(handle), lpString );
-    SendMessage( hwnd, WM_SETTEXT, 0, (LPARAM)USER_HEAP_SEG_ADDR(handle) );
-    USER_HEAP_FREE( handle );
+/*******************************************************************
+ *	     GetWindowText32A    (USER32.308)
+ */
+INT32 GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
+{
+    return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
+                                  (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ *	     GetWindowText32W    (USER32.311)
+ */
+INT32 GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
+{
+    return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
+                                  (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ *	     SetWindowText16    (USER.37)
+ */
+void SetWindowText16( HWND16 hwnd, SEGPTR lpString )
+{
+    SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ *	     SetWindowText32A    (USER32.)
+ */
+void SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
+{
+    SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
+}
+
+
+/*******************************************************************
+ *	     SetWindowText32W    (USER32.)
+ */
+void SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
+{
+    SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
 }
 
 
@@ -1345,7 +1459,7 @@
  */
 int GetWindowTextLength(HWND hwnd)
 {
-    return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0 );
+    return (int)SendMessage16(hwnd, WM_GETTEXTLENGTH, 0, 0 );
 }
 
 
@@ -1682,7 +1796,7 @@
         {
             HDC hDC = GetDC(hWnd);
             
-            if (!SendMessage( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
+            if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
                 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
             
             ReleaseDC( hWnd, hDC );
@@ -1702,7 +1816,7 @@
         if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
         else wparam = (hWnd == GetActiveWindow());
 
-        SendMessage( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
+        SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
         return wparam;
     }
 }
@@ -1790,7 +1904,7 @@
 
  ptrDragInfo->hScope = hQueryWnd;
 
- bResult = SendMessage( hQueryWnd ,WM_QUERYDROPOBJECT ,
+ bResult = SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
                        (WPARAM)wParam ,(LPARAM) spDragInfo );
  if( !bResult ) 
       ptrDragInfo->pt = pt;
@@ -1922,22 +2036,22 @@
     dprintf_msg(stddeb,"drag: got %04x\n",btemp);
 
     /* send WM_DRAGLOOP */
-    SendMessage( hWnd, WM_DRAGLOOP, (WPARAM)(hCurrentCursor != hBummer) , 
+    SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM)(hCurrentCursor != hBummer) , 
 	                            (LPARAM) spDragInfo );
     /* send WM_DRAGSELECT or WM_DRAGMOVE */
     if( hCurrentWnd != lpDragInfo->hScope )
 	{
 	 if( hCurrentWnd )
-	   SendMessage( hCurrentWnd, WM_DRAGSELECT, 0, 
+	   SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0, 
 		       (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
 				        HIWORD(spDragInfo)) );
 	 hCurrentWnd = lpDragInfo->hScope;
 	 if( hCurrentWnd )
-           SendMessage( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo); 
+           SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo); 
 	}
     else
 	if( hCurrentWnd )
-	   SendMessage( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
+	   SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
 
 
     /* check if we're done */
@@ -1956,7 +2070,7 @@
    }
 
  if( hCurrentCursor != hBummer ) 
-	dwRet = SendMessage( lpDragInfo->hScope, WM_DROPOBJECT, 
+	dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT, 
 			     (WPARAM)hWnd, (LPARAM)spDragInfo );
  GlobalFree16(hDragInfo);
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 39a18d6..841b63e 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -278,7 +278,7 @@
 
         /* Send the WM_NCHITTEST message (only if to the same task) */
         if ((*ppWnd)->hmemTaskQ != GetTaskQueue(0)) return HTCLIENT;
-        hittest = (INT)SendMessage( (*ppWnd)->hwndSelf, WM_NCHITTEST, 0,
+        hittest = (INT)SendMessage16( (*ppWnd)->hwndSelf, WM_NCHITTEST, 0,
                                     MAKELONG( pt.x, pt.y ) );
         if (hittest != HTTRANSPARENT) return hittest;  /* Found the window */
 
@@ -582,7 +582,7 @@
                 y  = wndPtr->ptMaxPos.y;
 
 		if( wndPtr->dwStyle & WS_MINIMIZE )
-		    if( !SendMessage( hwnd, WM_QUERYOPEN, 0, 0L ) )
+		    if( !SendMessage16( hwnd, WM_QUERYOPEN, 0, 0L ) )
 			{
 		         swpflags |= SWP_NOSIZE;
 			 break;
@@ -614,7 +614,7 @@
 
             if (wndPtr->dwStyle & WS_MINIMIZE)
             {
-                if( !SendMessage( hwnd, WM_QUERYOPEN, 0, 0L) )
+                if( !SendMessage16( hwnd, WM_QUERYOPEN, 0, 0L) )
                   {
                     swpflags |= SWP_NOSIZE;
                     break;
@@ -655,7 +655,7 @@
 	    break;
     }
 
-    SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
+    SendMessage16( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 );
     SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
 
     if (wndPtr->flags & WIN_NEED_SIZE)
@@ -665,10 +665,10 @@
 	wndPtr->flags &= ~WIN_NEED_SIZE;
 	if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED;
 	else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED;
-	SendMessage( hwnd, WM_SIZE, wParam,
+	SendMessage16( hwnd, WM_SIZE, wParam,
 		     MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
 			    wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-	SendMessage( hwnd, WM_MOVE, 0,
+	SendMessage16( hwnd, WM_MOVE, 0,
 		   MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) );
     }
 
@@ -832,7 +832,7 @@
  
     if (GetWindowTask(hWnd) != lpActStruct->hTaskSendTo) return 1;
 
-    SendMessage( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag,
+    SendMessage16( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag,
 		(LPARAM)((lpActStruct->hWindowTask)?lpActStruct->hWindowTask:0));
     return 1;
 }
@@ -886,18 +886,18 @@
     if( (hwndPrevActive = hwndActive) )
     {
 /* FIXME: need a Win32 translation for WINELIB32 */
-	if( !SendMessage(hwndPrevActive, WM_NCACTIVATE, 0, MAKELONG(hWnd,wIconized)) )
+	if( !SendMessage16(hwndPrevActive, WM_NCACTIVATE, 0, MAKELONG(hWnd,wIconized)) )
         {
 	    if (GetSysModalWindow() != hWnd) return 0;
 	    /* disregard refusal if hWnd is sysmodal */
         }
 
 #ifdef WINELIB32
-	SendMessage( hwndActive, WM_ACTIVATE,
+	SendMessage32A( hwndActive, WM_ACTIVATE,
 		     MAKEWPARAM( WA_INACTIVE, wIconized ),
 		     (LPARAM)hWnd );
 #else
-	SendMessage(hwndPrevActive, WM_ACTIVATE, WA_INACTIVE, 
+	SendMessage16(hwndPrevActive, WM_ACTIVATE, WA_INACTIVE, 
 		    MAKELONG(hWnd,wIconized));
 #endif
 
@@ -909,8 +909,8 @@
     hwndActive = hWnd;
 
     /* send palette messages */
-    if( SendMessage( hWnd, WM_QUERYNEWPALETTE, 0, 0L) )
-	SendMessage((HWND)-1, WM_PALETTEISCHANGING, (WPARAM)hWnd, 0L );
+    if( SendMessage16( hWnd, WM_QUERYNEWPALETTE, 0, 0L) )
+	SendMessage16((HWND16)-1, WM_PALETTEISCHANGING, (WPARAM)hWnd, 0L );
 
     /* if prev wnd is minimized redraw icon title 
   if( hwndPrevActive )
@@ -973,14 +973,14 @@
 
     wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
 /* FIXME: Needs a Win32 translation for WINELIB32 */
-    SendMessage( hWnd, WM_NCACTIVATE, 1,
+    SendMessage16( hWnd, WM_NCACTIVATE, 1,
 		 MAKELONG(hwndPrevActive,wIconized));
 #ifdef WINELIB32
-    SendMessage( hWnd, WM_ACTIVATE,
+    SendMessage32A( hWnd, WM_ACTIVATE,
 		 MAKEWPARAM( (fMouse)?WA_CLICKACTIVE:WA_ACTIVE, wIconized),
 		 (LPARAM)hwndPrevActive );
 #else
-    SendMessage( hWnd, WM_ACTIVATE, (fMouse)? WA_CLICKACTIVE : WA_ACTIVE,
+    SendMessage16( hWnd, WM_ACTIVATE, (fMouse)? WA_CLICKACTIVE : WA_ACTIVE,
 		 MAKELONG(hwndPrevActive,wIconized));
 #endif
 
@@ -1016,7 +1016,7 @@
 
     /* child windows get WM_CHILDACTIVATE message */
     if( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD )
-	return SendMessage(hWnd, WM_CHILDACTIVATE, 0, 0L);
+	return SendMessage16(hWnd, WM_CHILDACTIVATE, 0, 0L);
 
         /* owned popups imply owner activation - not sure */
     if ((wndPtr->dwStyle & WS_POPUP) && wndPtr->owner &&
@@ -1063,7 +1063,7 @@
 	params->rgrc[2] = *oldClientRect;
 	params->lppos = winpos;
     }
-    result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect,
+    result = SendMessage16( hwnd, WM_NCCALCSIZE, calcValidRect,
                           (LPARAM)SEGPTR_GET( params ) );
     dprintf_win(stddeb, "WINPOS_SendNCCalcSize: %d %d %d %d\n",
 		(int)params->rgrc[0].top,    (int)params->rgrc[0].left,
@@ -1075,15 +1075,34 @@
 
 
 /***********************************************************************
- *           WINPOS_HandleWindowPosChanging
+ *           WINPOS_HandleWindowPosChanging16
  *
  * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
  */
-LONG WINPOS_HandleWindowPosChanging( WINDOWPOS16 *winpos )
+LONG WINPOS_HandleWindowPosChanging16( WND *wndPtr, WINDOWPOS16 *winpos )
 {
     POINT16 maxSize;
-    WND *wndPtr = WIN_FindWndPtr( winpos->hwnd );
-    if (!wndPtr || (winpos->flags & SWP_NOSIZE)) return 0;
+    if (winpos->flags & SWP_NOSIZE) return 0;
+    if ((wndPtr->dwStyle & WS_THICKFRAME) ||
+	((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
+    {
+	NC_GetMinMaxInfo( winpos->hwnd, &maxSize, NULL, NULL, NULL );
+	winpos->cx = MIN( winpos->cx, maxSize.x );
+	winpos->cy = MIN( winpos->cy, maxSize.y );
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           WINPOS_HandleWindowPosChanging32
+ *
+ * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
+ */
+LONG WINPOS_HandleWindowPosChanging32( WND *wndPtr, WINDOWPOS32 *winpos )
+{
+    POINT16 maxSize;
+    if (winpos->flags & SWP_NOSIZE) return 0;
     if ((wndPtr->dwStyle & WS_THICKFRAME) ||
 	((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) == 0))
     {
@@ -1481,7 +1500,7 @@
       /* Send WM_WINDOWPOSCHANGING message */
 
     if (!(flags & SWP_NOSENDCHANGING))
-	SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)MAKE_SEGPTR(&winpos) );
+	SendMessage16( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)MAKE_SEGPTR(&winpos) );
 
       /* Calculate new position and size */
 
@@ -1696,8 +1715,8 @@
       /* And last, send the WM_WINDOWPOSCHANGED message */
 
     if (!(winpos.flags & SWP_NOSENDCHANGING))
-        SendMessage( winpos.hwnd, WM_WINDOWPOSCHANGED,
-                     0, (LPARAM)MAKE_SEGPTR(&winpos) );
+        SendMessage16( winpos.hwnd, WM_WINDOWPOSCHANGED,
+                       0, (LPARAM)MAKE_SEGPTR(&winpos) );
 
     return TRUE;
 }
diff --git a/windows/winproc.c b/windows/winproc.c
index 6e25b20..16ce933 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -7,21 +7,233 @@
 
 #include <stdio.h>
 #include "windows.h"
-#include "alias.h"
 #include "callback.h"
 #include "heap.h"
 #include "ldt.h"
 #include "stackframe.h"
+#include "string32.h"
 #include "struct32.h"
 #include "win.h"
+#include "winproc.h"
+
+
+typedef struct
+{
+    WNDPROC32       func;        /* 32-bit function, or 0 if free */
+    unsigned int    count : 30;  /* Reference count, or next free if func==0 */
+    WINDOWPROCTYPE  type : 2;    /* Function type */
+} WINDOWPROC;
+
+#define NB_WINPROCS    1024  /* Must be < 64K; 1024 should be enough for now */
+
+static WINDOWPROC winProcs[NB_WINPROCS];
+static int lastWinProc = 0;
+static int freeWinProc = NB_WINPROCS;
+
+/* Check if a win proc was created by WINPROC_AllocWinProc */
+#define IS_ALLOCATED_WINPROC(func)  (HIWORD(func) == 0xffff)
+
+/**********************************************************************
+ *	     WINPROC_AllocWinProc
+ *
+ * Allocate a new window procedure.
+ */
+WNDPROC16 WINPROC_AllocWinProc( WNDPROC32 func, WINDOWPROCTYPE type )
+{
+    WINDOWPROC *proc;
+    if (!func) return (WNDPROC16)0;  /* Null win proc remains null */
+    if (IS_ALLOCATED_WINPROC(func))  /* Already allocated? */
+    {
+        if (LOWORD(func) >= NB_WINPROCS) return (WNDPROC16)0;
+        proc = &winProcs[LOWORD(func)];
+        if (!proc->func) return (WNDPROC16)0;
+        proc->count++;
+        return (WNDPROC16)func;
+    }
+    if (freeWinProc < NB_WINPROCS)  /* There is a free entry */
+    {
+        proc = &winProcs[freeWinProc];
+        proc->func = func;
+        func = (WNDPROC32)MAKELONG( freeWinProc, 0xffff );
+        freeWinProc = proc->count;  /* Next free entry */
+        proc->count = 1;
+        proc->type  = type;
+        return (WNDPROC16)func;
+    }
+    if (lastWinProc < NB_WINPROCS)  /* There's a free entry at the end */
+    {
+        proc = &winProcs[lastWinProc];
+        proc->func = func;
+        func = (WNDPROC32)MAKELONG( lastWinProc, 0xffff );
+        lastWinProc++;
+        proc->count = 1;
+        proc->type  = type;
+        return (WNDPROC16)func;
+    }
+    fprintf( stderr, "WINPROC_AllocWinProc: out of window procedures.\n"
+                     "Please augment NB_WINPROCS in winproc.c\n" );
+    return (WNDPROC16)0;
+}
 
 
 /**********************************************************************
- *	     WINPROC_CallProc16To32
+ *	     WINPROC_GetWinProcType
+ *
+ * Return the type of a window procedure.
+ */
+WINDOWPROCTYPE WINPROC_GetWinProcType( WNDPROC16 func )
+{
+    WORD id = LOWORD(func);
+    if (!IS_ALLOCATED_WINPROC(func)) return WIN_PROC_16;
+    if ((id >= NB_WINPROCS) || !winProcs[id].func) return WIN_PROC_INVALID;
+    return winProcs[id].type;
+}
+
+
+/**********************************************************************
+ *	     WINPROC_GetWinProcFunc
+ *
+ * Return the 32-bit window procedure for a winproc.
+ */
+WNDPROC32 WINPROC_GetWinProcFunc( WNDPROC16 func )
+{
+    WORD id = LOWORD(func);
+    if (!IS_ALLOCATED_WINPROC(func)) return NULL;
+    if (id >= NB_WINPROCS) return NULL;
+    return winProcs[id].func;
+}
+
+
+/**********************************************************************
+ *	     WINPROC_FreeWinProc
+ *
+ * Free a window procedure.
+ */
+void WINPROC_FreeWinProc( WNDPROC16 func )
+{
+    WORD id = LOWORD(func);
+    if (!IS_ALLOCATED_WINPROC(func)) return;
+    if ((id >= NB_WINPROCS) || !winProcs[id].func)
+    {
+        fprintf( stderr, "WINPROC_FreeWinProc: invalid proc %08x\n",
+                 (UINT32)func );
+        return;
+    }
+    if (--winProcs[id].count == 0)
+    {
+        winProcs[id].func = 0;
+        winProcs[id].count = freeWinProc;
+        freeWinProc = id;
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_CallProc32ATo32W
+ *
+ * Call a window procedure, translating args from Ansi to Unicode.
+ */
+static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
+                                         UINT32 msg, WPARAM32 wParam,
+                                         LPARAM lParam )
+{
+    LRESULT result;
+
+    switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPWSTR str = (LPWSTR)HeapAlloc(SystemHeap,0,wParam*sizeof(WCHAR));
+            if (!str) return 0;
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
+            STRING32_UniToAnsi( (LPSTR)lParam, str );
+            HeapFree( SystemHeap, 0, str );
+            return strlen( (LPSTR)lParam ) + 1;
+        }
+
+    case WM_SETTEXT:
+        {
+            LPWSTR str = STRING32_DupAnsiToUni( (LPCSTR)lParam );
+            if (!str) return 0;
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
+            free( str );
+        }
+        return result;
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCT32W cs = *(CREATESTRUCT32W *)lParam;
+            cs.lpszName  = STRING32_DupAnsiToUni( (LPCSTR)cs.lpszName );
+            cs.lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs.lpszName );
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs );
+            free( (LPVOID)cs.lpszName );
+            free( (LPVOID)cs.lpszClass );
+        }
+        return result;
+	
+    default:  /* No translation needed */
+        return CallWndProc32( func, hwnd, msg, wParam, lParam );
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_CallProc32WTo32A
+ *
+ * Call a window procedure, translating args from Unicode to Ansi.
+ */
+static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
+                                         UINT32 msg, WPARAM32 wParam,
+                                         LPARAM lParam )
+{
+    LRESULT result;
+
+    switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPSTR str = (LPSTR)HeapAlloc( SystemHeap, 0, wParam );
+            if (!str) return 0;
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
+            STRING32_AnsiToUni( (LPWSTR)lParam, str );
+            HeapFree( SystemHeap, 0, str );
+            return STRING32_lstrlenW( (LPWSTR)lParam ) + 1;  /* FIXME? */
+        }
+
+    case WM_SETTEXT:
+        {
+            LPSTR str = STRING32_DupUniToAnsi( (LPCWSTR)lParam );
+            if (!str) return 0;
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
+            free( str );
+        }
+        return result;
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam;
+            cs.lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs );
+            free( (LPVOID)cs.lpszName );
+            free( (LPVOID)cs.lpszClass );
+        }
+        return result;
+	
+    default:  /* No translation needed */
+        return CallWndProc32( func, hwnd, msg, wParam, lParam );
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_CallProc16To32A
  *
  * Call a 32-bit window procedure, translating the 16-bit args.
  */
-static LRESULT WINPROC_CallProc16To32( WNDPROC32 func, HWND16 hwnd, UINT16 msg,
+static LRESULT WINPROC_CallProc16To32A(WNDPROC32 func, HWND16 hwnd, UINT16 msg,
                                        WPARAM16 wParam, LPARAM lParam )
 {
     LRESULT result;
@@ -41,6 +253,24 @@
         return CallWndProc32( func, hwnd, WM_CTLCOLORMSGBOX + HIWORD(lParam),
                               (WPARAM32)(HDC32)wParam,
                               (LPARAM)(HWND32)LOWORD(lParam) );
+    case WM_DRAWITEM:
+        {
+            DRAWITEMSTRUCT16*dis16 = (DRAWITEMSTRUCT16*)PTR_SEG_TO_LIN(lParam);
+            DRAWITEMSTRUCT32 dis;
+            dis.CtlType    = dis16->CtlType;
+            dis.CtlID      = dis16->CtlID;
+            dis.itemID     = dis16->itemID;
+            dis.itemAction = dis16->itemAction;
+            dis.itemState  = dis16->itemState;
+            dis.hwndItem   = dis16->hwndItem;
+            dis.hDC        = dis16->hDC;
+            dis.itemData   = dis16->itemData;
+            CONV_RECT16TO32( &dis16->rcItem, &dis.rcItem );
+            result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&dis );
+            /* We don't bother to translate it back */
+        }
+        return result;
+
     case WM_GETMINMAXINFO:
         {
             MINMAXINFO32 mmi;
@@ -53,7 +283,6 @@
         return result;
 
     case WM_GETTEXT:
-        /* FIXME: Unicode */
         return CallWndProc32( func, hwnd, msg, wParam,
                               (LPARAM)PTR_SEG_TO_LIN(lParam) );
     case WM_MDISETMENU:
@@ -148,7 +377,6 @@
     case WM_COMPAREITEM:
     case WM_DELETEITEM:
     case WM_DEVMODECHANGE:
-    case WM_DRAWITEM:
     case WM_MDIACTIVATE:
     case WM_MDICREATE:
     case WM_MEASUREITEM:
@@ -164,13 +392,52 @@
 
 
 /**********************************************************************
- *	     WINPROC_CallProc32To16
+ *	     WINPROC_CallProc16To32W
+ *
+ * Call a 32-bit window procedure, translating the 16-bit args.
+ */
+static LRESULT WINPROC_CallProc16To32W(WNDPROC32 func, HWND16 hwnd, UINT16 msg,
+                                       WPARAM16 wParam, LPARAM lParam )
+{
+    LRESULT result = 0;
+
+    switch(msg)
+    {
+    case WM_GETTEXT:
+    case WM_SETTEXT:
+        return WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam,
+                                         (LPARAM)PTR_SEG_TO_LIN(lParam) );
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCT16 *pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
+            CREATESTRUCT32A cs;
+
+            STRUCT32_CREATESTRUCT16to32A( pcs16, &cs );
+            cs.lpszName       = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName);
+            cs.lpszClass      = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass);
+            result = WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam,
+                                               (LPARAM)&cs );
+            pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
+            STRUCT32_CREATESTRUCT32Ato16( &cs, pcs16 );
+        }
+        return result;
+
+    default:  /* No Unicode translation needed */
+        return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
+    }
+}
+
+
+/**********************************************************************
+ *	     WINPROC_CallProc32ATo16
  *
  * Call a 16-bit window procedure, translating the 32-bit args.
  */
-static LRESULT WINPROC_CallProc32To16( WNDPROC16 func, WORD ds, HWND32 hwnd,
-                                       UINT32 msg, WPARAM32 wParam,
-                                       LPARAM lParam )
+static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, WORD ds, HWND32 hwnd,
+                                        UINT32 msg, WPARAM32 wParam,
+                                        LPARAM lParam )
 {
     LRESULT result;
 
@@ -195,6 +462,27 @@
         return CallWndProc16( func, ds, hwnd, WM_CTLCOLOR, (WPARAM16)wParam,
                               MAKELPARAM( (HWND16)lParam,
                                           (WORD)msg - WM_CTLCOLORMSGBOX ) );
+    case WM_DRAWITEM:
+        {
+            DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)lParam;
+            DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
+            if (!dis) return 0;
+            dis->CtlType    = (UINT16)dis32->CtlType;
+            dis->CtlID      = (UINT16)dis32->CtlID;
+            dis->itemID     = (UINT16)dis32->itemID;
+            dis->itemAction = (UINT16)dis32->itemAction;
+            dis->itemState  = (UINT16)dis32->itemState;
+            dis->hwndItem   = (HWND16)dis32->hwndItem;
+            dis->hDC        = (HDC16)dis32->hDC;
+            dis->itemData   = dis32->itemData;
+            CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
+            result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
+                                    (LPARAM)SEGPTR_GET(dis) );
+            /* We don't bother to translate it back */
+            SEGPTR_FREE(dis);
+        }
+        return result;
+
     case WM_GETMINMAXINFO:
         {
             MINMAXINFO16 *mmi = SEGPTR_NEW(MINMAXINFO16);
@@ -319,7 +607,6 @@
     case WM_COMPAREITEM:
     case WM_DELETEITEM:
     case WM_DEVMODECHANGE:
-    case WM_DRAWITEM:
     case WM_MDIACTIVATE:
     case WM_MDICREATE:
     case WM_MEASUREITEM:
@@ -335,29 +622,85 @@
 
 
 /**********************************************************************
+ *	     WINPROC_CallProc32WTo16
+ *
+ * Call a 16-bit window procedure, translating the 32-bit args.
+ */
+static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, WORD ds, HWND32 hwnd,
+                                        UINT32 msg, WPARAM32 wParam,
+                                        LPARAM lParam )
+{
+    LRESULT result;
+
+    switch(msg)
+    {
+    case WM_GETTEXT:
+        {
+            LPSTR str;
+            wParam = MIN( wParam, 0xff80 );  /* Size must be < 64K */
+            if (!(str = SEGPTR_ALLOC( wParam ))) return 0;
+            result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
+                                    (LPARAM)SEGPTR_GET(str) );
+            if (result > 0) STRING32_AnsiToUni( (LPWSTR)lParam, str );
+            SEGPTR_FREE(str);
+        }
+        return result;
+
+    case WM_NCCREATE:
+    case WM_CREATE:
+        {
+            CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam;
+            cs.lpszName  = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
+            result = WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam,
+                                              (LPARAM)&cs );
+            free( (LPVOID)cs.lpszName );
+            free( (LPVOID)cs.lpszClass );
+        }
+        return result;
+	
+    case WM_SETTEXT:
+        {
+            LPSTR str = SEGPTR_ALLOC( STRING32_lstrlenW( (LPWSTR)lParam ) );
+            if (!str) return 0;
+            STRING32_UniToAnsi( str, (LPWSTR)lParam );
+            result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
+                                    (LPARAM)SEGPTR_GET(str) );
+            SEGPTR_FREE(str);
+        }
+        return result;
+
+    default:  /* No Unicode translation needed */
+        return WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam, lParam );
+    }
+}
+
+
+/**********************************************************************
  *	     CallWindowProc16    (USER.122)
  */
 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
                           WPARAM16 wParam, LPARAM lParam )
 {
-    FUNCTIONALIAS *a;
+    WND *wndPtr;
 
-    /* check if we have something better than 16 bit relays */
-    if (!ALIAS_UseAliases || !(a=ALIAS_LookupAlias((DWORD)func)) ||
-        (!a->wine && !a->win32))
+    switch(WINPROC_GetWinProcType(func))
     {
-        WND *wndPtr = WIN_FindWndPtr( hwnd );
+    case WIN_PROC_16:
+        wndPtr = WIN_FindWndPtr( hwnd );
         return CallWndProc16( (FARPROC)func,
                               wndPtr ? wndPtr->hInstance : CURRENT_DS,
                               hwnd, msg, wParam, lParam );
+    case WIN_PROC_32A:
+        return WINPROC_CallProc16To32A( WINPROC_GetWinProcFunc(func),
+                                        hwnd, msg, wParam, lParam );
+    case WIN_PROC_32W:
+        return WINPROC_CallProc16To32W( WINPROC_GetWinProcFunc(func),
+                                        hwnd, msg, wParam, lParam );
+    default:
+        fprintf(stderr, "CallWindowProc16: invalid func %08x\n", (UINT32)func);
+        return 0;
     }
-
-    if(a->wine)
-        return ((LONG(*)(WORD,WORD,WORD,LONG))(a->wine))
-                            (hwnd,msg,wParam,lParam);
-
-    return WINPROC_CallProc16To32( (WNDPROC32)a->win32, hwnd, msg,
-                                   wParam, lParam );
 }
 
 
@@ -367,30 +710,25 @@
 LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
                            WPARAM32 wParam, LPARAM lParam )
 {
-    FUNCTIONALIAS *a = NULL;
     WND *wndPtr;
-    WORD ds;
 
-    /* check if we have something better than 16 bit relays */
-    if (ALIAS_UseAliases && (a=ALIAS_LookupAlias((DWORD)func)) &&
-        (a->wine || a->win32))
+    switch(WINPROC_GetWinProcType( (WNDPROC16)func ))
     {
-        /* FIXME: Unicode */
-        if (a->wine)
-            return ((WNDPROC32)a->wine)(hwnd,msg,wParam,lParam);
-        else return CallWndProc32( func, hwnd, msg, wParam, lParam );
-    }
-    wndPtr = WIN_FindWndPtr( hwnd );
-    ds = wndPtr ? wndPtr->hInstance : CURRENT_DS;
-
-    if (!a)
-    {
-        fprintf( stderr, "CallWindowProc32A: no alias for %p\n", func );
+    case WIN_PROC_16:
+        wndPtr = WIN_FindWndPtr( hwnd );
+        return WINPROC_CallProc32ATo16( (FARPROC)func,
+                                       wndPtr ? wndPtr->hInstance : CURRENT_DS,
+                                       hwnd, msg, wParam, lParam );
+    case WIN_PROC_32A:
+        return CallWndProc32( WINPROC_GetWinProcFunc( (WNDPROC16)func ),
+                              hwnd, msg, wParam, lParam );
+    case WIN_PROC_32W:
+        return WINPROC_CallProc32ATo32W(WINPROC_GetWinProcFunc((WNDPROC16)func),
+                                        hwnd, msg, wParam, lParam );
+    default:
+        fprintf(stderr,"CallWindowProc32A: invalid func %08x\n",(UINT32)func);
         return 0;
     }
-
-    return WINPROC_CallProc32To16( (WNDPROC16)a->win16, ds, hwnd, msg,
-                                   wParam, lParam );
 }
 
 
@@ -400,6 +738,23 @@
 LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
                            WPARAM32 wParam, LPARAM lParam )
 {
-    /* FIXME: Unicode translation */
-    return CallWindowProc32A( func, hwnd, msg, wParam, lParam );
+    WND *wndPtr;
+
+    switch(WINPROC_GetWinProcType( (WNDPROC16)func ))
+    {
+    case WIN_PROC_16:
+        wndPtr = WIN_FindWndPtr( hwnd );
+        return WINPROC_CallProc32WTo16( (FARPROC)func,
+                                       wndPtr ? wndPtr->hInstance : CURRENT_DS,
+                                       hwnd, msg, wParam, lParam );
+    case WIN_PROC_32A:
+        return WINPROC_CallProc32WTo32A(WINPROC_GetWinProcFunc((WNDPROC16)func),
+                                        hwnd, msg, wParam, lParam );
+    case WIN_PROC_32W:
+        return CallWndProc32( WINPROC_GetWinProcFunc( (WNDPROC16)func ),
+                              hwnd, msg, wParam, lParam );
+    default:
+        fprintf(stderr,"CallWindowProc32W: invalid func %08x\n",(UINT32)func);
+        return 0;
+    }
 }