Release 970824

Sat Aug 23 00:05:23 1997  Andreas Mohr <100.30936@germany.net>

	* [if1632/kernel.spec] [if1632/mmsystem.spec]
	Added some stubs.

	* [include/neexe.h] [loader/module.c]
	Added warning for OS/2 executables.

	* [multimedia/midi.c]
	Shortened MIDIOUT driver version string to be less than 31 chars.

	* [objects/gdiobj.c]
	Fixed DeleteObject32() to react properly when called with stock object.

Fri Aug 22 18:03:26 1997  Dimitrie O. Paun <dimi@cs.toronto.edu>

	* [controls/updown.c] [include/updown.h]
	First attempt at implementiong the UpDown class.

	* [controls/widgets.c]
	Added the UpDown class to be initialized by InitCommonControls().

Wed Aug 20 18:01:33 1997  Doug Ridgway <ridgway@routh.UCSD.EDU>

	* [graphics/*] [objects/*] [include/gdi.h]
	Made all GDI objects (except DCs) moveable.

Mon Aug 18 03:25:30 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [windows/event.c] [misc/winsock.c] [misc/winsock_dns.c]
	Removed IPC communication to speed up winsock services
	(tested only with 16-bit netscape 3.03).

	* [graphics/x11drv/xfont.c] [documentation/fonts]
	Miscellaneous improvements. Updated docs.

Sun Aug 17 20:39:55 1997  Ingo Schneider <schneidi@informatik.tu-muenchen.de>

	* [misc/comm.c]
	A couple of bug fixes.

Sun Aug 17 19:29:22 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [debugger/dbg.y]
	Display next instruction after stepi/nexti.

	* [if1632/relay.c] [include/callback.h] [tools/build.c]
	Replaced CallTo32_LargeStack with the CALL_LARGE_STACK macro for
	better Winelib support.

	* [include/sigcontext.h]
	Renamed to sig_context.h to avoid conflicts with libc.

	* [*/*]
	All API functions are now prefixed with WINAPI in prevision of
	future Winelib integration.

	* [loader/signal.c] [memory/ldt.c]
	Fixed assembly code to be -fPIC compatible.

Thu Aug 14 14:38:15 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [if1632/crtdll.spec][win32/except.c]
	_global_unwind, _local_unwind stub added.

	* [objects/dib.c]	
	Don't read memory you don't even need for the target bitmap (fixes
	one 'lazy' program).

	* [if1632/relay.c][if1632/thunk.c][if1632/kernel32.spec]
	  [win32/ordinals.c][memory/selector.c][memory/global.c]
	  [include/callback.h]
	Added/moved some more win95 ordinal stuff. Implemented QT_Thunk
	(not 100% correct yet) and some friends.

	* [loader/pe_image.c]
	Add possibility to break at the DLL entrypoint.

	* [controls/static.c][misc/commdlg.c][scheduler/thread.c]
	Misc bugfixes and additions.

	* [misc/registry.c]
	The registry seems to be case-preserving but case-insensitive.

	* [memory/global.c]	
	Adapted to new /proc/meminfo format.

	* [objects/font.c][graphics/x11drv/xfont.c]
	FONT_SelectObject and GetTextMetrics* get passed ranges in logical
 	and not device points (thanks to Marion Reyzl for pointing this
 	out).

	* [windows/caret.c]
	Use the windows own DC if present (The caret coordinates are
	logical coordinates based on it). Fixes another AMIPRO problem.

Wed Aug  6 18:22:22 1997  Morten Welinder  <terra@diku.dk>

	* [controls/menu.c]
	General clean-up and Win32 work: split item_flags into fType and
	fState; split item_id into wID and hSubMenu.  Improved
	debug-printing.  Implemented InsertMenuItem32[AW],
	SetMenuDefaultItem32, and SetMenuItemInfo32[AW].  Fixed
	GetMenuItemInfo32[AW].

	* [if1632/user32.spec]
	Define above new functions.

	* [include/windows.h]
	Define MF_DEFAULT and MF_RIGHTJUSTIFY.  Prototype above functions.

	* [include/menu.h]
	Don't prototype now-static MENU_InitSysMenuPopup.

	* [include/comm.h]
	Reduce MAX_PORTS to 9 (which the profile code can handle).

Tue Aug  5 20:16:22 1997  Victor Schneider <vischne@ibm.net>

	* [library/winestub.c] [libtest/expand.c]
	These patches let people porting Windows apps compile them using
	the same conventions regarding global _argc and _argv as those on
	Windows C/C++ compilers.
diff --git a/controls/Makefile.in b/controls/Makefile.in
index 3379b18..9d24345 100644
--- a/controls/Makefile.in
+++ b/controls/Makefile.in
@@ -16,6 +16,7 @@
 	scroll.c \
 	static.c \
 	status.c \
+	updown.c \
 	widgets.c
 
 all: $(MODULE).o
diff --git a/controls/button.c b/controls/button.c
index 07cc5e1..312282d 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -71,7 +71,8 @@
 /***********************************************************************
  *           ButtonWndProc
  */
-LRESULT ButtonWndProc(HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
+LRESULT WINAPI ButtonWndProc( HWND32 hWnd, UINT32 uMsg,
+                              WPARAM32 wParam, LPARAM lParam )
 {
     RECT16 rect;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
diff --git a/controls/combo.c b/controls/combo.c
index 3771933..3c3590f 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -83,30 +83,32 @@
  */
 static LRESULT COMBO_NCCreate(WND* wnd, LPARAM lParam)
 {
-  LPHEADCOMBO 		lphc;
+   LPHEADCOMBO 		lphc;
 
-  if ( wnd && COMBO_Init() &&
+   if ( wnd && COMBO_Init() &&
       (lphc = HeapAlloc(GetProcessHeap(), 0, sizeof(HEADCOMBO))) )
-  {
-       LPCREATESTRUCT32A     lpcs = (CREATESTRUCT32A*)lParam;
+   {
+	LPCREATESTRUCT32A     lpcs = (CREATESTRUCT32A*)lParam;
        
-       memset( lphc, 0, sizeof(HEADCOMBO) );
+	memset( lphc, 0, sizeof(HEADCOMBO) );
        *(LPHEADCOMBO*)wnd->wExtra = lphc;
 
        /* some braindead apps do try to use scrollbar/border flags */
 
-       lphc->dwStyle = (lpcs->style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL));
-       wnd->dwStyle &= ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);
+	lphc->dwStyle = (lpcs->style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL));
+	wnd->dwStyle &= ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);
 
-       if( !(lpcs->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) )
-             lphc->dwStyle |= CBS_HASSTRINGS;
+	if( !(lpcs->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) )
+              lphc->dwStyle |= CBS_HASSTRINGS;
+	if( !(wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) )
+	      lphc->wState |= CBF_NOTIFY;
 
-       dprintf_combo(stddeb, "COMBO_NCCreate: [0x%08x], style = %08x\n", 
-				              (UINT32)lphc, lphc->dwStyle );
+	dprintf_combo(stddeb, "COMBO_NCCreate: [0x%08x], style = %08x\n", 
+						(UINT32)lphc, lphc->dwStyle );
 
-       return (LRESULT)(UINT32)wnd->hwndSelf; 
-  }
-  return (LRESULT)FALSE;
+	return (LRESULT)(UINT32)wnd->hwndSelf; 
+    }
+    return (LRESULT)FALSE;
 }
 
 /***********************************************************************
@@ -1239,7 +1241,8 @@
  *
  * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/ctrl/src/combobox_15.htm
  */
-LRESULT ComboWndProc(HWND32 hwnd, UINT32 message, WPARAM32 wParam, LPARAM lParam)
+LRESULT WINAPI ComboWndProc( HWND32 hwnd, UINT32 message,
+                             WPARAM32 wParam, LPARAM lParam )
 {
     WND*	pWnd = WIN_FindWndPtr(hwnd);
    
diff --git a/controls/desktop.c b/controls/desktop.c
index 6708fb7..b1651f2 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -131,8 +131,8 @@
  *
  * Window procedure for the desktop window.
  */
-LRESULT DesktopWndProc( HWND32 hwnd, UINT32 message,
-                        WPARAM32 wParam, LPARAM lParam )
+LRESULT WINAPI DesktopWndProc( HWND32 hwnd, UINT32 message,
+                               WPARAM32 wParam, LPARAM lParam )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
@@ -169,7 +169,7 @@
 /***********************************************************************
  *           SetDeskPattern   (USER.279)
  */
-BOOL16 SetDeskPattern(void)
+BOOL16 WINAPI SetDeskPattern(void)
 {
     char buffer[100];
     GetProfileString32A( "desktop", "Pattern", "(None)", buffer, 100 );
@@ -180,7 +180,7 @@
 /***********************************************************************
  *           SetDeskWallPaper16   (USER.285)
  */
-BOOL16 SetDeskWallPaper16( LPCSTR filename )
+BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
 {
     return SetDeskWallPaper32( filename );
 }
@@ -191,7 +191,7 @@
  *
  * FIXME: is there a unicode version?
  */
-BOOL32 SetDeskWallPaper32( LPCSTR filename )
+BOOL32 WINAPI SetDeskWallPaper32( LPCSTR filename )
 {
     HBITMAP32 hbitmap;
     HDC32 hdc;
diff --git a/controls/edit.c b/controls/edit.c
index 0a8a3d48..28373cd 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -148,7 +148,8 @@
 /*
  *	This is the only exported function
  */
-LRESULT EditWndProc(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam);
+LRESULT WINAPI EditWndProc( HWND32 hwnd, UINT32 msg,
+                            WPARAM32 wParam, LPARAM lParam );
 /*
  *	Helper functions only valid for one type of control
  */
@@ -297,7 +298,8 @@
  *	names).
  *
  */
-LRESULT EditWndProc(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+LRESULT WINAPI EditWndProc( HWND32 hwnd, UINT32 msg,
+                            WPARAM32 wParam, LPARAM lParam )
 {
 	WND *wnd = WIN_FindWndPtr(hwnd);
 	EDITSTATE *es = *(EDITSTATE **)((wnd)->wExtra);
diff --git a/controls/icontitle.c b/controls/icontitle.c
index 1864086..b54801e 100644
--- a/controls/icontitle.c
+++ b/controls/icontitle.c
@@ -185,7 +185,8 @@
 /***********************************************************************
  *           IconTitleWndProc
  */
-LRESULT IconTitleWndProc( HWND32 hWnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam )
+LRESULT WINAPI IconTitleWndProc( HWND32 hWnd, UINT32 msg,
+                                 WPARAM32 wParam, LPARAM lParam )
 {
     WND *wnd = WIN_FindWndPtr( hWnd );
 
diff --git a/controls/listbox.c b/controls/listbox.c
index 71f56be..5466abe 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -233,7 +233,8 @@
     {
         INT32 diff = (descr->top_item - index) / descr->page_size * descr->column_width;
         if (scroll && (abs(diff) < descr->width))
-            ScrollWindow32( wnd->hwndSelf, diff, 0, NULL, NULL );
+            ScrollWindowEx32( wnd->hwndSelf, diff, 0, NULL, NULL, 0, NULL, 
+				SW_INVALIDATE | SW_ERASE );
         else
             scroll = FALSE;
     }
@@ -259,7 +260,8 @@
             diff = (descr->top_item - index) * descr->item_height;
 
         if (abs(diff) < descr->height)
-            ScrollWindow32( wnd->hwndSelf, 0, diff, NULL, NULL );
+            ScrollWindowEx32( wnd->hwndSelf, 0, diff, NULL, NULL, 0, NULL,
+					SW_INVALIDATE | SW_ERASE );
         else
             scroll = FALSE;
     }
@@ -1006,7 +1008,8 @@
     descr->horz_pos = pos;
     LISTBOX_UpdateScroll( wnd, descr );
     if (abs(diff) < descr->width)
-        ScrollWindow32( wnd->hwndSelf, diff, 0, NULL, NULL );
+        ScrollWindowEx32( wnd->hwndSelf, diff, 0, NULL, NULL, 0, NULL,
+			SW_INVALIDATE | SW_ERASE );
     else
         InvalidateRect32( wnd->hwndSelf, NULL, TRUE );
 }
@@ -2019,6 +2022,8 @@
 
     *(LB_DESCR **)wnd->wExtra = descr;
 
+/*    if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY;
+ */
     if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL;
     if (descr->style & LBS_MULTICOLUMN) descr->style &= ~LBS_OWNERDRAWVARIABLE;
     if (descr->style & LBS_OWNERDRAWVARIABLE) descr->style |= LBS_NOINTEGRALHEIGHT;
@@ -2066,7 +2071,8 @@
 /***********************************************************************
  *           ListBoxWndProc
  */
-LRESULT ListBoxWndProc(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+LRESULT WINAPI ListBoxWndProc( HWND32 hwnd, UINT32 msg,
+                               WPARAM32 wParam, LPARAM lParam )
 {
     LRESULT ret;
     LB_DESCR *descr;
@@ -2491,7 +2497,8 @@
  *  NOTE: in Windows, winproc address of the ComboLBox is the same 
  *	  as that of the Listbox.
  */
-LRESULT ComboLBWndProc(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
+LRESULT WINAPI ComboLBWndProc( HWND32 hwnd, UINT32 msg,
+                               WPARAM32 wParam, LPARAM lParam )
 {
     LRESULT lRet = 0;
     WND *wnd = WIN_FindWndPtr( hwnd );
diff --git a/controls/menu.c b/controls/menu.c
index 769084b..5a1e28c 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -51,26 +51,24 @@
 #define MM_SETMENUHANDLE	(WM_USER + 0)
 #define MM_GETMENUHANDLE	(WM_USER + 1)
 
-typedef struct
-{
-  HBITMAP32	hCheckBit;
-  HBITMAP32	hUnCheckBit;
-} CBITMAPS, *PCBITMAPS;
-
 /* Menu item structure */
-typedef struct
-{
-    UINT32      item_flags;    /* Item flags */
-    UINT32      item_id;       /* Item or popup id */
+typedef struct {
+    /* ----------- MENUITEMINFO Stuff ----------- */
+    UINT32 fType;		/* Item type. */
+    UINT32 fState;		/* Item state.  */
+    UINT32 wID;			/* Item id.  */
+    HMENU32 hSubMenu;		/* Pop-up menu.  */
+    HBITMAP32 hCheckBit;	/* Bitmap when checked.  */
+    HBITMAP32 hUnCheckBit;	/* Bitmap when unchecked.  */
+    LPSTR text;			/* Item text or bitmap handle.  */
+    DWORD dwItemData;		/* Application defined.  */
+    /* ----------- Wine stuff ----------- */
     RECT32      rect;          /* Item area (relative to menu window) */
     UINT32      xTab;          /* X position of text after Tab */
-    PCBITMAPS	pCB;	       /* checkmark bitmaps */
-    LPSTR       text;          /* Item text or bitmap handle */
 } MENUITEM;
 
 /* Popup menu structure */
-typedef struct
-{
+typedef struct {
     WORD        wFlags;       /* Menu flags (MF_POPUP, MF_SYSMENU) */
     WORD        wMagic;       /* Magic number */
     HQUEUE16    hTaskQ;       /* Task queue for this menu */
@@ -98,6 +96,7 @@
 } MTRACKER;
 
 #define MENU_MAGIC   0x554d  /* 'MU' */
+#define IS_A_MENU(pmenu) ((pmenu) && (pmenu)->wMagic == MENU_MAGIC)
 
 #define ITEM_PREV		-1
 #define ITEM_NEXT		 1
@@ -112,24 +111,33 @@
 #define POPUP_YSHADE		4
 
   /* Space between 2 menu bar items */
-int MENU_BAR_ITEMS_SPACE = 12;
+#define MENU_BAR_ITEMS_SPACE 12
 
   /* Minimum width of a tab character */
-int MENU_TAB_SPACE = 8;
+#define MENU_TAB_SPACE 8
 
   /* Height of a separator item */
-int SEPARATOR_HEIGHT = 5;
+#define SEPARATOR_HEIGHT 5
 
   /* (other menu->FocusedItem values give the position of the focused item) */
 #define NO_SELECTED_ITEM  0xffff
 
-#define IS_STRING_ITEM(flags) \
-    (!((flags) & (MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)))
+#define MENU_ITEM_TYPE(flags) \
+  ((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR))
+
+#define IS_STRING_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_STRING)
+
 #define IS_SYSTEM_MENU(menu)  \
 	(!((menu)->wFlags & MF_POPUP) && (menu)->wFlags & MF_SYSMENU)
 #define IS_SYSTEM_POPUP(menu) \
 	((menu)->wFlags & MF_POPUP && (menu)->wFlags & MF_SYSMENU)
 
+#define TYPE_MASK (MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \
+		   MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \
+		   MFT_RIGHTORDER | MFT_RIGHTJUSTIFY | \
+		   MF_POPUP | MF_SYSMENU | MF_HELP)
+#define STATE_MASK (~TYPE_MASK)
+
   /* 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;
@@ -150,6 +158,92 @@
 
 
 /***********************************************************************
+ *           debug_print_menuitem
+ *
+ * Print a menuitem in readable form.
+ */
+
+#define MENUOUT(text) \
+  dprintf_menu (stddeb, "%s%s", (count++ ? "," : ""), (text))
+
+#define MENUFLAG(bit,text) \
+  do { \
+    if (flags & (bit)) { flags &= ~(bit); MENUOUT ((text)); } \
+  } while (0)
+
+static void debug_print_menuitem(const char *prefix, MENUITEM * mp, const char *postfix)
+{
+    dprintf_menu(stddeb, "%s", prefix);
+    if (mp) {
+	UINT32 flags = mp->fType;
+	int typ = MENU_ITEM_TYPE(flags);
+	dprintf_menu(stddeb, "{ ID=0x%x", mp->wID);
+	if (flags & MF_POPUP)
+	    dprintf_menu(stddeb, ", Sub=0x%x", mp->hSubMenu);
+	if (flags) {
+	    int count = 0;
+	    dprintf_menu(stddeb, ", Typ=");
+	    if (typ == MFT_STRING)
+		/* Nothing */ ;
+	    else if (typ == MFT_SEPARATOR)
+		MENUOUT("sep");
+	    else if (typ == MFT_OWNERDRAW)
+		MENUOUT("own");
+	    else if (typ == MFT_BITMAP)
+		MENUOUT("bit");
+	    else
+		MENUOUT("???");
+	    flags -= typ;
+
+	    MENUFLAG(MF_POPUP, "pop");
+	    MENUFLAG(MFT_MENUBARBREAK, "barbrk");
+	    MENUFLAG(MFT_MENUBREAK, "brk");
+	    MENUFLAG(MFT_RADIOCHECK, "radio");
+	    MENUFLAG(MFT_RIGHTORDER, "rorder");
+	    MENUFLAG(MF_SYSMENU, "sys");
+	    MENUFLAG(MFT_RIGHTJUSTIFY, "right");
+
+	    if (flags)
+		dprintf_menu(stddeb, "+0x%x", flags);
+	}
+	flags = mp->fState;
+	if (flags) {
+	    int count = 0;
+	    dprintf_menu(stddeb, ", State=");
+	    MENUFLAG(MFS_GRAYED, "grey");
+	    MENUFLAG(MFS_DISABLED, "dis");
+	    MENUFLAG(MFS_CHECKED, "check");
+	    MENUFLAG(MFS_HILITE, "hi");
+	    MENUFLAG(MF_USECHECKBITMAPS, "usebit");
+	    MENUFLAG(MF_MOUSESELECT, "mouse");
+	    if (flags)
+		dprintf_menu(stddeb, "+0x%x", flags);
+	}
+	if (mp->hCheckBit)
+	    dprintf_menu(stddeb, ", Chk=0x%x", mp->hCheckBit);
+	if (mp->hUnCheckBit)
+	    dprintf_menu(stddeb, ", Unc=0x%x", mp->hUnCheckBit);
+
+	if (typ == MFT_STRING) {
+	    if (mp->text)
+		dprintf_menu(stddeb, ", Text=\"%s\"", mp->text);
+	    else
+		dprintf_menu(stddeb, ", Text=Null");
+	} else if (mp->text == NULL)
+	    /* Nothing */ ;
+	else
+	    dprintf_menu(stddeb, ", Text=%p", mp->text);
+	dprintf_menu(stddeb, " }");
+    } else {
+	dprintf_menu(stddeb, "NULL");
+    }
+    dprintf_menu(stddeb, "%s", postfix);
+}
+
+#undef MENUOUT
+#undef MENUFLAG
+
+/***********************************************************************
  *           MENU_CopySysPopup
  *
  * Return the default system menu.
@@ -167,7 +261,7 @@
 	fprintf( stderr, "Unable to load default system menu\n" );
     }
 
-    dprintf_menu( stddeb, "MENU_CopySysPopup: returning %d.\n", hMenu );
+    dprintf_menu( stddeb, "MENU_CopySysPopup: returning %x.\n", hMenu );
 
     return hMenu;
 }
@@ -200,7 +294,8 @@
 	{
 	    InsertMenu32A( hMenu, -1, MF_SYSMENU | MF_POPUP | MF_BYPOSITION, hPopupMenu, NULL );
 
-	    menu->items[0].item_flags = MF_SYSMENU | MF_POPUP;
+            menu->items[0].fType = MF_SYSMENU | MF_POPUP;
+            menu->items[0].fState = 0;
 	    menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hPopupMenu);
 	    menu->wFlags |= MF_SYSMENU;
 
@@ -260,7 +355,7 @@
  *
  * Grey the appropriate items in System menu.
  */
-void MENU_InitSysMenuPopup( HMENU32 hmenu, DWORD style, DWORD clsStyle )
+static void MENU_InitSysMenuPopup( HMENU32 hmenu, DWORD style, DWORD clsStyle )
 {
     BOOL32 gray;
 
@@ -299,7 +394,7 @@
 	return i;
 
     for( ; i < menu->nItems; ++i ) {
-	if( menu->items[i].item_flags & MF_MENUBARBREAK )
+	if (menu->items[i].fType & MF_MENUBARBREAK)
 	    return i;
     }
 
@@ -329,14 +424,14 @@
     /* Find the start of the column */
 
     for(i = menu->FocusedItem; i != 0 &&
-	    !(menu->items[i].item_flags & MF_MENUBARBREAK);
+	 !(menu->items[i].fType & MF_MENUBARBREAK);
 	--i); /* empty */
 
     if(i == 0)
 	return NO_SELECTED_ITEM;
 
     for(--i; i != 0; --i) {
-	if(menu->items[i].item_flags & MF_MENUBARBREAK)
+	if (menu->items[i].fType & MF_MENUBARBREAK)
 	    break;
     }
 
@@ -369,14 +464,14 @@
         MENUITEM *item = menu->items;
 	for (i = 0; i < menu->nItems; i++, item++)
 	{
-	    if (item->item_id == *nPos)
+	    if (item->wID == *nPos)
 	    {
 		*nPos = i;
 		return item;
 	    }
-	    else if (item->item_flags & MF_POPUP)
+	    else if (item->fType & MF_POPUP)
 	    {
-		HMENU32 hsubmenu = (HMENU32)item->item_id;
+		HMENU32 hsubmenu = item->hSubMenu;
 		MENUITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags );
 		if (subitem)
 		{
@@ -395,13 +490,8 @@
 static void MENU_FreeItemData( MENUITEM* item )
 {
     /* delete text */
-
-    if (IS_STRING_ITEM(item->item_flags) && item->text)
+    if (IS_STRING_ITEM(item->fType) && item->text)
         HeapFree( SystemHeap, 0, item->text );
-
-    /* delete checkmark stuff */
-
-    if (item->pCB) HeapFree( SystemHeap, 0, item->pCB );
 }
 
 /***********************************************************************
@@ -465,7 +555,7 @@
 	     key = toupper(key);
 	     for (i = 0; i < menu->nItems; i++, item++)
 	     {
-		if (IS_STRING_ITEM(item->item_flags))
+		if (IS_STRING_ITEM(item->fType))
 		{
 		    char *p = strchr( item->text, '&' );
 		    if (p && (p[1] != '&') && (toupper(p[1]) == key)) return i;
@@ -492,29 +582,29 @@
     DWORD dwSize;
     char *p;
 
-    dprintf_menu( stddeb, "MENU_CalcItemSize: HDC %p, item '%s', at "
-		  "(%d, %d) %s\n", (void *)hdc, lpitem->text, orgX, orgY,
-		  menuBar ? "(MenuBar)" : "" );
+    dprintf_menu(stddeb, "MENU_CalcItemSize: HDC 0x%x at (%d,%d): ",
+                 hdc, orgX, orgY);
+    debug_print_menuitem("", lpitem, (menuBar ? " (MenuBar)\n" : "\n"));
 
     SetRect32( &lpitem->rect, orgX, orgY, orgX, orgY );
 
-    if (lpitem->item_flags & MF_OWNERDRAW)
+    if (lpitem->fType & MF_OWNERDRAW)
     {
         MEASUREITEMSTRUCT32 mis;
         mis.CtlType    = ODT_MENU;
-        mis.itemID     = lpitem->item_id;
+        mis.itemID     = lpitem->wID;
         mis.itemData   = (DWORD)lpitem->text;
         mis.itemHeight = 16;
         mis.itemWidth  = 30;
         SendMessage32A( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)&mis );
         lpitem->rect.bottom += mis.itemHeight;
         lpitem->rect.right  += mis.itemWidth;
-        dprintf_menu( stddeb, "DrawMenuItem: MeasureItem %04x %dx%d!\n",
-                      lpitem->item_id, mis.itemWidth, mis.itemHeight );
+        dprintf_menu(stddeb, "MENU_CalcItemSize: %08x %dx%d\n",
+                     lpitem->wID, mis.itemWidth, mis.itemHeight);
         return;
     } 
 
-    if (lpitem->item_flags & MF_SEPARATOR)
+    if (lpitem->fType & MF_SEPARATOR)
     {
 	lpitem->rect.bottom += SEPARATOR_HEIGHT;
 	return;
@@ -523,11 +613,11 @@
     if (!menuBar)
     {
 	lpitem->rect.right += 2 * check_bitmap_width;
-	if (lpitem->item_flags & MF_POPUP)
+	if (lpitem->fType & MF_POPUP)
 	    lpitem->rect.right += arrow_bitmap_width;
     }
 
-    if (lpitem->item_flags & MF_BITMAP)
+    if (lpitem->fType & MF_BITMAP)
     {
 	BITMAP32 bm;
         if (GetObject32A( (HBITMAP32)lpitem->text, sizeof(bm), &bm ))
@@ -540,7 +630,7 @@
     
     /* If we get here, then it must be a text item */
 
-    if (IS_STRING_ITEM( lpitem->item_flags ))
+    if (IS_STRING_ITEM( lpitem->fType ))
     {
         dwSize = GetTextExtent( hdc, lpitem->text, strlen(lpitem->text) );
         lpitem->rect.right  += LOWORD(dwSize);
@@ -595,19 +685,16 @@
 	for (i = start; i < lppop->nItems; i++, lpitem++)
 	{
 	    if ((i != start) &&
-		(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+		(lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 
-	    dprintf_menu( stddeb, "MENU_PopupMenuCalcSize: calling "
-			  "MENU_CalcItemSize on '%s', org=(%d, %d)\n",
-			  lpitem->text, orgX, orgY );
 	    if(TWEAK_Win95Look)
 		++orgY;
 
 	    MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, FALSE );
-            if (lpitem->item_flags & MF_MENUBARBREAK) orgX++;
+            if (lpitem->fType & MF_MENUBARBREAK) orgX++;
 	    maxX = MAX( maxX, lpitem->rect.right );
 	    orgY = lpitem->rect.bottom;
-	    if (IS_STRING_ITEM(lpitem->item_flags) && lpitem->xTab)
+	    if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
 	    {
 		maxTab = MAX( maxTab, lpitem->xTab );
 		maxTabWidth = MAX(maxTabWidth,lpitem->rect.right-lpitem->xTab);
@@ -619,7 +706,7 @@
 	for (lpitem = &lppop->items[start]; start < i; start++, lpitem++)
 	{
 	    lpitem->rect.right = maxX;
-	    if (IS_STRING_ITEM(lpitem->item_flags) && lpitem->xTab)
+	    if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
                 lpitem->xTab = maxTab;
 	}
 	lppop->Height = MAX( lppop->Height, orgY );
@@ -663,9 +750,9 @@
 	  /* Parse items until line break or end of menu */
 	for (i = start; i < lppop->nItems; i++, lpitem++)
 	{
-	    if ((helpPos == -1) && (lpitem->item_flags & MF_HELP)) helpPos = i;
+	    if ((helpPos == -1) && (lpitem->fType & MF_HELP)) helpPos = i;
 	    if ((i != start) &&
-		(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+		(lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 
 
 	    dprintf_menu( stddeb, "MENU_MenuBarCalcSize: calling "
@@ -716,34 +803,36 @@
 {
     RECT32 rect;
 
-    if (lpitem->item_flags & MF_SYSMENU)
+    debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, "\n");
+
+    if (lpitem->fType & MF_SYSMENU)
     {
 	if( !IsIconic32(hwnd) ) {
 	    if(TWEAK_Win95Look)
 		NC_DrawSysButton95( hwnd, hdc,
-				    lpitem->item_flags &
+				    lpitem->fState &
 				    (MF_HILITE | MF_MOUSESELECT) );
 	    else
 		NC_DrawSysButton( hwnd, hdc, 
-				  lpitem->item_flags &
+				  lpitem->fState &
 				  (MF_HILITE | MF_MOUSESELECT) );
 	}
 
 	return;
     }
 
-    if (lpitem->item_flags & MF_OWNERDRAW)
+    if (lpitem->fType & MF_OWNERDRAW)
     {
         DRAWITEMSTRUCT32 dis;
 
         dprintf_menu( stddeb, "DrawMenuItem: Ownerdraw!\n" );
         dis.CtlType   = ODT_MENU;
-        dis.itemID    = lpitem->item_id;
+        dis.itemID    = lpitem->wID;
         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;
+        if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED;
+        if (lpitem->fState & MF_GRAYED)  dis.itemState |= ODS_GRAYED;
+        if (lpitem->fState & MF_HILITE)  dis.itemState |= ODS_SELECTED;
         dis.itemAction = ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS;
         dis.hwndItem   = hwnd;
         dis.hDC        = hdc;
@@ -752,7 +841,7 @@
         return;
     }
 
-    if (menuBar && (lpitem->item_flags & MF_SEPARATOR)) return;
+    if (menuBar && (lpitem->fType & MF_SEPARATOR)) return;
     rect = lpitem->rect;
 
     /* Draw the background */
@@ -770,7 +859,7 @@
 	*/
     }
 
-    if (lpitem->item_flags & MF_HILITE) {
+    if (lpitem->fState & MF_HILITE) {
 	RECT32  r = rect;
 	r.top += MENU_HighlightTopNudge;
 	r.bottom += MENU_HighlightBottomNudge;
@@ -791,7 +880,7 @@
 
       /* Draw the separator bar (if any) */
 
-    if (!menuBar && (lpitem->item_flags & MF_MENUBARBREAK))
+    if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
     {
 	if(TWEAK_Win95Look)
 	    TWEAK_DrawMenuSeparatorVert95(hdc, rect.left - 1, 3, height - 3);
@@ -801,7 +890,7 @@
 	    LineTo32( hdc, rect.left, height );
 	}
     }
-    if (lpitem->item_flags & MF_SEPARATOR)
+    if (lpitem->fType & MF_SEPARATOR)
     {
 	if(TWEAK_Win95Look)
 	    TWEAK_DrawMenuSeparatorHoriz95(hdc, rect.left + 1,
@@ -818,9 +907,9 @@
 
       /* Setup colors */
 
-    if (lpitem->item_flags & MF_HILITE)
+    if (lpitem->fState & MF_HILITE)
     {
-	if (lpitem->item_flags & MF_GRAYED)
+	if (lpitem->fState & MF_GRAYED)
 	    SetTextColor32( hdc, GetSysColor32( COLOR_GRAYTEXT ) );
 	else
 	    SetTextColor32( hdc, GetSysColor32( COLOR_HIGHLIGHTTEXT ) );
@@ -828,7 +917,7 @@
     }
     else
     {
-	if (lpitem->item_flags & MF_GRAYED)
+	if (lpitem->fState & MF_GRAYED)
 	    SetTextColor32( hdc, GetSysColor32( COLOR_GRAYTEXT ) );
 	else
 	    SetTextColor32( hdc, GetSysColor32( COLOR_MENUTEXT ) );
@@ -846,18 +935,18 @@
 	   * is 1 for a white pixel and 0 for a black one. 
 	   */
 
-	if (lpitem->item_flags & MF_CHECKED)
-            GRAPH_DrawBitmap( hdc, lpitem->pCB ? lpitem->pCB->hCheckBit
+	if (lpitem->fState & MF_CHECKED)
+            GRAPH_DrawBitmap( hdc, lpitem->hCheckBit ? lpitem->hCheckBit
 			      : hStdCheck, rect.left, (y - check_bitmap_height) / 2, 
 			      0, 0, check_bitmap_width, check_bitmap_height, TRUE );
-	else if (lpitem->pCB)
-	    GRAPH_DrawBitmap( hdc, lpitem->pCB->hUnCheckBit, rect.left, 
+        else if (lpitem->hUnCheckBit)
+            GRAPH_DrawBitmap( hdc, lpitem->hUnCheckBit, rect.left,
 			      (y - check_bitmap_height) / 2, 0, 0,
 			      check_bitmap_width, check_bitmap_height, TRUE );
 
 	  /* Draw the popup-menu arrow */
 
-	if (lpitem->item_flags & MF_POPUP)
+	if (lpitem->fType & MF_POPUP)
 	{
 	    GRAPH_DrawBitmap( hdc, hStdMnArrow,
 			      rect.right-arrow_bitmap_width-1,
@@ -871,7 +960,7 @@
 
       /* Draw the item text or bitmap */
 
-    if (lpitem->item_flags & MF_BITMAP)
+    if (lpitem->fType & MF_BITMAP)
     {
 	GRAPH_DrawBitmap( hdc, (HBITMAP32)lpitem->text,
                           rect.left, rect.top, 0, 0,
@@ -879,7 +968,7 @@
 	return;
     }
     /* No bitmap - process text if present */
-    else if (IS_STRING_ITEM(lpitem->item_flags))
+    else if (IS_STRING_ITEM(lpitem->fType))
     {
 	register int i;
 
@@ -902,12 +991,13 @@
 	    rect.left += MENU_ItemLeftNudge;
 	}
 
-	if(!TWEAK_Win95Look || !(lpitem->item_flags & MF_GRAYED)) {
+	if(!TWEAK_Win95Look || !(lpitem->fState & MF_GRAYED)) {
 	    DrawText32A( hdc, lpitem->text, i, &rect,
 			 DT_LEFT | DT_VCENTER | DT_SINGLELINE );
 	}
 	else {
-	    if (!(lpitem->item_flags & MF_HILITE)) {
+	    if (!(lpitem->fState & MF_HILITE))
+            {
 		++rect.left;
 		++rect.top;
 		++rect.right;
@@ -1119,7 +1209,7 @@
     if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
     {
-	menu->items[menu->FocusedItem].item_flags &= ~(MF_HILITE|MF_MOUSESELECT);
+	menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
 
@@ -1220,7 +1310,7 @@
     if (!lppop->nItems) return;
 
     if ((wIndex != NO_SELECTED_ITEM) && 
-	(lppop->items[wIndex].item_flags & MF_SEPARATOR))
+	(lppop->items[wIndex].fType & MF_SEPARATOR))
 	wIndex = NO_SELECTED_ITEM;
 
     if (lppop->FocusedItem == wIndex) return;
@@ -1230,7 +1320,7 @@
       /* Clear previous highlighted item */
     if (lppop->FocusedItem != NO_SELECTED_ITEM) 
     {
-	lppop->items[lppop->FocusedItem].item_flags &=~(MF_HILITE|MF_MOUSESELECT);
+	lppop->items[lppop->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
 	MENU_DrawMenuItem(lppop->hWnd,hdc,&lppop->items[lppop->FocusedItem],
                           lppop->Height, !(lppop->wFlags & MF_POPUP) );
     }
@@ -1239,13 +1329,16 @@
     lppop->FocusedItem = wIndex;
     if (lppop->FocusedItem != NO_SELECTED_ITEM) 
     {
-	lppop->items[lppop->FocusedItem].item_flags |= MF_HILITE;
+	lppop->items[lppop->FocusedItem].fState |= MF_HILITE;
 	MENU_DrawMenuItem( lppop->hWnd, hdc, &lppop->items[lppop->FocusedItem],
                            lppop->Height, !(lppop->wFlags & MF_POPUP) );
         if (sendMenuSelect)
-	    SendMessage16( hwndOwner, WM_MENUSELECT,
-                           lppop->items[lppop->FocusedItem].item_id,
-                           MAKELONG( lppop->items[lppop->FocusedItem].item_flags | MF_MOUSESELECT, hmenu));
+        {
+            MENUITEM *ip = &lppop->items[lppop->FocusedItem];
+	    SendMessage16( hwndOwner, WM_MENUSELECT, ip->wID,
+                           MAKELONG(ip->fType | (ip->fState | MF_MOUSESELECT),
+                                    hmenu) );
+        }
     }
     else if (sendMenuSelect)
         SendMessage16( hwndOwner, WM_MENUSELECT, hmenu,
@@ -1275,7 +1368,7 @@
 	if( menu->nItems == 1 ) return; else
 	for (i = menu->FocusedItem + offset ; i >= 0 && i < menu->nItems 
 					    ; i += offset)
-	    if (!(menu->items[i].item_flags & MF_SEPARATOR))
+	    if (!(menu->items[i].fType & MF_SEPARATOR))
 	    {
 		MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
 		return;
@@ -1284,7 +1377,7 @@
 
     for ( i = (offset > 0) ? 0 : menu->nItems - 1; 
 		  i >= 0 && i < menu->nItems ; i += offset)
-	if (!(menu->items[i].item_flags & MF_SEPARATOR))
+	if (!(menu->items[i].fType & MF_SEPARATOR))
 	{
 	    MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
 	    return;
@@ -1301,11 +1394,9 @@
 static BOOL32 MENU_SetItemData( MENUITEM *item, UINT32 flags, UINT32 id,
                                 LPCSTR str )
 {
-    LPSTR prevText = IS_STRING_ITEM(item->item_flags) ? item->text : NULL;
+    LPSTR prevText = IS_STRING_ITEM(item->fType) ? item->text : NULL;
 
-    dprintf_menu(stddeb,"SetItemData: %04x [%08x] '%s'  -> %04x [%08x] '%s'\n",
-		 item->item_flags, item->item_id, prevText ? prevText : "",
-		 flags, id, (IS_STRING_ITEM(flags) && str) ? str : "" );
+    debug_print_menuitem("MENU_SetItemData from: ", item, "\n");
 
     if (IS_STRING_ITEM(flags))
     {
@@ -1331,22 +1422,32 @@
     else if (flags & MF_OWNERDRAW) item->text = (LPSTR)str;
     else item->text = NULL;
 
-    if (item->item_flags & MF_POPUP && item->item_id != id )
-	DestroyMenu32( (HMENU32)item->item_id );   /* ModifyMenu() spec */
+    if (item->fType & MF_POPUP && item->hSubMenu != id )
+	DestroyMenu32( item->hSubMenu );   /* ModifyMenu() spec */
 
     if (flags & MF_POPUP)
     {
-	POPUPMENU*	menu = (POPUPMENU *)USER_HEAP_LIN_ADDR((UINT16)id);
-	if( menu && menu->wMagic == MENU_MAGIC) menu->wFlags |= MF_POPUP;
+	POPUPMENU *menu = (POPUPMENU *)USER_HEAP_LIN_ADDR((UINT16)id);
+        if (IS_A_MENU(menu)) menu->wFlags |= MF_POPUP;
 	else
-	    return (item->item_id = item->item_flags = FALSE);
+        {
+            item->wID = 0;
+            item->hSubMenu = 0;
+            item->fType = 0;
+            item->fState = 0;
+	    return FALSE;
+        }
     }
 
-    item->item_flags = flags & ~(MF_HILITE | MF_MOUSESELECT);
-    item->item_id    = id;
+    item->fType = flags & TYPE_MASK;
+    item->fState = (flags & STATE_MASK) &
+        ~(MF_HILITE | MF_MOUSESELECT | MF_BYPOSITION);
+    item->wID = item->hSubMenu = id;
 
     SetRectEmpty32( &item->rect );
     if (prevText) HeapFree( SystemHeap, 0, prevText );
+
+    debug_print_menuitem("MENU_SetItemData to  : ", item, "\n");
     return TRUE;
 }
 
@@ -1470,55 +1571,50 @@
  */
 static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU32 hMenu)
 {
-    DWORD flags;
-    DWORD state;
-    DWORD id;
-    LPCWSTR str;
     WORD resinfo;
+    do {
+	MENUITEMINFO32W mii;
 
-    do
-    {
-        /* printf ("%p:", res); */
-
-        flags = GET_DWORD(res);
+	mii.cbSize = sizeof(mii);
+	mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
+	mii.fType = GET_DWORD(res);
         res += sizeof(DWORD);
-        state = GET_DWORD(res);
+	mii.fState = GET_DWORD(res);
         res += sizeof(DWORD);
-        id = GET_DWORD(res);
+	mii.wID = GET_DWORD(res);
         res += sizeof(DWORD);
 	resinfo = GET_WORD(res); /* FIXME: for 16-bit apps this is a byte.  */
         res += sizeof(WORD);
 	/* Align the text on a word boundary.  */
 	res += (~((int)res - 1)) & 1;
-        str = (LPCWSTR)res;
-        res += (1 + lstrlen32W (str)) * sizeof(WCHAR);
+	mii.dwTypeData = (LPWSTR) res;
+	res += (1 + lstrlen32W(mii.dwTypeData)) * sizeof(WCHAR);
 	/* Align the following fields on a dword boundary.  */
 	res += (~((int)res - 1)) & 3;
 
         /* FIXME: This is inefficient and cannot be optimised away by gcc.  */
 	{
-	  LPSTR newstr = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
-	  dprintf_menu (stddeb, "Menu item: [%08lx,%08lx,%04lx,%04x,%s]\n",
-			flags, state, id, resinfo, newstr);
+	    LPSTR newstr = HEAP_strdupWtoA(GetProcessHeap(),
+					   0, mii.dwTypeData);
+	    dprintf_menu(stddeb, "Menu item: [%08x,%08x,%04x,%04x,%s]\n",
+			 mii.fType, mii.fState, mii.wID, resinfo, newstr);
 	  HeapFree( GetProcessHeap(), 0, newstr );
 	}
 
-        if (resinfo & 1) /* Pop-up? */
-        {
+	if (resinfo & 1) {	/* Pop-up? */
 	    DWORD helpid = GET_DWORD(res); /* FIXME: use this.  */
-            HMENU32 hSubMenu = CreatePopupMenu32();
 	    res += sizeof(DWORD);
-            if (!hSubMenu) return NULL;
-            if (!(res = MENUEX_ParseResource( res, hSubMenu)))
+	    mii.hSubMenu = CreatePopupMenu32();
+	    if (!mii.hSubMenu)
+		return NULL;
+	    if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
+		DestroyMenu32(mii.hSubMenu);
                 return NULL;
-            AppendMenu32W( hMenu, flags | MF_POPUP /* HACK!  FIXME */,
-			   (UINT32)hSubMenu, (LPCWSTR)str );
         }
-        else  /* Not a popup */
-        {
-	  AppendMenu32W( hMenu, flags, id,
-			 *(LPCWSTR)str ? (LPCWSTR)str : NULL );
+	    mii.fMask |= MIIM_SUBMENU;
+	    mii.fType |= MF_POPUP;
         }
+	InsertMenuItem32W(hMenu, -1, MF_BYPOSITION, &mii);
     } while (!(resinfo & MF_END));
     return res;
 }
@@ -1539,9 +1635,8 @@
     if (menu->FocusedItem == NO_SELECTED_ITEM) return 0;
 
     item = &menu->items[menu->FocusedItem];
-    if ((item->item_flags & (MF_POPUP | MF_MOUSESELECT))
-			 == (MF_POPUP | MF_MOUSESELECT))
-	return (HMENU32)item->item_id;
+    if ((item->fType & MF_POPUP) && (item->fState & MF_MOUSESELECT))
+        return item->hSubMenu;
     return 0;
 }
 
@@ -1565,10 +1660,10 @@
 	if (menu->FocusedItem != NO_SELECTED_ITEM)
 	{
 	    item = &menu->items[menu->FocusedItem];
-	    if (!(item->item_flags & MF_POPUP) ||
-		!(item->item_flags & MF_MOUSESELECT)) return;
-	    item->item_flags &= ~MF_MOUSESELECT;
-	    hsubmenu = (HMENU32)item->item_id;
+	    if (!(item->fType & MF_POPUP) ||
+		!(item->fState & MF_MOUSESELECT)) return;
+	    item->fState &= ~MF_MOUSESELECT;
+	    hsubmenu = item->hSubMenu;
 	} else return;
 
 	submenu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hsubmenu );
@@ -1609,17 +1704,18 @@
          (menu->FocusedItem == NO_SELECTED_ITEM)) return hmenu;
 
     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;
+    if (!(item->fType & MF_POPUP) ||
+         (item->fState & (MF_GRAYED | MF_DISABLED))) return hmenu;
+    item->fState |= MF_MOUSESELECT;
 
     if (IS_SYSTEM_MENU(menu))
     {
-	MENU_InitSysMenuPopup((HMENU16)item->item_id, wndPtr->dwStyle, wndPtr->class->style);
+	MENU_InitSysMenuPopup(item->hSubMenu, wndPtr->dwStyle, wndPtr->class->style);
 
 	NC_GetSysPopupPos( wndPtr, &rect );
 	rect.top = rect.bottom;
-	rect.right = SYSMETRICS_CXSIZE; rect.bottom = SYSMETRICS_CYSIZE;
+	rect.right = SYSMETRICS_CXSIZE;
+        rect.bottom = SYSMETRICS_CYSIZE;
     }
     else
     {
@@ -1639,11 +1735,11 @@
 	}
     }
 
-    MENU_ShowPopup( hwndOwner, (HMENU16)item->item_id, menu->FocusedItem,
+    MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem,
 		    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
-        MENU_MoveSelection( hwndOwner, (HMENU32)item->item_id, ITEM_NEXT );
-    return (HMENU32)item->item_id;
+        MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
+    return item->hSubMenu;
 }
 
 /***********************************************************************
@@ -1656,12 +1752,11 @@
    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hMenu );
    register UINT32 ht = menu->FocusedItem;
 
-#define HAS_POPUP(item)	(((item).item_flags & (MF_POPUP | MF_MOUSESELECT)) \
-			== (MF_POPUP | MF_MOUSESELECT))
    /* try subpopup first (if any) */
-   ht = (ht != NO_SELECTED_ITEM && HAS_POPUP(menu->items[ht]))
-	? (UINT32)MENU_PtMenu( menu->items[ht].item_id, pt ) : 0;
-#undef HAS_POPUP
+    ht = (ht != NO_SELECTED_ITEM &&
+          (menu->items[ht].fType & MF_POPUP) &&
+          (menu->items[ht].fState & MF_MOUSESELECT))
+        ? (UINT32) MENU_PtMenu(menu->items[ht].hSubMenu, pt) : 0;
 
    if( !ht )	/* check the current window (avoiding WM_HITTEST) */
    {
@@ -1694,18 +1789,21 @@
 	(menu->FocusedItem == NO_SELECTED_ITEM)) return TRUE;
 
     item = &menu->items[menu->FocusedItem];
-    if (!(item->item_flags & MF_POPUP))
+
+    dprintf_menu(stddeb, "MENU_ExecFocusedItem: %08x %08x %08x\n",
+                 hMenu, item->wID, item->hSubMenu);
+
+    if (!(item->fType & MF_POPUP))
     {
-	if (!(item->item_flags & (MF_GRAYED | MF_DISABLED)))
+	if (!(item->fState & (MF_GRAYED | MF_DISABLED)))
 	{
 	    if( menu->wFlags & MF_SYSMENU )
 	    {
-		PostMessage16( pmt->hOwnerWnd, WM_SYSCOMMAND, item->item_id,
+		PostMessage16( pmt->hOwnerWnd, WM_SYSCOMMAND, item->hSubMenu,
 			       MAKELPARAM((INT16)pmt->pt.x, (INT16)pmt->pt.y) );
 	    }
 	    else
-		PostMessage16( pmt->hOwnerWnd, WM_COMMAND,
-					item->item_id, 0 );
+		PostMessage16( pmt->hOwnerWnd, WM_COMMAND, item->wID, 0 );
 	    return FALSE;
 	}
 	else return TRUE;
@@ -1765,9 +1863,9 @@
 	    if( ptmenu->FocusedItem == id )
 	    {
 		/* nothing to do with already selected non-popup */
-		if( !(item->item_flags & MF_POPUP) ) return TRUE;
+		if( !(item->fType & MF_POPUP) ) return TRUE;
 
-	        if( item->item_flags & MF_MOUSESELECT )
+	        if( item->fState & MF_MOUSESELECT )
 		{
 		    if( ptmenu->wFlags & MF_POPUP )
 		    {
@@ -1812,9 +1910,9 @@
 
 	if( ptmenu->FocusedItem == id )
 	{
-	    if( !(item->item_flags & MF_POPUP) )
+	    if( !(item->fType & MF_POPUP) )
 		return MENU_ExecFocusedItem( pmt, hPtMenu );
-	    hPtMenu = (HMENU32)item->item_id;
+	    hPtMenu = item->hSubMenu;
 	    if( hPtMenu == pmt->hCurrentMenu )
 	    {
 	        /* Select first item of sub-popup */    
@@ -2390,8 +2488,8 @@
 /**********************************************************************
  *           TrackPopupMenu16   (USER.416)
  */
-BOOL16 TrackPopupMenu16( HMENU16 hMenu, UINT16 wFlags, INT16 x, INT16 y,
-                         INT16 nReserved, HWND16 hWnd, const RECT16 *lpRect )
+BOOL16 WINAPI TrackPopupMenu16( HMENU16 hMenu, UINT16 wFlags, INT16 x, INT16 y,
+                           INT16 nReserved, HWND16 hWnd, const RECT16 *lpRect )
 {
     RECT32 r;
     if (lpRect)
@@ -2404,8 +2502,8 @@
 /**********************************************************************
  *           TrackPopupMenu32   (USER32.548)
  */
-BOOL32 TrackPopupMenu32( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
-                         INT32 nReserved, HWND32 hWnd, const RECT32 *lpRect )
+BOOL32 WINAPI TrackPopupMenu32( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
+                           INT32 nReserved, HWND32 hWnd, const RECT32 *lpRect )
 {
     BOOL32 ret = FALSE;
 
@@ -2419,8 +2517,8 @@
 /**********************************************************************
  *           TrackPopupMenuEx   (USER32.549)
  */
-BOOL32 TrackPopupMenuEx( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
-			 HWND32 hWnd, LPTPMPARAMS lpTpm )
+BOOL32 WINAPI TrackPopupMenuEx( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y,
+                                HWND32 hWnd, LPTPMPARAMS lpTpm )
 {
     fprintf( stderr, "TrackPopupMenuEx: not fully implemented\n" );
     return TrackPopupMenu32( hMenu, wFlags, x, y, 0, hWnd,
@@ -2432,8 +2530,8 @@
  *
  * NOTE: Windows has totally different (and undocumented) popup wndproc.
  */
-LRESULT PopupMenuWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
-                          LPARAM lParam )
+LRESULT WINAPI PopupMenuWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
+                                 LPARAM lParam )
 {    
     WND* wndPtr = WIN_FindWndPtr(hwnd);
 
@@ -2517,7 +2615,7 @@
     WND *wndPtr;
     LPPOPUPMENU lppop;
 
-    dprintf_menu( stddeb, "MENU_GetMenuBarHeight: HWND 0x%lx, width %d, "
+    dprintf_menu( stddeb, "MENU_GetMenuBarHeight: HWND 0x%x, width %d, "
 		  "at (%d, %d).\n", hwnd, menubarWidth, orgX, orgY );
     
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
@@ -2534,8 +2632,8 @@
 /*******************************************************************
  *         ChangeMenu16    (USER.153)
  */
-BOOL16 ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
-                     UINT16 id, UINT16 flags )
+BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
+                            UINT16 id, UINT16 flags )
 {
     dprintf_menu( stddeb,"ChangeMenu16: menu=%04x pos=%d data=%08lx id=%04x flags=%04x\n",
                   hMenu, pos, (DWORD)data, id, flags );
@@ -2560,8 +2658,8 @@
 /*******************************************************************
  *         ChangeMenu32A    (USER32.22)
  */
-BOOL32 ChangeMenu32A( HMENU32 hMenu, UINT32 pos, LPCSTR data,
-                      UINT32 id, UINT32 flags )
+BOOL32 WINAPI 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 );
@@ -2581,8 +2679,8 @@
 /*******************************************************************
  *         ChangeMenu32W    (USER32.23)
  */
-BOOL32 ChangeMenu32W( HMENU32 hMenu, UINT32 pos, LPCWSTR data,
-                      UINT32 id, UINT32 flags )
+BOOL32 WINAPI 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 );
@@ -2602,7 +2700,7 @@
 /*******************************************************************
  *         CheckMenuItem16    (USER.154)
  */
-BOOL16 CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
+BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
 {
     return (BOOL16)CheckMenuItem32( hMenu, id, flags );
 }
@@ -2611,16 +2709,16 @@
 /*******************************************************************
  *         CheckMenuItem32    (USER32.45)
  */
-DWORD CheckMenuItem32( HMENU32 hMenu, UINT32 id, UINT32 flags )
+DWORD WINAPI CheckMenuItem32( HMENU32 hMenu, UINT32 id, UINT32 flags )
 {
     MENUITEM *item;
     DWORD ret;
 
     dprintf_menu( stddeb,"CheckMenuItem: %04x %04x %04x\n", hMenu, id, flags );
     if (!(item = MENU_FindItem( &hMenu, &id, flags ))) return -1;
-    ret = item->item_flags & MF_CHECKED;
-    if (flags & MF_CHECKED) item->item_flags |= MF_CHECKED;
-    else item->item_flags &= ~MF_CHECKED;
+    ret = item->fState & MF_CHECKED;
+    if (flags & MF_CHECKED) item->fState |= MF_CHECKED;
+    else item->fState &= ~MF_CHECKED;
     return ret;
 }
 
@@ -2628,7 +2726,7 @@
 /**********************************************************************
  *         EnableMenuItem16    (USER.155)
  */
-BOOL16 EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
+BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
 {
     return EnableMenuItem32( hMenu, wItemID, wFlags );
 }
@@ -2637,7 +2735,7 @@
 /**********************************************************************
  *         EnableMenuItem32    (USER32.169)
  */
-BOOL32 EnableMenuItem32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
+BOOL32 WINAPI EnableMenuItem32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
 {
     BOOL32    bRet = FALSE;
     MENUITEM *item, *first = NULL;
@@ -2647,20 +2745,20 @@
 
     while( (item = MENU_FindItem( &hMenu, &wItemID, wFlags )) )
     {
-      if( !(item->item_flags & MF_POPUP) )
+      if( !(item->fType & MF_POPUP) )
       {
            /* We can't have MF_GRAYED and MF_DISABLED together */
            if (wFlags & MF_GRAYED)
            {
-  	     item->item_flags = (item->item_flags & ~MF_DISABLED) | MF_GRAYED;
+  	     item->fState = (item->fState & ~MF_DISABLED) | MF_GRAYED;
            }
            else if (wFlags & MF_DISABLED)
            {
-	     item->item_flags = (item->item_flags & ~MF_GRAYED) | MF_DISABLED;
+	     item->fState = (item->fState & ~MF_GRAYED) | MF_DISABLED;
            }
            else   /* MF_ENABLED */
            {
-	     item->item_flags &= ~(MF_GRAYED | MF_DISABLED);
+	     item->fState &= ~(MF_GRAYED | MF_DISABLED);
            } 
 	   bRet = TRUE;
 	   break;
@@ -2675,8 +2773,8 @@
 /*******************************************************************
  *         GetMenuString16    (USER.161)
  */
-INT16 GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
-                       LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
+INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
+                              LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
 {
     return GetMenuString32A( hMenu, wItemID, str, nMaxSiz, wFlags );
 }
@@ -2685,8 +2783,8 @@
 /*******************************************************************
  *         GetMenuString32A    (USER32.267)
  */
-INT32 GetMenuString32A( HMENU32 hMenu, UINT32 wItemID,
-                        LPSTR str, INT32 nMaxSiz, UINT32 wFlags )
+INT32 WINAPI GetMenuString32A( HMENU32 hMenu, UINT32 wItemID,
+                               LPSTR str, INT32 nMaxSiz, UINT32 wFlags )
 {
     MENUITEM *item;
 
@@ -2695,7 +2793,7 @@
     if (!str || !nMaxSiz) return 0;
     str[0] = '\0';
     if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0;
-    if (!IS_STRING_ITEM(item->item_flags)) return 0;
+    if (!IS_STRING_ITEM(item->fType)) return 0;
     lstrcpyn32A( str, item->text, nMaxSiz );
     dprintf_menu( stddeb, "GetMenuString32A: returning '%s'\n", str );
     return strlen(str);
@@ -2705,8 +2803,8 @@
 /*******************************************************************
  *         GetMenuString32W    (USER32.268)
  */
-INT32 GetMenuString32W( HMENU32 hMenu, UINT32 wItemID,
-                        LPWSTR str, INT32 nMaxSiz, UINT32 wFlags )
+INT32 WINAPI GetMenuString32W( HMENU32 hMenu, UINT32 wItemID,
+                               LPWSTR str, INT32 nMaxSiz, UINT32 wFlags )
 {
     MENUITEM *item;
 
@@ -2715,7 +2813,7 @@
     if (!str || !nMaxSiz) return 0;
     str[0] = '\0';
     if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0;
-    if (!IS_STRING_ITEM(item->item_flags)) return 0;
+    if (!IS_STRING_ITEM(item->fType)) return 0;
     lstrcpynAtoW( str, item->text, nMaxSiz );
     return lstrlen32W(str);
 }
@@ -2724,8 +2822,8 @@
 /**********************************************************************
  *         HiliteMenuItem16    (USER.162)
  */
-BOOL16 HiliteMenuItem16( HWND16 hWnd, HMENU16 hMenu, UINT16 wItemID,
-                         UINT16 wHilite )
+BOOL16 WINAPI HiliteMenuItem16( HWND16 hWnd, HMENU16 hMenu, UINT16 wItemID,
+                                UINT16 wHilite )
 {
     return HiliteMenuItem32( hWnd, hMenu, wItemID, wHilite );
 }
@@ -2734,8 +2832,8 @@
 /**********************************************************************
  *         HiliteMenuItem32    (USER32.317)
  */
-BOOL32 HiliteMenuItem32( HWND32 hWnd, HMENU32 hMenu, UINT32 wItemID,
-                         UINT32 wHilite )
+BOOL32 WINAPI HiliteMenuItem32( HWND32 hWnd, HMENU32 hMenu, UINT32 wItemID,
+                                UINT32 wHilite )
 {
     LPPOPUPMENU menu;
     dprintf_menu(stddeb,"HiliteMenuItem(%04x, %04x, %04x, %04x);\n", 
@@ -2752,7 +2850,7 @@
 /**********************************************************************
  *         GetMenuState16    (USER.250)
  */
-UINT16 GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
+UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
 {
     return GetMenuState32( hMenu, wItemID, wFlags );
 }
@@ -2761,31 +2859,32 @@
 /**********************************************************************
  *         GetMenuState32    (USER32.266)
  */
-UINT32 GetMenuState32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
+UINT32 WINAPI GetMenuState32( HMENU32 hMenu, UINT32 wItemID, UINT32 wFlags )
 {
     MENUITEM *item;
     dprintf_menu(stddeb,"GetMenuState(%04x, %04x, %04x);\n", 
 		 hMenu, wItemID, wFlags);
     if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
-    if (item->item_flags & MF_POPUP)
+    if (item->fType & MF_POPUP)
     {
-	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( (HMENU16)item->item_id );
+	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( item->hSubMenu );
 	if (!menu) return -1;
 	else return (menu->nItems << 8) | (menu->wFlags & 0xff);
     }
     else
-      /* Non POPUP Menus only return flags in the lower byte */
-      return (item->item_flags & 0x00ff);
+        /* Non POPUP Menus only return flags in the lower byte */
+        /* XXX ??? */
+	return ((item->fType | item->fState) & 0x00ff);
 }
 
 
 /**********************************************************************
  *         GetMenuItemCount16    (USER.263)
  */
-INT16 GetMenuItemCount16( HMENU16 hMenu )
+INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
 {
     LPPOPUPMENU	menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
-    if (!menu || (menu->wMagic != MENU_MAGIC)) return -1;
+    if (!IS_A_MENU(menu)) return -1;
     dprintf_menu( stddeb,"GetMenuItemCount16(%04x) returning %d\n", 
                   hMenu, menu->nItems );
     return menu->nItems;
@@ -2795,10 +2894,10 @@
 /**********************************************************************
  *         GetMenuItemCount32    (USER32.261)
  */
-INT32 GetMenuItemCount32( HMENU32 hMenu )
+INT32 WINAPI GetMenuItemCount32( HMENU32 hMenu )
 {
     LPPOPUPMENU	menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
-    if (!menu || (menu->wMagic != MENU_MAGIC)) return -1;
+    if (!IS_A_MENU(menu)) return -1;
     dprintf_menu( stddeb,"GetMenuItemCount32(%04x) returning %d\n", 
                   hMenu, menu->nItems );
     return menu->nItems;
@@ -2808,36 +2907,37 @@
 /**********************************************************************
  *         GetMenuItemID16    (USER.264)
  */
-UINT16 GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
+UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
 {
     LPPOPUPMENU	menu;
 
     if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1;
     if ((nPos < 0) || ((UINT16) nPos >= menu->nItems)) return -1;
-    if (menu->items[nPos].item_flags & MF_POPUP) return -1;
-    return menu->items[nPos].item_id;
+    if (menu->items[nPos].fType & MF_POPUP) return -1;
+    return menu->items[nPos].wID;
 }
 
 
 /**********************************************************************
  *         GetMenuItemID32    (USER32.262)
  */
-UINT32 GetMenuItemID32( HMENU32 hMenu, INT32 nPos )
+UINT32 WINAPI GetMenuItemID32( HMENU32 hMenu, INT32 nPos )
 {
     LPPOPUPMENU	menu;
 
     if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1;
     if ((nPos < 0) || (nPos >= menu->nItems)) return -1;
-    if (menu->items[nPos].item_flags & MF_POPUP) return -1;
-    return menu->items[nPos].item_id;
+    /* FIXME: Now that submenus can have ids, is this still right?  */
+    if (menu->items[nPos].fType & MF_POPUP) return -1;
+    return menu->items[nPos].wID;
 }
 
 
 /*******************************************************************
  *         InsertMenu16    (USER.410)
  */
-BOOL16 InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
-                     UINT16 id, SEGPTR data )
+BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
+                            UINT16 id, SEGPTR data )
 {
     UINT32 pos32 = (UINT32)pos;
     if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT32)-1;
@@ -2851,8 +2951,8 @@
 /*******************************************************************
  *         InsertMenu32A    (USER32.321)
  */
-BOOL32 InsertMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
-                      UINT32 id, LPCSTR str )
+BOOL32 WINAPI InsertMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                             UINT32 id, LPCSTR str )
 {
     MENUITEM *item;
 
@@ -2875,7 +2975,8 @@
     if (flags & MF_POPUP)  /* Set the MF_POPUP flag on the popup-menu */
 	((POPUPMENU *)USER_HEAP_LIN_ADDR((HMENU16)id))->wFlags |= MF_POPUP;
 
-    item->pCB = NULL;
+    item->hCheckBit = item->hUnCheckBit = 0;
+    item->dwItemData = 0;
     return TRUE;
 }
 
@@ -2883,8 +2984,8 @@
 /*******************************************************************
  *         InsertMenu32W    (USER32.324)
  */
-BOOL32 InsertMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
-                      UINT32 id, LPCWSTR str )
+BOOL32 WINAPI InsertMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                             UINT32 id, LPCWSTR str )
 {
     BOOL32 ret;
 
@@ -2902,7 +3003,7 @@
 /*******************************************************************
  *         AppendMenu16    (USER.411)
  */
-BOOL16 AppendMenu16( HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data )
+BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
 {
     return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
 }
@@ -2911,7 +3012,8 @@
 /*******************************************************************
  *         AppendMenu32A    (USER32.4)
  */
-BOOL32 AppendMenu32A( HMENU32 hMenu, UINT32 flags, UINT32 id, LPCSTR data )
+BOOL32 WINAPI AppendMenu32A( HMENU32 hMenu, UINT32 flags,
+                             UINT32 id, LPCSTR data )
 {
     return InsertMenu32A( hMenu, -1, flags | MF_BYPOSITION, id, data );
 }
@@ -2920,7 +3022,8 @@
 /*******************************************************************
  *         AppendMenu32W    (USER32.5)
  */
-BOOL32 AppendMenu32W( HMENU32 hMenu, UINT32 flags, UINT32 id, LPCWSTR data )
+BOOL32 WINAPI AppendMenu32W( HMENU32 hMenu, UINT32 flags,
+                             UINT32 id, LPCWSTR data )
 {
     return InsertMenu32W( hMenu, -1, flags | MF_BYPOSITION, id, data );
 }
@@ -2929,7 +3032,7 @@
 /**********************************************************************
  *         RemoveMenu16    (USER.412)
  */
-BOOL16 RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
+BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
 {
     return RemoveMenu32( hMenu, nPos, wFlags );
 }
@@ -2938,7 +3041,7 @@
 /**********************************************************************
  *         RemoveMenu32    (USER32.440)
  */
-BOOL32 RemoveMenu32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags )
+BOOL32 WINAPI RemoveMenu32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags )
 {
     LPPOPUPMENU	menu;
     MENUITEM *item;
@@ -2974,7 +3077,7 @@
 /**********************************************************************
  *         DeleteMenu16    (USER.413)
  */
-BOOL16 DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
+BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
 {
     return DeleteMenu32( hMenu, nPos, wFlags );
 }
@@ -2983,11 +3086,11 @@
 /**********************************************************************
  *         DeleteMenu32    (USER32.128)
  */
-BOOL32 DeleteMenu32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags )
+BOOL32 WINAPI DeleteMenu32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags )
 {
     MENUITEM *item = MENU_FindItem( &hMenu, &nPos, wFlags );
     if (!item) return FALSE;
-    if (item->item_flags & MF_POPUP) DestroyMenu32( (HMENU32)item->item_id );
+    if (item->fType & MF_POPUP) DestroyMenu32( item->hSubMenu );
       /* nPos is now the position of the item */
     RemoveMenu32( hMenu, nPos, wFlags | MF_BYPOSITION );
     return TRUE;
@@ -2997,8 +3100,8 @@
 /*******************************************************************
  *         ModifyMenu16    (USER.414)
  */
-BOOL16 ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
-                     UINT16 id, SEGPTR data )
+BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
+                            UINT16 id, SEGPTR data )
 {
     if (IS_STRING_ITEM(flags))
         return ModifyMenu32A( hMenu, pos, flags, id,
@@ -3010,8 +3113,8 @@
 /*******************************************************************
  *         ModifyMenu32A    (USER32.396)
  */
-BOOL32 ModifyMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
-                      UINT32 id, LPCSTR str )
+BOOL32 WINAPI ModifyMenu32A( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                             UINT32 id, LPCSTR str )
 {
     MENUITEM *item;
 
@@ -3035,8 +3138,8 @@
 /*******************************************************************
  *         ModifyMenu32W    (USER32.397)
  */
-BOOL32 ModifyMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
-                      UINT32 id, LPCWSTR str )
+BOOL32 WINAPI ModifyMenu32W( HMENU32 hMenu, UINT32 pos, UINT32 flags,
+                             UINT32 id, LPCWSTR str )
 {
     BOOL32 ret;
 
@@ -3054,7 +3157,7 @@
 /**********************************************************************
  *         CreatePopupMenu16    (USER.415)
  */
-HMENU16 CreatePopupMenu16(void)
+HMENU16 WINAPI CreatePopupMenu16(void)
 {
     return CreatePopupMenu32();
 }
@@ -3063,7 +3166,7 @@
 /**********************************************************************
  *         CreatePopupMenu32    (USER32.81)
  */
-HMENU32 CreatePopupMenu32(void)
+HMENU32 WINAPI CreatePopupMenu32(void)
 {
     HMENU32 hmenu;
     POPUPMENU *menu;
@@ -3078,7 +3181,7 @@
 /**********************************************************************
  *         GetMenuCheckMarkDimensions    (USER.417) (USER32.257)
  */
-DWORD GetMenuCheckMarkDimensions(void)
+DWORD WINAPI GetMenuCheckMarkDimensions(void)
 {
     return MAKELONG( check_bitmap_width, check_bitmap_height );
 }
@@ -3087,8 +3190,8 @@
 /**********************************************************************
  *         SetMenuItemBitmaps16    (USER.418)
  */
-BOOL16 SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
-                             HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck )
+BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
+                                    HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
 {
     return SetMenuItemBitmaps32( hMenu, nPos, wFlags, hNewUnCheck, hNewCheck );
 }
@@ -3097,8 +3200,8 @@
 /**********************************************************************
  *         SetMenuItemBitmaps32    (USER32.489)
  */
-BOOL32 SetMenuItemBitmaps32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags,
-                             HBITMAP32 hNewUnCheck, HBITMAP32 hNewCheck )
+BOOL32 WINAPI SetMenuItemBitmaps32( HMENU32 hMenu, UINT32 nPos, UINT32 wFlags,
+                                    HBITMAP32 hNewUnCheck, HBITMAP32 hNewCheck)
 {
     MENUITEM *item;
     dprintf_menu(stddeb,"SetMenuItemBitmaps(%04x, %04x, %04x, %04x, %04x)\n",
@@ -3107,17 +3210,13 @@
 
     if (!hNewCheck && !hNewUnCheck)
     {
-	if( item->pCB ) HeapFree( SystemHeap, 0, item->pCB );
-	item->pCB = NULL;
-	item->item_flags &= ~MF_USECHECKBITMAPS;
+	item->fState &= ~MF_USECHECKBITMAPS;
     }
     else  /* Install new bitmaps */
     {
-	if( item->pCB == NULL ) 
-	    item->pCB = HeapAlloc( SystemHeap, 0, sizeof(CBITMAPS));
-	item->pCB->hCheckBit = hNewCheck;
-	item->pCB->hUnCheckBit = hNewUnCheck;
-	item->item_flags |= MF_USECHECKBITMAPS;
+	item->hCheckBit = hNewCheck;
+	item->hUnCheckBit = hNewUnCheck;
+	item->fState |= MF_USECHECKBITMAPS;
     }
     return TRUE;
 }
@@ -3126,7 +3225,7 @@
 /**********************************************************************
  *         CreateMenu16    (USER.151)
  */
-HMENU16 CreateMenu16(void)
+HMENU16 WINAPI CreateMenu16(void)
 {
     return CreateMenu32();
 }
@@ -3135,7 +3234,7 @@
 /**********************************************************************
  *         CreateMenu32    (USER32.80)
  */
-HMENU32 CreateMenu32(void)
+HMENU32 WINAPI CreateMenu32(void)
 {
     HMENU32 hMenu;
     LPPOPUPMENU menu;
@@ -3158,7 +3257,7 @@
 /**********************************************************************
  *         DestroyMenu16    (USER.152)
  */
-BOOL16 DestroyMenu16( HMENU16 hMenu )
+BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
 {
     return DestroyMenu32( hMenu );
 }
@@ -3167,7 +3266,7 @@
 /**********************************************************************
  *         DestroyMenu32    (USER32.133)
  */
-BOOL32 DestroyMenu32( HMENU32 hMenu )
+BOOL32 WINAPI DestroyMenu32( HMENU32 hMenu )
 {
     dprintf_menu(stddeb,"DestroyMenu(%04x)\n", hMenu);
 
@@ -3180,7 +3279,7 @@
 	if( pTopPopupWnd && (hMenu == *(HMENU32*)pTopPopupWnd->wExtra) )
 	  *(UINT32*)pTopPopupWnd->wExtra = 0;
 
-	if (lppop && (lppop->wMagic == MENU_MAGIC))
+	if (IS_A_MENU( lppop ))
 	{
 	    lppop->wMagic = 0;  /* Mark it as destroyed */
 
@@ -3194,8 +3293,7 @@
 	        MENUITEM *item = lppop->items;
 	        for (i = lppop->nItems; i > 0; i--, item++)
 	        {
-	            if (item->item_flags & MF_POPUP)
-	                DestroyMenu32( (HMENU32)item->item_id );
+	            if (item->fType & MF_POPUP) DestroyMenu32(item->hSubMenu);
 		    MENU_FreeItemData( item );
 	        }
 	        HeapFree( SystemHeap, 0, lppop->items );
@@ -3211,7 +3309,7 @@
 /**********************************************************************
  *         GetSystemMenu16    (USER.156)
  */
-HMENU16 GetSystemMenu16( HWND16 hWnd, BOOL16 bRevert )
+HMENU16 WINAPI GetSystemMenu16( HWND16 hWnd, BOOL16 bRevert )
 {
     return GetSystemMenu32( hWnd, bRevert );
 }
@@ -3220,7 +3318,7 @@
 /**********************************************************************
  *         GetSystemMenu32    (USER32.290)
  */
-HMENU32 GetSystemMenu32( HWND32 hWnd, BOOL32 bRevert )
+HMENU32 WINAPI GetSystemMenu32( HWND32 hWnd, BOOL32 bRevert )
 {
     WND *wndPtr = WIN_FindWndPtr( hWnd );
 
@@ -3237,8 +3335,8 @@
 	    {
 		POPUPMENU *menu = (POPUPMENU*) 
 			   USER_HEAP_LIN_ADDR(wndPtr->hSysMenu);
-		if( menu->items[0].item_id == MENU_DefSysPopup )
-		    menu->items[0].item_id = MENU_CopySysPopup();
+		if( menu->items[0].hSubMenu == MENU_DefSysPopup )
+		    menu->items[0].hSubMenu = MENU_CopySysPopup();
 	    }
 	}
 
@@ -3255,7 +3353,7 @@
 /*******************************************************************
  *         SetSystemMenu16    (USER.280)
  */
-BOOL16 SetSystemMenu16( HWND16 hwnd, HMENU16 hMenu )
+BOOL16 WINAPI SetSystemMenu16( HWND16 hwnd, HMENU16 hMenu )
 {
     return SetSystemMenu32( hwnd, hMenu );
 }
@@ -3264,7 +3362,7 @@
 /*******************************************************************
  *         SetSystemMenu32    (USER32.507)
  */
-BOOL32 SetSystemMenu32( HWND32 hwnd, HMENU32 hMenu )
+BOOL32 WINAPI SetSystemMenu32( HWND32 hwnd, HMENU32 hMenu )
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
@@ -3281,7 +3379,7 @@
 /**********************************************************************
  *         GetMenu16    (USER.157)
  */
-HMENU16 GetMenu16( HWND16 hWnd ) 
+HMENU16 WINAPI GetMenu16( HWND16 hWnd ) 
 {
     WND * wndPtr = WIN_FindWndPtr(hWnd);
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD)) 
@@ -3293,7 +3391,7 @@
 /**********************************************************************
  *         GetMenu32    (USER32.256)
  */
-HMENU32 GetMenu32( HWND32 hWnd ) 
+HMENU32 WINAPI GetMenu32( HWND32 hWnd ) 
 { 
     WND * wndPtr = WIN_FindWndPtr(hWnd);
     if (wndPtr && !(wndPtr->dwStyle & WS_CHILD)) 
@@ -3305,7 +3403,7 @@
 /**********************************************************************
  *         SetMenu16    (USER.158)
  */
-BOOL16 SetMenu16( HWND16 hWnd, HMENU16 hMenu )
+BOOL16 WINAPI SetMenu16( HWND16 hWnd, HMENU16 hMenu )
 {
     return SetMenu32( hWnd, hMenu );
 }
@@ -3314,7 +3412,7 @@
 /**********************************************************************
  *         SetMenu32    (USER32.486)
  */
-BOOL32 SetMenu32( HWND32 hWnd, HMENU32 hMenu )
+BOOL32 WINAPI SetMenu32( HWND32 hWnd, HMENU32 hMenu )
 {
     WND * wndPtr = WIN_FindWndPtr(hWnd);
 
@@ -3347,7 +3445,7 @@
 /**********************************************************************
  *         GetSubMenu16    (USER.159)
  */
-HMENU16 GetSubMenu16( HMENU16 hMenu, INT16 nPos )
+HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
 {
     return GetSubMenu32( hMenu, nPos );
 }
@@ -3356,21 +3454,21 @@
 /**********************************************************************
  *         GetSubMenu32    (USER32.287)
  */
-HMENU32 GetSubMenu32( HMENU32 hMenu, INT32 nPos )
+HMENU32 WINAPI GetSubMenu32( HMENU32 hMenu, INT32 nPos )
 {
     LPPOPUPMENU lppop;
 
     if (!(lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return 0;
     if ((UINT32)nPos >= lppop->nItems) return 0;
-    if (!(lppop->items[nPos].item_flags & MF_POPUP)) return 0;
-    return (HMENU32)lppop->items[nPos].item_id;
+    if (!(lppop->items[nPos].fType & MF_POPUP)) return 0;
+    return lppop->items[nPos].hSubMenu;
 }
 
 
 /**********************************************************************
  *         DrawMenuBar16    (USER.160)
  */
-void DrawMenuBar16( HWND16 hWnd )
+void WINAPI DrawMenuBar16( HWND16 hWnd )
 {
     DrawMenuBar32( hWnd );
 }
@@ -3379,7 +3477,7 @@
 /**********************************************************************
  *         DrawMenuBar32    (USER32.160)
  */
-BOOL32 DrawMenuBar32( HWND32 hWnd )
+BOOL32 WINAPI DrawMenuBar32( HWND32 hWnd )
 {
     LPPOPUPMENU lppop;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
@@ -3400,7 +3498,7 @@
 /***********************************************************************
  *           EndMenu   (USER.187) (USER32.174)
  */
-void EndMenu(void)
+void WINAPI EndMenu(void)
 {
     fEndMenu = TRUE;
 }
@@ -3409,7 +3507,7 @@
 /***********************************************************************
  *           LookupMenuHandle   (USER.217)
  */
-HMENU16 LookupMenuHandle( HMENU16 hmenu, INT16 id )
+HMENU16 WINAPI LookupMenuHandle( HMENU16 hmenu, INT16 id )
 {
     HMENU32 hmenu32 = hmenu;
     INT32 id32 = id;
@@ -3421,7 +3519,7 @@
 /**********************************************************************
  *	    LoadMenu16    (USER.150)
  */
-HMENU16 LoadMenu16( HINSTANCE16 instance, SEGPTR name )
+HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, SEGPTR name )
 {
     HRSRC16 hRsrc;
     HGLOBAL16 handle;
@@ -3454,7 +3552,7 @@
 /*****************************************************************
  *        LoadMenu32A   (USER32.370)
  */
-HMENU32 LoadMenu32A( HINSTANCE32 instance, LPCSTR name )
+HMENU32 WINAPI LoadMenu32A( HINSTANCE32 instance, LPCSTR name )
 {
     HRSRC32 hrsrc = FindResource32A( instance, name, (LPSTR)RT_MENU );
     if (!hrsrc) return 0;
@@ -3465,7 +3563,7 @@
 /*****************************************************************
  *        LoadMenu32W   (USER32.372)
  */
-HMENU32 LoadMenu32W( HINSTANCE32 instance, LPCWSTR name )
+HMENU32 WINAPI LoadMenu32W( HINSTANCE32 instance, LPCWSTR name )
 {
     HRSRC32 hrsrc = FindResource32W( instance, name, (LPWSTR)RT_MENU );
     if (!hrsrc) return 0;
@@ -3476,7 +3574,7 @@
 /**********************************************************************
  *	    LoadMenuIndirect16    (USER.220)
  */
-HMENU16 LoadMenuIndirect16( LPCVOID template )
+HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
 {
     HMENU16 hMenu;
     WORD version, offset;
@@ -3505,7 +3603,7 @@
 /**********************************************************************
  *	    LoadMenuIndirect32A    (USER32.370)
  */
-HMENU32 LoadMenuIndirect32A( LPCVOID template )
+HMENU32 WINAPI LoadMenuIndirect32A( LPCVOID template )
 {
     HMENU16 hMenu;
     WORD version, offset;
@@ -3547,7 +3645,7 @@
 /**********************************************************************
  *	    LoadMenuIndirect32W    (USER32.371)
  */
-HMENU32 LoadMenuIndirect32W( LPCVOID template )
+HMENU32 WINAPI LoadMenuIndirect32W( LPCVOID template )
 {
     /* FIXME: is there anything different between A and W? */
     return LoadMenuIndirect32A( template );
@@ -3557,11 +3655,20 @@
 /**********************************************************************
  *		IsMenu16    (USER.358)
  */
-BOOL16 IsMenu16( HMENU16 hmenu )
+BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
 {
-    LPPOPUPMENU menu;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
-    return (menu->wMagic == MENU_MAGIC);
+    LPPOPUPMENU menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hmenu);
+    return IS_A_MENU(menu);
+}
+
+
+/**********************************************************************
+ *		IsMenu32    (USER32.345)
+ */
+BOOL32 WINAPI IsMenu32(HMENU32 hmenu)
+{
+    LPPOPUPMENU menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hmenu);
+    return IS_A_MENU(menu);
 }
 
 /**********************************************************************
@@ -3574,40 +3681,48 @@
 					 BOOL32 unicode)
 {
   MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos);
-  if (!menu) return FALSE;
+    debug_print_menuitem("GetMenuItemInfo32_common: ", menu, "\n");
+    if (!menu)
+	return FALSE;
 
-  if (lpmii->fMask && MIIM_TYPE)
-    {
-      lpmii->fType = menu->item_flags;
-      lpmii->dwTypeData = menu->text;
-      if (IS_STRING_ITEM (menu->item_flags))
-	{
-	  lpmii->cch = strlen (menu->text);
+    if (lpmii->fMask & MIIM_TYPE) {
+	lpmii->fType = menu->fType;
+	switch (MENU_ITEM_TYPE(menu->fType)) {
+	case MF_STRING:
+	    if (menu->text && lpmii->dwTypeData && lpmii->cch) {
 	  if (unicode)
-	    ; /* UGH! FIXME */
+		    lstrcpynAtoW((LPWSTR) lpmii->dwTypeData,
+				 menu->text,
+				 lpmii->cch);
+		else
+		    lstrcpyn32A(lpmii->dwTypeData,
+				menu->text,
+				lpmii->cch);
 	}
-      else
-	lpmii->cch = 0;
+	    break;
+	case MF_OWNERDRAW:
+	case MF_BITMAP:
+	    lpmii->dwTypeData = menu->text;
+	    break;
+	default:
+	    break;
     }
-
-  if (lpmii->fMask && MIIM_STATE)
-    lpmii->fState = 0; /* FIXME -- not saved.  */
-
-  if (lpmii->wID && MIIM_ID)
-    lpmii->fType = menu->item_id;
-
-  if (lpmii->fMask && MIIM_SUBMENU)
-    lpmii->hSubMenu = menu->item_id; /* FIXME: ??? */
-
-  if (lpmii->fMask && MIIM_CHECKMARKS)
-    {
-      PCBITMAPS pCB = menu->pCB;
-      lpmii->hbmpChecked = pCB ? pCB->hCheckBit : 0;
-      lpmii->hbmpUnchecked = pCB ? pCB->hUnCheckBit : 0;
     }
+    if (lpmii->fMask & MIIM_STATE)
+	lpmii->fState = menu->fState;
 
-  if (lpmii->fMask && MIIM_DATA)
-    lpmii->dwItemData = 0; /* FIXME -- not saved.  */
+    if (lpmii->fMask & MIIM_ID)
+	lpmii->wID = menu->wID;
+
+    if (lpmii->fMask & MIIM_SUBMENU)
+	lpmii->hSubMenu = menu->hSubMenu;
+
+    if (lpmii->fMask & MIIM_CHECKMARKS) {
+	lpmii->hbmpChecked = menu->hCheckBit;
+	lpmii->hbmpUnchecked = menu->hUnCheckBit;
+    }
+    if (lpmii->fMask & MIIM_DATA)
+	lpmii->dwItemData = menu->dwItemData;
 
   return TRUE;
 }
@@ -3615,8 +3730,8 @@
 /**********************************************************************
  *		GetMenuItemInfo32A    (USER32.263)
  */
-BOOL32 GetMenuItemInfo32A( HMENU32 hmenu, UINT32 item, BOOL32 bypos,
-			   LPMENUITEMINFO32A lpmii)
+BOOL32 WINAPI GetMenuItemInfo32A( HMENU32 hmenu, UINT32 item, BOOL32 bypos,
+                                  LPMENUITEMINFO32A lpmii)
 {
     return GetMenuItemInfo32_common (hmenu, item, bypos, lpmii, FALSE);
 }
@@ -3624,20 +3739,136 @@
 /**********************************************************************
  *		GetMenuItemInfo32W    (USER32.264)
  */
-BOOL32 GetMenuItemInfo32W( HMENU32 hmenu, UINT32 item, BOOL32 bypos,
-			   LPMENUITEMINFO32W lpmii)
+BOOL32 WINAPI GetMenuItemInfo32W( HMENU32 hmenu, UINT32 item, BOOL32 bypos,
+                                  LPMENUITEMINFO32W lpmii)
 {
     return GetMenuItemInfo32_common (hmenu, item, bypos,
                                      (LPMENUITEMINFO32A)lpmii, TRUE);
 }
 
+/**********************************************************************
+ *		SetMenuItemInfo32_common
+ */
+
+static BOOL32 SetMenuItemInfo32_common(MENUITEM * menu,
+				       const MENUITEMINFO32A *lpmii,
+				       BOOL32 unicode)
+{
+    if (!menu) return FALSE;
+
+    if (lpmii->fMask & MIIM_TYPE) {
+	/* Get rid of old string.  */
+	if (IS_STRING_ITEM(menu->fType) && menu->text)
+	    HeapFree(SystemHeap, 0, menu->text);
+
+	menu->fType = lpmii->fType;
+	menu->text = lpmii->dwTypeData;
+	if (IS_STRING_ITEM(menu->fType) && menu->text) {
+	    menu->text =
+		unicode
+		? HEAP_strdupWtoA(SystemHeap, 0,
+				  (LPWSTR) lpmii->dwTypeData)
+		: HEAP_strdupA(SystemHeap, 0, lpmii->dwTypeData);
+	}
+    }
+    if (lpmii->fMask & MIIM_STATE)
+	menu->fState = lpmii->fState;
+
+    if (lpmii->fMask & MIIM_ID)
+	menu->wID = lpmii->wID;
+
+    if (lpmii->fMask & MIIM_SUBMENU)
+	menu->hSubMenu = lpmii->hSubMenu;
+
+    if (lpmii->fMask & MIIM_CHECKMARKS)
+    {
+	menu->hCheckBit = lpmii->hbmpChecked;
+	menu->hUnCheckBit = lpmii->hbmpUnchecked;
+    }
+    if (lpmii->fMask & MIIM_DATA)
+	menu->dwItemData = lpmii->dwItemData;
+
+    debug_print_menuitem("SetMenuItemInfo32_common: ", menu, "\n");
+    return TRUE;
+}
 
 /**********************************************************************
- *		IsMenu32    (USER32.345)
+ *		SetMenuItemInfo32A    (USER32.490)
  */
-BOOL32 IsMenu32( HMENU32 hmenu )
+BOOL32 WINAPI SetMenuItemInfo32A(HMENU32 hmenu, UINT32 item, BOOL32 bypos,
+                                 const MENUITEMINFO32A *lpmii) 
 {
-    LPPOPUPMENU menu;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
-    return (menu->wMagic == MENU_MAGIC);
+    return SetMenuItemInfo32_common(MENU_FindItem(&hmenu, &item, bypos),
+				    lpmii, FALSE);
+}
+
+/**********************************************************************
+ *		SetMenuItemInfo32W    (USER32.491)
+ */
+BOOL32 WINAPI SetMenuItemInfo32W(HMENU32 hmenu, UINT32 item, BOOL32 bypos,
+                                 const MENUITEMINFO32W *lpmii)
+{
+    return SetMenuItemInfo32_common(MENU_FindItem(&hmenu, &item, bypos),
+				    (const MENUITEMINFO32A*)lpmii, TRUE);
+}
+
+/**********************************************************************
+ *		SetMenuDefaultItem32    (USER32.488)
+ */
+BOOL32 WINAPI SetMenuDefaultItem32(HMENU32 hmenu, UINT32 item, BOOL32 bypos)
+{
+    MENUITEM *menu = MENU_FindItem(&hmenu, &item, bypos);
+    if (!menu) return FALSE;
+    debug_print_menuitem("SetMenuDefaultItem32: ", menu, "\n");
+    fprintf(stdnimp, "SetMenuDefaultItem32 (0x%x,%d,%d), empty stub!\n",
+	    hmenu, item, bypos);
+    return TRUE;
+}
+
+/*******************************************************************
+ *              InsertMenuItem16   (USER.441)
+ *
+ * FIXME: untested
+ */
+BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
+                                const MENUITEMINFO16 *mii )
+{
+    MENUITEMINFO32A miia;
+
+    miia.cbSize        = sizeof(miia);
+    miia.fMask         = mii->fMask;
+    miia.dwTypeData    = miia.dwTypeData;
+    miia.fType         = mii->fType;
+    miia.fState        = mii->fState;
+    miia.wID           = mii->wID;
+    miia.hSubMenu      = mii->hSubMenu;
+    miia.hbmpChecked   = mii->hbmpChecked;
+    miia.hbmpUnchecked = mii->hbmpUnchecked;
+    miia.dwItemData    = mii->dwItemData;
+    miia.cch           = mii->cch;
+    if (IS_STRING_ITEM(miia.fType))
+        miia.dwTypeData = PTR_SEG_TO_LIN(miia.dwTypeData);
+    return InsertMenuItem32A( hmenu, pos, byposition, &miia );
+}
+
+
+/**********************************************************************
+ *		InsertMenuItem32A    (USER32.322)
+ */
+BOOL32 WINAPI InsertMenuItem32A(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos,
+                                const MENUITEMINFO32A *lpmii)
+{
+    MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos);
+    return SetMenuItemInfo32_common(item, lpmii, FALSE);
+}
+
+
+/**********************************************************************
+ *		InsertMenuItem32W    (USER32.323)
+ */
+BOOL32 WINAPI InsertMenuItem32W(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos,
+                                const MENUITEMINFO32W *lpmii)
+{
+    MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos);
+    return SetMenuItemInfo32_common(item, (const MENUITEMINFO32A*)lpmii, TRUE);
 }
diff --git a/controls/scroll.c b/controls/scroll.c
index d2371f1..b8a3d4e 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -756,8 +756,8 @@
 /***********************************************************************
  *           ScrollBarWndProc
  */
-LRESULT ScrollBarWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
-                          LPARAM lParam )
+LRESULT WINAPI ScrollBarWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
+                                 LPARAM lParam )
 {
     switch(message)
     {
@@ -893,8 +893,8 @@
 /*************************************************************************
  *           SetScrollInfo16   (USER.475)
  */
-INT16 SetScrollInfo16( HWND16 hwnd, INT16 nBar, const SCROLLINFO *info,
-                       BOOL16 bRedraw )
+INT16 WINAPI SetScrollInfo16( HWND16 hwnd, INT16 nBar, const SCROLLINFO *info,
+                              BOOL16 bRedraw )
 {
     return (INT16)SetScrollInfo32( hwnd, nBar, info, bRedraw );
 }
@@ -903,8 +903,8 @@
 /*************************************************************************
  *           SetScrollInfo32   (USER32.500)
  */
-INT32 SetScrollInfo32( HWND32 hwnd, INT32 nBar, const SCROLLINFO *info,
-                       BOOL32 bRedraw )
+INT32 WINAPI SetScrollInfo32( HWND32 hwnd, INT32 nBar, const SCROLLINFO *info,
+                              BOOL32 bRedraw )
 {
     SCROLLBAR_INFO *infoPtr;
     UINT32 new_flags;
@@ -1007,7 +1007,7 @@
 /*************************************************************************
  *           GetScrollInfo16   (USER.476)
  */
-BOOL16 GetScrollInfo16( HWND16 hwnd, INT16 nBar, LPSCROLLINFO info )
+BOOL16 WINAPI GetScrollInfo16( HWND16 hwnd, INT16 nBar, LPSCROLLINFO info )
 {
     return GetScrollInfo32( hwnd, nBar, info );
 }
@@ -1016,7 +1016,7 @@
 /*************************************************************************
  *           GetScrollInfo32   (USER32.283)
  */
-BOOL32 GetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO info )
+BOOL32 WINAPI GetScrollInfo32( HWND32 hwnd, INT32 nBar, LPSCROLLINFO info )
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -1041,7 +1041,8 @@
 /*************************************************************************
  *           SetScrollPos16   (USER.62)
  */
-INT16 SetScrollPos16( HWND16 hwnd, INT16 nBar, INT16 nPos, BOOL16 bRedraw )
+INT16 WINAPI SetScrollPos16( HWND16 hwnd, INT16 nBar, INT16 nPos,
+                             BOOL16 bRedraw )
 {
     return (INT16)SetScrollPos32( hwnd, nBar, nPos, bRedraw );
 }
@@ -1050,7 +1051,8 @@
 /*************************************************************************
  *           SetScrollPos32   (USER32.501)
  */
-INT32 SetScrollPos32( HWND32 hwnd, INT32 nBar, INT32 nPos, BOOL32 bRedraw )
+INT32 WINAPI SetScrollPos32( HWND32 hwnd, INT32 nBar, INT32 nPos,
+                             BOOL32 bRedraw )
 {
     SCROLLINFO info;
     SCROLLBAR_INFO *infoPtr;
@@ -1069,7 +1071,7 @@
 /*************************************************************************
  *           GetScrollPos16   (USER.63)
  */
-INT16 GetScrollPos16( HWND16 hwnd, INT16 nBar )
+INT16 WINAPI GetScrollPos16( HWND16 hwnd, INT16 nBar )
 {
     return (INT16)GetScrollPos32( hwnd, nBar );
 }
@@ -1078,7 +1080,7 @@
 /*************************************************************************
  *           GetScrollPos32   (USER32.284)
  */
-INT32 GetScrollPos32( HWND32 hwnd, INT32 nBar )
+INT32 WINAPI GetScrollPos32( HWND32 hwnd, INT32 nBar )
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -1090,8 +1092,8 @@
 /*************************************************************************
  *           SetScrollRange16   (USER.64)
  */
-void SetScrollRange16( HWND16 hwnd, INT16 nBar, INT16 MinVal, INT16 MaxVal,
-                       BOOL16 bRedraw )
+void WINAPI SetScrollRange16( HWND16 hwnd, INT16 nBar,
+                              INT16 MinVal, INT16 MaxVal, BOOL16 bRedraw )
 {
     /* Invalid range -> range is set to (0,0) */
     if ((INT32)MaxVal - (INT32)MinVal > 0x7fff) MinVal = MaxVal = 0;
@@ -1102,8 +1104,8 @@
 /*************************************************************************
  *           SetScrollRange32   (USER32.502)
  */
-BOOL32 SetScrollRange32( HWND32 hwnd, INT32 nBar, INT32 MinVal, INT32 MaxVal,
-                         BOOL32 bRedraw )
+BOOL32 WINAPI SetScrollRange32( HWND32 hwnd, INT32 nBar,
+                                INT32 MinVal, INT32 MaxVal, BOOL32 bRedraw )
 {
     SCROLLINFO info;
 
@@ -1153,7 +1155,8 @@
 /*************************************************************************
  *           GetScrollRange16   (USER.65)
  */
-BOOL16 GetScrollRange16( HWND16 hwnd, INT16 nBar, LPINT16 lpMin, LPINT16 lpMax)
+BOOL16 WINAPI GetScrollRange16( HWND16 hwnd, INT16 nBar,
+                                LPINT16 lpMin, LPINT16 lpMax)
 {
     INT32 min, max;
     BOOL16 ret = GetScrollRange32( hwnd, nBar, &min, &max );
@@ -1166,7 +1169,8 @@
 /*************************************************************************
  *           GetScrollRange32   (USER32.285)
  */
-BOOL32 GetScrollRange32( HWND32 hwnd, INT32 nBar, LPINT32 lpMin, LPINT32 lpMax)
+BOOL32 WINAPI GetScrollRange32( HWND32 hwnd, INT32 nBar,
+                                LPINT32 lpMin, LPINT32 lpMax)
 {
     SCROLLBAR_INFO *infoPtr;
 
@@ -1185,7 +1189,7 @@
 /*************************************************************************
  *           ShowScrollBar16   (USER.267)
  */
-void ShowScrollBar16( HWND16 hwnd, INT16 nBar, BOOL16 fShow )
+void WINAPI ShowScrollBar16( HWND16 hwnd, INT16 nBar, BOOL16 fShow )
 {
     ShowScrollBar32( hwnd, nBar, fShow );
 }
@@ -1194,7 +1198,7 @@
 /*************************************************************************
  *           ShowScrollBar32   (USER32.531)
  */
-BOOL32 ShowScrollBar32( HWND32 hwnd, INT32 nBar, BOOL32 fShow )
+BOOL32 WINAPI ShowScrollBar32( HWND32 hwnd, INT32 nBar, BOOL32 fShow )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -1261,7 +1265,7 @@
 /*************************************************************************
  *           EnableScrollBar16   (USER.482)
  */
-BOOL16 EnableScrollBar16( HWND16 hwnd, INT16 nBar, UINT16 flags )
+BOOL16 WINAPI EnableScrollBar16( HWND16 hwnd, INT16 nBar, UINT16 flags )
 {
     return EnableScrollBar32( hwnd, nBar, flags );
 }
@@ -1270,7 +1274,7 @@
 /*************************************************************************
  *           EnableScrollBar32   (USER32.170)
  */
-BOOL32 EnableScrollBar32( HWND32 hwnd, INT32 nBar, UINT32 flags )
+BOOL32 WINAPI EnableScrollBar32( HWND32 hwnd, INT32 nBar, UINT32 flags )
 {
     SCROLLBAR_INFO *infoPtr;
 
diff --git a/controls/static.c b/controls/static.c
index 6a547e2..ecd4a02 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -50,13 +50,17 @@
 {
     HICON16 prevIcon;
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
+    CURSORICONINFO *info = hicon?(CURSORICONINFO *) GlobalLock16( hicon ):NULL;
 
     if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return 0;
+    if (hicon && !info) {
+	fprintf(stderr,"STATIC_SetIcon: huh? hicon!=0, but info=0???\n");
+    	return 0;
+    }
     prevIcon = infoPtr->hIcon;
     infoPtr->hIcon = hicon;
     if (hicon)
     {
-        CURSORICONINFO *info = (CURSORICONINFO *) GlobalLock16( hicon );
         SetWindowPos32( wndPtr->hwndSelf, 0, 0, 0, info->nWidth, info->nHeight,
                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
         GlobalUnlock16( hicon );
@@ -95,8 +99,8 @@
 /***********************************************************************
  *           StaticWndProc
  */
-LRESULT StaticWndProc( HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam,
-                       LPARAM lParam )
+LRESULT WINAPI StaticWndProc( HWND32 hWnd, UINT32 uMsg, WPARAM32 wParam,
+                              LPARAM lParam )
 {
     LRESULT lResult = 0;
     WND *wndPtr = WIN_FindWndPtr(hWnd);
diff --git a/controls/status.c b/controls/status.c
index feef96c..0732664 100644
--- a/controls/status.c
+++ b/controls/status.c
@@ -38,7 +38,8 @@
 /***********************************************************************
  *           DrawStatusText32A   (COMCTL32.3)
  */
-void DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style )
+void WINAPI DrawStatusText32A( HDC32 hdc, LPRECT32 lprc, LPCSTR text,
+                               UINT32 style )
 {
     RECT32		r, rt;
     int	oldbkmode;
@@ -435,8 +436,8 @@
     return 0;
 }
 
-LRESULT StatusWindowProc( HWND32 hwnd, UINT32 msg,
-                          WPARAM32 wParam, LPARAM lParam )
+LRESULT WINAPI StatusWindowProc( HWND32 hwnd, UINT32 msg,
+                                 WPARAM32 wParam, LPARAM lParam )
 {
     STATUSWINDOWINFO *self;
 
@@ -480,8 +481,8 @@
 /***********************************************************************
  *           CreateStatusWindow32A   (COMCTL32.4)
  */
-HWND32 CreateStatusWindow32A( INT32 style, LPCSTR text, HWND32 parent,
-                              UINT32 wid )
+HWND32 WINAPI CreateStatusWindow32A( INT32 style, LPCSTR text, HWND32 parent,
+                                     UINT32 wid )
 {
     HWND32 ret;
     ATOM atom;
diff --git a/controls/updown.c b/controls/updown.c
new file mode 100644
index 0000000..a3a75ef
--- /dev/null
+++ b/controls/updown.c
@@ -0,0 +1,865 @@
+/*		
+ * Updown control
+ *
+ * Copyright 1997 Dimitrie O. Paun
+ *
+ * TODO:
+ *   - subclass the buddy window (in UPDOWN_SetBuddy) to process the
+ *     arrow keys
+ *   - I am not sure about the default values for the Min, Max, Pos
+ *     (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal)
+ * Testing:
+ *   Not much. The following  have not been tested at all:
+ *     - horizontal arrows
+ *     - listbox as buddy window
+ *     - acceleration
+ *     - base 16
+ *     - UDS_ALIGNLEFT, ~UDS_WRAP
+ *     - integers with thousand separators.
+ *   Even though the above list seems rather large, the control seems to
+ *   behave very well so I am confident it does work in most (all) of the
+ *   untested cases.
+ * Problems:
+ *   At the moment, the control will no draw itself very well because it
+ *   uses some features in DrawEdge that are not yet implemented. 
+ *   In other words, there is no known problem, exempt for the things in
+ *   the TODO list above.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include "windows.h"
+#include "winnls.h"
+#include "syscolor.h"
+#include "sysmetrics.h"
+#include "updown.h"
+#include "graphics.h"
+#include "heap.h"
+#include "win.h"
+#include "stddebug.h"
+/*#define  DEBUG_UPDOWN*/
+#include "debug.h"
+
+/* Control configuration constants */
+
+#define INITIAL_DELAY    500 /* initial timer until auto-increment kicks in */
+#define REPEAT_DELAY     50  /* delay between auto-increments */
+
+#define DEFAULT_WIDTH    10  /* default width of the ctrl */
+#define DEFAULT_XSEP     0   /* default separation between buddy and crtl */
+#define DEFAULT_ADDTOP   1   /* amount to extend above the buddy window */
+#define DEFAULT_ADDBOT   1   /* amount to extend below the buddy window */
+
+
+/* Work constants */
+
+#define FLAG_INCR        0x01
+#define FLAG_DECR        0x02
+#define FLAG_MOUSEIN     0x04
+#define FLAG_CLICKED     (FLAG_INCR | FLAG_DECR)
+
+#define TIMERID1         1
+#define TIMERID2         2
+
+static int accelIndex = -1;
+
+#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
+
+#define UNKNOWN_PARAM(msg, wParam, lParam) dprintf_updown(stddeb, \
+        "UpDown Ctrl: Unknown parameter(s) for message " #msg     \
+	"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
+
+#define UPDOWN_GetInfoPtr(wndPtr) ((UPDOWN_INFO *)wndPtr->wExtra)
+
+/***********************************************************************
+ *           UPDOWN_InBounds
+ * Tests if a given value 'val' is between the Min&Max limits
+ */
+static BOOL32 UPDOWN_InBounds(WND *wndPtr, int val)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+
+  if(infoPtr->MaxVal > infoPtr->MinVal)
+    return (infoPtr->MinVal <= val) && (val <= infoPtr->MaxVal);
+  else
+    return (infoPtr->MaxVal <= val) && (val <= infoPtr->MinVal);
+}
+
+/***********************************************************************
+ *           UPDOWN_OffsetVal
+ * Tests if we can change the current value by delta. If so, it changes
+ * it and returns TRUE. Else, it leaves it unchanged and returns FALSE.
+ */
+static BOOL32 UPDOWN_OffsetVal(WND *wndPtr, int delta)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+
+  /* check if we can do the modification first */
+  if(!UPDOWN_InBounds(wndPtr, infoPtr->CurVal+delta)){
+    if(wndPtr->dwStyle & UDS_WRAP)
+      delta += (delta < 0 ? -1 : 1) *
+	(infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1) *
+	(infoPtr->MinVal - infoPtr->MaxVal) +
+	(delta < 0 ? 1 : -1);
+    else
+      return FALSE;
+  }
+
+  infoPtr->CurVal += delta;
+  return TRUE;
+}
+
+/***********************************************************************
+ *           UPDOWN_GetArrawRect
+ * wndPtr   - pointer to the up-down wnd
+ * rect     - will hold the rectangle
+ * incr     - TRUE  get the "increment" rect (up or right)
+ *            FALSE get the "decrement" rect (down or left)
+ *          
+ */
+static void UPDOWN_GetArrowRect(WND *wndPtr, RECT32 *rect, BOOL32 incr)
+{
+  int len; /* will hold the width or height */
+
+  GetClientRect32(wndPtr->hwndSelf, rect);
+
+  if (wndPtr->dwStyle & UDS_HORZ) {
+    len = rect->right - rect->left; /* compute the width */
+    if (incr)
+      rect->left = len/2;
+    else
+      rect->right = len/2;
+  }
+  else {
+    len = rect->bottom - rect->top; /* compute the height */
+    if (incr)
+      rect->bottom = len/2;
+    else
+      rect->top = len/2;
+  }
+}
+
+/***********************************************************************
+ *           UPDOWN_GetArrowFromPoint
+ * Returns the rectagle (for the up or down arrow) that contains pt.
+ * If it returns the up rect, it returns TRUE.
+ * If it returns the down rect, it returns FALSE.
+ */
+static int UPDOWN_GetArrowFromPoint(WND *wndPtr, RECT32 *rect, POINT32 pt)
+{
+  UPDOWN_GetArrowRect(wndPtr, rect, TRUE);
+  if(PtInRect32(rect, pt))
+    return TRUE;
+
+  UPDOWN_GetArrowRect(wndPtr, rect, FALSE);
+  return FALSE;
+}
+
+
+/***********************************************************************
+ *           UPDOWN_GetThousandSep
+ * Returns the thousand sep. If an error occurs, it returns ','.
+ */
+static char UPDOWN_GetThousandSep()
+{
+  char sep[2];
+
+  if(GetLocaleInfo32A(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, 
+		      sep, sizeof(sep)) != 1)
+    return ',';
+
+  return sep[0];
+}
+
+/***********************************************************************
+ *           UPDOWN_GetBuddyInt
+ * Tries to read the pos from the buddy window and if it succeeds,
+ * it stores it in the control's CurVal
+ * returns:
+ *   TRUE  - if it read the integer from the buddy successfully
+ *   FALSE - if an error occured
+ */
+static BOOL32 UPDOWN_GetBuddyInt(WND *wndPtr)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+  char txt[20], sep, *src, *dst;
+  int newVal;
+
+  if (!IsWindow32(infoPtr->Buddy))
+    return FALSE;
+
+  /*if the buddy is a list window, we must set curr index */
+  if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_LISTBOX)){
+    newVal = SendMessage32A(infoPtr->Buddy, LB_GETCARETINDEX32, 0, 0);
+    if(newVal < 0)
+      return FALSE;
+  }
+  else{
+    /* we have a regural window, so will get the text */
+    if (!GetWindowText32A(infoPtr->Buddy, txt, sizeof(txt)))
+      return FALSE;
+
+    sep = UPDOWN_GetThousandSep(); 
+
+    /* now get rid of the separators */
+    for(src = dst = txt; *src; src++)
+      if(*src != sep)
+	*dst++ = *src;
+    *dst = 0;
+
+    /* try to convert the number and validate it */
+    newVal = strtol(txt, &src, infoPtr->Base);
+    if(*src || !UPDOWN_InBounds(wndPtr, newVal)) 
+      return FALSE;
+
+    dprintf_updown(stddeb, "UpDown Ctrl: new value(%d) read from buddy "
+		   "(old=%d)\n",  newVal, infoPtr->CurVal);
+  }
+  
+  infoPtr->CurVal = newVal;
+  return TRUE;
+}
+
+
+/***********************************************************************
+ *           UPDOWN_SetBuddyInt
+ * Tries to set the pos to the buddy window based on current pos
+ * returns:
+ *   TRUE  - if it set the caption of the  buddy successfully
+ *   FALSE - if an error occured
+ */
+static BOOL32 UPDOWN_SetBuddyInt(WND *wndPtr)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+  char txt1[20], sep;
+  int len;
+
+  if (!IsWindow32(infoPtr->Buddy)) 
+    return FALSE;
+
+  dprintf_updown(stddeb, "UpDown Ctrl: set new value(%d) to buddy.\n",
+		 infoPtr->CurVal);
+
+  /*if the buddy is a list window, we must set curr index */
+  if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_LISTBOX)){
+    SendMessage32A(infoPtr->Buddy, LB_SETCURSEL32, infoPtr->CurVal, 0);
+  }
+  else{ /* Regural window, so set caption to the number */
+    len = sprintf(txt1, (infoPtr->Base==16) ? "%X" : "%d", infoPtr->CurVal);
+
+    sep = UPDOWN_GetThousandSep(); 
+
+    if (!(wndPtr->dwStyle & UDS_NOTHOUSANDS)) {
+      char txt2[20], *src = txt1, *dst = txt2;
+      if(len%3 > 0){
+	strncpy(dst, src, len%3);
+	dst += len%3;
+	src += len%3;
+      }
+      for(len=0; *src; len++,src++){
+	if(len%3==0)
+	  *dst++ = sep;
+	*dst++ = *src++;
+      }
+      *dst = 0;           /* null terminate it */
+      strcpy(txt1, txt2); /* move it to the proper place */
+    }
+    SetWindowText32A(infoPtr->Buddy, txt1);
+  }
+
+  return TRUE;
+} 
+
+/***********************************************************************
+ *           UPDOWN_DrawArraw
+ * Draw the arrows for the up-down control. The arrows are drawn with the
+ * current pen and filled with the current brush.
+ * Input:
+ * hdc      - the DC to draw on
+ * rect     - rectangle holding the arrow
+ * incr     - TRUE  if we draw the "increment" arrow
+ *            FALSE if we draw the "decrement" arrow
+ * pressed  - TRUE  if the arrow is pressed (clicked)
+ *            FALSE if the arrow is not pressed (clicked)
+ * horz     - TRUE  if the arrow is horizontal
+ *            FLASE if the arrow is vertical
+ */
+static void UPDOWN_DrawArrow(HDC32 hdc, RECT32 *rect, BOOL32 incr, 
+			     BOOL32 pressed, BOOL32 horz)
+{
+  const int w = rect->right - rect->left;
+  const int h = rect->bottom - rect->top;
+  int offset = pressed ? 1 : 0, tmp;
+  POINT32 pts[3];
+
+  if(horz){ /* horizontal arrows */
+    pts[0].x = rect->right  - max(2, w/3) + offset;
+    pts[0].y = rect->top    + max(2, h/4) + offset;
+    pts[1].x = pts[0].x;
+    pts[1].y = rect->bottom - max(2, h/4) + offset;
+    pts[2].x = rect->left + w/3 + offset;
+    pts[2].y = (pts[0].y + pts[1].y)/2;
+    if(pts[2].x-2<rect->left)
+      pts[2].x = rect->left + 2;
+    if(pts[2].x <= pts[0].x)
+      pts[2].x = pts[0].x - 1;
+
+    if(incr){
+      tmp = pts[2].x;
+      pts[2].x = pts[0].x;
+      pts[0].x = pts[1].x = tmp;
+    }
+  }
+  else{                   /* vertical arrows */
+    pts[0].x = rect->left + max(2, w/4) + offset;
+    pts[0].y = rect->top  + max(2, h/3) + offset;
+    pts[1].x = rect->right- max(2, w/4) + offset;
+    pts[1].y = pts[0].y;
+    pts[2].x = (pts[0].x + pts[1].x)/2;
+    pts[2].y = pts[0].y + h/3 + offset;
+    if(pts[2].y+2>rect->bottom)
+      pts[2].y = rect->bottom - 2;
+    if(pts[2].y <= pts[0].y)
+      pts[2].y = pts[0].y + 1;
+
+    if(incr){
+      tmp = pts[2].y;
+      pts[2].y = pts[0].y;
+      pts[0].y = pts[1].y = tmp;
+    }
+  }
+  Polygon32(hdc, pts, 3);
+
+}
+
+/***********************************************************************
+ *           UPDOWN_Paint
+ * Draw the arrows. The background need not be erased.
+ */
+static void UPDOWN_Paint(WND *wndPtr)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+  PAINTSTRUCT32 ps;
+  BOOL32 prssed;
+  RECT32 rect;
+  HDC32 hdc;
+  HBRUSH32 oldBrush;
+
+  hdc = BeginPaint32( wndPtr->hwndSelf, &ps );
+
+  /*FIXME - this is just for test */
+  /*      - when DrawEdge works properly, this should dissapear 
+	  as DrawEdge will erase the background */
+/*oldBrush = SelectObject32(hdc, GetStockObject32(GRAY_BRUSH));
+  GetClientRect32(wndPtr->hwndSelf, &rect);
+  Rectangle32(hdc, rect.left, rect.top, rect.right, rect.bottom);
+  SelectObject32(hdc, oldBrush);*/
+
+  /* First select the proper brush */
+  oldBrush = wndPtr->dwStyle & WS_DISABLED ? GRAY_BRUSH : BLACK_BRUSH;
+  oldBrush = SelectObject32(hdc, GetStockObject32(oldBrush));
+
+  /* Draw the incr button */
+  UPDOWN_GetArrowRect(wndPtr, &rect, TRUE);
+  prssed = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
+  DrawEdge32(hdc, &rect, prssed ? EDGE_SUNKEN : EDGE_RAISED, 
+	   BF_RECT | BF_SOFT | BF_MIDDLE);
+  UPDOWN_DrawArrow(hdc, &rect, TRUE, prssed, wndPtr->dwStyle & UDS_HORZ);
+		    
+  /* Draw the decr button */
+  UPDOWN_GetArrowRect(wndPtr, &rect, FALSE);
+  prssed = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
+  DrawEdge32(hdc, &rect, prssed ? EDGE_SUNKEN : EDGE_RAISED, 
+	   BF_RECT | BF_SOFT | BF_MIDDLE);
+  UPDOWN_DrawArrow(hdc, &rect, FALSE, prssed, wndPtr->dwStyle & UDS_HORZ);
+
+  /* clean-up */  
+  SelectObject32(hdc, oldBrush);
+  EndPaint32( wndPtr->hwndSelf, &ps );
+}
+
+/***********************************************************************
+ *           UPDOWN_SetBuddy
+ * Tests if 'hwndBud' is a valid window handle. If not, returns FALSE.
+ * Else, sets it as a new Buddy.
+ * Then, it should subclass the buddy 
+ * If window has the UDS_ARROWKEYS, it subcalsses the buddy window to
+ * process the UP/DOWN arrow keys.
+ * If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
+ * the size/pos of the buddy and the control are adjusted accordingly.
+ */
+static BOOL32 UPDOWN_SetBuddy(WND *wndPtr, HWND32 hwndBud)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr); 
+  RECT32 budRect; /* new coord for the buddy */
+  int x;          /* new x position and width for the up-down */
+ 	  
+  /* Is is a valid bud? */
+  if(!IsWindow32(hwndBud))
+    return FALSE;
+
+  if(wndPtr->dwStyle & UDS_ARROWKEYS){
+    /* FIXME: we need to subclass the buddy to process the arrow keys. */
+    fprintf(stderr, "UpDown Ctrl: we should subclass the buddy window!\n");
+  }
+
+  /* do we need to do any adjustments? */
+  if(!(wndPtr->dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)))
+    return TRUE;
+
+  /* Get the rect of the buddy relative to its parent */
+  GetWindowRect32(infoPtr->Buddy, &budRect);
+  MapWindowPoints32(HWND_DESKTOP, GetParent32(infoPtr->Buddy),
+		  (POINT32 *)(&budRect.left), 2);
+	  
+  /* now do the positioning */
+  if(wndPtr->dwStyle & UDS_ALIGNRIGHT){
+    budRect.right -= DEFAULT_WIDTH+DEFAULT_XSEP;
+    x  = budRect.right+DEFAULT_XSEP;
+  }
+  else{ /* UDS_ALIGNLEFT */
+    x  = budRect.left;
+    budRect.left += DEFAULT_WIDTH+DEFAULT_XSEP;
+  }
+
+  /* first adjust the buddy to accomodate the up/down */
+  SetWindowPos32(infoPtr->Buddy, 0, budRect.left, budRect.top,
+	       budRect.right  - budRect.left, budRect.bottom - budRect.top, 
+	       SWP_NOACTIVATE|SWP_NOZORDER);
+
+  /* now position the up/down */
+  /* Since the UDS_ALIGN* flags were used, */
+  /* we will pick the position and size of the window. */
+  SetWindowPos32(wndPtr->hwndSelf,0,x,budRect.top-DEFAULT_ADDTOP,DEFAULT_WIDTH,
+		 (budRect.bottom-budRect.top)+DEFAULT_ADDTOP+DEFAULT_ADDBOT,
+		 SWP_NOACTIVATE|SWP_NOZORDER); 
+
+  return TRUE;
+}	  
+
+/***********************************************************************
+ *           UPDOWN_DoAction
+ *
+ * This function increments/decrements the CurVal by the 
+ * 'delta' amount according to the 'incr' flag
+ * It notifies the parent as required.
+ * It handles wraping and non-wraping correctly.
+ * It is assumed that delta>0
+ */
+static void UPDOWN_DoAction(WND *wndPtr, int delta, BOOL32 incr)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr); 
+  int old_val = infoPtr->CurVal;
+  NM_UPDOWN ni;
+
+  dprintf_updown(stddeb, "UpDown Ctrl action: %s by %d\n",
+		 incr ? "inc" : "dec", delta);
+
+  /* check if we can do the modification first */
+  delta *= (incr ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
+  if(!UPDOWN_OffsetVal(wndPtr, delta))
+    return;
+
+  /* so, if we can do the change, recompute delta and restore old value */
+  delta = infoPtr->CurVal - old_val;
+  infoPtr->CurVal = old_val;
+
+  /* We must notify parent now to obtain permission */
+  ni.iPos = infoPtr->CurVal;
+  ni.iDelta = delta;
+  ni.hdr.hwndFrom = wndPtr->hwndSelf;
+  ni.hdr.idFrom = wndPtr->wIDmenu;
+  ni.hdr.code = UDN_DELTAPOS; 
+  if(SendMessage32A(wndPtr->parent->hwndSelf, 
+		    WM_NOTIFY, wndPtr->wIDmenu, (LPARAM)&ni))
+    return; /* we are not allowed to change */
+  
+  /* Now adjust value with (maybe new) delta */
+  if(!UPDOWN_OffsetVal(wndPtr, ni.iDelta))
+    return;
+
+  /* Now take care about our buddy */
+  if(!IsWindow32(infoPtr->Buddy)) 
+    return; /* Nothing else to do */
+
+
+  if(wndPtr->dwStyle & UDS_SETBUDDYINT)
+    UPDOWN_SetBuddyInt(wndPtr);
+
+  /* Also, notify it */
+  /* FIXME: do we need to send the notification only if
+            we do not have the UDS_SETBUDDYINT style set? */
+  SendMessage32A(infoPtr->Buddy, 
+		 wndPtr->dwStyle & UDS_HORZ ? WM_HSCROLL : WM_VSCROLL, 
+		 MAKELONG(incr ? SB_LINEUP : SB_LINEDOWN, infoPtr->CurVal),
+		 wndPtr->hwndSelf);
+}
+
+/***********************************************************************
+ *           UPDOWN_IsEnabled
+ *
+ * Returns TRUE if it is enabled as well as its buddy (if any)
+ *         FALSE otherwise
+ */
+static BOOL32 UPDOWN_IsEnabled(WND *wndPtr)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+
+  if(wndPtr->dwStyle & WS_DISABLED)
+    return FALSE;
+  return IsWindowEnabled32(infoPtr->Buddy);
+}
+
+/***********************************************************************
+ *           UPDOWN_CancelMode
+ *
+ * Deletes any timers, releases the mouse and does  redraw if necessary.
+ * If the control is not in "capture" mode, it does nothing.
+ * If the control was not in cancel mode, it returns FALSE. 
+ * If the control was in cancel mode, it returns TRUE.
+ */
+static BOOL32 UPDOWN_CancelMode(WND *wndPtr)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+ 
+  /* if not in 'capture' mode, do nothing */
+  if(!(infoPtr->Flags & FLAG_CLICKED))
+    return FALSE;
+
+  KillTimer32(wndPtr->hwndSelf, TIMERID1); /* kill all possible timers */
+  KillTimer32(wndPtr->hwndSelf, TIMERID2);
+  
+  if(GetCapture32() == wndPtr->hwndSelf)   /* let the mouse go         */
+    ReleaseCapture();          /* if we still have it      */  
+  
+  infoPtr->Flags = 0;          /* get rid of any flags     */
+  UPDOWN_Paint(wndPtr);        /* redraw the control just in case */
+  
+  return TRUE;
+}
+
+/***********************************************************************
+ *           UPDOWN_HandleMouseEvent
+ *
+ * Handle a mouse event for the updown.
+ * 'pt' is the location of the mouse event in client or
+ * windows coordinates. 
+ */
+static void UPDOWN_HandleMouseEvent(WND *wndPtr, UINT32 msg, POINT32 pt)
+{
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr);
+  RECT32 rect;
+  int temp;
+
+  switch(msg)
+    {
+    case WM_LBUTTONDOWN:  /* Initialise mouse tracking */
+      /* If we are already in the 'clicked' mode, then nothing to do */
+      if(infoPtr->Flags & FLAG_CLICKED)
+	return;
+
+      /* If the buddy is an edit, will set focus to it */
+      if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_EDIT))
+	SetFocus32(infoPtr->Buddy);
+
+      /* Now see which one is the 'active' arrow */
+      temp = UPDOWN_GetArrowFromPoint(wndPtr, &rect, pt);
+
+      /* Update the CurVal if necessary */
+      if(wndPtr->dwStyle & UDS_SETBUDDYINT)
+	UPDOWN_GetBuddyInt(wndPtr);
+	
+      /* Before we proceed, see if we can spin... */
+      if(!(wndPtr->dwStyle & UDS_WRAP))
+	if(( temp && infoPtr->CurVal==infoPtr->MaxVal) ||
+	   (!temp && infoPtr->CurVal==infoPtr->MinVal))
+	  return;
+
+      /* Set up the correct flags */
+      infoPtr->Flags  = 0; 
+      infoPtr->Flags |= temp ? FLAG_INCR : FLAG_DECR;
+      infoPtr->Flags |= FLAG_MOUSEIN;
+      
+      /* repaint the control */
+      UPDOWN_Paint(wndPtr);
+
+      /* process the click */
+      UPDOWN_DoAction(wndPtr, 1, infoPtr->Flags & FLAG_INCR);
+
+      /* now capture all mouse messages */
+      SetCapture32(wndPtr->hwndSelf);
+
+      /* and startup the first timer */
+      SetTimer32(wndPtr->hwndSelf, TIMERID1, INITIAL_DELAY, 0); 
+      break;
+
+    case WM_MOUSEMOVE:
+      /* If we are not in the 'clicked' mode, then nothing to do */
+      if(!(infoPtr->Flags & FLAG_CLICKED))
+	return;
+
+      /* save the flags to see if any got modified */
+      temp = infoPtr->Flags;
+
+      /* Now get the 'active' arrow rectangle */
+      if (infoPtr->Flags & FLAG_INCR)
+	UPDOWN_GetArrowRect(wndPtr, &rect, TRUE);
+      else
+	UPDOWN_GetArrowRect(wndPtr, &rect, FALSE);
+
+      /* Update the flags if we are in/out */
+      if(PtInRect32(&rect, pt))
+	infoPtr->Flags |=  FLAG_MOUSEIN;
+      else{
+	infoPtr->Flags &= ~FLAG_MOUSEIN;
+	if(accelIndex != -1) /* if we have accel info */
+	  accelIndex = 0;    /* reset it              */
+      }
+      /* If state changed, redraw the control */
+      if(temp != infoPtr->Flags)
+	UPDOWN_Paint(wndPtr);
+      break;
+
+      default:
+	fprintf(stderr, "UpDown: Impossible case in proc "
+		"UPDOWN_HandleMouseEvent");
+    }
+
+}
+
+/***********************************************************************
+ *           UpDownWndProc
+ */
+LRESULT WINAPI UpDownWindowProc(HWND32 hwnd, UINT32 message, WPARAM32 wParam,
+                                LPARAM lParam)
+{
+  WND *wndPtr = WIN_FindWndPtr(hwnd);
+  UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(wndPtr); 
+  int temp;
+
+  switch(message)
+    {
+    case WM_CREATE:
+      /* initialize the info struct */
+      infoPtr->AccelCount=0; infoPtr->AccelVect=0; 
+      infoPtr->CurVal=0; infoPtr->MinVal=0; infoPtr->MaxVal=100; /*FIXME*/
+      infoPtr->Base  = 10; /* Default to base 10  */
+      infoPtr->Buddy = 0;  /* No buddy window yet */
+      infoPtr->Flags = 0;  /* And no flags        */
+
+      /* Do we pick the buddy win ourselves? */
+      if(wndPtr->dwStyle & UDS_AUTOBUDDY)
+	UPDOWN_SetBuddy(wndPtr, GetWindow32(wndPtr->hwndSelf, GW_HWNDPREV));
+	
+      dprintf_updown(stddeb, "UpDown Ctrl creation, hwnd=%04x\n", hwnd);
+      break;
+    
+    case WM_DESTROY:
+      if(infoPtr->AccelVect)
+	free(infoPtr->AccelVect);
+      dprintf_updown(stddeb, "UpDown Ctrl destruction, hwnd=%04x\n", hwnd);
+      break;
+	
+    case WM_ENABLE:
+      if(wndPtr->dwStyle & WS_DISABLED)
+	UPDOWN_CancelMode(wndPtr);
+      UPDOWN_Paint(wndPtr);
+      break;
+
+    case WM_TIMER:
+      /* if initial timer, kill it and start the repeat timer */
+      if(wParam == TIMERID1){
+	KillTimer32(hwnd, TIMERID1);
+	/* if no accel info given, used default timer */
+	if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0){
+	  accelIndex = -1;
+	  temp = REPEAT_DELAY;
+	}
+	else{
+	  accelIndex = 0; /* otherwise, use it */
+	  temp = infoPtr->AccelVect[accelIndex].nSec * 1000 + 1;
+	}
+	SetTimer32(hwnd, TIMERID2, temp, 0);
+      }
+
+      /* now, if the mouse is above us, do the thing...*/
+      if(infoPtr->Flags & FLAG_MOUSEIN){
+	temp = accelIndex==-1 ? 1 : infoPtr->AccelVect[accelIndex].nInc;
+	UPDOWN_DoAction(wndPtr, temp, infoPtr->Flags & FLAG_INCR);
+	
+	if(accelIndex!=-1 && accelIndex < infoPtr->AccelCount-1){
+	  KillTimer32(hwnd, TIMERID2);
+	  accelIndex++; /* move to the next accel info */
+	  temp = infoPtr->AccelVect[accelIndex].nSec * 1000 + 1;
+	  /* make sure we have at least 1ms intervals */
+	  SetTimer32(hwnd, TIMERID2, temp, 0);	    
+	}
+      }
+      break;
+
+    case WM_CANCELMODE:
+      UPDOWN_CancelMode(wndPtr);
+      break;
+
+    case WM_LBUTTONUP:
+      if(!UPDOWN_CancelMode(wndPtr))
+	break;
+      /*If we released the mouse and our buddy is an edit */
+      /* we must select all text in it.                   */
+      if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr->Buddy), BIC32_EDIT))
+	SendMessage32A(infoPtr->Buddy, EM_SETSEL32, 0, MAKELONG(0, -1));
+      break;
+      
+    case WM_LBUTTONDOWN:
+    case WM_MOUSEMOVE:
+      if(UPDOWN_IsEnabled(wndPtr)){
+	POINT32 pt;
+	CONV_POINT16TO32( (POINT16 *)&lParam, &pt );
+	UPDOWN_HandleMouseEvent( wndPtr, message, pt );
+      }
+    break;
+
+    case WM_KEYDOWN:
+      if((wndPtr->dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(wndPtr)){
+	switch(wParam){
+	case VK_UP:  
+	case VK_DOWN:
+	  UPDOWN_GetBuddyInt(wndPtr);
+	  UPDOWN_DoAction(wndPtr, 1, wParam==VK_UP);
+	  break;
+	}
+      }
+      break;
+      
+    case WM_PAINT:
+      UPDOWN_Paint(wndPtr);
+      break;
+    
+    case UDM_GETACCEL:
+      if (wParam==0 && lParam==0)    /*if both zero, */
+	return infoPtr->AccelCount;  /*just return the accel count*/
+      if (wParam || lParam){
+	UNKNOWN_PARAM(UDM_GETACCEL, wParam, lParam);
+	return 0;
+      }
+      temp = min(infoPtr->AccelCount, wParam);
+      memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
+      return temp;
+
+    case UDM_SETACCEL:
+      dprintf_updown(stddeb, "UpDown Ctrl new accel info, hwnd=%04x\n", hwnd);
+      if(infoPtr->AccelVect){
+	free(infoPtr->AccelVect);
+	infoPtr->AccelCount = 0;
+	infoPtr->AccelVect  = 0;
+      }
+      if(wParam==0)
+	return TRUE;
+      infoPtr->AccelVect = malloc(wParam*sizeof(UDACCEL));
+      if(infoPtr->AccelVect==0)
+	return FALSE;
+      memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
+      return TRUE;
+
+    case UDM_GETBASE:
+      if (wParam || lParam)
+	UNKNOWN_PARAM(UDM_GETBASE, wParam, lParam);
+      return infoPtr->Base;
+
+    case UDM_SETBASE:
+      dprintf_updown(stddeb, "UpDown Ctrl new base(%d), hwnd=%04x\n", 
+		     wParam, hwnd);
+      if ( !(wParam==10 || wParam==16) || lParam)
+	UNKNOWN_PARAM(UDM_SETBASE, wParam, lParam);
+      if (wParam==10 || wParam==16){
+	temp = infoPtr->Base;
+	infoPtr->Base = wParam;
+	return temp;       /* return the prev base */
+      }
+      break;
+
+    case UDM_GETBUDDY:
+      if (wParam || lParam)
+	UNKNOWN_PARAM(UDM_GETBUDDY, wParam, lParam);
+      return infoPtr->Buddy;
+
+    case UDM_SETBUDDY:
+      if (lParam)
+	UNKNOWN_PARAM(UDM_SETBUDDY, wParam, lParam);
+      temp = infoPtr->Buddy;
+      infoPtr->Buddy = wParam;
+      UPDOWN_SetBuddy(wndPtr, wParam);
+      dprintf_updown(stddeb, "UpDown Ctrl new buddy(%04x), hwnd=%04x\n", 
+		     infoPtr->Buddy, hwnd);
+      return temp;
+
+    case UDM_GETPOS:
+      if (wParam || lParam)
+	UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
+      temp = UPDOWN_GetBuddyInt(wndPtr);
+      return MAKELONG(infoPtr->CurVal, temp ? 0 : 1);
+
+    case UDM_SETPOS:
+      if (wParam || HIWORD(lParam))
+	UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
+      temp = SLOWORD(lParam);
+      dprintf_updown(stddeb, "UpDown Ctrl new value(%d), hwnd=%04x\n",
+		     temp, hwnd);
+      if(!UPDOWN_InBounds(wndPtr, temp)){
+	if(temp < infoPtr->MinVal)  
+	  temp = infoPtr->MinVal;
+	if(temp > infoPtr->MaxVal)
+	  temp = infoPtr->MaxVal;
+      }
+      wParam = infoPtr->CurVal; /* save prev value   */
+      infoPtr->CurVal = temp;   /* set the new value */
+      if(wndPtr->dwStyle & UDS_SETBUDDYINT)
+	UPDOWN_SetBuddyInt(wndPtr);
+      return wParam;            /* return prev value */
+      
+    case UDM_GETRANGE:
+      if (wParam || lParam)
+	UNKNOWN_PARAM(UDM_GETRANGE, wParam, lParam);
+      return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);
+
+    case UDM_SETRANGE:
+      if (wParam)
+	UNKNOWN_PARAM(UDM_SETRANGE, wParam, lParam); /* we must have:     */
+      infoPtr->MaxVal = SLOWORD(lParam); /* UD_MINVAL <= Max <= UD_MAXVAL */
+      infoPtr->MinVal = SHIWORD(lParam); /* UD_MINVAL <= Min <= UD_MAXVAL */
+                                         /* |Max-Min| <= UD_MAXVAL        */
+      dprintf_updown(stddeb, "UpDown Ctrl new range(%d to %d), hwnd=%04x\n", 
+		     infoPtr->MinVal, infoPtr->MaxVal, hwnd);
+      break;                             
+
+    default: 
+      if (message >= WM_USER) 
+	fprintf( stderr, "UpDown Ctrl: unknown msg %04x wp=%04x lp=%08lx\n", 
+		 message, wParam, lParam );
+      return DefWindowProc32A( hwnd, message, wParam, lParam ); 
+    } 
+
+    return 0;
+}
+
+/***********************************************************************
+ *           CreateUpDownControl  (COMCTL32.14)
+ */
+HWND32 WINAPI CreateUpDownControl( DWORD style, INT32 x, INT32 y,
+                                   INT32 cx, INT32 cy, HWND32 parent,
+                                   INT32 id, HINSTANCE32 inst, HWND32 buddy,
+                                   INT32 maxVal, INT32 minVal, INT32 curVal )
+{
+  HWND32 hUD = CreateWindow32A(UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
+			       parent, id, inst, 0);
+  if(hUD){
+    SendMessage32A(hUD, UDM_SETBUDDY, buddy, 0);
+    SendMessage32A(hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
+    SendMessage32A(hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));     
+  }
+
+  return hUD;
+}
diff --git a/controls/widgets.c b/controls/widgets.c
index 20fe5a5..c8b9990 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -12,6 +12,7 @@
 #include "static.h"
 #include "status.h"
 #include "scroll.h"
+#include "updown.h"
 #include "desktop.h"
 #include "mdi.h"
 #include "gdi.h"
@@ -20,18 +21,18 @@
 
 /* Window procedures */
 
-extern LRESULT EditWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
-                            LPARAM lParam );
-extern LRESULT ComboWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
-                             LPARAM lParam );
-extern LRESULT ComboLBWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
-                               LPARAM lParam );
-extern LRESULT ListBoxWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
-                               LPARAM lParam );
-extern LRESULT PopupMenuWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
-                                 LPARAM lParam );
-extern LRESULT IconTitleWndProc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
-				 LPARAM lParam );
+extern LRESULT WINAPI EditWndProc( HWND32 hwnd, UINT32 msg,
+                                   WPARAM32 wParam, LPARAM lParam );
+extern LRESULT WINAPI ComboWndProc( HWND32 hwnd, UINT32 msg,
+                                    WPARAM32 wParam, LPARAM lParam );
+extern LRESULT WINAPI ComboLBWndProc( HWND32 hwnd, UINT32 msg,
+                                      WPARAM32 wParam, LPARAM lParam );
+extern LRESULT WINAPI ListBoxWndProc( HWND32 hwnd, UINT32 msg,
+                                      WPARAM32 wParam, LPARAM lParam );
+extern LRESULT WINAPI PopupMenuWndProc( HWND32 hwnd, UINT32 msg,
+                                        WPARAM32 wParam, LPARAM lParam );
+extern LRESULT WINAPI IconTitleWndProc( HWND32 hwnd, UINT32 msg,
+                                        WPARAM32 wParam, LPARAM lParam );
 
 /* Win16 class info */
 
@@ -102,6 +103,8 @@
 {
     { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, StatusWindowProc, 0,
       sizeof(STATUSWINDOWINFO), 0, 0, 0, 0, 0, STATUSCLASSNAME32A },
+    { CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW, UpDownWindowProc, 0,
+      sizeof(UPDOWN_INFO), 0, 0, 0, 0, 0, UPDOWN_CLASS32A }
 };
 
 #define NB_COMMON_CONTROLS32 \
@@ -160,7 +163,7 @@
 /***********************************************************************
  *           InitCommonControls   (COMCTL32.15)
  */
-void InitCommonControls(void)
+void WINAPI InitCommonControls(void)
 {
     int i;
     char name[30];