All driver functions are now properly separated.
[wine] / controls / menu.c
index 3a33c9c..2bb7f2d 100644 (file)
@@ -4,6 +4,20 @@
  * Copyright 1993 Martin Ayotte
  * Copyright 1994 Alexandre Julliard
  * Copyright 1997 Morten Welinder
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
@@ -12,6 +26,9 @@
  * This is probably not the meaning this style has in MS-Windows.
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include "wingdi.h"
 #include "wine/winbase16.h"
 #include "wine/winuser16.h"
+#include "wownt32.h"
+#include "wine/server.h"
 #include "wine/unicode.h"
-#include "wine/port.h"
 #include "win.h"
-#include "task.h"
-#include "heap.h"
 #include "controls.h"
 #include "nonclient.h"
 #include "user.h"
-#include "message.h"
-#include "queue.h"
+#include "wine/debug.h"
 
-#include "debugtools.h"
-
-DEFAULT_DEBUG_CHANNEL(menu);
-DECLARE_DEBUG_CHANNEL(accel);
+WINE_DEFAULT_DEBUG_CHANNEL(menu);
+WINE_DECLARE_DEBUG_CHANNEL(accel);
 
 /* internal popup menu window messages */
 
@@ -65,10 +78,9 @@ typedef struct {
 typedef struct {
     WORD        wFlags;       /* Menu flags (MF_POPUP, MF_SYSMENU) */
     WORD        wMagic;       /* Magic number */
-    HQUEUE16    hTaskQ;       /* Task queue for this menu */
     WORD       Width;        /* Width of the whole menu */
     WORD       Height;       /* Height of the whole menu */
-    WORD       nItems;       /* Number of items in the menu */
+    UINT        nItems;       /* Number of items in the menu */
     HWND        hWnd;         /* Window containing the menu */
     MENUITEM    *items;       /* Array of menu items */
     UINT        FocusedItem;  /* Currently focused item */
@@ -99,7 +111,6 @@ typedef struct
 } MTRACKER;
 
 #define MENU_MAGIC   0x554d  /* 'MU' */
-#define IS_A_MENU(pmenu) ((pmenu) && (pmenu)->wMagic == MENU_MAGIC)
 
 #define ITEM_PREV              -1
 #define ITEM_NEXT               1
@@ -149,15 +160,7 @@ typedef struct
 static WORD arrow_bitmap_width = 0, arrow_bitmap_height = 0;
 
 static HBITMAP hStdMnArrow = 0;
-
-/* Minimze/restore/close buttons to be inserted in menubar */
-static HBITMAP hBmpMinimize = 0;
-static HBITMAP hBmpMinimizeD = 0;
-static HBITMAP hBmpMaximize = 0;
-static HBITMAP hBmpMaximizeD = 0;
-static HBITMAP hBmpClose = 0;
-static HBITMAP hBmpCloseD = 0;
-
+static HBITMAP hBmpSysMenu = 0;
 
 static HBRUSH  hShadeBrush = 0;
 static HFONT   hMenuFont = 0;
@@ -166,10 +169,8 @@ static HFONT       hMenuFontBold = 0;
 static HMENU MENU_DefSysPopup = 0;  /* Default system menu popup */
 
 /* Use global popup window because there's no way 2 menus can
- * be tracked at the same time.  */ 
-
-static WND* pTopPopupWnd   = 0;
-static UINT uSubPWndLevel = 0;
+ * be tracked at the same time.  */
+static HWND top_popup;
 
   /* Flag set by EndMenu() to force an exit from menu tracking */
 static BOOL fEndMenu = FALSE;
@@ -209,30 +210,30 @@ const struct builtin_class_descr MENU_builtin_class =
     if (flags & (bit)) { flags &= ~(bit); MENUOUT ((text)); } \
   } while (0)
 
-static void do_debug_print_menuitem(const char *prefix, MENUITEM * mp, 
+static void do_debug_print_menuitem(const char *prefix, MENUITEM * mp,
                                    const char *postfix)
 {
     TRACE("%s ", prefix);
     if (mp) {
        UINT flags = mp->fType;
-       int typ = MENU_ITEM_TYPE(flags);
+       int type = MENU_ITEM_TYPE(flags);
        DPRINTF( "{ ID=0x%x", mp->wID);
        if (flags & MF_POPUP)
            DPRINTF( ", Sub=0x%x", mp->hSubMenu);
        if (flags) {
            int count = 0;
-           DPRINTF( ", Typ=");
-           if (typ == MFT_STRING)
+           DPRINTF( ", Type=");
+           if (type == MFT_STRING)
                /* Nothing */ ;
-           else if (typ == MFT_SEPARATOR)
+           else if (type == MFT_SEPARATOR)
                MENUOUT("sep");
-           else if (typ == MFT_OWNERDRAW)
+           else if (type == MFT_OWNERDRAW)
                MENUOUT("own");
-           else if (typ == MFT_BITMAP)
+           else if (type == MFT_BITMAP)
                MENUOUT("bit");
            else
                MENUOUT("???");
-           flags -= typ;
+           flags -= type;
 
            MENUFLAG(MF_POPUP, "pop");
            MENUFLAG(MFT_MENUBARBREAK, "barbrk");
@@ -264,7 +265,7 @@ static void do_debug_print_menuitem(const char *prefix, MENUITEM * mp,
        if (mp->hUnCheckBit)
            DPRINTF( ", Unc=0x%x", mp->hUnCheckBit);
 
-       if (typ == MFT_STRING) {
+       if (type == MFT_STRING) {
            if (mp->text)
                DPRINTF( ", Text=%s", debugstr_w(mp->text));
            else
@@ -292,18 +293,34 @@ static void do_debug_print_menuitem(const char *prefix, MENUITEM * mp,
  *
  * Validate the given menu handle and returns the menu structure pointer.
  */
-POPUPMENU *MENU_GetMenu(HMENU hMenu)
+static POPUPMENU *MENU_GetMenu(HMENU hMenu)
 {
-    POPUPMENU *menu;
-    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(hMenu);
-    if (!IS_A_MENU(menu)) 
+    POPUPMENU *menu = USER_HEAP_LIN_ADDR(hMenu);
+    if (!menu || menu->wMagic != MENU_MAGIC)
     {
-        WARN("invalid menu handle=%x, ptr=%p, magic=%x\n", hMenu, menu, menu? menu->wMagic:0); 
+        WARN("invalid menu handle=%x, ptr=%p, magic=%x\n", hMenu, menu, menu? menu->wMagic:0);
         menu = NULL;
     }
     return menu;
 }
 
+/***********************************************************************
+ *           get_win_sys_menu
+ *
+ * Get the system menu of a window
+ */
+static HMENU get_win_sys_menu( HWND hwnd )
+{
+    HMENU ret = 0;
+    WND *win = WIN_FindWndPtr( hwnd );
+    if (win)
+    {
+        ret = win->hSysMenu;
+        WIN_ReleaseWndPtr( win );
+    }
+    return ret;
+}
+
 /***********************************************************************
  *           MENU_CopySysPopup
  *
@@ -314,74 +331,43 @@ static HMENU MENU_CopySysPopup(void)
     HMENU hMenu = LoadMenuA(GetModuleHandleA("USER32"), "SYSMENU");
 
     if( hMenu ) {
-        POPUPMENU* menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(hMenu);
+        POPUPMENU* menu = MENU_GetMenu(hMenu);
         menu->wFlags |= MF_SYSMENU | MF_POPUP;
        SetMenuDefaultItem(hMenu, SC_CLOSE, FALSE);
     }
-    else {
-       hMenu = 0;
+    else
        ERR("Unable to load default system menu\n" );
-    }
 
     TRACE("returning %x.\n", hMenu );
 
     return hMenu;
 }
 
-/***********************************************************************
- *           MENU_GetTopPopupWnd()
- *
- * Return the locked pointer pTopPopupWnd.
- */
-static WND *MENU_GetTopPopupWnd()
-{
-    return WIN_LockWndPtr(pTopPopupWnd);
-}
-/***********************************************************************
- *           MENU_ReleaseTopPopupWnd()
- *
- * Release the locked pointer pTopPopupWnd.
- */
-static void MENU_ReleaseTopPopupWnd()
-{
-    WIN_ReleaseWndPtr(pTopPopupWnd);
-}
-/***********************************************************************
- *           MENU_DestroyTopPopupWnd()
- *
- * Destroy the locked pointer pTopPopupWnd.
- */
-static void MENU_DestroyTopPopupWnd()
-{
-    WND *tmpWnd = pTopPopupWnd;
-    pTopPopupWnd = NULL;
-    WIN_ReleaseWndPtr(tmpWnd);
-}
-
-
 
 /**********************************************************************
  *           MENU_GetSysMenu
  *
  * Create a copy of the system menu. System menu in Windows is
  * a special menu bar with the single entry - system menu popup.
- * This popup is presented to the outside world as a "system menu". 
- * However, the real system menu handle is sometimes seen in the 
+ * This popup is presented to the outside world as a "system menu".
+ * However, the real system menu handle is sometimes seen in the
  * WM_MENUSELECT parameters (and Word 6 likes it this way).
  */
 HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu )
 {
     HMENU hMenu;
 
+    TRACE("loading system menu, hWnd %04x, hPopupMenu %04x\n", hWnd, hPopupMenu);
     if ((hMenu = CreateMenu()))
     {
-       POPUPMENU *menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hMenu);
+       POPUPMENU *menu = MENU_GetMenu(hMenu);
        menu->wFlags = MF_SYSMENU;
-       menu->hWnd = hWnd;
+       menu->hWnd = WIN_GetFullHandle( hWnd );
+       TRACE("hWnd %04x (hMenu %04x)\n", menu->hWnd, hMenu);
 
        if (hPopupMenu == (HMENU)(-1))
            hPopupMenu = MENU_CopySysPopup();
-       else if( !hPopupMenu ) hPopupMenu = MENU_DefSysPopup; 
+       else if( !hPopupMenu ) hPopupMenu = MENU_DefSysPopup;
 
        if (hPopupMenu)
        {
@@ -389,10 +375,9 @@ HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu )
 
             menu->items[0].fType = MF_SYSMENU | MF_POPUP;
             menu->items[0].fState = 0;
-           menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hPopupMenu);
-           menu->wFlags |= MF_SYSMENU;
+            if ((menu = MENU_GetMenu(hPopupMenu))) menu->wFlags |= MF_SYSMENU;
 
-           TRACE("GetSysMenu hMenu=%04x (%04x)\n", hMenu, hPopupMenu );
+           TRACE("hMenu=%04x (hPopup %04x)\n", hMenu, hPopupMenu );
            return hMenu;
        }
        DestroyMenu( hMenu );
@@ -420,12 +405,7 @@ BOOL MENU_Init()
     /* Load menu bitmaps */
     hStdMnArrow = LoadBitmapA(0, MAKEINTRESOURCEA(OBM_MNARROW));
     /* Load system buttons bitmaps */
-    hBmpMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
-    hBmpMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
-    hBmpMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
-    hBmpMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
-    hBmpClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE));
-    hBmpCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
+    hBmpSysMenu = LoadBitmapA(0, MAKEINTRESOURCEA(OBM_CLOSE));
 
     if (hStdMnArrow)
     {
@@ -436,12 +416,12 @@ BOOL MENU_Init()
     } else
        return FALSE;
 
-    if (! (hBitmap = CreateBitmap( 8, 8, 1, 1, shade_bits))) 
+    if (! (hBitmap = CreateBitmap( 8, 8, 1, 1, shade_bits)))
        return FALSE;
 
-    if(!(hShadeBrush = CreatePatternBrush( hBitmap ))) 
+    if(!(hShadeBrush = CreatePatternBrush( hBitmap )))
        return FALSE;
-       
+
     DeleteObject( hBitmap );
     if (!(MENU_DefSysPopup = MENU_CopySysPopup()))
        return FALSE;
@@ -449,7 +429,7 @@ BOOL MENU_Init()
     ncm.cbSize = sizeof (NONCLIENTMETRICSA);
     if (!(SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &ncm, 0)))
        return FALSE;
-       
+
     if (!(hMenuFont = CreateFontIndirectA( &ncm.lfMenuFont )))
        return FALSE;
 
@@ -500,12 +480,13 @@ static void MENU_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle )
 static UINT  MENU_GetStartOfNextColumn(
     HMENU  hMenu )
 {
-    POPUPMENU  *menu = (POPUPMENU *)USER_HEAP_LIN_ADDR(hMenu);
-    UINT  i = menu->FocusedItem + 1;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
+    UINT i;
 
     if(!menu)
        return NO_SELECTED_ITEM;
 
+    i = menu->FocusedItem + 1;
     if( i == NO_SELECTED_ITEM )
        return i;
 
@@ -528,7 +509,7 @@ static UINT  MENU_GetStartOfNextColumn(
 static UINT  MENU_GetStartOfPrevColumn(
     HMENU  hMenu )
 {
-    POPUPMENU const  *menu = (POPUPMENU *)USER_HEAP_LIN_ADDR(hMenu);
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
     UINT  i;
 
     if( !menu )
@@ -603,7 +584,7 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
 /***********************************************************************
  *           MENU_FindSubMenu
  *
- * Find a Sub menu. Return the position of the submenu, and modifies 
+ * Find a Sub menu. Return the position of the submenu, and modifies
  * *hmenu in case it is found in another sub-menu.
  * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
  */
@@ -612,8 +593,8 @@ UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget )
     POPUPMENU *menu;
     UINT i;
     MENUITEM *item;
-    if (((*hmenu)==0xffff) || 
-            (!(menu = MENU_GetMenu(*hmenu)))) 
+    if (((*hmenu)==0xffff) ||
+            (!(menu = MENU_GetMenu(*hmenu))))
         return NO_SELECTED_ITEM;
     item = menu->items;
     for (i = 0; i < menu->nItems; i++, item++) {
@@ -646,11 +627,11 @@ static void MENU_FreeItemData( MENUITEM* item )
 /***********************************************************************
  *           MENU_FindItemByCoords
  *
- * Find the item at the specified coordinates (screen coords). Does 
- * not work for child windows and therefore should not be called for 
+ * Find the item at the specified coordinates (screen coords). Does
+ * not work for child windows and therefore should not be called for
  * an arbitrary system menu.
  */
-static MENUITEM *MENU_FindItemByCoords( POPUPMENU *menu, 
+static MENUITEM *MENU_FindItemByCoords( POPUPMENU *menu,
                                        POINT pt, UINT *pos )
 {
     MENUITEM *item;
@@ -679,17 +660,12 @@ static MENUITEM *MENU_FindItemByCoords( POPUPMENU *menu,
  * Find the menu item selected by a key press.
  * Return item id, -1 if none, -2 if we should close the menu.
  */
-static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, 
+static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu,
                                  UINT key, BOOL forceMenuChar )
 {
     TRACE("\tlooking for '%c' in [%04x]\n", (char)key, (UINT16)hmenu );
 
-    if (!IsMenu( hmenu )) 
-    {
-       WND* w = WIN_FindWndPtr(hwndOwner);
-       hmenu = GetSubMenu(w->hSysMenu, 0);
-        WIN_ReleaseWndPtr(w);
-    }
+    if (!IsMenu( hmenu )) hmenu = GetSubMenu( get_win_sys_menu(hwndOwner), 0);
 
     if (hmenu)
     {
@@ -704,7 +680,7 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu,
             key = toupper(key);
             for (i = 0; i < menu->nItems; i++, item++)
             {
-               if (item->text && (IS_STRING_ITEM(item->fType)))
+               if (IS_STRING_ITEM(item->fType) && item->text)
                {
                    WCHAR *p = item->text - 2;
                    do
@@ -716,54 +692,157 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu,
                }
             }
        }
-       menuchar = SendMessageA( hwndOwner, WM_MENUCHAR, 
+       menuchar = SendMessageA( hwndOwner, WM_MENUCHAR,
                                    MAKEWPARAM( key, menu->wFlags ), hmenu );
        if (HIWORD(menuchar) == 2) return LOWORD(menuchar);
        if (HIWORD(menuchar) == 1) return (UINT)(-2);
     }
     return (UINT)(-1);
 }
+
+
 /***********************************************************************
- *           MENU_LoadMagicItem
+ *           MENU_GetBitmapItemSize
  *
- * Load the bitmap associated with the magic menu item and its style
- */
-
-static HBITMAP MENU_LoadMagicItem(UINT id, BOOL hilite, DWORD dwItemData)
-{
-    /*
-     * Magic menu item id's section
-     * These magic id's are used by windows to insert "standard" mdi
-     * buttons (minimize,restore,close) on menu. Under windows,
-     * these magic id's make sure the right things appear when those
-     * bitmap buttons are pressed/selected/released.
-     */
-
-    switch(id & 0xffff)
-    {   case HBMMENU_SYSTEM:
-           return (dwItemData) ?
-               (HBITMAP)dwItemData :
-               (hilite ? hBmpMinimizeD : hBmpMinimize);
-       case HBMMENU_MBAR_RESTORE:
-           return (hilite ? hBmpMaximizeD: hBmpMaximize);
-       case HBMMENU_MBAR_MINIMIZE:
-           return (hilite ? hBmpMinimizeD : hBmpMinimize);
-       case HBMMENU_MBAR_CLOSE:
-           return (hilite ? hBmpCloseD : hBmpClose);
-       case HBMMENU_CALLBACK:
-       case HBMMENU_MBAR_CLOSE_D:
-       case HBMMENU_MBAR_MINIMIZE_D:
-       case HBMMENU_POPUP_CLOSE:
-       case HBMMENU_POPUP_RESTORE:
-       case HBMMENU_POPUP_MAXIMIZE:
-       case HBMMENU_POPUP_MINIMIZE:
-       default:
-           FIXME("Magic 0x%08x not implemented\n", id);
-           return 0;
+ * Get the size of a bitmap item.
+ */
+static void MENU_GetBitmapItemSize( UINT id, DWORD data, SIZE *size )
+{
+    BITMAP bm;
+    HBITMAP bmp = (HBITMAP)id;
+
+    size->cx = size->cy = 0;
+
+    /* check if there is a magic menu item associated with this item */
+    if (id && IS_MAGIC_ITEM( id ))
+    {
+        switch(LOWORD(id))
+        {
+        case HBMMENU_SYSTEM:
+            if (data)
+            {
+                bmp = (HBITMAP)data;
+                break;
+            }
+            /* fall through */
+        case HBMMENU_MBAR_RESTORE:
+        case HBMMENU_MBAR_MINIMIZE:
+        case HBMMENU_MBAR_MINIMIZE_D:
+        case HBMMENU_MBAR_CLOSE:
+        case HBMMENU_MBAR_CLOSE_D:
+            size->cx = GetSystemMetrics( SM_CXSIZE );
+            size->cy = GetSystemMetrics( SM_CYSIZE );
+            return;
+        case HBMMENU_CALLBACK:
+        case HBMMENU_POPUP_CLOSE:
+        case HBMMENU_POPUP_RESTORE:
+        case HBMMENU_POPUP_MAXIMIZE:
+        case HBMMENU_POPUP_MINIMIZE:
+        default:
+            FIXME("Magic 0x%08x not implemented\n", id);
+            return;
+        }
+    }
+    if (GetObjectA(bmp, sizeof(bm), &bm ))
+    {
+        size->cx = bm.bmWidth;
+        size->cy = bm.bmHeight;
     }
+}
+
+/***********************************************************************
+ *           MENU_DrawBitmapItem
+ *
+ * Draw a bitmap item.
+ */
+static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect, BOOL menuBar )
+{
+    BITMAP bm;
+    DWORD rop;
+    HDC hdcMem;
+    HBITMAP bmp = (HBITMAP)lpitem->text;
+    int w = rect->right - rect->left;
+    int h = rect->bottom - rect->top;
+    int bmp_xoffset = 0;
+    int left, top;
 
+    /* Check if there is a magic menu item associated with this item */
+    if (lpitem->text && IS_MAGIC_ITEM(lpitem->text))
+    {
+        UINT flags = 0;
+        RECT r;
+
+        switch(LOWORD(lpitem->text))
+        {
+        case HBMMENU_SYSTEM:
+            if (lpitem->dwItemData)
+            {
+                bmp = (HBITMAP)lpitem->dwItemData;
+                if (!GetObjectA( bmp, sizeof(bm), &bm )) return;
+            }
+            else
+            {
+                bmp = hBmpSysMenu;
+                if (!GetObjectA( bmp, sizeof(bm), &bm )) return;
+                /* only use right half of the bitmap */
+                bmp_xoffset = bm.bmWidth / 2;
+                bm.bmWidth -= bmp_xoffset;
+            }
+            goto got_bitmap;
+        case HBMMENU_MBAR_RESTORE:
+            flags = DFCS_CAPTIONRESTORE;
+            break;
+        case HBMMENU_MBAR_MINIMIZE:
+            flags = DFCS_CAPTIONMIN;
+            break;
+        case HBMMENU_MBAR_MINIMIZE_D:
+            flags = DFCS_CAPTIONMIN | DFCS_INACTIVE;
+            break;
+        case HBMMENU_MBAR_CLOSE:
+            flags = DFCS_CAPTIONCLOSE;
+            break;
+        case HBMMENU_MBAR_CLOSE_D:
+            flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
+            break;
+        case HBMMENU_CALLBACK:
+        case HBMMENU_POPUP_CLOSE:
+        case HBMMENU_POPUP_RESTORE:
+        case HBMMENU_POPUP_MAXIMIZE:
+        case HBMMENU_POPUP_MINIMIZE:
+        default:
+            FIXME("Magic 0x%08x not implemented\n", LOWORD(lpitem->text));
+            return;
+        }
+        r = *rect;
+        InflateRect( &r, -1, -1 );
+        if (lpitem->fState & MF_HILITE) flags |= DFCS_PUSHED;
+        DrawFrameControl( hdc, &r, DFC_CAPTION, flags );
+        return;
+    }
+
+    if (!bmp || !GetObjectA( bmp, sizeof(bm), &bm )) return;
+
+ got_bitmap:
+    hdcMem = CreateCompatibleDC( hdc );
+    SelectObject( hdcMem, bmp );
+
+    /* handle fontsize > bitmap_height */
+    top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top;
+    left=rect->left;
+    if (TWEAK_WineLook == WIN95_LOOK) {
+        rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_ITEM(lpitem->text)) ? NOTSRCCOPY : SRCCOPY;
+        if ((lpitem->fState & MF_HILITE) && IS_BITMAP_ITEM(lpitem->fType))
+            SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
+    } else {
+        left++;
+        w-=2;
+        rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_ITEM(lpitem->text) && (!menuBar)) ? MERGEPAINT : SRCCOPY;
+    }
+    BitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop );
+    DeleteDC( hdcMem );
 }
 
+
 /***********************************************************************
  *           MENU_CalcItemSize
  *
@@ -776,7 +855,7 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
     UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
 
     TRACE("dc=0x%04x owner=0x%04x (%d,%d)\n", hdc, hwndOwner, orgX, orgY);
-    debug_print_menuitem("MENU_CalcItemSize: menuitem:", lpitem, 
+    debug_print_menuitem("MENU_CalcItemSize: menuitem:", lpitem,
                         (menuBar ? " (MenuBar)" : ""));
 
     SetRect( &lpitem->rect, orgX, orgY, orgX, orgY );
@@ -803,7 +882,7 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
        if (menuBar)
        {
             lpitem->rect.right += MENU_BAR_ITEMS_SPACE;
-       
+
 
              /* under at least win95 you seem to be given a standard
                 height for the menu and the height value is ignored */
@@ -815,11 +894,11 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
         }
         else
             lpitem->rect.bottom += mis.itemHeight;
-       
+
        TRACE("id=%04x size=%dx%d\n",
                      lpitem->wID, mis.itemWidth, mis.itemHeight);
         /* Fall through to get check/arrow width calculation. */
-    } 
+    }
 
     if (lpitem->fType & MF_SEPARATOR)
     {
@@ -839,38 +918,26 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
 
     if (IS_BITMAP_ITEM(lpitem->fType))
     {
-       BITMAP bm;
-       HBITMAP resBmp = 0;
-
-       /* Check if there is a magic menu item associated with this item */
-       if (IS_MAGIC_ITEM(lpitem->text))
-       {
-           resBmp = MENU_LoadMagicItem((int)lpitem->text, (lpitem->fType & MF_HILITE),
-                                       lpitem->dwItemData);
-        }
-        else
-            resBmp = (HBITMAP)lpitem->text;
+        SIZE size;
 
-        if (GetObjectA(resBmp, sizeof(bm), &bm ))
+        MENU_GetBitmapItemSize( (int)lpitem->text, lpitem->dwItemData, &size );
+        lpitem->rect.right  += size.cx;
+        lpitem->rect.bottom += size.cy;
+        if (TWEAK_WineLook == WIN98_LOOK)
         {
-            lpitem->rect.right  += bm.bmWidth;
-            lpitem->rect.bottom += bm.bmHeight;
-            if (TWEAK_WineLook == WIN98_LOOK) {
-                /* Leave space for the sunken border */
-                lpitem->rect.right  += 2;
-                lpitem->rect.bottom += 2;
-            }
-
+            /* Leave space for the sunken border */
+            lpitem->rect.right  += 2;
+            lpitem->rect.bottom += 2;
         }
     }
-    
+
 
     /* it must be a text item - unless it's the system menu */
     if (!(lpitem->fType & MF_SYSMENU) && IS_STRING_ITEM( lpitem->fType ))
     {   SIZE size;
 
        GetTextExtentPoint32W(hdc, lpitem->text,  strlenW(lpitem->text), &size);
-       
+
        lpitem->rect.right  += size.cx;
        if (TWEAK_WineLook == WIN31_LOOK)
            lpitem->rect.bottom += max( size.cy, GetSystemMetrics(SM_CYMENU) );
@@ -893,7 +960,7 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner,
        {
            if (strchrW( lpitem->text, '\b' ))
                lpitem->rect.right += MENU_TAB_SPACE;
-           lpitem->xTab = lpitem->rect.right - check_bitmap_width 
+           lpitem->xTab = lpitem->rect.right - check_bitmap_width
                           - arrow_bitmap_width;
        }
     }
@@ -918,7 +985,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner )
     hdc = GetDC( 0 );
 
     SelectObject( hdc, hMenuFont);
-    
+
     start = 0;
     maxX = (TWEAK_WineLook == WIN31_LOOK) ? GetSystemMetrics(SM_CXBORDER) : 2+1 ;
 
@@ -955,7 +1022,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner )
            lpitem->rect.right = maxX;
            if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
                lpitem->xTab = maxTab;
-       
+
        }
        lppop->Height = max( lppop->Height, orgY );
     }
@@ -990,7 +1057,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect,
 
     if ((lprect == NULL) || (lppop == NULL)) return;
     if (lppop->nItems == 0) return;
-    TRACE("left=%d top=%d right=%d bottom=%d\n", 
+    TRACE("left=%d top=%d right=%d bottom=%d\n",
                  lprect->left, lprect->top, lprect->right, lprect->bottom);
     lppop->Width  = lprect->right - lprect->left;
     lppop->Height = 0;
@@ -1010,7 +1077,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect,
            if ((i != start) &&
                (lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 
-           TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", 
+           TRACE("calling MENU_CalcItemSize org=(%d, %d)\n",
                         orgX, orgY );
            debug_print_menuitem ("  item: ", lpitem, "");
            MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, TRUE );
@@ -1067,7 +1134,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
                                    lpitem->fState &
                                    (MF_HILITE | MF_MOUSESELECT) );
            else
-               NC_DrawSysButton( hwnd, hdc, 
+               NC_DrawSysButton( hwnd, hdc,
                                  lpitem->fState &
                                  (MF_HILITE | MF_MOUSESELECT) );
        }
@@ -1097,12 +1164,12 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         if (lpitem->fState & MF_GRAYED)  dis.itemState |= ODS_GRAYED;
         if (lpitem->fState & MF_HILITE)  dis.itemState |= ODS_SELECTED;
         dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
-        dis.hwndItem   = hmenu;
+        dis.hwndItem   = (HWND)hmenu;
         dis.hDC        = hdc;
         dis.rcItem     = lpitem->rect;
         TRACE("Ownerdraw: owner=%04x itemID=%d, itemState=%d, itemAction=%d, "
              "hwndItem=%04x, hdc=%04x, rcItem={%d,%d,%d,%d}\n", hwndOwner,
-             dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem, 
+             dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
              dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
              dis.rcItem.bottom);
         SendMessageA( hwndOwner, WM_DRAWITEM, 0, (LPARAM)&dis );
@@ -1144,16 +1211,16 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         /* vertical separator */
         if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
         {
-           if (TWEAK_WineLook > WIN31_LOOK) 
+           if (TWEAK_WineLook > WIN31_LOOK)
            {
                RECT rc = rect;
                rc.top = 3;
                rc.bottom = height - 3;
                DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
            }
-           else 
+           else
            {
-               SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
+               SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
                MoveToEx( hdc, rect.left, 0, NULL );
                LineTo( hdc, rect.left, height );
            }
@@ -1162,7 +1229,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         /* horizontal separator */
         if (lpitem->fType & MF_SEPARATOR)
         {
-           if (TWEAK_WineLook > WIN31_LOOK) 
+           if (TWEAK_WineLook > WIN31_LOOK)
            {
                RECT rc = rect;
                rc.left++;
@@ -1170,9 +1237,9 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
                rc.top += SEPARATOR_HEIGHT / 2;
                DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
            }
-           else 
+           else
            {
-               SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
+               SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
                MoveToEx( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2, NULL );
                LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 );
            }
@@ -1215,7 +1282,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
 
        /* helper lines for debugging */
 /*     FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
-       SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
+       SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
        MoveToEx( hdc, rect.left, (rect.top + rect.bottom)/2, NULL );
        LineTo( hdc, rect.right, (rect.top + rect.bottom)/2 );
 */
@@ -1231,7 +1298,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
              /* Draw the check mark
               *
               * FIXME:
-              * Custom checkmark bitmaps are monochrome but not always 1bpp. 
+              * Custom checkmark bitmaps are monochrome but not always 1bpp.
               */
             HBITMAP bm = (lpitem->fState & MF_CHECKED) ? lpitem->hCheckBit : lpitem->hUnCheckBit;
             if (bm)  /* we have a custom bitmap */
@@ -1259,7 +1326,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
                 DeleteObject( bm );
             }
         }
-       
+
          /* Draw the popup-menu arrow */
        if (lpitem->fType & MF_POPUP)
        {
@@ -1286,53 +1353,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
     /* Draw the item text or bitmap */
     if (IS_BITMAP_ITEM(lpitem->fType))
     {
-        int left,top,w,h;
-        DWORD rop;
-
-        HBITMAP resBmp = 0;
-
-        HDC hdcMem = CreateCompatibleDC( hdc );
-
-        /*
-         * Check if there is a magic menu item associated with this item
-         * and load the appropriate bitmap
-         */
-       if (IS_MAGIC_ITEM(lpitem->text))
-       {
-           resBmp = MENU_LoadMagicItem((int)lpitem->text, (lpitem->fState & MF_HILITE),
-                                       lpitem->dwItemData);
-        }
-        else
-            resBmp = (HBITMAP)lpitem->text;
-
-       if (resBmp)
-       {
-           BITMAP bm;
-           GetObjectA( resBmp, sizeof(bm), &bm );
-       
-           SelectObject(hdcMem,resBmp );
-       
-           /* handle fontsize > bitmap_height */
-            h=rect.bottom - rect.top;
-           top = (h>bm.bmHeight) ? 
-               rect.top+(h-bm.bmHeight)/2 : rect.top;
-            w=rect.right - rect.left;
-            left=rect.left;
-            if (TWEAK_WineLook == WIN95_LOOK) {
-                rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_ITEM(lpitem->text)) ? NOTSRCCOPY : SRCCOPY;
-                if ((lpitem->fState & MF_HILITE) && IS_BITMAP_ITEM(lpitem->fType))
-                    SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
-            } else {
-                left++;
-                w-=2;
-                rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_ITEM(lpitem->text) && (!menuBar)) ? MERGEPAINT : SRCCOPY;
-            }
-           BitBlt( hdc, left, top, w,
-                 h, hdcMem, 0, 0,
-                  rop);
-       }
-       DeleteDC( hdcMem );
-
+        MENU_DrawBitmapItem( hdc, lpitem, &rect, menuBar );
        return;
 
     }
@@ -1341,7 +1362,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
     {
        register int i;
        HFONT hfontOld = 0;
-       
+
        UINT uFormat = (menuBar) ?
                        DT_CENTER | DT_VCENTER | DT_SINGLELINE :
                        DT_LEFT | DT_VCENTER | DT_SINGLELINE;
@@ -1355,16 +1376,13 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
        {
            rect.left += MENU_BAR_ITEMS_SPACE / 2;
            rect.right -= MENU_BAR_ITEMS_SPACE / 2;
-           i = strlenW( lpitem->text );
-       }
-       else
-       {
-           for (i = 0; lpitem->text[i]; i++)
-               if ((lpitem->text[i] == '\t') || (lpitem->text[i] == '\b'))
-                   break;
        }
 
-       if( !(TWEAK_WineLook == WIN31_LOOK) && (lpitem->fState & MF_GRAYED))
+       for (i = 0; lpitem->text[i]; i++)
+           if ((lpitem->text[i] == '\t') || (lpitem->text[i] == '\b'))
+               break;
+
+       if( (TWEAK_WineLook != WIN31_LOOK) && (lpitem->fState & MF_GRAYED))
        {
            if (!(lpitem->fState & MF_HILITE) )
            {
@@ -1375,23 +1393,23 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
            }
            SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
        }
-       
+
        DrawTextW( hdc, lpitem->text, i, &rect, uFormat);
 
        /* paint the shortcut text */
-       if (lpitem->text[i])  /* There's a tab or flush-right char */
+       if (!menuBar && lpitem->text[i])  /* There's a tab or flush-right char */
        {
            if (lpitem->text[i] == '\t')
            {
                rect.left = lpitem->xTab;
                uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
            }
-           else 
+           else
            {
                uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
            }
 
-           if( !(TWEAK_WineLook == WIN31_LOOK) && (lpitem->fState & MF_GRAYED))
+           if( (TWEAK_WineLook != WIN31_LOOK) && (lpitem->fState & MF_GRAYED))
            {
                if (!(lpitem->fState & MF_HILITE) )
                {
@@ -1405,7 +1423,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
            DrawTextW( hdc, lpitem->text + i + 1, -1, &rect, uFormat );
        }
 
-       if (hfontOld) 
+       if (hfontOld)
            SelectObject (hdc, hfontOld);
     }
 }
@@ -1425,17 +1443,17 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
 
     GetClientRect( hwnd, &rect );
 
-    if(TWEAK_WineLook == WIN31_LOOK) 
+    if(TWEAK_WineLook == WIN31_LOOK)
     {
        rect.bottom -= POPUP_YSHADE * GetSystemMetrics(SM_CYBORDER);
        rect.right -= POPUP_XSHADE * GetSystemMetrics(SM_CXBORDER);
-    } 
+    }
 
-    if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) )) 
+    if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) ))
         && (SelectObject( hdc, hMenuFont)))
     {
        HPEN hPrevPen;
-       
+
        Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom );
 
        hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) );
@@ -1475,11 +1493,11 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
                UINT u;
 
                for (u = menu->nItems, item = menu->items; u > 0; u--, item++)
-                   MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc, item, 
+                   MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc, item,
                                       menu->Height, FALSE, ODA_DRAWENTIRE );
 
            }
-       } else 
+       } else
        {
            SelectObject( hdc, hPrevBrush );
        }
@@ -1498,10 +1516,9 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
     LPPOPUPMENU lppop;
     UINT i,retvalue;
     HFONT hfontOld = 0;
+    HMENU hMenu = GetMenu(hwnd);
 
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    
-    lppop = MENU_GetMenu ((HMENU)wndPtr->wIDmenu );
+    lppop = MENU_GetMenu( hMenu );
     if (lppop == NULL || lprect == NULL)
     {
         retvalue = GetSystemMetrics(SM_CYMENU);
@@ -1525,15 +1542,15 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
 
     FillRect(hDC, lprect, GetSysColorBrush(COLOR_MENU) );
 
-    if (TWEAK_WineLook == WIN31_LOOK) 
+    if (TWEAK_WineLook == WIN31_LOOK)
     {
-       SelectObject( hDC, GetSysColorPen(COLOR_WINDOWFRAME) );
+       SelectObject( hDC, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
        MoveToEx( hDC, lprect->left, lprect->bottom, NULL );
        LineTo( hDC, lprect->right, lprect->bottom );
     }
-    else 
+    else
     {
-       SelectObject( hDC, GetSysColorPen(COLOR_3DFACE));
+       SelectObject( hDC, SYSCOLOR_GetPen(COLOR_3DFACE));
        MoveToEx( hDC, lprect->left, lprect->bottom, NULL );
        LineTo( hDC, lprect->right, lprect->bottom );
     }
@@ -1546,77 +1563,17 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
 
     for (i = 0; i < lppop->nItems; i++)
     {
-       MENU_DrawMenuItem( hwnd, (HMENU)wndPtr->wIDmenu, hwnd,
-                        hDC, &lppop->items[i], lppop->Height, TRUE, ODA_DRAWENTIRE );
+        MENU_DrawMenuItem( hwnd, hMenu, hwnd,
+                           hDC, &lppop->items[i], lppop->Height, TRUE, ODA_DRAWENTIRE );
     }
     retvalue = lppop->Height;
 
 END:
-    if (hfontOld) 
-       SelectObject (hDC, hfontOld);
-       
-    WIN_ReleaseWndPtr(wndPtr);
+    if (hfontOld) SelectObject (hDC, hfontOld);
     return retvalue;
-} 
-
-/***********************************************************************
- *          MENU_PatchResidentPopup
- */
-BOOL MENU_PatchResidentPopup( HQUEUE16 checkQueue, WND* checkWnd )
-{
-    WND *pTPWnd = MENU_GetTopPopupWnd();
-    
-    if( pTPWnd )
-    {
-       HTASK16 hTask = 0;
-
-       TRACE("patching resident popup: %04x %04x [%04x %04x]\n", 
-               checkQueue, checkWnd ? checkWnd->hwndSelf : 0, pTPWnd->hmemTaskQ,
-               pTPWnd->owner ? pTPWnd->owner->hwndSelf : 0);
-
-       switch( checkQueue )
-       {
-           case 0: /* checkWnd is the new popup owner */
-                if( checkWnd )
-                {
-                    pTPWnd->owner = checkWnd;
-                    if( pTPWnd->hmemTaskQ != checkWnd->hmemTaskQ )
-                        hTask = QUEUE_GetQueueTask( checkWnd->hmemTaskQ );
-                }
-                break;
-
-           case 0xFFFF: /* checkWnd is destroyed */
-                if( pTPWnd->owner == checkWnd )
-                     pTPWnd->owner = NULL;
-                 MENU_ReleaseTopPopupWnd();
-                return TRUE; 
-
-           default: /* checkQueue is exiting */
-                if( pTPWnd->hmemTaskQ == checkQueue )
-                {
-                    hTask = QUEUE_GetQueueTask( pTPWnd->hmemTaskQ );
-                    hTask = TASK_GetNextTask( hTask );
-                }
-                break;
-       }
-
-       if( hTask )
-       {
-           TDB* task = TASK_GetPtr( hTask );
-           if( task )
-           {
-               pTPWnd->hInstance = task->hInstance;
-                pTPWnd->hmemTaskQ = task->hQueue;
-                MENU_ReleaseTopPopupWnd();
-               return TRUE;
-           } 
-           else WARN("failed to patch resident popup.\n");
-       } 
-    }
-    MENU_ReleaseTopPopupWnd();
-    return FALSE;
 }
 
+
 /***********************************************************************
  *           MENU_ShowPopup
  *
@@ -1625,8 +1582,8 @@ BOOL MENU_PatchResidentPopup( HQUEUE16 checkQueue, WND* checkWnd )
 static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id,
                               INT x, INT y, INT xanchor, INT yanchor )
 {
-    POPUPMENU  *menu;
-    WND        *wndOwner = NULL;
+    POPUPMENU *menu;
+    UINT width, height;
 
     TRACE("owner=0x%04x hmenu=0x%04x id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
     hwndOwner, hmenu, id, x, y, xanchor, yanchor);
@@ -1641,99 +1598,52 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id,
     /* store the owner for DrawItem */
     menu->hwndOwner = hwndOwner;
 
-    if( (wndOwner = WIN_FindWndPtr( hwndOwner )) )
-    {
-       UINT    width, height;
-
-       MENU_PopupMenuCalcSize( menu, hwndOwner );
-
-       /* adjust popup menu pos so that it fits within the desktop */
-
-       width = menu->Width + GetSystemMetrics(SM_CXBORDER);
-       height = menu->Height + GetSystemMetrics(SM_CYBORDER); 
-
-       if( x + width > GetSystemMetrics(SM_CXSCREEN ))
-       {
-           if( xanchor )
-               x -= width - xanchor;
-            if( x + width > GetSystemMetrics(SM_CXSCREEN))
-               x = GetSystemMetrics(SM_CXSCREEN) - width;
-       }
-       if( x < 0 ) x = 0;
-
-       if( y + height > GetSystemMetrics(SM_CYSCREEN ))
-       { 
-           if( yanchor )
-               y -= height + yanchor;
-           if( y + height > GetSystemMetrics(SM_CYSCREEN ))
-               y = GetSystemMetrics(SM_CYSCREEN) - height;
-       }
-       if( y < 0 ) y = 0;
 
-       if( TWEAK_WineLook == WIN31_LOOK )
-       {
-           width += POPUP_XSHADE * GetSystemMetrics(SM_CXBORDER);      /* add space for shading */
-           height += POPUP_YSHADE * GetSystemMetrics(SM_CYBORDER);
-       }
+    MENU_PopupMenuCalcSize( menu, hwndOwner );
 
-       /* NOTE: In Windows, top menu popup is not owned. */
-       if (!pTopPopupWnd)      /* create top level popup menu window */
-       {
-           assert( uSubPWndLevel == 0 );
+    /* adjust popup menu pos so that it fits within the desktop */
 
-           pTopPopupWnd = WIN_FindWndPtr(CreateWindowA( POPUPMENU_CLASS_ATOM, NULL,
-                                         WS_POPUP, x, y, width, height,
-                                         hwndOwner, 0, wndOwner->hInstance,
-                                         (LPVOID)hmenu ));
-            if (!pTopPopupWnd)
-            {
-                WIN_ReleaseWndPtr(wndOwner);
-                return FALSE;
-            }
-           menu->hWnd = pTopPopupWnd->hwndSelf;
-            MENU_ReleaseTopPopupWnd();
-       } 
-       else
-           if( uSubPWndLevel )
-           {
-               /* create a new window for the submenu */
+    width = menu->Width + GetSystemMetrics(SM_CXBORDER);
+    height = menu->Height + GetSystemMetrics(SM_CYBORDER);
 
-               menu->hWnd = CreateWindowA( POPUPMENU_CLASS_ATOM, NULL,
-                                         WS_POPUP, x, y, width, height,
-                                         hwndOwner, 0, wndOwner->hInstance,
-                                         (LPVOID)hmenu );
-                if( !menu->hWnd )
-                {
-                    WIN_ReleaseWndPtr(wndOwner);
-                    return FALSE;
-                }
-           }
-           else /* top level popup menu window already exists */
-           {
-                WND *pTPWnd = MENU_GetTopPopupWnd();
-               menu->hWnd = pTPWnd->hwndSelf;
-
-               MENU_PatchResidentPopup( 0, wndOwner );
-               SendMessageA( pTPWnd->hwndSelf, MM_SETMENUHANDLE, (WPARAM16)hmenu, 0L);
+    if( x + width > GetSystemMetrics(SM_CXSCREEN ))
+    {
+        if( xanchor )
+            x -= width - xanchor;
+        if( x + width > GetSystemMetrics(SM_CXSCREEN))
+            x = GetSystemMetrics(SM_CXSCREEN) - width;
+    }
+    if( x < 0 ) x = 0;
 
-               /* adjust its size */
+    if( y + height > GetSystemMetrics(SM_CYSCREEN ))
+    {
+        if( yanchor )
+            y -= height + yanchor;
+        if( y + height > GetSystemMetrics(SM_CYSCREEN ))
+            y = GetSystemMetrics(SM_CYSCREEN) - height;
+    }
+    if( y < 0 ) y = 0;
 
-               SetWindowPos( menu->hWnd, 0, x, y, width, height,
-                               SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW);
-                MENU_ReleaseTopPopupWnd();
-           }
+    if( TWEAK_WineLook == WIN31_LOOK )
+    {
+        width += POPUP_XSHADE * GetSystemMetrics(SM_CXBORDER);  /* add space for shading */
+        height += POPUP_YSHADE * GetSystemMetrics(SM_CYBORDER);
+    }
 
-       uSubPWndLevel++;        /* menu level counter */
+    /* NOTE: In Windows, top menu popup is not owned. */
+    menu->hWnd = CreateWindowA( POPUPMENU_CLASS_ATOM, NULL,
+                                WS_POPUP, x, y, width, height,
+                                hwndOwner, 0, GetWindowLongA(hwndOwner,GWL_HINSTANCE),
+                                (LPVOID)hmenu );
+    if( !menu->hWnd ) return FALSE;
+    if (!top_popup) top_popup = menu->hWnd;
 
-      /* Display the window */
+    /* Display the window */
 
-       SetWindowPos( menu->hWnd, HWND_TOP, 0, 0, 0, 0,
-                       SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
-       UpdateWindow( menu->hWnd );
-        WIN_ReleaseWndPtr(wndOwner);
-       return TRUE;
-    }
-    return FALSE;
+    SetWindowPos( menu->hWnd, HWND_TOP, 0, 0, 0, 0,
+                  SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
+    UpdateWindow( menu->hWnd );
+    return TRUE;
 }
 
 
@@ -1749,16 +1659,17 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
     TRACE("owner=0x%04x menu=0x%04x index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect);
 
     lppop = MENU_GetMenu( hmenu );
-    if ((!lppop) || (!lppop->nItems)) return;
+    if ((!lppop) || (!lppop->nItems) || (!lppop->hWnd)) return;
 
     if (lppop->FocusedItem == wIndex) return;
     if (lppop->wFlags & MF_POPUP) hdc = GetDC( lppop->hWnd );
     else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW);
+    if (!top_popup) top_popup = lppop->hWnd;
 
     SelectObject( hdc, hMenuFont);
 
       /* Clear previous highlighted item */
-    if (lppop->FocusedItem != NO_SELECTED_ITEM) 
+    if (lppop->FocusedItem != NO_SELECTED_ITEM)
     {
        lppop->items[lppop->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
        MENU_DrawMenuItem(lppop->hWnd, hmenu, hwndOwner, hdc,&lppop->items[lppop->FocusedItem],
@@ -1768,18 +1679,18 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
 
       /* Highlight new item (if any) */
     lppop->FocusedItem = wIndex;
-    if (lppop->FocusedItem != NO_SELECTED_ITEM) 
+    if (lppop->FocusedItem != NO_SELECTED_ITEM)
     {
         if(!(lppop->items[wIndex].fType & MF_SEPARATOR)) {
             lppop->items[wIndex].fState |= MF_HILITE;
-            MENU_DrawMenuItem( lppop->hWnd, hmenu, hwndOwner, hdc, 
+            MENU_DrawMenuItem( lppop->hWnd, hmenu, hwndOwner, hdc,
                     &lppop->items[wIndex], lppop->Height,
                     !(lppop->wFlags & MF_POPUP), ODA_SELECT );
         }
         if (sendMenuSelect)
         {
             MENUITEM *ip = &lppop->items[lppop->FocusedItem];
-           SendMessageA( hwndOwner, WM_MENUSELECT, 
+           SendMessageA( hwndOwner, WM_MENUSELECT,
                      MAKELONG(ip->fType & MF_POPUP ? wIndex: ip->wID,
                      ip->fType | ip->fState | MF_MOUSESELECT |
                      (lppop->wFlags & MF_SYSMENU)), hmenu);
@@ -1789,9 +1700,9 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
         if(topmenu){
             int pos;
             if((pos=MENU_FindSubMenu(&topmenu, hmenu))!=NO_SELECTED_ITEM){
-                POPUPMENU *ptm = (POPUPMENU *) USER_HEAP_LIN_ADDR( topmenu );
+                POPUPMENU *ptm = MENU_GetMenu( topmenu );
                 MENUITEM *ip = &ptm->items[pos];
-                SendMessageA( hwndOwner, WM_MENUSELECT, MAKELONG(pos, 
+                SendMessageA( hwndOwner, WM_MENUSELECT, MAKELONG(pos,
                          ip->fType | ip->fState | MF_MOUSESELECT |
                          (ptm->wFlags & MF_SYSMENU)), topmenu);
             }
@@ -1821,7 +1732,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
     if ( menu->FocusedItem != NO_SELECTED_ITEM )
     {
        if( menu->nItems == 1 ) return; else
-       for (i = menu->FocusedItem + offset ; i >= 0 && i < menu->nItems 
+       for (i = menu->FocusedItem + offset ; i >= 0 && i < menu->nItems
                                            ; i += offset)
            if (!(menu->items[i].fType & MF_SEPARATOR))
            {
@@ -1830,7 +1741,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
            }
     }
 
-    for ( i = (offset > 0) ? 0 : menu->nItems - 1; 
+    for ( i = (offset > 0) ? 0 : menu->nItems - 1;
                  i >= 0 && i < menu->nItems ; i += offset)
        if (!(menu->items[i].fType & MF_SEPARATOR))
        {
@@ -1843,7 +1754,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
 /**********************************************************************
  *         MENU_SetItemData
  *
- * Set an item flags, id and text ptr. Called by InsertMenu() and
+ * Set an item's flags, id and text ptr. Called by InsertMenu() and
  * ModifyMenu().
  */
 static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id,
@@ -1870,7 +1781,9 @@ static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id,
                 flags |= MF_HELP;
                 str++;
             }
-            if (!(text = HEAP_strdupW( GetProcessHeap(), 0, str ))) return FALSE;
+            if (!(text = HeapAlloc( GetProcessHeap(), 0, (strlenW(str)+1) * sizeof(WCHAR) )))
+                return FALSE;
+            strcpyW( text, str );
             item->text = text;
         }
     }
@@ -1878,7 +1791,7 @@ static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id,
         item->text = (LPWSTR)(HBITMAP)LOWORD(str);
     else item->text = NULL;
 
-    if (flags & MF_OWNERDRAW) 
+    if (flags & MF_OWNERDRAW)
         item->dwItemData = (DWORD)str;
     else
         item->dwItemData = 0;
@@ -1898,7 +1811,7 @@ static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id,
             item->fState = 0;
            return FALSE;
         }
-    } 
+    }
 
     item->wID = id;
     if (flags & MF_POPUP)
@@ -1925,23 +1838,23 @@ static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id,
 /**********************************************************************
  *         MENU_InsertItem
  *
- * Insert a new item into a menu.
+ * Insert (allocate) a new item into a menu.
  */
 static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags )
 {
     MENUITEM *newItems;
     POPUPMENU *menu;
 
-    if (!(menu = MENU_GetMenu(hMenu))) 
+    if (!(menu = MENU_GetMenu(hMenu)))
         return NULL;
 
     /* Find where to insert new item */
 
     if (flags & MF_BYPOSITION) {
-        if (pos > menu->nItems) 
+        if (pos > menu->nItems)
             pos = menu->nItems;
     } else {
-        if (!MENU_FindItem( &hMenu, &pos, flags )) 
+        if (!MENU_FindItem( &hMenu, &pos, flags ))
             pos = menu->nItems;
         else {
             if (!(menu = MENU_GetMenu( hMenu )))
@@ -2059,10 +1972,16 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
            if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
                DestroyMenu(mii.hSubMenu);
                 return NULL;
-        }
+           }
            mii.fMask |= MIIM_SUBMENU;
            mii.fType |= MF_POPUP;
         }
+       else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
+       {
+           WARN("Converting NULL menu item %04x, type %04x to SEPARATOR\n",
+               mii.wID, mii.fType);
+           mii.fType |= MF_SEPARATOR;
+       }
        InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
     } while (!(resinfo & MF_END));
     return res;
@@ -2102,7 +2021,7 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
 
     TRACE("owner=0x%04x hmenu=0x%04x 0x%04x\n", hwndOwner, hmenu, sendMenuSelect);
 
-    if (menu && uSubPWndLevel)
+    if (menu && top_popup)
     {
        HMENU hsubmenu;
        POPUPMENU *submenu;
@@ -2120,18 +2039,8 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
        submenu = MENU_GetMenu( hsubmenu );
        MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE );
        MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
-
-       if (submenu->hWnd == MENU_GetTopPopupWnd()->hwndSelf )
-       {
-           ShowWindow( submenu->hWnd, SW_HIDE );
-           uSubPWndLevel = 0;
-       }
-       else
-       {
-           DestroyWindow( submenu->hWnd );
-           submenu->hWnd = 0;
-       }
-        MENU_ReleaseTopPopupWnd();
+        DestroyWindow( submenu->hWnd );
+        submenu->hWnd = 0;
     }
 }
 
@@ -2148,27 +2057,17 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
     RECT rect;
     POPUPMENU *menu;
     MENUITEM *item;
-    WND *wndPtr;
     HDC hdc;
 
     TRACE("owner=0x%04x hmenu=0x%04x 0x%04x\n", hwndOwner, hmenu, selectFirst);
 
     if (!(menu = MENU_GetMenu( hmenu ))) return hmenu;
 
-    if (!(wndPtr = WIN_FindWndPtr( menu->hWnd )) ||
-        (menu->FocusedItem == NO_SELECTED_ITEM))
-    {
-        WIN_ReleaseWndPtr(wndPtr);
-        return hmenu;
-    }
+    if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu;
 
     item = &menu->items[menu->FocusedItem];
-    if (!(item->fType & MF_POPUP) ||
-        (item->fState & (MF_GRAYED | MF_DISABLED)))
-    {
-        WIN_ReleaseWndPtr(wndPtr);
+    if (!(item->fType & MF_POPUP) || (item->fState & (MF_GRAYED | MF_DISABLED)))
         return hmenu;
-    }
 
     /* message must be sent before using item,
        because nearly everything may be changed by the application ! */
@@ -2182,7 +2081,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
     rect = item->rect;
 
     /* correct item if modified as a reaction to WM_INITMENUPOPUP message */
-    if (!(item->fState & MF_HILITE)) 
+    if (!(item->fState & MF_HILITE))
     {
         if (menu->wFlags & MF_POPUP) hdc = GetDC( menu->hWnd );
         else hdc = GetDCEx( menu->hWnd, 0, DCX_CACHE | DCX_WINDOW);
@@ -2190,7 +2089,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
         SelectObject( hdc, hMenuFont);
 
         item->fState |= MF_HILITE;
-        MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE ); 
+        MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE );
        ReleaseDC( menu->hWnd, hdc );
     }
     if (!item->rect.top && !item->rect.left && !item->rect.bottom && !item->rect.right)
@@ -2200,26 +2099,29 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
 
     if (IS_SYSTEM_MENU(menu))
     {
-       MENU_InitSysMenuPopup(item->hSubMenu, wndPtr->dwStyle, GetClassLongA(wndPtr->hwndSelf, GCL_STYLE));
+       MENU_InitSysMenuPopup(item->hSubMenu,
+                              GetWindowLongA( menu->hWnd, GWL_STYLE ),
+                              GetClassLongA( menu->hWnd, GCL_STYLE));
 
-       NC_GetSysPopupPos( wndPtr, &rect );
+       NC_GetSysPopupPos( menu->hWnd, &rect );
        rect.top = rect.bottom;
        rect.right = GetSystemMetrics(SM_CXSIZE);
         rect.bottom = GetSystemMetrics(SM_CYSIZE);
     }
     else
     {
+        GetWindowRect( menu->hWnd, &rect );
        if (menu->wFlags & MF_POPUP)
        {
-           rect.left = wndPtr->rectWindow.left + item->rect.right - GetSystemMetrics(SM_CXBORDER);
-           rect.top = wndPtr->rectWindow.top + item->rect.top;
+           rect.left += item->rect.right - GetSystemMetrics(SM_CXBORDER);
+           rect.top += item->rect.top;
            rect.right = item->rect.left - item->rect.right + GetSystemMetrics(SM_CXBORDER);
            rect.bottom = item->rect.top - item->rect.bottom;
        }
        else
        {
-           rect.left = wndPtr->rectWindow.left + item->rect.left;
-           rect.top = wndPtr->rectWindow.top + item->rect.bottom;
+           rect.left += item->rect.left;
+           rect.top += item->rect.bottom;
            rect.right = item->rect.right - item->rect.left;
            rect.bottom = item->rect.bottom - item->rect.top;
        }
@@ -2229,7 +2131,6 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
                    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
         MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
-    WIN_ReleaseWndPtr(wndPtr);
     return item->hSubMenu;
 }
 
@@ -2240,7 +2141,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
  */
 BOOL MENU_IsMenuActive(void)
 {
-    return pTopPopupWnd && (pTopPopupWnd->dwStyle & WS_VISIBLE);
+    return (top_popup != 0);
 }
 
 /***********************************************************************
@@ -2251,30 +2152,28 @@ BOOL MENU_IsMenuActive(void)
 static HMENU MENU_PtMenu( HMENU hMenu, POINT pt )
 {
    POPUPMENU *menu = MENU_GetMenu( hMenu );
-   register UINT ht = menu->FocusedItem;
+   UINT item = menu->FocusedItem;
+   HMENU ret;
 
    /* try subpopup first (if any) */
-    ht = (ht != NO_SELECTED_ITEM &&
-          (menu->items[ht].fType & MF_POPUP) &&
-          (menu->items[ht].fState & MF_MOUSESELECT))
-        ? (UINT) MENU_PtMenu(menu->items[ht].hSubMenu, pt) : 0;
+   ret = (item != NO_SELECTED_ITEM &&
+          (menu->items[item].fType & MF_POPUP) &&
+          (menu->items[item].fState & MF_MOUSESELECT))
+        ? MENU_PtMenu(menu->items[item].hSubMenu, pt) : 0;
 
-   if( !ht )   /* check the current window (avoiding WM_HITTEST) */
+   if (!ret)  /* check the current window (avoiding WM_HITTEST) */
    {
-       ht = (UINT)NC_HandleNCHitTest( menu->hWnd, pt );
-       if( menu->wFlags & MF_POPUP )
-           ht =  (ht != (UINT)HTNOWHERE && 
-                  ht != (UINT)HTERROR) ? (UINT)hMenu : 0;
-       else
-       {
-           WND* wndPtr = WIN_FindWndPtr(menu->hWnd);
-
-           ht = ( ht == HTSYSMENU ) ? (UINT)(wndPtr->hSysMenu)
-                : ( ht == HTMENU ) ? (UINT)(wndPtr->wIDmenu) : 0;
-            WIN_ReleaseWndPtr(wndPtr);
-       }
+       INT ht = NC_HandleNCHitTest( menu->hWnd, pt );
+       if( menu->wFlags & MF_POPUP )
+       {
+           if (ht != HTNOWHERE && ht != HTERROR) ret = hMenu;
+       }
+       else if (ht == HTSYSMENU)
+           ret = get_win_sys_menu( menu->hWnd );
+       else if (ht == HTMENU)
+           ret = GetMenu( menu->hWnd );
    }
-   return (HMENU)ht;
+   return ret;
 }
 
 /***********************************************************************
@@ -2294,7 +2193,7 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags )
 
     TRACE("%p hmenu=0x%04x\n", pmt, hMenu);
 
-    if (!menu || !menu->nItems || 
+    if (!menu || !menu->nItems ||
        (menu->FocusedItem == NO_SELECTED_ITEM)) return -1;
 
     item = &menu->items[menu->FocusedItem];
@@ -2306,8 +2205,8 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags )
     {
        if (!(item->fState & (MF_GRAYED | MF_DISABLED)) && !(item->fType & MF_SEPARATOR))
        {
-           /* If TPM_RETURNCMD is set you return the id, but 
-              do not send a message to the owner */       
+           /* If TPM_RETURNCMD is set you return the id, but
+              do not send a message to the owner */
            if(!(wFlags & TPM_RETURNCMD))
            {
                if( menu->wFlags & MF_SYSMENU )
@@ -2357,7 +2256,7 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id )
  */
 static BOOL MENU_ButtonDown( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
 {
-    TRACE("%p hmenu=0x%04x\n", pmt, hPtMenu);
+    TRACE("%p hPtMenu=0x%04x\n", pmt, hPtMenu);
 
     if (hPtMenu)
     {
@@ -2382,11 +2281,11 @@ static BOOL MENU_ButtonDown( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
 
                /* In win31, a newly popped menu always remains opened for the next buttonup */
                if(TWEAK_WineLook == WIN31_LOOK)
-                   ptmenu->bTimeToHide = FALSE;                    
+                   ptmenu->bTimeToHide = FALSE;
            }
 
            return TRUE;
-       } 
+       }
        /* Else the click was on the menu bar, finish the tracking */
     }
     return FALSE;
@@ -2449,13 +2348,13 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
            id = 0;
         else
             MENU_FindItemByCoords( ptmenu, pmt->pt, &id );
-    } 
+    }
 
     if( id == NO_SELECTED_ITEM )
     {
-       MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, 
+       MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu,
                         NO_SELECTED_ITEM, TRUE, pmt->hTopMenu);
-        
+
     }
     else if( ptmenu->FocusedItem != id )
     {
@@ -2466,6 +2365,30 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
 }
 
 
+/***********************************************************************
+ *           MENU_SetCapture
+ */
+static void MENU_SetCapture( HWND hwnd )
+{
+    HWND previous = 0;
+
+    SERVER_START_REQ( set_capture_window )
+    {
+        req->handle = hwnd;
+        req->flags  = CAPTURE_MENU;
+        if (!wine_server_call_err( req ))
+        {
+            previous = reply->previous;
+            hwnd = reply->full_handle;
+        }
+    }
+    SERVER_END_REQ;
+
+    if (previous && previous != hwnd)
+        SendMessageW( previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd );
+}
+
+
 /***********************************************************************
  *           MENU_DoNextMenu
  *
@@ -2478,95 +2401,85 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk )
     if( (vk == VK_LEFT &&  menu->FocusedItem == 0 ) ||
         (vk == VK_RIGHT && menu->FocusedItem == menu->nItems - 1))
     {
-       WND*    wndPtr;
+        MDINEXTMENU next_menu;
        HMENU hNewMenu;
        HWND  hNewWnd;
        UINT  id = 0;
-       LRESULT l = SendMessageA( pmt->hOwnerWnd, WM_NEXTMENU, vk, 
-               (IS_SYSTEM_MENU(menu)) ? GetSubMenu16(pmt->hTopMenu,0) : pmt->hTopMenu );
+
+        next_menu.hmenuIn = (IS_SYSTEM_MENU(menu)) ? GetSubMenu(pmt->hTopMenu,0) : pmt->hTopMenu;
+        next_menu.hmenuNext = 0;
+        next_menu.hwndNext = 0;
+        SendMessageW( pmt->hOwnerWnd, WM_NEXTMENU, vk, (LPARAM)&next_menu );
 
        TRACE("%04x [%04x] -> %04x [%04x]\n",
-                    (UINT16)pmt->hCurrentMenu, (UINT16)pmt->hOwnerWnd, LOWORD(l), HIWORD(l) );
+              pmt->hCurrentMenu, pmt->hOwnerWnd, next_menu.hmenuNext, next_menu.hwndNext );
 
-       if( l == 0 )
+       if (!next_menu.hmenuNext || !next_menu.hwndNext)
        {
-           wndPtr = WIN_FindWndPtr(pmt->hOwnerWnd);
-
+            DWORD style = GetWindowLongA( pmt->hOwnerWnd, GWL_STYLE );
            hNewWnd = pmt->hOwnerWnd;
            if( IS_SYSTEM_MENU(menu) )
            {
                /* switch to the menu bar */
 
-               if( wndPtr->dwStyle & WS_CHILD || !wndPtr->wIDmenu ) 
-                {
-                    WIN_ReleaseWndPtr(wndPtr);
-                   return FALSE;
-                }
+                if(style & WS_CHILD || !(hNewMenu = GetMenu(hNewWnd))) return FALSE;
 
-               hNewMenu = wndPtr->wIDmenu;
                if( vk == VK_LEFT )
                {
                    menu = MENU_GetMenu( hNewMenu );
                    id = menu->nItems - 1;
                }
            }
-           else if( wndPtr->dwStyle & WS_SYSMENU ) 
+           else if (style & WS_SYSMENU )
            {
                /* switch to the system menu */
-               hNewMenu = wndPtr->hSysMenu; 
+               hNewMenu = get_win_sys_menu( hNewWnd );
            }
-            else
-            {
-                WIN_ReleaseWndPtr(wndPtr);
-                return FALSE;
-       }
-            WIN_ReleaseWndPtr(wndPtr);
+            else return FALSE;
        }
        else    /* application returned a new menu to switch to */
        {
-           hNewMenu = LOWORD(l); hNewWnd = HIWORD(l);
+            hNewMenu = next_menu.hmenuNext;
+            hNewWnd = WIN_GetFullHandle( next_menu.hwndNext );
 
            if( IsMenu(hNewMenu) && IsWindow(hNewWnd) )
            {
-               wndPtr = WIN_FindWndPtr(hNewWnd);
+                DWORD style = GetWindowLongA( hNewWnd, GWL_STYLE );
 
-               if( wndPtr->dwStyle & WS_SYSMENU &&
-                   GetSubMenu16(wndPtr->hSysMenu, 0) == hNewMenu )
+               if (style & WS_SYSMENU &&
+                   GetSubMenu(get_win_sys_menu(hNewWnd), 0) == hNewMenu )
                {
                    /* get the real system menu */
-                   hNewMenu =  wndPtr->hSysMenu;
+                   hNewMenu =  get_win_sys_menu(hNewWnd);
                }
-               else if( wndPtr->dwStyle & WS_CHILD || wndPtr->wIDmenu != hNewMenu )
+               else if (style & WS_CHILD || GetMenu(hNewWnd) != hNewMenu )
                {
                    /* FIXME: Not sure what to do here;
                     * perhaps try to track hNewMenu as a popup? */
 
                    TRACE(" -- got confused.\n");
-                    WIN_ReleaseWndPtr(wndPtr);
                    return FALSE;
                }
-                WIN_ReleaseWndPtr(wndPtr);
            }
            else return FALSE;
        }
 
        if( hNewMenu != pmt->hTopMenu )
        {
-           MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, 
+           MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM,
                     FALSE, 0 );
-           if( pmt->hCurrentMenu != pmt->hTopMenu ) 
+           if( pmt->hCurrentMenu != pmt->hTopMenu )
                MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE );
        }
 
        if( hNewWnd != pmt->hOwnerWnd )
        {
-           ReleaseCapture(); 
            pmt->hOwnerWnd = hNewWnd;
-           EVENT_Capture( pmt->hOwnerWnd, HTMENU );
+           MENU_SetCapture( pmt->hOwnerWnd );
        }
 
        pmt->hTopMenu = pmt->hCurrentMenu = hNewMenu; /* all subpopups are hidden */
-       MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, id, TRUE, 0 ); 
+       MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, id, TRUE, 0 );
 
        return TRUE;
     }
@@ -2611,10 +2524,45 @@ static BOOL MENU_SuspendPopup( MTRACKER* pmt, UINT16 uMsg )
     return FALSE;
 }
 
+/***********************************************************************
+ *           MENU_KeyEscape
+ *
+ * Handle a VK_ESCAPE key event in a menu.
+ */
+static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
+{
+    BOOL bEndMenu = TRUE;
+
+    if (pmt->hCurrentMenu != pmt->hTopMenu)
+    {
+        POPUPMENU *menu = MENU_GetMenu(pmt->hCurrentMenu);
+
+        if (menu->wFlags & MF_POPUP)
+        {
+            HMENU hmenutmp, hmenuprev;
+
+            hmenuprev = hmenutmp = pmt->hTopMenu;
+
+            /* close topmost popup */
+            while (hmenutmp != pmt->hCurrentMenu)
+            {
+                hmenuprev = hmenutmp;
+                hmenutmp = MENU_GetSubPopup( hmenuprev );
+            }
+
+            MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE );
+            pmt->hCurrentMenu = hmenuprev;
+            bEndMenu = FALSE;
+        }
+    }
+
+    return bEndMenu;
+}
+
 /***********************************************************************
  *           MENU_KeyLeft
  *
- * Handle a VK_LEFT key event in a menu. 
+ * Handle a VK_LEFT key event in a menu.
  */
 static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
 {
@@ -2626,9 +2574,9 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
     menu = MENU_GetMenu( hmenutmp );
 
     /* Try to move 1 column left (if possible) */
-    if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) != 
+    if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) !=
        NO_SELECTED_ITEM ) {
-       
+
        MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu,
                         prevcol, TRUE, 0 );
        return;
@@ -2642,7 +2590,7 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
     }
 
     MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE );
-    pmt->hCurrentMenu = hmenuprev; 
+    pmt->hCurrentMenu = hmenuprev;
 
     if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) )
     {
@@ -2693,7 +2641,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags )
     }
 
     /* Check to see if there's another column */
-    if( (nextcol = MENU_GetStartOfNextColumn( pmt->hCurrentMenu )) != 
+    if( (nextcol = MENU_GetStartOfNextColumn( pmt->hCurrentMenu )) !=
        NO_SELECTED_ITEM ) {
        TRACE("Going to %d.\n", nextcol );
        MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu,
@@ -2715,7 +2663,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags )
 
        if( hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP )
            if( !MENU_SuspendPopup(pmt, WM_KEYDOWN) )
-               pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, 
+               pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd,
                                                       pmt->hTopMenu, TRUE, wFlags);
     }
 }
@@ -2738,7 +2686,7 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
     mt.trackFlags = 0;
     mt.hCurrentMenu = hmenu;
     mt.hTopMenu = hmenu;
-    mt.hOwnerWnd = hwnd;
+    mt.hOwnerWnd = WIN_GetFullHandle( hwnd );
     mt.pt.x = x;
     mt.pt.y = y;
 
@@ -2749,37 +2697,53 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
     fEndMenu = FALSE;
     if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
 
-    if (wFlags & TPM_BUTTONDOWN) 
+    if (wFlags & TPM_BUTTONDOWN)
     {
        /* Get the result in order to start the tracking or not */
        fRemove = MENU_ButtonDown( &mt, hmenu, wFlags );
-       fEndMenu = !fRemove;   
+       fEndMenu = !fRemove;
     }
 
-    EVENT_Capture( mt.hOwnerWnd, HTMENU );
+    MENU_SetCapture( mt.hOwnerWnd );
 
     while (!fEndMenu)
     {
        menu = MENU_GetMenu( mt.hCurrentMenu );
        if (!menu) /* sometimes happens if I do a window manager close */
            break;
-       msg.hwnd = (wFlags & TPM_ENTERIDLEEX && menu->wFlags & MF_POPUP) ? menu->hWnd : 0;
 
        /* we have to keep the message in the queue until it's
         * clear that menu loop is not over yet. */
 
-       if (!MSG_InternalGetMessage( &msg, msg.hwnd, mt.hOwnerWnd, 0, 0,
-                                    MSGF_MENU, PM_NOREMOVE, !enterIdleSent, &enterIdleSent )) break;
+        for (;;)
+        {
+            if (PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ))
+            {
+                if (!CallMsgFilterA( &msg, MSGF_MENU )) break;
+                /* remove the message from the queue */
+                PeekMessageA( &msg, 0, msg.message, msg.message, PM_REMOVE );
+            }
+            else
+            {
+                if (!enterIdleSent)
+                {
+                    HWND win = (wFlags & TPM_ENTERIDLEEX && menu->wFlags & MF_POPUP) ? menu->hWnd : 0;
+                    enterIdleSent = TRUE;
+                    SendMessageW( mt.hOwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM)win );
+                }
+                WaitMessage();
+            }
+        }
 
        /* check if EndMenu() tried to cancel us, by posting this message */
-        if(msg.message == WM_CANCELMODE) 
+        if(msg.message == WM_CANCELMODE)
        {
            /* we are now out of the loop */
            fEndMenu = TRUE;
 
            /* remove the message from the queue */
            PeekMessageA( &msg, 0, msg.message, msg.message, PM_REMOVE );
-          
+
            /* break out of internal loop, ala ESCAPE */
            break;
        }
@@ -2793,15 +2757,13 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
         fRemove = FALSE;
        if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
        {
-            /* 
-             * use the mouse coordinates in lParam instead of those in the MSG
-             * struct to properly handle synthetic messages. lParam coords are 
-             * relative to client area, so they must be converted; since they can
-             * be negative, we must use SLOWORD/SHIWORD instead of LOWORD/HIWORD.
+            /*
+             * Use the mouse coordinates in lParam instead of those in the MSG
+             * struct to properly handle synthetic messages. They are already
+             * in screen coordinates.
              */
             mt.pt.x = SLOWORD(msg.lParam);
             mt.pt.y = SHIWORD(msg.lParam);
-            ClientToScreen(msg.hwnd,&mt.pt);
 
            /* Find a menu for this mouse event */
            hmenu = MENU_PtMenu( mt.hTopMenu, mt.pt );
@@ -2821,7 +2783,7 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                    fRemove = MENU_ButtonDown( &mt, hmenu, wFlags );
                    fEndMenu = !fRemove;
                    break;
-               
+
                case WM_RBUTTONUP:
                    if (!(wFlags & TPM_RIGHTBUTTON)) break;
                    /* fall through */
@@ -2840,16 +2802,16 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                        with the menu tracking. If not, stop it */
                     else
                         fEndMenu = ((wFlags & TPM_POPUPMENU) ? FALSE : TRUE);
-                    
+
                    break;
-               
+
                case WM_MOUSEMOVE:
                     /* In win95 winelook, the selected menu item must be changed every time the
                        mouse moves. In Win31 winelook, the mouse button has to be held down */
-                     
-                    if ( (TWEAK_WineLook > WIN31_LOOK) ||
+
+                    if ( hmenu && ((TWEAK_WineLook > WIN31_LOOK) ||
                          ( (msg.wParam & MK_LBUTTON) ||
-                           ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON))) )
+                           ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON)))) )
 
                        fEndMenu |= !MENU_MouseMove( &mt, hmenu, wFlags );
 
@@ -2865,11 +2827,11 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                {
                case VK_HOME:
                case VK_END:
-                   MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu, 
+                   MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu,
                                     NO_SELECTED_ITEM, FALSE, 0 );
                /* fall through */
                case VK_UP:
-                   MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu, 
+                   MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu,
                                       (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV );
                    break;
 
@@ -2885,13 +2847,13 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                case VK_LEFT:
                    MENU_KeyLeft( &mt, wFlags );
                    break;
-                   
+
                case VK_RIGHT:
                    MENU_KeyRight( &mt, wFlags );
                    break;
-                   
+
                case VK_ESCAPE:
-                   fEndMenu = TRUE;
+                    fEndMenu = MENU_KeyEscape(&mt, wFlags);
                    break;
 
                case VK_F1:
@@ -2899,10 +2861,10 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                        HELPINFO hi;
                        hi.cbSize = sizeof(HELPINFO);
                        hi.iContextType = HELPINFO_MENUITEM;
-                       if (menu->FocusedItem == NO_SELECTED_ITEM) 
+                       if (menu->FocusedItem == NO_SELECTED_ITEM)
                            hi.iCtrlId = 0;
-                       else    
-                           hi.iCtrlId = menu->items[menu->FocusedItem].wID; 
+                       else
+                           hi.iCtrlId = menu->items[menu->FocusedItem].wID;
                        hi.hItemHandle = hmenu;
                        hi.dwContextId = menu->dwContextHelpID;
                        hi.MousePos = msg.pt;
@@ -2921,7 +2883,7 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                case VK_MENU:
                    fEndMenu = TRUE;
                    break;
-                   
+
                }
                break;  /* WM_SYSKEYDOWN */
 
@@ -2941,7 +2903,7 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                      /* We will find a better way real soon... */
                    if ((msg.wParam <= 32) || (msg.wParam >= 127)) break;
 
-                   pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.hCurrentMenu, 
+                   pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.hCurrentMenu,
                                               LOWORD(msg.wParam), FALSE );
                    if (pos == (UINT)-2) fEndMenu = TRUE;
                    else if (pos == (UINT)-1) MessageBeep(0);
@@ -2952,7 +2914,7 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                         executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags);
                         fEndMenu = (executedMenuId != -1);
                    }
-               }                   
+               }
                break;
            }  /* switch(msg.message) - kbd */
        }
@@ -2970,7 +2932,7 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
        else mt.trackFlags &= ~TF_SKIPREMOVE;
     }
 
-    ReleaseCapture();
+    MENU_SetCapture(0);  /* release the capture */
 
     /* If dropdown is still painted and the close box is clicked on
        then the menu will be destroyed as part of the DispatchMessage above.
@@ -2984,10 +2946,10 @@ static INT MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
         {
            MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE );
 
-           if (menu && menu->wFlags & MF_POPUP) 
+           if (menu && menu->wFlags & MF_POPUP)
            {
-               ShowWindow( menu->hWnd, SW_HIDE );
-               uSubPWndLevel = 0;
+                DestroyWindow( menu->hWnd );
+                menu->hWnd = 0;
            }
            MENU_SelectItem( mt.hOwnerWnd, mt.hTopMenu, NO_SELECTED_ITEM, FALSE, 0 );
            SendMessageA( mt.hOwnerWnd, WM_MENUSELECT, MAKELONG(0,0xffff), 0 );
@@ -3014,7 +2976,7 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
     if (!(wFlags & TPM_NONOTIFY))
        SendMessageA( hWnd, WM_ENTERMENULOOP, bPopup, 0 );
 
-    SendMessageA( hWnd, WM_SETCURSOR, hWnd, HTCAPTION );
+    SendMessageA( hWnd, WM_SETCURSOR, (WPARAM)hWnd, HTCAPTION );
 
     if (!(wFlags & TPM_NONOTIFY))
     {
@@ -3023,12 +2985,9 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
        if ((menu = MENU_GetMenu( hMenu )) && (!menu->Height))
        { /* app changed/recreated menu bar entries in WM_INITMENU
             Recalculate menu sizes else clicks will not work */
-           RECT r;
-           HDC hdc = GetDCEx( hWnd, 0, DCX_CACHE | DCX_WINDOW );
-           SelectObject( hdc, hMenuFont);
-           GetClientRect(hWnd, &r); /* probably too simple */
-           MENU_MenuBarCalcSize( hdc, &r, menu, hWnd );
-           ReleaseDC(hWnd, hdc);
+          SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+                        SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+
        }
     }
     return TRUE;
@@ -3050,16 +3009,19 @@ static BOOL MENU_ExitTracking(HWND hWnd)
  *
  * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
  */
-void MENU_TrackMouseMenuBar( WND* wndPtr, INT ht, POINT pt )
+void MENU_TrackMouseMenuBar( HWND hWnd, INT ht, POINT pt )
 {
-    HWND  hWnd = wndPtr->hwndSelf;
-    HMENU hMenu = (ht == HTSYSMENU) ? wndPtr->hSysMenu : wndPtr->wIDmenu;
+    HMENU hMenu = (ht == HTSYSMENU) ? get_win_sys_menu( hWnd ) : GetMenu( hWnd );
     UINT wFlags = TPM_ENTERIDLEEX | TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
 
-    TRACE("pwnd=%p ht=0x%04x (%ld,%ld)\n", wndPtr, ht, pt.x, pt.y);
+    TRACE("wnd=%x ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
 
     if (IsMenu(hMenu))
     {
+        /* map point to parent client coordinates */
+        HWND parent = GetAncestor( hWnd, GA_PARENT );
+        if (parent != GetDesktopWindow()) ScreenToClient( parent, &pt );
+
        MENU_InitTracking( hWnd, hMenu, FALSE, wFlags );
        MENU_TrackMenu( hMenu, wFlags, pt.x, pt.y, hWnd, NULL );
        MENU_ExitTracking(hWnd);
@@ -3072,73 +3034,54 @@ void MENU_TrackMouseMenuBar( WND* wndPtr, INT ht, POINT pt )
  *
  * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
  */
-void MENU_TrackKbdMenuBar( WND* wndPtr, UINT wParam, INT vkey)
+void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, INT vkey)
 {
-   UINT uItem = NO_SELECTED_ITEM;
-   HMENU hTrackMenu; 
-   UINT wFlags = TPM_ENTERIDLEEX | TPM_LEFTALIGN | TPM_LEFTBUTTON;
+    UINT uItem = NO_SELECTED_ITEM;
+    HMENU hTrackMenu;
+    UINT wFlags = TPM_ENTERIDLEEX | TPM_LEFTALIGN | TPM_LEFTBUTTON;
 
     /* find window that has a menu */
-    while( wndPtr->dwStyle & WS_CHILD)
-       if( !(wndPtr = wndPtr->parent) ) return;
+
+    while (GetWindowLongA( hwnd, GWL_STYLE ) & WS_CHILD)
+        if (!(hwnd = GetParent( hwnd ))) return;
 
     /* check if we have to track a system menu */
-          
-    if( (wndPtr->dwStyle & (WS_CHILD | WS_MINIMIZE)) || 
-       !wndPtr->wIDmenu || vkey == VK_SPACE )
+
+    hTrackMenu = GetMenu( hwnd );
+    if (!hTrackMenu || IsIconic(hwnd) || vkey == VK_SPACE )
     {
-       if( !(wndPtr->dwStyle & WS_SYSMENU) ) return;
-       hTrackMenu = wndPtr->hSysMenu;
-       uItem = 0;
-       wParam |= HTSYSMENU;    /* prevent item lookup */
+        if (!(GetWindowLongA( hwnd, GWL_STYLE ) & WS_SYSMENU)) return;
+        hTrackMenu = get_win_sys_menu( hwnd );
+        uItem = 0;
+        wParam |= HTSYSMENU; /* prevent item lookup */
     }
-    else
-       hTrackMenu = wndPtr->wIDmenu;
 
-    if (IsMenu( hTrackMenu ))
-    {
-       MENU_InitTracking( wndPtr->hwndSelf, hTrackMenu, FALSE, wFlags );
+    if (!IsMenu( hTrackMenu )) return;
+
+    MENU_InitTracking( hwnd, hTrackMenu, FALSE, wFlags );
 
-        if( vkey && vkey != VK_SPACE )
+    if( vkey && vkey != VK_SPACE )
+    {
+        uItem = MENU_FindItemByKey( hwnd, hTrackMenu, vkey, (wParam & HTSYSMENU) );
+        if( uItem >= (UINT)(-2) )
         {
-            uItem = MENU_FindItemByKey( wndPtr->hwndSelf, hTrackMenu, 
-                                       vkey, (wParam & HTSYSMENU) );
-           if( uItem >= (UINT)(-2) )
-           {
-               if( uItem == (UINT)(-1) ) MessageBeep(0);
-               hTrackMenu = 0;
-           }
+            if( uItem == (UINT)(-1) ) MessageBeep(0);
+            hTrackMenu = 0;
         }
+    }
 
-       if( hTrackMenu )
-       {
-           MENU_SelectItem( wndPtr->hwndSelf, hTrackMenu, uItem, TRUE, 0 );
+    if( hTrackMenu )
+    {
+        MENU_SelectItem( hwnd, hTrackMenu, uItem, TRUE, 0 );
 
-           if( uItem == NO_SELECTED_ITEM )
-               MENU_MoveSelection( wndPtr->hwndSelf, hTrackMenu, ITEM_NEXT );
-           else if( vkey )
-               PostMessageA( wndPtr->hwndSelf, WM_KEYDOWN, VK_DOWN, 0L );
+        if( uItem == NO_SELECTED_ITEM )
+            MENU_MoveSelection( hwnd, hTrackMenu, ITEM_NEXT );
+        else if( vkey )
+            PostMessageA( hwnd, WM_KEYDOWN, VK_DOWN, 0L );
 
-           MENU_TrackMenu( hTrackMenu, wFlags, 0, 0, wndPtr->hwndSelf, NULL );
-       }
-
-       MENU_ExitTracking (wndPtr->hwndSelf);
+        MENU_TrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL );
     }
-}
-
-
-/**********************************************************************
- *           TrackPopupMenu16   (USER.416)
- */
-BOOL16 WINAPI TrackPopupMenu16( HMENU16 hMenu, UINT16 wFlags, INT16 x, INT16 y,
-                           INT16 nReserved, HWND16 hWnd, const RECT16 *lpRect )
-{
-    RECT r;
-    if (lpRect)
-        CONV_RECT16TO32( lpRect, &r );
-    return TrackPopupMenu( hMenu, wFlags, x, y, nReserved, hWnd,
-                             lpRect ? &r : NULL );
+    MENU_ExitTracking( hwnd );
 }
 
 
@@ -3216,24 +3159,9 @@ static LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam,
         return 1;
 
     case WM_DESTROY:
-
-       /* zero out global pointer in case resident popup window
-        * was somehow destroyed. */
-
-       if(MENU_GetTopPopupWnd() )
-       {
-           if( hwnd == pTopPopupWnd->hwndSelf )
-           {
-               ERR("resident popup destroyed!\n");
-
-                MENU_DestroyTopPopupWnd();
-               uSubPWndLevel = 0;
-           }
-           else
-               uSubPWndLevel--;
-            MENU_ReleaseTopPopupWnd();
-       }
-       break;
+        /* zero out global pointer in case resident popup window was destroyed. */
+        if (hwnd == top_popup) top_popup = 0;
+        break;
 
     case WM_SHOWWINDOW:
 
@@ -3269,35 +3197,24 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth,
 {
     HDC hdc;
     RECT rectBar;
-    WND *wndPtr;
     LPPOPUPMENU lppop;
-    UINT retvalue;
 
     TRACE("HWND 0x%x, width %d, at (%d, %d).\n",
-                hwnd, menubarWidth, orgX, orgY );
-    
-    if (!(wndPtr = WIN_FindWndPtr( hwnd )))
-       return 0;
+          hwnd, menubarWidth, orgX, orgY );
 
-    if (!(lppop = MENU_GetMenu((HMENU16)wndPtr->wIDmenu)))
-    {
-       WIN_ReleaseWndPtr(wndPtr);
-       return 0;
-    }
+    if (!(lppop = MENU_GetMenu( GetMenu(hwnd) ))) return 0;
 
     hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
-    SelectObject( hdc, hMenuFont);       
+    SelectObject( hdc, hMenuFont);
     SetRect(&rectBar, orgX, orgY, orgX+menubarWidth, orgY+GetSystemMetrics(SM_CYMENU));
-    MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );    
+    MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
     ReleaseDC( hwnd, hdc );
-    retvalue = lppop->Height;
-    WIN_ReleaseWndPtr(wndPtr);
-    return retvalue;
+    return lppop->Height;
 }
 
 
 /*******************************************************************
- *         ChangeMenu16    (USER.153)
+ *         ChangeMenu    (USER.153)
  */
 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
                             UINT16 id, UINT16 flags )
@@ -3365,7 +3282,7 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UINT pos, LPCWSTR data,
 
 
 /*******************************************************************
- *         CheckMenuItem16    (USER.154)
+ *         CheckMenuItem    (USER.154)
  */
 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
 {
@@ -3391,7 +3308,7 @@ DWORD WINAPI CheckMenuItem( HMENU hMenu, UINT id, UINT flags )
 
 
 /**********************************************************************
- *         EnableMenuItem16    (USER.155)
+ *         EnableMenuItem    (USER.155)
  */
 UINT16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
 {
@@ -3408,11 +3325,11 @@ UINT WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
     MENUITEM *item;
     POPUPMENU *menu;
 
-    TRACE("(%04x, %04X, %04X) !\n", 
+    TRACE("(%04x, %04X, %04X) !\n",
                 hMenu, wItemID, wFlags);
 
     /* Get the Popupmenu to access the owner menu */
-    if (!(menu = MENU_GetMenu(hMenu))) 
+    if (!(menu = MENU_GetMenu(hMenu)))
        return (UINT)-1;
 
     if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags )))
@@ -3422,7 +3339,7 @@ UINT WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
     item->fState ^= (oldflags ^ wFlags) & (MF_GRAYED | MF_DISABLED);
 
     /* In win95 if the close item in the system menu change update the close button */
-    if (TWEAK_WineLook == WIN95_LOOK)    
+    if (TWEAK_WineLook == WIN95_LOOK)
        if((item->wID == SC_CLOSE) && (oldflags != wFlags))
        {
            if (menu->hSysMenuOwner != 0)
@@ -3430,7 +3347,7 @@ UINT WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
                POPUPMENU* parentMenu;
 
                /* Get the parent menu to access*/
-               if (!(parentMenu = MENU_GetMenu(menu->hSysMenuOwner))) 
+               if (!(parentMenu = MENU_GetMenu(menu->hSysMenuOwner)))
                    return (UINT)-1;
 
                /* Refresh the frame to reflect the change*/
@@ -3438,13 +3355,13 @@ UINT WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
                             SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
            }
        }
-          
+
     return oldflags;
 }
 
 
 /*******************************************************************
- *         GetMenuString16    (USER.161)
+ *         GetMenuString    (USER.161)
  */
 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
                               LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
@@ -3456,12 +3373,12 @@ INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
 /*******************************************************************
  *         GetMenuStringA    (USER32.@)
  */
-INT WINAPI GetMenuStringA( 
+INT WINAPI GetMenuStringA(
        HMENU hMenu,    /* [in] menuhandle */
        UINT wItemID,   /* [in] menu item (dep. on wFlags) */
        LPSTR str,      /* [out] outbuffer. If NULL, func returns entry length*/
        INT nMaxSiz,    /* [in] length of buffer. if 0, func returns entry len*/
-       UINT wFlags     /* [in] MF_ flags */ 
+       UINT wFlags     /* [in] MF_ flags */
 ) {
     MENUITEM *item;
 
@@ -3497,16 +3414,6 @@ INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID,
 }
 
 
-/**********************************************************************
- *         HiliteMenuItem16    (USER.162)
- */
-BOOL16 WINAPI HiliteMenuItem16( HWND16 hWnd, HMENU16 hMenu, UINT16 wItemID,
-                                UINT16 wHilite )
-{
-    return HiliteMenuItem( hWnd, hMenu, wItemID, wHilite );
-}
-
-
 /**********************************************************************
  *         HiliteMenuItem    (USER32.@)
  */
@@ -3514,7 +3421,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
                                 UINT wHilite )
 {
     LPPOPUPMENU menu;
-    TRACE("(%04x, %04x, %04x, %04x);\n", 
+    TRACE("(%04x, %04x, %04x, %04x);\n",
                  hWnd, hMenu, wItemID, wHilite);
     if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE;
     if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
@@ -3526,7 +3433,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
 
 
 /**********************************************************************
- *         GetMenuState16    (USER.250)
+ *         GetMenuState    (USER.250)
  */
 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
 {
@@ -3540,7 +3447,7 @@ UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
 UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags )
 {
     MENUITEM *item;
-    TRACE("(menu=%04x, id=%04x, flags=%04x);\n", 
+    TRACE("(menu=%04x, id=%04x, flags=%04x);\n",
                 hMenu, wItemID, wFlags);
     if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
     debug_print_menuitem ("  item: ", item, "");
@@ -3561,13 +3468,13 @@ UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags )
 
 
 /**********************************************************************
- *         GetMenuItemCount16    (USER.263)
+ *         GetMenuItemCount    (USER.263)
  */
 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
 {
     LPPOPUPMENU        menu = MENU_GetMenu(hMenu);
     if (!menu) return -1;
-    TRACE("(%04x) returning %d\n", 
+    TRACE("(%04x) returning %d\n",
                   hMenu, menu->nItems );
     return menu->nItems;
 }
@@ -3580,13 +3487,13 @@ INT WINAPI GetMenuItemCount( HMENU hMenu )
 {
     LPPOPUPMENU        menu = MENU_GetMenu(hMenu);
     if (!menu) return -1;
-    TRACE("(%04x) returning %d\n", 
+    TRACE("(%04x) returning %d\n",
                   hMenu, menu->nItems );
     return menu->nItems;
 }
 
 /**********************************************************************
- *         GetMenuItemID16    (USER.264)
+ *         GetMenuItemID    (USER.264)
  */
 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
 {
@@ -3600,14 +3507,14 @@ UINT WINAPI GetMenuItemID( HMENU hMenu, INT nPos )
 {
     MENUITEM * lpmi;
 
-    if (!(lpmi = MENU_FindItem(&hMenu,&nPos,MF_BYPOSITION))) return 0;
+    if (!(lpmi = MENU_FindItem(&hMenu,&nPos,MF_BYPOSITION))) return -1;
     if (lpmi->fType & MF_POPUP) return -1;
     return lpmi->wID;
 
 }
 
 /*******************************************************************
- *         InsertMenu16    (USER.410)
+ *         InsertMenu    (USER.410)
  */
 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
                             UINT16 id, SEGPTR data )
@@ -3630,7 +3537,7 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UINT pos, UINT flags,
 
     if (IS_STRING_ITEM(flags) && str)
         TRACE("hMenu %04x, pos %d, flags %08x, "
-                     "id %04x, str '%s'\n",
+                     "id %04x, str %s\n",
                       hMenu, pos, flags, id, debugstr_w(str) );
     else TRACE("hMenu %04x, pos %d, flags %08x, "
                       "id %04x, str %08lx (not a string)\n",
@@ -3658,13 +3565,18 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UINT pos, UINT flags,
 BOOL WINAPI InsertMenuA( HMENU hMenu, UINT pos, UINT flags,
                              UINT id, LPCSTR str )
 {
-    BOOL ret;
+    BOOL ret = FALSE;
 
     if (IS_STRING_ITEM(flags) && str)
     {
-        LPWSTR newstr = HEAP_strdupAtoW( GetProcessHeap(), 0, str );
-        ret = InsertMenuW( hMenu, pos, flags, id, newstr );
-        HeapFree( GetProcessHeap(), 0, newstr );
+        INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+        LPWSTR newstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if (newstr)
+        {
+            MultiByteToWideChar( CP_ACP, 0, str, -1, newstr, len );
+            ret = InsertMenuW( hMenu, pos, flags, id, newstr );
+            HeapFree( GetProcessHeap(), 0, newstr );
+        }
         return ret;
     }
     else return InsertMenuW( hMenu, pos, flags, id, (LPCWSTR)str );
@@ -3672,7 +3584,7 @@ BOOL WINAPI InsertMenuA( HMENU hMenu, UINT pos, UINT flags,
 
 
 /*******************************************************************
- *         AppendMenu16    (USER.411)
+ *         AppendMenu    (USER.411)
  */
 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
 {
@@ -3701,7 +3613,7 @@ BOOL WINAPI AppendMenuW( HMENU hMenu, UINT flags,
 
 
 /**********************************************************************
- *         RemoveMenu16    (USER.412)
+ *         RemoveMenu   (USER.412)
  */
 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
 {
@@ -3720,7 +3632,7 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
     TRACE("(menu=%04x pos=%04x flags=%04x)\n",hMenu, nPos, wFlags);
     if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
     if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
-    
+
       /* Remove item */
 
     MENU_FreeItemData( item );
@@ -3746,7 +3658,7 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
 
 
 /**********************************************************************
- *         DeleteMenu16    (USER.413)
+ *         DeleteMenu    (USER.413)
  */
 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
 {
@@ -3769,7 +3681,7 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags )
 
 
 /*******************************************************************
- *         ModifyMenu16    (USER.414)
+ *         ModifyMenu    (USER.414)
  */
 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
                             UINT16 id, SEGPTR data )
@@ -3790,8 +3702,8 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
 
     if (IS_STRING_ITEM(flags))
     {
-       TRACE("%04x %d %04x %04x '%s'\n",
-                      hMenu, pos, flags, id, str ? debugstr_w(str) : "#NULL#" );
+       TRACE("%04x %d %04x %04x %s\n",
+                      hMenu, pos, flags, id, debugstr_w(str) );
         if (!str) return FALSE;
     }
     else
@@ -3811,13 +3723,18 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
 BOOL WINAPI ModifyMenuA( HMENU hMenu, UINT pos, UINT flags,
                              UINT id, LPCSTR str )
 {
-    BOOL ret;
+    BOOL ret = FALSE;
 
     if (IS_STRING_ITEM(flags) && str)
     {
-        LPWSTR newstr = HEAP_strdupAtoW( GetProcessHeap(), 0, str );
-        ret = ModifyMenuW( hMenu, pos, flags, id, newstr );
-        HeapFree( GetProcessHeap(), 0, newstr );
+        INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+        LPWSTR newstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if (newstr)
+        {
+            MultiByteToWideChar( CP_ACP, 0, str, -1, newstr, len );
+            ret = ModifyMenuW( hMenu, pos, flags, id, newstr );
+            HeapFree( GetProcessHeap(), 0, newstr );
+        }
         return ret;
     }
     else return ModifyMenuW( hMenu, pos, flags, id, (LPCWSTR)str );
@@ -3825,7 +3742,7 @@ BOOL WINAPI ModifyMenuA( HMENU hMenu, UINT pos, UINT flags,
 
 
 /**********************************************************************
- *         CreatePopupMenu16    (USER.415)
+ *         CreatePopupMenu    (USER.415)
  */
 HMENU16 WINAPI CreatePopupMenu16(void)
 {
@@ -3842,7 +3759,7 @@ HMENU WINAPI CreatePopupMenu(void)
     POPUPMENU *menu;
 
     if (!(hmenu = CreateMenu())) return 0;
-    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
+    menu = MENU_GetMenu( hmenu );
     menu->wFlags |= MF_POPUP;
     menu->bTimeToHide = FALSE;
     return hmenu;
@@ -3850,7 +3767,8 @@ HMENU WINAPI CreatePopupMenu(void)
 
 
 /**********************************************************************
- *         GetMenuCheckMarkDimensions    (USER.417) (USER32.@)
+ *         GetMenuCheckMarkDimensions    (USER.417)
+ *         GetMenuCheckMarkDimensions    (USER32.@)
  */
 DWORD WINAPI GetMenuCheckMarkDimensions(void)
 {
@@ -3859,7 +3777,7 @@ DWORD WINAPI GetMenuCheckMarkDimensions(void)
 
 
 /**********************************************************************
- *         SetMenuItemBitmaps16    (USER.418)
+ *         SetMenuItemBitmaps    (USER.418)
  */
 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
                                     HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
@@ -3894,7 +3812,7 @@ BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags,
 
 
 /**********************************************************************
- *         CreateMenu16    (USER.151)
+ *         CreateMenu    (USER.151)
  */
 HMENU16 WINAPI CreateMenu16(void)
 {
@@ -3924,7 +3842,7 @@ HMENU WINAPI CreateMenu(void)
 
 
 /**********************************************************************
- *         DestroyMenu16    (USER.152)
+ *         DestroyMenu    (USER.152)
  */
 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
 {
@@ -3943,54 +3861,35 @@ BOOL WINAPI DestroyMenu( HMENU hMenu )
 
     if (hMenu && hMenu != MENU_DefSysPopup)
     {
-        LPPOPUPMENU lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
-        WND *pTPWnd = MENU_GetTopPopupWnd();
+        LPPOPUPMENU lppop = MENU_GetMenu(hMenu);
 
-       if( pTPWnd && (hMenu == *(HMENU*)pTPWnd->wExtra) )
-         *(UINT*)pTPWnd->wExtra = 0;
+        if (!lppop) return FALSE;
 
-        if (!IS_A_MENU(lppop)) lppop = NULL;
-       if ( lppop )
-       {
-           lppop->wMagic = 0;  /* Mark it as destroyed */
+        lppop->wMagic = 0;  /* Mark it as destroyed */
 
-           if ((lppop->wFlags & MF_POPUP) && lppop->hWnd &&
-               (!pTPWnd || (lppop->hWnd != pTPWnd->hwndSelf)))
-               DestroyWindow( lppop->hWnd );
+        if ((lppop->wFlags & MF_POPUP) && lppop->hWnd)
+        {
+            DestroyWindow( lppop->hWnd );
+            lppop->hWnd = 0;
+        }
 
-           if (lppop->items)   /* recursively destroy submenus */
-           {
-               int i;
-               MENUITEM *item = lppop->items;
-               for (i = lppop->nItems; i > 0; i--, item++)
-               {
-                   if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu);
-                   MENU_FreeItemData( item );
-               }
-               HeapFree( GetProcessHeap(), 0, lppop->items );
-           }
-           USER_HEAP_FREE( hMenu );
-            MENU_ReleaseTopPopupWnd();
-       }
-        else
+        if (lppop->items) /* recursively destroy submenus */
         {
-            MENU_ReleaseTopPopupWnd();
-            return FALSE;
+            int i;
+            MENUITEM *item = lppop->items;
+            for (i = lppop->nItems; i > 0; i--, item++)
+            {
+                if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu);
+                MENU_FreeItemData( item );
+            }
+            HeapFree( GetProcessHeap(), 0, lppop->items );
         }
+        USER_HEAP_FREE( hMenu );
     }
     return (hMenu != MENU_DefSysPopup);
 }
 
 
-/**********************************************************************
- *         GetSystemMenu16    (USER.156)
- */
-HMENU16 WINAPI GetSystemMenu16( HWND16 hWnd, BOOL16 bRevert )
-{
-    return GetSystemMenu( hWnd, bRevert );
-}
-
-
 /**********************************************************************
  *         GetSystemMenu    (USER32.@)
  */
@@ -4005,20 +3904,20 @@ HMENU WINAPI GetSystemMenu( HWND hWnd, BOOL bRevert )
        {
            if( bRevert )
            {
-               DestroyMenu(wndPtr->hSysMenu); 
+               DestroyMenu(wndPtr->hSysMenu);
                wndPtr->hSysMenu = 0;
            }
            else
            {
                POPUPMENU *menu = MENU_GetMenu( wndPtr->hSysMenu );
-               if( menu ) 
+               if( menu )
                 {
                   if( menu->nItems > 0 && menu->items[0].hSubMenu == MENU_DefSysPopup )
                      menu->items[0].hSubMenu = MENU_CopySysPopup();
                }
-               else 
+               else
                {
-                  WARN("Current sys-menu (%04x) of wnd %04x is broken\n", 
+                  WARN("Current sys-menu (%04x) of wnd %04x is broken\n",
                        wndPtr->hSysMenu, hWnd);
                   wndPtr->hSysMenu = 0;
                }
@@ -4031,7 +3930,7 @@ HMENU WINAPI GetSystemMenu( HWND hWnd, BOOL bRevert )
        if( wndPtr->hSysMenu )
         {
            POPUPMENU *menu;
-           retvalue = GetSubMenu16(wndPtr->hSysMenu, 0);
+           retvalue = GetSubMenu(wndPtr->hSysMenu, 0);
 
            /* Store the dummy sysmenu handle to facilitate the refresh */
            /* of the close button if the SC_CLOSE item change */
@@ -4045,15 +3944,6 @@ HMENU WINAPI GetSystemMenu( HWND hWnd, BOOL bRevert )
 }
 
 
-/*******************************************************************
- *         SetSystemMenu16    (USER.280)
- */
-BOOL16 WINAPI SetSystemMenu16( HWND16 hwnd, HMENU16 hMenu )
-{
-    return SetSystemMenu( hwnd, hMenu );
-}
-
-
 /*******************************************************************
  *         SetSystemMenu    (USER32.@)
  */
@@ -4072,87 +3962,55 @@ BOOL WINAPI SetSystemMenu( HWND hwnd, HMENU hMenu )
 }
 
 
-/**********************************************************************
- *         GetMenu16    (USER.157)
- */
-HMENU16 WINAPI GetMenu16( HWND16 hWnd ) 
-{
-    return (HMENU16)GetMenu(hWnd);
-}
-
-
 /**********************************************************************
  *         GetMenu    (USER32.@)
  */
-HMENU WINAPI GetMenu( HWND hWnd ) 
+HMENU WINAPI GetMenu( HWND hWnd )
 {
-    HMENU retvalue;
-    WND * wndPtr = WIN_FindWndPtr(hWnd);
-
-    if (!wndPtr) return 0;
-
-    retvalue = (HMENU)wndPtr->wIDmenu;
-    TRACE("for %swindow %04x returning %04x\n",
-          (wndPtr->dwStyle & WS_CHILD) ? "child " : "", hWnd, retvalue);
-    WIN_ReleaseWndPtr(wndPtr);
+    HMENU retvalue = (HMENU)GetWindowLongA( hWnd, GWL_ID );
+    TRACE("for %04x returning %04x\n", hWnd, retvalue);
     return retvalue;
 }
 
 
-/**********************************************************************
- *         SetMenu16    (USER.158)
- */
-BOOL16 WINAPI SetMenu16( HWND16 hWnd, HMENU16 hMenu )
-{
-    return SetMenu( hWnd, hMenu );
-}
-
-
 /**********************************************************************
  *         SetMenu    (USER32.@)
  */
 BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
 {
-    WND * wndPtr = WIN_FindWndPtr(hWnd);
-    BOOL res = FALSE;
-
     TRACE("(%04x, %04x);\n", hWnd, hMenu);
 
     if (hMenu && !IsMenu(hMenu))
     {
-       WARN("hMenu is not a menu handle\n");
-       goto exit;
+        WARN("hMenu %x is not a menu handle\n", hMenu);
+        return FALSE;
     }
+    if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_CHILD) return FALSE;
 
-    if (wndPtr && !(wndPtr->dwStyle & WS_CHILD))
-    {
-       if (GetCapture() == hWnd) ReleaseCapture();
+    hWnd = WIN_GetFullHandle( hWnd );
+    if (GetCapture() == hWnd) MENU_SetCapture(0);  /* release the capture */
 
-       wndPtr->wIDmenu = (UINT)hMenu;
-       if (hMenu != 0)
-       {
-           LPPOPUPMENU lpmenu;
+    if (hMenu != 0)
+    {
+        LPPOPUPMENU lpmenu;
 
-            if (!(lpmenu = MENU_GetMenu(hMenu)))
-               goto exit;
+        if (!(lpmenu = MENU_GetMenu(hMenu))) return FALSE;
 
-            lpmenu->hWnd = hWnd;
-            lpmenu->Height = 0;  /* Make sure we recalculate the size */
-       }
-       if (IsWindowVisible(hWnd))
-            SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
-                        SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
-       res = TRUE;
+        lpmenu->hWnd = hWnd;
+        lpmenu->Height = 0;  /* Make sure we recalculate the size */
     }
-exit:
-    WIN_ReleaseWndPtr(wndPtr);
-    return res;
+    SetWindowLongA( hWnd, GWL_ID, hMenu );
+
+    if (IsWindowVisible(hWnd))
+        SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+                      SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+    return TRUE;
 }
 
 
 
 /**********************************************************************
- *         GetSubMenu16    (USER.159)
+ *         GetSubMenu    (USER.159)
  */
 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
 {
@@ -4173,58 +4031,47 @@ HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos )
 }
 
 
-/**********************************************************************
- *         DrawMenuBar16    (USER.160)
- */
-void WINAPI DrawMenuBar16( HWND16 hWnd )
-{
-    DrawMenuBar( hWnd );
-}
-
-
 /**********************************************************************
  *         DrawMenuBar    (USER32.@)
  */
 BOOL WINAPI DrawMenuBar( HWND hWnd )
 {
     LPPOPUPMENU lppop;
-    WND *wndPtr = WIN_FindWndPtr(hWnd);
-    if (wndPtr && !(wndPtr->dwStyle & WS_CHILD) && wndPtr->wIDmenu)
-    {
-        lppop = MENU_GetMenu((HMENU16)wndPtr->wIDmenu);
-        if (lppop == NULL)
-        {
-            WIN_ReleaseWndPtr(wndPtr);
-            return FALSE;
-        }
+    HMENU hMenu = GetMenu(hWnd);
 
-        lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
-       lppop->hwndOwner = hWnd;
-        SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
-                        SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
-        WIN_ReleaseWndPtr(wndPtr);
-        return TRUE;
-    }
-    WIN_ReleaseWndPtr(wndPtr);
-    return FALSE;
+    if (GetWindowLongA( hWnd, GWL_STYLE ) & WS_CHILD) return FALSE;
+    if (!hMenu || !(lppop = MENU_GetMenu( hMenu ))) return FALSE;
+
+    lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
+    lppop->hwndOwner = hWnd;
+    SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+                  SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+    return TRUE;
 }
 
 /***********************************************************************
  *           DrawMenuBarTemp   (USER32.@)
+ *
+ * UNDOCUMENTED !!
+ *
+ * called by W98SE desk.cpl Control Panel Applet
+ *
+ * Not 100% sure about the param names, but close.
  */
-DWORD WINAPI DrawMenuBarTemp(DWORD p1, DWORD p2)
+DWORD WINAPI DrawMenuBarTemp(HWND someHWND, HDC someHDC, LPRECT someRECT, HMENU someHMENU, HFONT someFONT)
 {
-    FIXME("(%08lx %08lx): stub\n", p1, p2);
+    FIXME("(0x%08x, 0x%08x, %p, 0x%08x, 0x%08x): stub\n", someHWND, someHDC, someRECT, someHMENU, someFONT);
     return 0;
 }
 
 /***********************************************************************
- *           EndMenu   (USER.187) (USER32.@)
+ *           EndMenu   (USER.187)
+ *           EndMenu   (USER32.@)
  */
 void WINAPI EndMenu(void)
 {
     /* if we are in the menu code, and it is active */
-    if (fEndMenu == FALSE && MENU_IsMenuActive()) 
+    if (!fEndMenu && top_popup)
     {
        /* terminate the menu handling code */
         fEndMenu = TRUE;
@@ -4233,7 +4080,7 @@ void WINAPI EndMenu(void)
        /* which will now terminate the menu, in the event that */
        /* the main window was minimized, or lost focus, so we */
        /* don't end up with an orphaned menu */
-       PostMessageA( pTopPopupWnd->hwndSelf, WM_CANCELMODE, 0, 0);
+        PostMessageA( top_popup, WM_CANCELMODE, 0, 0);
     }
 }
 
@@ -4251,7 +4098,7 @@ HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
 
 
 /**********************************************************************
- *         LoadMenu16    (USER.150)
+ *         LoadMenu    (USER.150)
  */
 HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
 {
@@ -4259,7 +4106,7 @@ HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
     HGLOBAL16 handle;
     HMENU16 hMenu;
 
-    TRACE("(%04x,%s)\n", instance, debugres_a(name) );
+    TRACE("(%04x,%s)\n", instance, debugstr_a(name) );
 
     if (HIWORD(name))
     {
@@ -4303,7 +4150,7 @@ HMENU WINAPI LoadMenuW( HINSTANCE instance, LPCWSTR name )
 
 
 /**********************************************************************
- *         LoadMenuIndirect16    (USER.220)
+ *         LoadMenuIndirect    (USER.220)
  */
 HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
 {
@@ -4340,11 +4187,11 @@ HMENU WINAPI LoadMenuIndirectA( LPCVOID template )
     WORD version, offset;
     LPCSTR p = (LPCSTR)template;
 
-    TRACE("%p\n", template );
     version = GET_WORD(p);
     p += sizeof(WORD);
+    TRACE("%p, ver %d\n", template, version );
     switch (version)
-      {
+    {
       case 0:
        offset = GET_WORD(p);
        p += sizeof(WORD) + offset;
@@ -4368,7 +4215,7 @@ HMENU WINAPI LoadMenuIndirectA( LPCVOID template )
       default:
         ERR("version %d not supported.\n", version);
         return 0;
-      }
+    }
 }
 
 
@@ -4383,12 +4230,11 @@ HMENU WINAPI LoadMenuIndirectW( LPCVOID template )
 
 
 /**********************************************************************
- *             IsMenu16    (USER.358)
+ *             IsMenu    (USER.358)
  */
 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
 {
-    LPPOPUPMENU menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hmenu);
-    return IS_A_MENU(menu);
+    return IsMenu( hmenu );
 }
 
 
@@ -4397,8 +4243,8 @@ BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
  */
 BOOL WINAPI IsMenu(HMENU hmenu)
 {
-    LPPOPUPMENU menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hmenu);
-    return IS_A_MENU(menu);
+    LPPOPUPMENU menu = MENU_GetMenu(hmenu);
+    return menu != NULL;
 }
 
 /**********************************************************************
@@ -4488,7 +4334,7 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
 BOOL WINAPI GetMenuItemInfoA( HMENU hmenu, UINT item, BOOL bypos,
                                   LPMENUITEMINFOA lpmii)
 {
-    return GetMenuItemInfo_common (hmenu, item, bypos, 
+    return GetMenuItemInfo_common (hmenu, item, bypos,
                                     (LPMENUITEMINFOW)lpmii, FALSE);
 }
 
@@ -4502,6 +4348,30 @@ BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos,
                                      lpmii, TRUE);
 }
 
+
+/* set a menu item text from a ASCII or Unicode string */
+inline static void set_menu_item_text( MENUITEM *menu, LPCWSTR text, BOOL unicode )
+{
+    if (!text)
+    {
+        menu->text = NULL;
+        menu->fType |= MF_SEPARATOR;
+    }
+    else if (unicode)
+    {
+        if ((menu->text = HeapAlloc( GetProcessHeap(), 0, (strlenW(text)+1) * sizeof(WCHAR) )))
+            strcpyW( menu->text, text );
+    }
+    else
+    {
+        LPCSTR str = (LPCSTR)text;
+        int len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+        if ((menu->text = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+            MultiByteToWideChar( CP_ACP, 0, str, -1, menu->text, len );
+    }
+}
+
+
 /**********************************************************************
  *             SetMenuItemInfo_common
  */
@@ -4515,28 +4385,20 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
     debug_print_menuitem("MENU_SetItemInfo_common from: ", menu, "");
 
     if (lpmii->fMask & MIIM_TYPE ) {
-       /* Get rid of old string.  */
-       if ( IS_STRING_ITEM(menu->fType) && menu->text) {
+       /* Get rid of old string. */
+       if (IS_STRING_ITEM(menu->fType) && menu->text) {
            HeapFree(GetProcessHeap(), 0, menu->text);
            menu->text = NULL;
        }
 
-       /* make only MENU_ITEM_TYPE bits in menu->fType equal lpmii->fType */ 
+       /* make only MENU_ITEM_TYPE bits in menu->fType equal lpmii->fType */
        menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
        menu->fType |= MENU_ITEM_TYPE(lpmii->fType);
 
        menu->text = lpmii->dwTypeData;
 
-       if (IS_STRING_ITEM(menu->fType)) {
-            if (menu->text) {
-                if (unicode)
-                   menu->text = HEAP_strdupW(GetProcessHeap(), 0,  lpmii->dwTypeData);
-                else
-                   menu->text = HEAP_strdupAtoW(GetProcessHeap(), 0, (LPSTR)lpmii->dwTypeData);
-                }
-            else
-                menu->fType |= MF_SEPARATOR;
-       }
+       if (IS_STRING_ITEM(menu->fType))
+           set_menu_item_text( menu, lpmii->dwTypeData, unicode );
     }
 
     if (lpmii->fMask & MIIM_FTYPE ) {
@@ -4553,22 +4415,15 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
 
     if (lpmii->fMask & MIIM_STRING ) {
        /* free the string when used */
-       if ( IS_STRING_ITEM(menu->fType) && menu->text) {
+       if (IS_STRING_ITEM(menu->fType) && menu->text) {
            HeapFree(GetProcessHeap(), 0, menu->text);
-            if (lpmii->dwTypeData) {
-               if (unicode)
-                   menu->text = HEAP_strdupW(GetProcessHeap(), 0,  lpmii->dwTypeData);
-               else
-                   menu->text = HEAP_strdupAtoW(GetProcessHeap(), 0, (LPSTR) lpmii->dwTypeData);
-            }
-            else
-                menu->fType |= MF_SEPARATOR;
+            set_menu_item_text( menu, lpmii->dwTypeData, unicode );
        }
     }
 
     if (lpmii->fMask & MIIM_STATE)
     {
-       /* fixme: MFS_DEFAULT do we have to reset the other menu items? */
+       /* FIXME: MFS_DEFAULT do we have to reset the other menu items? */
        menu->fState = lpmii->fState;
     }
 
@@ -4578,7 +4433,7 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
     if (lpmii->fMask & MIIM_SUBMENU) {
        menu->hSubMenu = lpmii->hSubMenu;
        if (menu->hSubMenu) {
-           POPUPMENU *subMenu = MENU_GetMenu((UINT16)menu->hSubMenu);
+           POPUPMENU *subMenu = MENU_GetMenu(menu->hSubMenu);
            if (subMenu) {
                subMenu->wFlags |= MF_POPUP;
                menu->fType |= MF_POPUP;
@@ -4610,8 +4465,17 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
  *             SetMenuItemInfoA    (USER32.@)
  */
 BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
-                                 const MENUITEMINFOA *lpmii) 
-{
+                                 const MENUITEMINFOA *lpmii)
+{
+    if ((lpmii->fType & (MF_HILITE|MF_POPUP)) || (lpmii->fState)) {
+       /* QuickTime does pass invalid data into SetMenuItemInfo.
+        * do some of the checks Windows does.
+        */
+        WARN("Bad masks for type (0x%08x) or state (0x%08x)\n",
+             lpmii->fType,lpmii->fState );
+       return FALSE;
+    }
+
     return SetMenuItemInfo_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0),
                                    (const MENUITEMINFOW *)lpmii, FALSE);
 }
@@ -4635,7 +4499,7 @@ BOOL WINAPI SetMenuDefaultItem(HMENU hmenu, UINT uItem, UINT bypos)
        UINT i;
        POPUPMENU *menu;
        MENUITEM *item;
-       
+
        TRACE("(0x%x,%d,%d)\n", hmenu, uItem, bypos);
 
        if (!(menu = MENU_GetMenu(hmenu))) return FALSE;
@@ -4646,7 +4510,7 @@ BOOL WINAPI SetMenuDefaultItem(HMENU hmenu, UINT uItem, UINT bypos)
        {
            item->fState &= ~MFS_DEFAULT;
        }
-       
+
        /* no default item */
        if ( -1 == uItem)
        {
@@ -4670,7 +4534,7 @@ BOOL WINAPI SetMenuDefaultItem(HMENU hmenu, UINT uItem, UINT bypos)
                     return TRUE;
                }
            }
-               
+
        }
        return FALSE;
 }
@@ -4690,16 +4554,16 @@ UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags)
 
        /* find default item */
        item = menu->items;
-       
+
        /* empty menu */
        if (! item) return -1;
-       
+
        while ( !( item->fState & MFS_DEFAULT ) )
        {
            i++; item++;
            if  (i >= menu->nItems ) return -1;
        }
-       
+
        /* default: don't return disabled items */
        if ( (!(GMDI_USEDISABLED & flags)) && (item->fState & MFS_DISABLED )) return -1;
 
@@ -4717,7 +4581,7 @@ UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags)
 }
 
 /*******************************************************************
- *              InsertMenuItem16   (USER.441)
+ *              InsertMenuItem   (USER.441)
  *
  * FIXME: untested
  */
@@ -4804,9 +4668,8 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
 }
 
 /**********************************************************************
- *             CheckMenuRadioItem16    (not a Windows API)
+ *             CheckMenuRadioItem (USER.666)
  */
-
 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu,
                                   UINT16 first, UINT16 last, UINT16 check,
                                   BOOL16 bypos)
@@ -4817,10 +4680,10 @@ BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu,
 /**********************************************************************
  *             GetMenuItemRect    (USER32.@)
  *
- *      ATTENTION: Here, the returned values in rect are the screen 
- *                 coordinates of the item just like if the menu was 
+ *      ATTENTION: Here, the returned values in rect are the screen
+ *                 coordinates of the item just like if the menu was
  *                 always on the upper left side of the application.
- *                 
+ *
  */
 BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
                                 LPRECT rect)
@@ -4837,7 +4700,7 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
      if(!hwnd)
      {
         itemMenu = MENU_GetMenu(hMenu);
-        if (itemMenu == NULL) 
+        if (itemMenu == NULL)
             return FALSE;
 
         if(itemMenu->hWnd == 0)
@@ -4845,7 +4708,7 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
         referenceHwnd = itemMenu->hWnd;
      }
 
-     if ((rect == NULL) || (item == NULL)) 
+     if ((rect == NULL) || (item == NULL))
         return FALSE;
 
      *rect = item->rect;
@@ -4855,21 +4718,6 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
      return TRUE;
 }
 
-/**********************************************************************
- *             GetMenuItemRect16    (USER.665)
- */
-
-BOOL16 WINAPI GetMenuItemRect16 (HWND16 hwnd, HMENU16 hMenu, UINT16 uItem,
-                                LPRECT16 rect)
-{
-     RECT r32;
-     BOOL res;
-
-     if (!rect) return FALSE;
-     res = GetMenuItemRect (hwnd, hMenu, uItem, &r32);
-     CONV_RECT32TO16 (&r32, rect);
-     return res;
-}
 
 /**********************************************************************
  *             SetMenuInfo    (USER32.@)
@@ -4943,7 +4791,7 @@ BOOL WINAPI GetMenuInfo (HMENU hMenu, LPMENUINFO lpmi)
 }
 
 /**********************************************************************
- *         SetMenuContextHelpId16    (USER.384)
+ *         SetMenuContextHelpId    (USER.384)
  */
 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
 {
@@ -4969,13 +4817,13 @@ BOOL WINAPI SetMenuContextHelpId( HMENU hMenu, DWORD dwContextHelpID)
 }
 
 /**********************************************************************
- *         GetMenuContextHelpId16    (USER.385)
+ *         GetMenuContextHelpId    (USER.385)
  */
 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
 {
        return GetMenuContextHelpId( hMenu );
 }
+
 /**********************************************************************
  *         GetMenuContextHelpId    (USER32.@)
  */
@@ -4997,9 +4845,14 @@ DWORD WINAPI GetMenuContextHelpId( HMENU hMenu )
  */
 UINT WINAPI MenuItemFromPoint(HWND hWnd, HMENU hMenu, POINT ptScreen)
 {
-    FIXME("(0x%04x,0x%04x,(%ld,%ld)):stub\n", 
-         hWnd, hMenu, ptScreen.x, ptScreen.y);
-    return 0;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
+    UINT pos;
+    MENUITEM *item;
+
+    /*FIXME: Do we have to handle hWnd here? */
+    item = MENU_FindItemByCoords(menu, ptScreen, &pos);
+
+    return pos;
 }
 
 
@@ -5059,11 +4912,9 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
     {
         HMENU hMenu, hSubMenu, hSysMenu;
         UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
-        WND* wndPtr = WIN_FindWndPtr(hWnd);
 
-        hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU)wndPtr->wIDmenu;
-        hSysMenu = wndPtr->hSysMenu;
-        WIN_ReleaseWndPtr(wndPtr);
+        hMenu = (GetWindowLongA( hWnd, GWL_STYLE ) & WS_CHILD) ? 0 : GetMenu(hWnd);
+        hSysMenu = get_win_sys_menu( hWnd );
 
         /* find menu item and ask application to initialize it */
         /* 1. in the system menu */
@@ -5135,11 +4986,11 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
     }
     else
     {
-        /*  some reasons for NOT sending the WM_{SYS}COMMAND message: 
+        /*  some reasons for NOT sending the WM_{SYS}COMMAND message:
          *   #0: unknown (please report!)
          *   #1: for WM_KEYUP,WM_SYSKEYUP
          *   #2: mouse is captured
-         *   #3: window is disabled 
+         *   #3: window is disabled
          *   #4: it's a disabled system menu option
          *   #5: it's a menu option, but window is iconic
          *   #6: it's a menu option, but disabled
@@ -5153,6 +5004,8 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
 
 /**********************************************************************
  *      TranslateAccelerator      (USER32.@)
+ *      TranslateAcceleratorA     (USER32.@)
+ *      TranslateAcceleratorW     (USER32.@)
  */
 INT WINAPI TranslateAccelerator( HWND hWnd, HACCEL hAccel, LPMSG msg )
 {
@@ -5165,7 +5018,7 @@ INT WINAPI TranslateAccelerator( HWND hWnd, HACCEL hAccel, LPMSG msg )
         WARN_(accel)("msg null; should hang here to be win compatible\n");
         return 0;
     }
-    if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel)))
+    if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(HACCEL_16(hAccel))))
     {
         WARN_(accel)("invalid accel handle=%x\n", hAccel);
         return 0;
@@ -5190,43 +5043,3 @@ INT WINAPI TranslateAccelerator( HWND hWnd, HACCEL hAccel, LPMSG msg )
     WARN_(accel)("couldn't translate accelerator key\n");
     return 0;
 }
-
-
-/**********************************************************************
- *           TranslateAccelerator16      (USER.178)
- */
-INT16 WINAPI TranslateAccelerator16( HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg )
-{
-    LPACCEL16 lpAccelTbl;
-    int i;
-
-    if (msg == NULL)
-    {
-        WARN_(accel)("msg null; should hang here to be win compatible\n");
-        return 0;
-    }
-    if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel)))
-    {
-        WARN_(accel)("invalid accel handle=%x\n", hAccel);
-        return 0;
-    }
-    if ((msg->message != WM_KEYDOWN &&
-         msg->message != WM_KEYUP &&
-         msg->message != WM_SYSKEYDOWN &&
-         msg->message != WM_SYSKEYUP &&
-         msg->message != WM_CHAR)) return 0;
-
-    TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x,"
-                  "msg->hwnd=%04x, msg->message=%04x, wParam=%04x, lParam=%lx\n",
-                  hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam);
-
-    i = 0;
-    do
-    {
-        if (translate_accelerator( hWnd, msg->message, msg->wParam, msg->lParam,
-                                   lpAccelTbl[i].fVirt, lpAccelTbl[i].key, lpAccelTbl[i].cmd ))
-            return 1;
-    } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
-    WARN_(accel)("couldn't translate accelerator key\n");
-    return 0;
-}