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