[PATCH] user32: Don't depend on HMENU being valid for popup menus

Andrew Eikum aeikum at codeweavers.com
Tue May 6 09:28:14 CDT 2014


Now we use raw struct pointers internally instead of HMENUs. This lets
an application call DestroyMenu() without invalidating a menu that is
in use internally.
---

I couldn't think of a good way to split this patch, as we lose the HMENU
refcounting that some of the tests depend on by passing the raw
pointers.

 dlls/user32/menu.c       | 756 +++++++++++++++++++++++------------------------
 dlls/user32/tests/menu.c |   4 +-
 2 files changed, 375 insertions(+), 385 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index ab3f73b..4b091b0 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -67,13 +67,15 @@ WINE_DECLARE_DEBUG_CHANNEL(accel);
 #define MM_SETMENUHANDLE	(WM_USER + 0)
 #define MM_GETMENUHANDLE	(WM_USER + 1)
 
+typedef struct _POPUPMENU POPUPMENU, *LPPOPUPMENU;
+
 /* Menu item structure */
 typedef struct {
     /* ----------- MENUITEMINFO Stuff ----------- */
     UINT fType;			/* Item type. */
     UINT fState;		/* Item state.  */
     UINT_PTR wID;		/* Item id.  */
-    HMENU hSubMenu;		/* Pop-up menu.  */
+    POPUPMENU *submenu;
     HBITMAP hCheckBit;		/* Bitmap when checked.  */
     HBITMAP hUnCheckBit;	/* Bitmap when unchecked.  */
     LPWSTR text;		/* Item text. */
@@ -88,7 +90,7 @@ typedef struct {
 } MENUITEM;
 
 /* Popup menu structure */
-typedef struct {
+struct _POPUPMENU {
     struct user_object obj;
     WORD        wFlags;       /* Menu flags (MF_POPUP, MF_SYSMENU) */
     WORD	Width;        /* Width of the whole menu */
@@ -102,6 +104,7 @@ typedef struct {
     BOOL        bScrolling;   /* Scroll arrows are active */
     UINT        nScrollPos;   /* Current scroll position */
     UINT        nTotalHeight; /* Total height of menu items inside menu */
+    LONG        refcount;
     /* ------------ MENUINFO members ------ */
     DWORD	dwStyle;	/* Extended menu style */
     UINT	cyMax;		/* max height of the whole menu, 0 is screen height */
@@ -110,7 +113,7 @@ typedef struct {
     DWORD	dwMenuData;	/* application defined value */
     HMENU       hSysMenuOwner;  /* Handle to the dummy sys menu holder */
     WORD        textOffset;     /* Offset of text when items have both bitmaps and text */
-} POPUPMENU, *LPPOPUPMENU;
+};
 
 /* internal flags for menu tracking */
 
@@ -121,8 +124,8 @@ typedef struct {
 typedef struct
 {
     UINT	trackFlags;
-    HMENU	hCurrentMenu; /* current submenu (can be equal to hTopMenu)*/
-    HMENU	hTopMenu;     /* initial menu */
+    POPUPMENU *current_menu;
+    POPUPMENU *top_menu;
     HWND	hOwnerWnd;    /* where notifications are sent */
     POINT	pt;
 } MTRACKER;
@@ -178,7 +181,7 @@ static UINT     ODitemheight; /* default owner drawn item height */
 /* Use global popup window because there's no way 2 menus can
  * be tracked at the same time.  */
 static HWND top_popup;
-static HMENU top_popup_hmenu;
+static POPUPMENU *top_popup_menu;
 
   /* Flag set by EndMenu() to force an exit from menu tracking */
 static BOOL fEndMenu = FALSE;
@@ -186,6 +189,7 @@ static BOOL fEndMenu = FALSE;
 DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont);
 
 static BOOL SetMenuItemInfo_common( MENUITEM *, const MENUITEMINFOW *, BOOL);
+static BOOL MENU_ReleaseMenu( POPUPMENU *lppop );
 
 /*********************************************************************
  * menu class descriptor
@@ -200,6 +204,10 @@ const struct builtin_class_descr MENU_builtin_class =
     (HBRUSH)(COLOR_MENU+1)         /* brush */
 };
 
+static HMENU MENU_GetHandle(POPUPMENU *menu)
+{
+    return menu ? menu->obj.handle : NULL;
+}
 
 /***********************************************************************
  *           debug_print_menuitem
@@ -229,8 +237,8 @@ static void do_debug_print_menuitem(const char *prefix, const MENUITEM *mp,
     if (mp) {
         UINT flags = mp->fType;
         TRACE( "{ ID=0x%lx", mp->wID);
-        if ( mp->hSubMenu)
-            TRACE( ", Sub=%p", mp->hSubMenu);
+        if ( mp->submenu)
+            TRACE( ", Sub=%p", MENU_GetHandle(mp->submenu));
         if (flags) {
             int count = 0;
             TRACE( ", fType=");
@@ -533,16 +541,11 @@ static void MENU_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle )
 
 
 /******************************************************************************
- *
- *   UINT  MENU_GetStartOfNextColumn(
- *     HMENU  hMenu )
- *
+ *   MENU_GetStartOfNextColumn
  *****************************************************************************/
 
-static UINT  MENU_GetStartOfNextColumn(
-    HMENU  hMenu )
+static UINT  MENU_GetStartOfNextColumn( POPUPMENU *menu )
 {
-    POPUPMENU *menu = MENU_GetMenu(hMenu);
     UINT i;
 
     if(!menu)
@@ -562,16 +565,11 @@ static UINT  MENU_GetStartOfNextColumn(
 
 
 /******************************************************************************
- *
- *   UINT  MENU_GetStartOfPrevColumn(
- *     HMENU  hMenu )
- *
+ *   MENU_GetStartOfPrevColumn
  *****************************************************************************/
 
-static UINT  MENU_GetStartOfPrevColumn(
-    HMENU  hMenu )
+static UINT  MENU_GetStartOfPrevColumn( POPUPMENU *menu )
 {
-    POPUPMENU *menu = MENU_GetMenu(hMenu);
     UINT  i;
 
     if( !menu )
@@ -604,17 +602,18 @@ static UINT  MENU_GetStartOfPrevColumn(
 /***********************************************************************
  *           MENU_FindItem
  *
- * Find a menu item. Return a pointer on the item, and modifies *hmenu
+ * Find a menu item. Return a pointer on the item, and modifies *pmenu
  * in case the item was in a sub-menu.
  */
-static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
+static MENUITEM *MENU_FindItem( POPUPMENU **pmenu, UINT *nPos, UINT wFlags )
 {
-    POPUPMENU *menu;
+    POPUPMENU *menu = *pmenu;
     MENUITEM *fallback = NULL;
     UINT fallback_pos = 0;
     UINT i;
 
-    if ((*hmenu == (HMENU)0xffff) || (!(menu = MENU_GetMenu(*hmenu)))) return NULL;
+    if (!menu) return NULL;
+
     if (wFlags & MF_BYPOSITION)
     {
 	if (*nPos >= menu->nItems) return NULL;
@@ -627,11 +626,11 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
 	{
 	    if (item->fType & MF_POPUP)
 	    {
-		HMENU hsubmenu = item->hSubMenu;
-		MENUITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags );
+		POPUPMENU *submenu = item->submenu;
+		MENUITEM *subitem = MENU_FindItem( &submenu, nPos, wFlags );
 		if (subitem)
 		{
-		    *hmenu = hsubmenu;
+		    *pmenu = submenu;
 		    return subitem;
 		}
 		else if (item->wID == *nPos)
@@ -659,28 +658,27 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
  *           MENU_FindSubMenu
  *
  * Find a Sub menu. Return the position of the submenu, and modifies
- * *hmenu in case it is found in another sub-menu.
+ * *pmenu in case it is found in another sub-menu.
  * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
  */
-static UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget )
+static UINT MENU_FindSubMenu( POPUPMENU **pmenu, POPUPMENU *subTarget )
 {
-    POPUPMENU *menu;
+    POPUPMENU *menu = *pmenu;
     UINT i;
     MENUITEM *item;
-    if (((*hmenu)==(HMENU)0xffff) ||
-            (!(menu = MENU_GetMenu(*hmenu))))
+    if (!menu)
         return NO_SELECTED_ITEM;
     item = menu->items;
     for (i = 0; i < menu->nItems; i++, item++) {
         if(!(item->fType & MF_POPUP)) continue;
-        if (item->hSubMenu == hSubTarget) {
+        if (item->submenu == subTarget) {
             return i;
         }
         else  {
-            HMENU hsubmenu = item->hSubMenu;
-            UINT pos = MENU_FindSubMenu( &hsubmenu, hSubTarget );
+            POPUPMENU *submenu = item->submenu;
+            UINT pos = MENU_FindSubMenu( &submenu, subTarget );
             if (pos != NO_SELECTED_ITEM) {
-                *hmenu = hsubmenu;
+                *pmenu = submenu;
                 return pos;
             }
         }
@@ -757,16 +755,15 @@ static MENUITEM *MENU_FindItemByCoords( const 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, POPUPMENU *menu,
                                 WCHAR key, BOOL forceMenuChar )
 {
-    TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)key, key, hmenu );
+    TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)key, key, menu );
 
-    if (!IsMenu( hmenu )) hmenu = GetSubMenu( get_win_sys_menu(hwndOwner), 0);
+    if (!menu) menu = MENU_GetMenu(GetSubMenu( get_win_sys_menu(hwndOwner), 0));
 
-    if (hmenu)
+    if (menu)
     {
-	POPUPMENU *menu = MENU_GetMenu( hmenu );
 	MENUITEM *item = menu->items;
 	LRESULT menuchar;
 
@@ -792,7 +789,7 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu,
 	     }
 	}
 	menuchar = SendMessageW( hwndOwner, WM_MENUCHAR,
-                                 MAKEWPARAM( key, menu->wFlags ), (LPARAM)hmenu );
+                                 MAKEWPARAM( key, menu->wFlags ), (LPARAM)MENU_GetHandle(menu) );
 	if (HIWORD(menuchar) == MNC_EXECUTE) return LOWORD(menuchar);
 	if (HIWORD(menuchar) == MNC_CLOSE) return (UINT)(-2);
     }
@@ -867,7 +864,7 @@ static void MENU_GetBitmapItemSize( MENUITEM *lpitem, SIZE *size,
  * Draw a bitmap item.
  */
 static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect,
-                    HMENU hmenu, HWND hwndOwner, UINT odaction, BOOL menuBar)
+                    POPUPMENU *menu, HWND hwndOwner, UINT odaction, BOOL menuBar)
 {
     BITMAP bm;
     DWORD rop;
@@ -934,7 +931,7 @@ static void MENU_DrawBitmapItem( HDC hdc, MENUITEM *lpitem, const RECT *rect,
                 drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
                 drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
                 drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
-                drawItem.hwndItem = (HWND)hmenu;
+                drawItem.hwndItem = (HWND)MENU_GetHandle(menu);
                 drawItem.hDC = hdc;
                 drawItem.itemData = lpitem->dwItemData;
                 drawItem.rcItem = *rect;
@@ -1396,14 +1393,13 @@ static void draw_popup_arrow( HDC hdc, RECT rect, UINT arrow_bitmap_width,
  *
  * Draw a single menu item.
  */
-static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc, MENUITEM *lpitem,
+static void MENU_DrawMenuItem( HWND hwnd, POPUPMENU *menu, HWND hwndOwner, HDC hdc, MENUITEM *lpitem,
 			       UINT height, BOOL menuBar, UINT odaction )
 {
     RECT rect;
     BOOL flat_menu = FALSE;
     int bkgnd;
     UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0;
-    POPUPMENU *menu = MENU_GetMenu(hmenu);
     RECT bmprc;
 
     debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, "");
@@ -1451,7 +1447,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
 
     TRACE("rect=%s\n", wine_dbgstr_rect( &lpitem->rect));
     rect = lpitem->rect;
-    MENU_AdjustMenuItemRect(MENU_GetMenu(hmenu), &rect);
+    MENU_AdjustMenuItemRect(menu, &rect);
 
     if (lpitem->fType & MF_OWNERDRAW)
     {
@@ -1475,7 +1471,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         if (lpitem->fState & MF_GRAYED)  dis.itemState |= ODS_GRAYED|ODS_DISABLED;
         if (lpitem->fState & MF_HILITE)  dis.itemState |= ODS_SELECTED;
         dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
-        dis.hwndItem   = (HWND)hmenu;
+        dis.hwndItem   = (HWND)MENU_GetHandle(menu);
         dis.hDC        = hdc;
         dis.rcItem     = rect;
         TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
@@ -1637,7 +1633,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
             POINT origorg;
             /* some applications make this assumption on the DC's origin */
             SetViewportOrgEx( hdc, rect.left, rect.top, &origorg);
-            MENU_DrawBitmapItem(hdc, lpitem, &bmprc, hmenu, hwndOwner,
+            MENU_DrawBitmapItem(hdc, lpitem, &bmprc, menu, hwndOwner,
                     odaction, FALSE);
             SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
         }
@@ -1655,7 +1651,7 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         POINT origorg;
         
         SetViewportOrgEx( hdc, rect.left, rect.top, &origorg);
-        MENU_DrawBitmapItem( hdc, lpitem, &bmprc, hmenu, hwndOwner,
+        MENU_DrawBitmapItem( hdc, lpitem, &bmprc, menu, hwndOwner,
                 odaction, menuBar);
         SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
     }
@@ -1781,7 +1777,7 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
 
                     item = menu->items;
                     for( u = menu->nItems; u > 0; u--, item++)
-                        MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc,
+                        MENU_DrawMenuItem( hwnd, menu, menu->hwndOwner, hdc,
                                 item, menu->Height, FALSE, ODA_DRAWENTIRE );
                 }
                 /* draw scroll arrows */
@@ -1821,14 +1817,13 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd )
  *
  * Popup menu initialization before WM_ENTERMENULOOP.
  */
-static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
+static BOOL MENU_InitPopup( HWND hwndOwner, POPUPMENU *menu, UINT flags )
 {
-    POPUPMENU *menu;
     DWORD ex_style = 0;
 
-    TRACE("owner=%p hmenu=%p\n", hwndOwner, hmenu);
+    TRACE("owner=%p menu=%p\n", hwndOwner, menu);
 
-    if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+    if (!menu) return FALSE;
 
     /* store the owner for DrawItem */
     if (!IsWindow( hwndOwner ))
@@ -1845,7 +1840,7 @@ static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
     menu->hWnd = CreateWindowExW( ex_style, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL,
                                 WS_POPUP, 0, 0, 0, 0,
                                 hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
-                                (LPVOID)hmenu );
+                                (LPVOID)MENU_GetHandle(menu) );
     if( !menu->hWnd ) return FALSE;
     return TRUE;
 }
@@ -1856,21 +1851,23 @@ static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags )
  *
  * Display a popup menu.
  */
-static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
+static BOOL MENU_ShowPopup( HWND hwndOwner, POPUPMENU *menu, UINT id, UINT flags,
                               INT x, INT y, INT xanchor, INT yanchor )
 {
-    POPUPMENU *menu;
     INT width, height;
     POINT pt;
     HMONITOR monitor;
     MONITORINFO info;
 
-    TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
-          hwndOwner, hmenu, id, x, y, xanchor, yanchor);
+    TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
+          hwndOwner, menu, id, x, y, xanchor, yanchor);
 
-    if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+    if (!menu) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
     {
+        ERR("focused: %u, nitms: 0x%x\n",
+                menu->FocusedItem,
+                menu->nItems);
 	menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
@@ -1921,7 +1918,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
 
     if (!top_popup) {
         top_popup = menu->hWnd;
-        top_popup_hmenu = hmenu;
+        top_popup_menu = menu;
     }
     /* Display the window */
 
@@ -1976,15 +1973,13 @@ MENU_EnsureMenuItemVisible(LPPOPUPMENU lppop, UINT wIndex, HDC hdc)
 /***********************************************************************
  *           MENU_SelectItem
  */
-static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
-                             BOOL sendMenuSelect, HMENU topmenu )
+static void MENU_SelectItem( HWND hwndOwner, POPUPMENU *lppop, UINT wIndex,
+                             BOOL sendMenuSelect, POPUPMENU *topmenu )
 {
-    LPPOPUPMENU lppop;
     HDC hdc;
 
-    TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect);
+    TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, lppop, wIndex, sendMenuSelect);
 
-    lppop = MENU_GetMenu( hmenu );
     if ((!lppop) || (!lppop->nItems) || (!lppop->hWnd)) return;
 
     if (lppop->FocusedItem == wIndex) return;
@@ -1992,7 +1987,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
     else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW);
     if (!top_popup) {
         top_popup = lppop->hWnd;
-        top_popup_hmenu = hmenu;
+        top_popup_menu = lppop;
     }
 
     SelectObject( hdc, get_menu_font(FALSE));
@@ -2001,7 +1996,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
     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],
+	MENU_DrawMenuItem(lppop->hWnd, lppop, hwndOwner, hdc,&lppop->items[lppop->FocusedItem],
                           lppop->Height, !(lppop->wFlags & MF_POPUP),
 			  ODA_SELECT );
     }
@@ -2013,7 +2008,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
         if(!(lppop->items[wIndex].fType & MF_SEPARATOR)) {
             lppop->items[wIndex].fState |= MF_HILITE;
             MENU_EnsureMenuItemVisible(lppop, wIndex, hdc);
-            MENU_DrawMenuItem( lppop->hWnd, hmenu, hwndOwner, hdc,
+            MENU_DrawMenuItem( lppop->hWnd, lppop, hwndOwner, hdc,
                     &lppop->items[wIndex], lppop->Height,
                     !(lppop->wFlags & MF_POPUP), ODA_SELECT );
         }
@@ -2023,18 +2018,17 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
 	    SendMessageW( hwndOwner, WM_MENUSELECT,
                      MAKEWPARAM(ip->fType & MF_POPUP ? wIndex: ip->wID,
                      ip->fType | ip->fState |
-                     (lppop->wFlags & MF_SYSMENU)), (LPARAM)hmenu);
+                     (lppop->wFlags & MF_SYSMENU)), (LPARAM)MENU_GetHandle(lppop));
         }
     }
     else if (sendMenuSelect) {
         if(topmenu){
             int pos;
-            if((pos=MENU_FindSubMenu(&topmenu, hmenu))!=NO_SELECTED_ITEM){
-                POPUPMENU *ptm = MENU_GetMenu( topmenu );
-                MENUITEM *ip = &ptm->items[pos];
+            if((pos=MENU_FindSubMenu(&topmenu, lppop))!=NO_SELECTED_ITEM){
+                MENUITEM *ip = &topmenu->items[pos];
                 SendMessageW( hwndOwner, WM_MENUSELECT, MAKEWPARAM(pos,
                          ip->fType | ip->fState |
-                         (ptm->wFlags & MF_SYSMENU)), (LPARAM)topmenu);
+                         (topmenu->wFlags & MF_SYSMENU)), (LPARAM)topmenu);
             }
         }
     }
@@ -2049,14 +2043,12 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex,
  * If there is no selection then it should select the last item if
  * offset is ITEM_PREV or the first item if offset is ITEM_NEXT.
  */
-static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
+static void MENU_MoveSelection( HWND hwndOwner, POPUPMENU *menu, INT offset )
 {
     INT i;
-    POPUPMENU *menu;
 
-    TRACE("hwnd=%p hmenu=%p off=0x%04x\n", hwndOwner, hmenu, offset);
+    TRACE("hwnd=%p menu=%p off=0x%04x\n", hwndOwner, menu, offset);
 
-    menu = MENU_GetMenu( hmenu );
     if ((!menu) || (!menu->items)) return;
 
     if ( menu->FocusedItem != NO_SELECTED_ITEM )
@@ -2066,7 +2058,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
 					    ; i += offset)
 	    if (!(menu->items[i].fType & MF_SEPARATOR))
 	    {
-		MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 );
+		MENU_SelectItem( hwndOwner, menu, i, TRUE, 0 );
 		return;
 	    }
     }
@@ -2075,7 +2067,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
 		  i >= 0 && i < menu->nItems ; i += offset)
 	if (!(menu->items[i].fType & MF_SEPARATOR))
 	{
-	    MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 );
+	    MENU_SelectItem( hwndOwner, menu, i, TRUE, 0 );
 	    return;
 	}
 }
@@ -2100,12 +2092,9 @@ static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags )
         if (pos > menu->nItems)
             pos = menu->nItems;
     } else {
-        if (!MENU_FindItem( &hMenu, &pos, flags ))
+        MENUITEM *item = MENU_FindItem( &menu, &pos, flags );
+        if (!item)
             pos = menu->nItems;
-        else {
-            if (!(menu = MENU_GetMenu( hMenu )))
-                return NULL;
-        }
     }
 
     /* Make sure that MDI system buttons stay on the right side.
@@ -2246,21 +2235,18 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
 /***********************************************************************
  *           MENU_GetSubPopup
  *
- * Return the handle of the selected sub-popup menu (if any).
+ * Return the selected sub-popup menu (if any).
  */
-static HMENU MENU_GetSubPopup( HMENU hmenu )
+static POPUPMENU *MENU_GetSubPopup( POPUPMENU *menu )
 {
-    POPUPMENU *menu;
     MENUITEM *item;
 
-    menu = MENU_GetMenu( hmenu );
-
-    if ((!menu) || (menu->FocusedItem == NO_SELECTED_ITEM)) return 0;
+    if ((!menu) || (menu->FocusedItem == NO_SELECTED_ITEM)) return NULL;
 
     item = &menu->items[menu->FocusedItem];
     if ((item->fType & MF_POPUP) && (item->fState & MF_MOUSESELECT))
-        return item->hSubMenu;
-    return 0;
+        return item->submenu;
+    return NULL;
 }
 
 
@@ -2269,16 +2255,14 @@ static HMENU MENU_GetSubPopup( HMENU hmenu )
  *
  * Hide the sub-popup menus of this menu.
  */
-static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
+static void MENU_HideSubPopups( HWND hwndOwner, POPUPMENU *menu,
                                 BOOL sendMenuSelect, UINT wFlags )
 {
-    POPUPMENU *menu = MENU_GetMenu( hmenu );
 
-    TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, sendMenuSelect);
+    TRACE("owner=%p menu=%p 0x%04x\n", hwndOwner, menu, sendMenuSelect);
 
     if (menu && top_popup)
     {
-	HMENU hsubmenu;
 	POPUPMENU *submenu;
 	MENUITEM *item;
 
@@ -2288,17 +2272,17 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
 	    if (!(item->fType & MF_POPUP) ||
 		!(item->fState & MF_MOUSESELECT)) return;
 	    item->fState &= ~MF_MOUSESELECT;
-	    hsubmenu = item->hSubMenu;
+	    submenu = item->submenu;
 	} else return;
 
-	if (!(submenu = MENU_GetMenu( hsubmenu ))) return;
-	MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE, wFlags );
-	MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
+        if (!submenu) return;
+        MENU_HideSubPopups( hwndOwner, submenu, FALSE, wFlags );
+        MENU_SelectItem( hwndOwner, submenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
         DestroyWindow( submenu->hWnd );
         submenu->hWnd = 0;
 
         if (!(wFlags & TPM_NONOTIFY))
-           SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)hsubmenu,
+           SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)MENU_GetHandle(submenu),
                          MAKELPARAM(0, IS_SYSTEM_MENU(submenu)) );
     }
 }
@@ -2308,32 +2292,31 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu,
  *           MENU_ShowSubPopup
  *
  * Display the sub-menu of the selected item of this menu.
- * Return the handle of the submenu, or hmenu if no submenu to display.
+ * Return the handle of the submenu, or menu if no submenu to display.
  */
-static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
+static POPUPMENU *MENU_ShowSubPopup( HWND hwndOwner, POPUPMENU *menu,
                                   BOOL selectFirst, UINT wFlags )
 {
     RECT rect;
-    POPUPMENU *menu;
     MENUITEM *item;
     HDC hdc;
 
-    TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, selectFirst);
+    TRACE("owner=%p menu=%p 0x%04x\n", hwndOwner, menu, selectFirst);
 
-    if (!(menu = MENU_GetMenu( hmenu ))) return hmenu;
+    if (!menu) return NULL;
 
-    if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu;
+    if (menu->FocusedItem == NO_SELECTED_ITEM) return menu;
 
     item = &menu->items[menu->FocusedItem];
     if (!(item->fType & MF_POPUP) || (item->fState & (MF_GRAYED | MF_DISABLED)))
-        return hmenu;
+        return menu;
 
     /* message must be sent before using item,
        because nearly everything may be changed by the application ! */
 
     /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
     if (!(wFlags & TPM_NONOTIFY))
-       SendMessageW( hwndOwner, WM_INITMENUPOPUP, (WPARAM)item->hSubMenu,
+       SendMessageW( hwndOwner, WM_INITMENUPOPUP, (WPARAM)MENU_GetHandle(item->submenu),
                      MAKELPARAM( menu->FocusedItem, IS_SYSTEM_MENU(menu) ));
 
     item = &menu->items[menu->FocusedItem];
@@ -2348,7 +2331,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
         SelectObject( hdc, get_menu_font(FALSE));
 
         item->fState |= MF_HILITE;
-        MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE );
+        MENU_DrawMenuItem( menu->hWnd, menu, 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)
@@ -2358,7 +2341,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
 
     if (IS_SYSTEM_MENU(menu))
     {
-	MENU_InitSysMenuPopup(item->hSubMenu,
+	MENU_InitSysMenuPopup(MENU_GetHandle(item->submenu),
                               GetWindowLongW( menu->hWnd, GWL_STYLE ),
                               GetClassLongW( menu->hWnd, GCL_STYLE));
 
@@ -2403,13 +2386,13 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
     /* use default alignment for submenus */
     wFlags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
 
-    MENU_InitPopup( hwndOwner, item->hSubMenu, wFlags );
+    MENU_InitPopup( hwndOwner, item->submenu, wFlags );
 
-    MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, wFlags,
+    MENU_ShowPopup( hwndOwner, item->submenu, menu->FocusedItem, wFlags,
 		    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
-        MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
-    return item->hSubMenu;
+        MENU_MoveSelection( hwndOwner, item->submenu, ITEM_NEXT );
+    return item->submenu;
 }
 
 
@@ -2431,9 +2414,7 @@ HWND MENU_IsMenuActive(void)
  */
 void MENU_EndMenu( HWND hwnd )
 {
-    POPUPMENU *menu;
-    menu = top_popup_hmenu ? MENU_GetMenu( top_popup_hmenu ) : NULL;
-    if (menu && (hwnd == menu->hWnd || hwnd == menu->hwndOwner)) EndMenu();
+    if (top_popup_menu && (hwnd == top_popup_menu->hWnd || hwnd == top_popup_menu->hwndOwner)) EndMenu();
 }
 
 /***********************************************************************
@@ -2441,29 +2422,28 @@ void MENU_EndMenu( HWND hwnd )
  *
  * Walks menu chain trying to find a menu pt maps to.
  */
-static HMENU MENU_PtMenu( HMENU hMenu, POINT pt )
+static POPUPMENU *MENU_PtMenu( POPUPMENU *menu, POINT pt )
 {
-   POPUPMENU *menu = MENU_GetMenu( hMenu );
    UINT item = menu->FocusedItem;
-   HMENU ret;
+   POPUPMENU *ret;
 
    /* try subpopup first (if any) */
    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;
+        ? MENU_PtMenu(menu->items[item].submenu, pt) : 0;
 
    if (!ret)  /* check the current window (avoiding WM_HITTEST) */
    {
        INT ht = NC_HandleNCHitTest( menu->hWnd, pt );
        if( menu->wFlags & MF_POPUP )
        {
-           if (ht != HTNOWHERE && ht != HTERROR) ret = hMenu;
+           if (ht != HTNOWHERE && ht != HTERROR) ret = menu;
        }
        else if (ht == HTSYSMENU)
-           ret = get_win_sys_menu( menu->hWnd );
+           ret = MENU_GetMenu(get_win_sys_menu( menu->hWnd ));
        else if (ht == HTMENU)
-           ret = GetMenu( menu->hWnd );
+           ret = MENU_GetMenu(GetMenu( menu->hWnd ));
    }
    return ret;
 }
@@ -2478,19 +2458,18 @@ static HMENU MENU_PtMenu( HMENU hMenu, POINT pt )
  * sending unwanted message.
  *
  */
-static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags )
+static INT MENU_ExecFocusedItem( MTRACKER* pmt, POPUPMENU *menu, UINT wFlags )
 {
     MENUITEM *item;
-    POPUPMENU *menu = MENU_GetMenu( hMenu );
 
-    TRACE("%p hmenu=%p\n", pmt, hMenu);
+    TRACE("%p menu=%p\n", pmt, menu);
 
     if (!menu || !menu->nItems ||
 	(menu->FocusedItem == NO_SELECTED_ITEM)) return -1;
 
     item = &menu->items[menu->FocusedItem];
 
-    TRACE("hMenu %p wID %08lx hSubMenu %p fType %04x\n", hMenu, item->wID, item->hSubMenu, item->fType);
+    TRACE("menu %p wID %08lx submenu %p fType %04x\n", menu, item->wID, item->submenu, item->fType);
 
     if (!(item->fType & MF_POPUP))
     {
@@ -2505,12 +2484,11 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags )
 				  MAKELPARAM((INT16)pmt->pt.x, (INT16)pmt->pt.y) );
 		else
 		{
-                    POPUPMENU *topmenu = MENU_GetMenu( pmt->hTopMenu );
-                    DWORD dwStyle = menu->dwStyle | (topmenu ? topmenu->dwStyle : 0);
+                    DWORD dwStyle = menu->dwStyle | (pmt->top_menu ? pmt->top_menu->dwStyle : 0);
 
                     if (dwStyle & MNS_NOTIFYBYPOS)
                         PostMessageW( pmt->hOwnerWnd, WM_MENUCOMMAND, menu->FocusedItem,
-                                      (LPARAM)hMenu);
+                                      (LPARAM)MENU_GetHandle(menu));
                     else
                         PostMessageW( pmt->hOwnerWnd, WM_COMMAND, item->wID, 0 );
 		}
@@ -2520,7 +2498,7 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags )
     }
     else
     {
-	pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hMenu, TRUE, wFlags);
+	pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, menu, TRUE, wFlags);
 	return -2;
     }
 
@@ -2532,23 +2510,20 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags )
  *
  * Helper function for menu navigation routines.
  */
-static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFlags )
+static void MENU_SwitchTracking( MTRACKER* pmt, POPUPMENU *ptmenu, UINT id, UINT wFlags )
 {
-    POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu );
-    POPUPMENU *topmenu = MENU_GetMenu( pmt->hTopMenu );
+    TRACE("%p ptmenu=%p 0x%04x\n", pmt, ptmenu, id);
 
-    TRACE("%p hmenu=%p 0x%04x\n", pmt, hPtMenu, id);
-
-    if( pmt->hTopMenu != hPtMenu &&
-	!((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) )
+    if( pmt->top_menu != ptmenu &&
+        !((ptmenu->wFlags | pmt->top_menu->wFlags) & MF_POPUP) )
     {
-	/* both are top level menus (system and menu-bar) */
-	MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
-	MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 );
-        pmt->hTopMenu = hPtMenu;
+        /* both are top level menus (system and menu-bar) */
+        MENU_HideSubPopups( pmt->hOwnerWnd, pmt->top_menu, FALSE, wFlags );
+        MENU_SelectItem( pmt->hOwnerWnd, pmt->top_menu, NO_SELECTED_ITEM, FALSE, 0 );
+        pmt->top_menu = ptmenu;
     }
-    else MENU_HideSubPopups( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags );
-    MENU_SelectItem( pmt->hOwnerWnd, hPtMenu, id, TRUE, 0 );
+    else MENU_HideSubPopups( pmt->hOwnerWnd, ptmenu, FALSE, wFlags );
+    MENU_SelectItem( pmt->hOwnerWnd, ptmenu, id, TRUE, 0 );
 }
 
 
@@ -2557,14 +2532,13 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFl
  *
  * Return TRUE if we can go on with menu tracking.
  */
-static BOOL MENU_ButtonDown( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
+static BOOL MENU_ButtonDown( MTRACKER* pmt, POPUPMENU *ptmenu, UINT wFlags )
 {
-    TRACE("%p hPtMenu=%p\n", pmt, hPtMenu);
+    TRACE("%p ptmenu=%p\n", pmt, ptmenu);
 
-    if (hPtMenu)
+    if (ptmenu)
     {
 	UINT id = 0;
-	POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu );
 	MENUITEM *item;
 
 	if( IS_SYSTEM_MENU(ptmenu) )
@@ -2575,12 +2549,12 @@ static BOOL MENU_ButtonDown( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
 	if( item )
 	{
 	    if( ptmenu->FocusedItem != id )
-		MENU_SwitchTracking( pmt, hPtMenu, id, wFlags );
+		MENU_SwitchTracking( pmt, ptmenu, id, wFlags );
 
 	    /* If the popup menu is not already "popped" */
 	    if(!(item->fState & MF_MOUSESELECT ))
 	    {
-		pmt->hCurrentMenu = MENU_ShowSubPopup( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags );
+		pmt->current_menu = MENU_ShowSubPopup( pmt->hOwnerWnd, ptmenu, FALSE, wFlags );
 	    }
 
 	    return TRUE;
@@ -2598,14 +2572,13 @@ static BOOL MENU_ButtonDown( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
  * A -1 return value indicates that we go on with menu tracking.
  *
  */
-static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags)
+static INT MENU_ButtonUp( MTRACKER* pmt, POPUPMENU *ptmenu, UINT wFlags)
 {
-    TRACE("%p hmenu=%p\n", pmt, hPtMenu);
+    TRACE("%p menu=%p\n", pmt, ptmenu);
 
-    if (hPtMenu)
+    if (ptmenu)
     {
 	UINT id = 0;
-	POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu );
 	MENUITEM *item;
 
         if( IS_SYSTEM_MENU(ptmenu) )
@@ -2619,7 +2592,7 @@ static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags)
 
 	    if( !(item->fType & MF_POPUP) )
 	    {
-	        INT executedMenuId = MENU_ExecFocusedItem( pmt, hPtMenu, wFlags);
+	        INT executedMenuId = MENU_ExecFocusedItem( pmt, ptmenu, wFlags);
                 if (executedMenuId == -1 || executedMenuId == -2) return -1;
                 return executedMenuId;
 	    }
@@ -2627,7 +2600,7 @@ static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags)
 	    /* If we are dealing with the top-level menu            */
 	    /* and this is a click on an already "popped" item:     */
 	    /* Stop the menu tracking and close the opened submenus */
-	    if((pmt->hTopMenu == hPtMenu) && ptmenu->bTimeToHide)
+	    if(pmt->top_menu == ptmenu && ptmenu->bTimeToHide)
 		return 0;
 	}
 	ptmenu->bTimeToHide = TRUE;
@@ -2641,14 +2614,12 @@ static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags)
  *
  * Return TRUE if we can go on with menu tracking.
  */
-static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
+static BOOL MENU_MouseMove( MTRACKER* pmt, POPUPMENU *ptmenu, UINT wFlags )
 {
     UINT id = NO_SELECTED_ITEM;
-    POPUPMENU *ptmenu = NULL;
 
-    if( hPtMenu )
+    if( ptmenu )
     {
-	ptmenu = MENU_GetMenu( hPtMenu );
         if( IS_SYSTEM_MENU(ptmenu) )
 	    id = 0;
         else
@@ -2657,14 +2628,14 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
 
     if( id == NO_SELECTED_ITEM )
     {
-	MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu,
-			 NO_SELECTED_ITEM, TRUE, pmt->hTopMenu);
+        MENU_SelectItem( pmt->hOwnerWnd, pmt->current_menu,
+                         NO_SELECTED_ITEM, TRUE, pmt->top_menu);
 
     }
     else if( ptmenu->FocusedItem != id )
     {
-	    MENU_SwitchTracking( pmt, hPtMenu, id, wFlags );
-	    pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hPtMenu, FALSE, wFlags);
+            MENU_SwitchTracking( pmt, ptmenu, id, wFlags );
+            pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, ptmenu, FALSE, wFlags);
     }
     return TRUE;
 }
@@ -2677,35 +2648,34 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
  */
 static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
 {
-    POPUPMENU *menu = MENU_GetMenu( pmt->hTopMenu );
     BOOL atEnd = FALSE;
 
     /* When skipping left, we need to do something special after the
        first menu.                                                  */
-    if (vk == VK_LEFT && menu->FocusedItem == 0)
+    if (vk == VK_LEFT && pmt->top_menu->FocusedItem == 0)
     {
         atEnd = TRUE;
     }
     /* When skipping right, for the non-system menu, we need to
        handle the last non-special menu item (ie skip any window
        icons such as MDI maximize, restore or close)             */
-    else if ((vk == VK_RIGHT) && !IS_SYSTEM_MENU(menu))
+    else if ((vk == VK_RIGHT) && !IS_SYSTEM_MENU(pmt->top_menu))
     {
-        UINT i = menu->FocusedItem + 1;
-        while (i < menu->nItems) {
-            if ((menu->items[i].wID >= SC_SIZE &&
-                 menu->items[i].wID <= SC_RESTORE)) {
+        UINT i = pmt->top_menu->FocusedItem + 1;
+        while (i < pmt->top_menu->nItems) {
+            if ((pmt->top_menu->items[i].wID >= SC_SIZE &&
+                 pmt->top_menu->items[i].wID <= SC_RESTORE)) {
                 i++;
             } else break;
         }
-        if (i == menu->nItems) {
+        if (i == pmt->top_menu->nItems) {
             atEnd = TRUE;
         }
     }
     /* When skipping right, we need to cater for the system menu */
-    else if ((vk == VK_RIGHT) && IS_SYSTEM_MENU(menu))
+    else if ((vk == VK_RIGHT) && IS_SYSTEM_MENU(pmt->top_menu))
     {
-        if (menu->FocusedItem == (menu->nItems - 1)) {
+        if (pmt->top_menu->FocusedItem == (pmt->top_menu->nItems - 1)) {
             atEnd = TRUE;
         }
     }
@@ -2717,19 +2687,19 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
 	HWND  hNewWnd;
 	UINT  id = 0;
 
-        next_menu.hmenuIn = (IS_SYSTEM_MENU(menu)) ? GetSubMenu(pmt->hTopMenu,0) : pmt->hTopMenu;
+        next_menu.hmenuIn = (IS_SYSTEM_MENU(pmt->top_menu)) ? GetSubMenu(MENU_GetHandle(pmt->top_menu), 0) : MENU_GetHandle(pmt->top_menu);
         next_menu.hmenuNext = 0;
         next_menu.hwndNext = 0;
         SendMessageW( pmt->hOwnerWnd, WM_NEXTMENU, vk, (LPARAM)&next_menu );
 
         TRACE("%p [%p] -> %p [%p]\n",
-              pmt->hCurrentMenu, pmt->hOwnerWnd, next_menu.hmenuNext, next_menu.hwndNext );
+              pmt->current_menu, pmt->hOwnerWnd, next_menu.hmenuNext, next_menu.hwndNext );
 
 	if (!next_menu.hmenuNext || !next_menu.hwndNext)
 	{
             DWORD style = GetWindowLongW( pmt->hOwnerWnd, GWL_STYLE );
 	    hNewWnd = pmt->hOwnerWnd;
-	    if( IS_SYSTEM_MENU(menu) )
+	    if( IS_SYSTEM_MENU(pmt->top_menu) )
 	    {
 		/* switch to the menu bar */
 
@@ -2737,7 +2707,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
 
 	        if( vk == VK_LEFT )
 	        {
-		    menu = MENU_GetMenu( hNewMenu );
+		    POPUPMENU *menu = MENU_GetMenu( hNewMenu );
 		    id = menu->nItems - 1;
 
                     /* Skip backwards over any system predefined icons,
@@ -2781,12 +2751,12 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
 	    else return FALSE;
 	}
 
-	if( hNewMenu != pmt->hTopMenu )
+	if( pmt->top_menu && hNewMenu != MENU_GetHandle(pmt->top_menu) )
 	{
-	    MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM,
+	    MENU_SelectItem( pmt->hOwnerWnd, pmt->top_menu, NO_SELECTED_ITEM,
                     FALSE, 0 );
-	    if( pmt->hCurrentMenu != pmt->hTopMenu )
-		MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+	    if( pmt->current_menu != pmt->top_menu )
+		MENU_HideSubPopups( pmt->hOwnerWnd, pmt->top_menu, FALSE, wFlags );
 	}
 
 	if( hNewWnd != pmt->hOwnerWnd )
@@ -2795,8 +2765,8 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
             set_capture_window( pmt->hOwnerWnd, GUI_INMENUMODE, NULL );
 	}
 
-	pmt->hTopMenu = pmt->hCurrentMenu = hNewMenu; /* all subpopups are hidden */
-	MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, id, TRUE, 0 );
+	pmt->top_menu = pmt->current_menu = MENU_GetMenu(hNewMenu); /* all subpopups are hidden */
+	MENU_SelectItem( pmt->hOwnerWnd, pmt->top_menu, id, TRUE, 0 );
 
 	return TRUE;
     }
@@ -2850,25 +2820,23 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
 {
     BOOL bEndMenu = TRUE;
 
-    if (pmt->hCurrentMenu != pmt->hTopMenu)
+    if (pmt->current_menu != pmt->top_menu)
     {
-        POPUPMENU *menu = MENU_GetMenu(pmt->hCurrentMenu);
-
-        if (menu->wFlags & MF_POPUP)
+        if (pmt->current_menu->wFlags & MF_POPUP)
         {
-            HMENU hmenutmp, hmenuprev;
+            POPUPMENU *menutmp, *menuprev;
 
-            hmenuprev = hmenutmp = pmt->hTopMenu;
+            menuprev = menutmp = pmt->top_menu;
 
             /* close topmost popup */
-            while (hmenutmp != pmt->hCurrentMenu)
+            while (menutmp != pmt->current_menu)
             {
-                hmenuprev = hmenutmp;
-                hmenutmp = MENU_GetSubPopup( hmenuprev );
+                menuprev = menutmp;
+                menutmp = MENU_GetSubPopup( menuprev );
             }
 
-            MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
-            pmt->hCurrentMenu = hmenuprev;
+            MENU_HideSubPopups( pmt->hOwnerWnd, menuprev, TRUE, wFlags );
+            pmt->current_menu = menuprev;
             bEndMenu = FALSE;
         }
     }
@@ -2883,47 +2851,45 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
  */
 static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
 {
-    POPUPMENU *menu;
-    HMENU hmenutmp, hmenuprev;
+    POPUPMENU *menu, *menutmp, *menuprev;
     UINT  prevcol;
 
-    hmenuprev = hmenutmp = pmt->hTopMenu;
-    menu = MENU_GetMenu( hmenutmp );
+    menu = menuprev = menutmp = pmt->top_menu;
 
     /* Try to move 1 column left (if possible) */
-    if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) !=
+    if( (prevcol = MENU_GetStartOfPrevColumn( pmt->current_menu )) !=
 	NO_SELECTED_ITEM ) {
 
-	MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu,
+	MENU_SelectItem( pmt->hOwnerWnd, pmt->current_menu,
 			 prevcol, TRUE, 0 );
 	return;
     }
 
     /* close topmost popup */
-    while (hmenutmp != pmt->hCurrentMenu)
+    while (menutmp != pmt->current_menu)
     {
-	hmenuprev = hmenutmp;
-	hmenutmp = MENU_GetSubPopup( hmenuprev );
+        menuprev = menutmp;
+        menutmp = MENU_GetSubPopup( menuprev );
     }
 
-    MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
-    pmt->hCurrentMenu = hmenuprev;
+    MENU_HideSubPopups( pmt->hOwnerWnd, menuprev, TRUE, wFlags );
+    pmt->current_menu = menuprev;
 
-    if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) )
+    if ( (menuprev == pmt->top_menu) && !(menu->wFlags & MF_POPUP) )
     {
 	/* move menu bar selection if no more popups are left */
 
 	if( !MENU_DoNextMenu( pmt, VK_LEFT, wFlags ) )
-	     MENU_MoveSelection( pmt->hOwnerWnd, pmt->hTopMenu, ITEM_PREV );
+	     MENU_MoveSelection( pmt->hOwnerWnd, pmt->top_menu, ITEM_PREV );
 
-	if ( hmenuprev != hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP )
+	if ( menuprev != menutmp || pmt->trackFlags & TF_SUSPENDPOPUP )
 	{
 	   /* A sublevel menu was displayed - display the next one
 	    * unless there is another displacement coming up */
 
 	    if( !MENU_SuspendPopup( pmt, WM_KEYDOWN ) )
-		pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd,
-						pmt->hTopMenu, TRUE, wFlags);
+		pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd,
+						pmt->top_menu, TRUE, wFlags);
 	}
     }
 }
@@ -2936,51 +2902,50 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
  */
 static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags )
 {
-    HMENU hmenutmp;
-    POPUPMENU *menu = MENU_GetMenu( pmt->hTopMenu );
+    POPUPMENU *menutmp;
     UINT  nextcol;
 
     TRACE("MENU_KeyRight called, cur %p (%s), top %p (%s).\n",
-          pmt->hCurrentMenu,
-          debugstr_w((MENU_GetMenu(pmt->hCurrentMenu))->items[0].text),
-          pmt->hTopMenu, debugstr_w(menu->items[0].text) );
+          pmt->current_menu,
+          debugstr_w(pmt->current_menu->items[0].text),
+          pmt->top_menu, debugstr_w(pmt->top_menu->items[0].text) );
 
-    if ( (menu->wFlags & MF_POPUP) || (pmt->hCurrentMenu != pmt->hTopMenu))
+    if ( (pmt->top_menu->wFlags & MF_POPUP) || (pmt->current_menu != pmt->top_menu))
     {
 	/* If already displaying a popup, try to display sub-popup */
 
-	hmenutmp = pmt->hCurrentMenu;
-	pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hmenutmp, TRUE, wFlags);
+	menutmp = pmt->current_menu;
+	pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, menutmp, TRUE, wFlags);
 
 	/* if subpopup was displayed then we are done */
-	if (hmenutmp != pmt->hCurrentMenu) return;
+	if (menutmp != pmt->current_menu) return;
     }
 
     /* Check to see if there's another column */
-    if( (nextcol = MENU_GetStartOfNextColumn( pmt->hCurrentMenu )) !=
+    if( (nextcol = MENU_GetStartOfNextColumn( pmt->current_menu )) !=
 	NO_SELECTED_ITEM ) {
 	TRACE("Going to %d.\n", nextcol );
-	MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu,
+	MENU_SelectItem( pmt->hOwnerWnd, pmt->current_menu,
 			 nextcol, TRUE, 0 );
 	return;
     }
 
-    if (!(menu->wFlags & MF_POPUP))	/* menu bar tracking */
+    if (!(pmt->top_menu->wFlags & MF_POPUP))	/* menu bar tracking */
     {
-	if( pmt->hCurrentMenu != pmt->hTopMenu )
+	if( pmt->current_menu != pmt->top_menu)
 	{
-	    MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
-	    hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu;
-	} else hmenutmp = 0;
+	    MENU_HideSubPopups( pmt->hOwnerWnd, pmt->top_menu, FALSE, wFlags );
+	    menutmp = pmt->current_menu = pmt->top_menu;
+	} else menutmp = 0;
 
 	/* try to move to the next item */
 	if( !MENU_DoNextMenu( pmt, VK_RIGHT, wFlags ) )
-	     MENU_MoveSelection( pmt->hOwnerWnd, pmt->hTopMenu, ITEM_NEXT );
+	     MENU_MoveSelection( pmt->hOwnerWnd, pmt->top_menu, ITEM_NEXT );
 
-	if( hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP )
+	if( menutmp || pmt->trackFlags & TF_SUSPENDPOPUP )
 	    if( !MENU_SuspendPopup(pmt, WM_KEYDOWN) )
-		pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd,
-						       pmt->hTopMenu, TRUE, wFlags);
+		pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd,
+						       pmt->top_menu, TRUE, wFlags);
     }
 }
 
@@ -2994,11 +2959,10 @@ static void CALLBACK release_capture( BOOL __normal )
  *
  * Menu tracking code.
  */
-static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
+static BOOL MENU_TrackMenu( POPUPMENU *menu, UINT wFlags, INT x, INT y,
                             HWND hwnd, const RECT *lprect )
 {
     MSG msg;
-    POPUPMENU *menu;
     BOOL fRemove;
     INT executedMenuId = -1;
     MTRACKER mt;
@@ -3006,18 +2970,17 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
     HWND capture_win;
 
     mt.trackFlags = 0;
-    mt.hCurrentMenu = hmenu;
-    mt.hTopMenu = hmenu;
+    mt.current_menu = mt.top_menu = menu;
     mt.hOwnerWnd = WIN_GetFullHandle( hwnd );
     mt.pt.x = x;
     mt.pt.y = y;
 
-    TRACE("hmenu=%p flags=0x%08x (%d,%d) hwnd=%p %s\n",
-          hmenu, wFlags, x, y, hwnd, wine_dbgstr_rect( lprect));
+    TRACE("menu=%p flags=0x%08x (%d,%d) hwnd=%p %s\n",
+          menu, wFlags, x, y, hwnd, wine_dbgstr_rect( lprect));
 
-    if (!(menu = MENU_GetMenu( hmenu )))
+    if (!menu)
     {
-        WARN("Invalid menu handle %p\n", hmenu);
+        WARN("Invalid menu handle %p\n", menu);
         SetLastError(ERROR_INVALID_MENU_HANDLE);
         return FALSE;
     }
@@ -3025,7 +2988,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
     if (wFlags & TPM_BUTTONDOWN)
     {
 	/* Get the result in order to start the tracking or not */
-	fRemove = MENU_ButtonDown( &mt, hmenu, wFlags );
+	fRemove = MENU_ButtonDown( &mt, menu, wFlags );
 	fEndMenu = !fRemove;
     }
 
@@ -3037,7 +3000,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 
     __TRY while (!fEndMenu)
     {
-	menu = MENU_GetMenu( mt.hCurrentMenu );
+	menu = mt.current_menu;
 	if (!menu) /* sometimes happens if I do a window manager close */
 	    break;
 
@@ -3095,7 +3058,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
             mt.pt.y = (short)HIWORD(msg.lParam);
 
 	    /* Find a menu for this mouse event */
-	    hmenu = MENU_PtMenu( mt.hTopMenu, mt.pt );
+	    menu = MENU_PtMenu( mt.top_menu, mt.pt );
 
 	    switch(msg.message)
 	    {
@@ -3109,7 +3072,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 		case WM_LBUTTONDOWN:
 		    /* If the message belongs to the menu, removes it from the queue */
 		    /* Else, end menu tracking */
-		    fRemove = MENU_ButtonDown( &mt, hmenu, wFlags );
+		    fRemove = MENU_ButtonDown( &mt, menu, wFlags );
 		    fEndMenu = !fRemove;
 		    break;
 
@@ -3118,9 +3081,9 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 		    /* fall through */
 		case WM_LBUTTONUP:
 		    /* Check if a menu was selected by the mouse */
-		    if (hmenu)
+		    if (menu)
 		    {
-                        executedMenuId = MENU_ButtonUp( &mt, hmenu, wFlags);
+                        executedMenuId = MENU_ButtonUp( &mt, menu, wFlags);
                         TRACE("executedMenuId %d\n", executedMenuId);
 
 			/* End the loop if executedMenuId is an item ID */
@@ -3139,8 +3102,8 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
                     /* the selected menu item must be changed every time */
 		     /* the mouse moves. */
 
-                    if (hmenu)
-			fEndMenu |= !MENU_MouseMove( &mt, hmenu, wFlags );
+                    if (menu)
+			fEndMenu |= !MENU_MouseMove( &mt, menu, wFlags );
 
 	    } /* switch(msg.message) - mouse */
 	}
@@ -3160,20 +3123,20 @@ static BOOL 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.current_menu,
 				     NO_SELECTED_ITEM, FALSE, 0 );
-		    MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu,
+		    MENU_MoveSelection( mt.hOwnerWnd, mt.current_menu,
 				       (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV );
 		    break;
 
 		case VK_UP:
 		case VK_DOWN: /* If on menu bar, pull-down the menu */
 
-		    menu = MENU_GetMenu( mt.hCurrentMenu );
+		    menu = mt.current_menu;
 		    if (!(menu->wFlags & MF_POPUP))
-			mt.hCurrentMenu = MENU_ShowSubPopup(mt.hOwnerWnd, mt.hTopMenu, TRUE, wFlags);
+			mt.current_menu = MENU_ShowSubPopup(mt.hOwnerWnd, mt.top_menu, TRUE, wFlags);
 		    else      /* otherwise try to move selection */
-			MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu, 
+			MENU_MoveSelection( mt.hOwnerWnd, mt.current_menu, 
                                        (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT );
 		    break;
 
@@ -3198,7 +3161,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 			    hi.iCtrlId = 0;
 		        else
 			    hi.iCtrlId = menu->items[menu->FocusedItem].wID;
-			hi.hItemHandle = hmenu;
+			hi.hItemHandle = MENU_GetHandle(menu);
 			hi.dwContextId = menu->dwContextHelpID;
 			hi.MousePos = msg.pt;
 			SendMessageW(hwnd, WM_HELP, 0, (LPARAM)&hi);
@@ -3217,7 +3180,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 
 		    if (msg.wParam == '\r' || msg.wParam == ' ')
 		    {
-                        executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags);
+                        executedMenuId = MENU_ExecFocusedItem(&mt,mt.current_menu, wFlags);
                         fEndMenu = (executedMenuId != -2);
 
 			break;
@@ -3227,15 +3190,15 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 		      /* We will find a better way real soon... */
 		    if (msg.wParam < 32) break;
 
-		    pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.hCurrentMenu,
+		    pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.current_menu,
                                               LOWORD(msg.wParam), FALSE );
 		    if (pos == (UINT)-2) fEndMenu = TRUE;
 		    else if (pos == (UINT)-1) MessageBeep(0);
 		    else
 		    {
-			MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu, pos,
+			MENU_SelectItem( mt.hOwnerWnd, mt.current_menu, pos,
                                 TRUE, 0 );
-                        executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags);
+                        executedMenuId = MENU_ExecFocusedItem(&mt,mt.current_menu, wFlags);
                         fEndMenu = (executedMenuId != -2);
 		    }
 		}
@@ -3261,31 +3224,29 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 
     /* If dropdown is still painted and the close box is clicked on
        then the menu will be destroyed as part of the DispatchMessage above.
-       This will then invalidate the menu handle in mt.hTopMenu. We should
+       This will then invalidate the menu handle in mt.top_menu. We should
        check for this first.  */
-    if( IsMenu( mt.hTopMenu ) )
+    if( mt.top_menu )
     {
-	menu = MENU_GetMenu( mt.hTopMenu );
-
         if( IsWindow( mt.hOwnerWnd ) )
         {
-	    MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE, wFlags );
+	    MENU_HideSubPopups( mt.hOwnerWnd, mt.top_menu, FALSE, wFlags );
 
-	    if (menu && (menu->wFlags & MF_POPUP))
+	    if (mt.top_menu && (mt.top_menu->wFlags & MF_POPUP))
 	    {
-                DestroyWindow( menu->hWnd );
-                menu->hWnd = 0;
+                DestroyWindow( mt.top_menu->hWnd );
+                mt.top_menu->hWnd = 0;
 
                 if (!(wFlags & TPM_NONOTIFY))
-                   SendMessageW( mt.hOwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.hTopMenu,
-                                 MAKELPARAM(0, IS_SYSTEM_MENU(menu)) );
+                   SendMessageW( mt.hOwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)MENU_GetHandle(mt.top_menu),
+                                 MAKELPARAM(0, IS_SYSTEM_MENU(mt.top_menu)) );
 	    }
-	    MENU_SelectItem( mt.hOwnerWnd, mt.hTopMenu, NO_SELECTED_ITEM, FALSE, 0 );
+	    MENU_SelectItem( mt.hOwnerWnd, mt.top_menu, NO_SELECTED_ITEM, FALSE, 0 );
 	    SendMessageW( mt.hOwnerWnd, WM_MENUSELECT, MAKEWPARAM(0,0xffff), 0 );
         }
 
-        /* Reset the variable for hiding menu */
-        if( menu ) menu->bTimeToHide = FALSE;
+        /* Reset the variable for hiding mt.top_menu */
+        if( mt.top_menu ) mt.top_menu->bTimeToHide = FALSE;
     }
 
     /* The return value is only used by TrackPopupMenu */
@@ -3297,15 +3258,13 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 /***********************************************************************
  *           MENU_InitTracking
  */
-static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
+static BOOL MENU_InitTracking(HWND hWnd, POPUPMENU *menu, BOOL bPopup, UINT wFlags)
 {
-    POPUPMENU *menu;
-    
-    TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
+    TRACE("hwnd=%p menu=%p\n", hWnd, menu);
 
     HideCaret(0);
 
-    if (!(menu = MENU_GetMenu( hMenu ))) return FALSE;
+    if (!menu) return FALSE;
 
     /* This makes the menus of applications built with Delphi work.
      * It also enables menus to be displayed in more than one window,
@@ -3315,7 +3274,7 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
     if (!top_popup)
     {
         top_popup = menu->hWnd;
-        top_popup_hmenu = hMenu;
+        top_popup_menu = menu;
     }
 
     fEndMenu = FALSE;
@@ -3328,7 +3287,7 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
 
     if (!(wFlags & TPM_NONOTIFY))
     {
-       SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
+       SendMessageW( hWnd, WM_INITMENU, (WPARAM)MENU_GetHandle(menu), 0 );
        /* If an app changed/recreated menu bar entries in WM_INITMENU
         * menu sizes will be recalculated once the menu created/shown.
         */
@@ -3347,7 +3306,7 @@ static BOOL MENU_ExitTracking(HWND hWnd, BOOL bPopup)
     SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
     ShowCaret(0);
     top_popup = 0;
-    top_popup_hmenu = NULL;
+    top_popup_menu = NULL;
     return TRUE;
 }
 
@@ -3366,11 +3325,11 @@ void MENU_TrackMouseMenuBar( HWND hWnd, INT ht, POINT pt )
     if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
     if (IsMenu(hMenu))
     {
-	MENU_InitTracking( hWnd, hMenu, FALSE, wFlags );
+	MENU_InitTracking( hWnd, MENU_GetMenu(hMenu), FALSE, wFlags );
 
         /* fetch the window menu again, it may have changed */
         hMenu = (ht == HTSYSMENU) ? get_win_sys_menu( hWnd ) : GetMenu( hWnd );
-	MENU_TrackMenu( hMenu, wFlags, pt.x, pt.y, hWnd, NULL );
+	MENU_TrackMenu( MENU_GetMenu(hMenu), wFlags, pt.x, pt.y, hWnd, NULL );
 	MENU_ExitTracking(hWnd, FALSE);
     }
 }
@@ -3386,6 +3345,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar)
     UINT uItem = NO_SELECTED_ITEM;
     HMENU hTrackMenu;
     UINT wFlags = TPM_LEFTALIGN | TPM_LEFTBUTTON;
+    POPUPMENU *trackmenu;
 
     TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hwnd, wParam, wChar);
 
@@ -3406,16 +3366,18 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar)
     }
     if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
 
-    if (!IsMenu( hTrackMenu )) return;
+    trackmenu = MENU_GetMenu(hTrackMenu);
+    if (!trackmenu ) return;
 
-    MENU_InitTracking( hwnd, hTrackMenu, FALSE, wFlags );
+    MENU_InitTracking( hwnd, trackmenu, FALSE, wFlags );
 
     /* fetch the window menu again, it may have changed */
     hTrackMenu = (wParam & HTSYSMENU) ? get_win_sys_menu( hwnd ) : GetMenu( hwnd );
+    trackmenu = MENU_GetMenu(hTrackMenu);
 
     if( wChar && wChar != ' ' )
     {
-        uItem = MENU_FindItemByKey( hwnd, hTrackMenu, wChar, (wParam & HTSYSMENU) );
+        uItem = MENU_FindItemByKey( hwnd, trackmenu, wChar, (wParam & HTSYSMENU) );
         if ( uItem >= (UINT)(-2) )
         {
             if( uItem == (UINT)(-1) ) MessageBeep(0);
@@ -3425,18 +3387,18 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar)
         }
     }
 
-    MENU_SelectItem( hwnd, hTrackMenu, uItem, TRUE, 0 );
+    MENU_SelectItem( hwnd, trackmenu, uItem, TRUE, 0 );
 
     if (!(wParam & HTSYSMENU) || wChar == ' ')
     {
         if( uItem == NO_SELECTED_ITEM )
-            MENU_MoveSelection( hwnd, hTrackMenu, ITEM_NEXT );
+            MENU_MoveSelection( hwnd, trackmenu, ITEM_NEXT );
         else
             PostMessageW( hwnd, WM_KEYDOWN, VK_RETURN, 0 );
     }
 
 track_menu:
-    MENU_TrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL );
+    MENU_TrackMenu( trackmenu, wFlags, 0, 0, hwnd, NULL );
     MENU_ExitTracking( hwnd, FALSE );
 }
 
@@ -3454,8 +3416,6 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
             lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" );
 
     /* Parameter check */
-    /* FIXME: this check is performed several times, here and in the called
-       functions. That could be optimized */
     if (!(menu = MENU_GetMenu( hMenu )))
     {
         SetLastError( ERROR_INVALID_MENU_HANDLE );
@@ -3468,16 +3428,16 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
         return FALSE;
     }
 
-    if (MENU_InitPopup( hWnd, hMenu, wFlags ))
+    if (MENU_InitPopup( hWnd, menu, wFlags ))
     {
-        MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
+        MENU_InitTracking(hWnd, menu, TRUE, wFlags);
 
         /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
         if (!(wFlags & TPM_NONOTIFY))
             SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
 
-        if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
-            ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
+        if (MENU_ShowPopup( hWnd, menu, 0, wFlags, x, y, 0, 0 ))
+            ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
                                   lpTpm ? &lpTpm->rcExclude : NULL );
         MENU_ExitTracking(hWnd, TRUE);
 
@@ -3553,7 +3513,7 @@ LRESULT WINAPI PopupMenuWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM
         /* zero out global pointer in case resident popup window was destroyed. */
         if (hwnd == top_popup) {
             top_popup = 0;
-            top_popup_hmenu = NULL;
+            top_popup_menu = NULL;
         }
         break;
 
@@ -3652,10 +3612,11 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UINT pos, LPCWSTR data,
  */
 DWORD WINAPI CheckMenuItem( HMENU hMenu, UINT id, UINT flags )
 {
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
     MENUITEM *item;
     DWORD ret;
 
-    if (!(item = MENU_FindItem( &hMenu, &id, flags ))) return -1;
+    if (!(item = MENU_FindItem( &menu, &id, flags ))) return -1;
     ret = item->fState & MF_CHECKED;
     if (flags & MF_CHECKED) item->fState |= MF_CHECKED;
     else item->fState &= ~MF_CHECKED;
@@ -3678,7 +3639,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
     if (!(menu = MENU_GetMenu(hMenu)))
 	return (UINT)-1;
 
-    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags )))
+    if (!(item = MENU_FindItem( &menu, &wItemID, wFlags )))
 	return (UINT)-1;
 
     oldflags = item->fState & (MF_GRAYED | MF_DISABLED);
@@ -3718,10 +3679,11 @@ INT WINAPI GetMenuStringA(
 	UINT wFlags	/* [in] MF_ flags */
 ) {
     MENUITEM *item;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
 
     TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags );
     if (str && nMaxSiz) str[0] = '\0';
-    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) {
+    if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) {
         SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
         return 0;
     }
@@ -3741,10 +3703,11 @@ INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID,
                                LPWSTR str, INT nMaxSiz, UINT wFlags )
 {
     MENUITEM *item;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
 
     TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags );
     if (str && nMaxSiz) str[0] = '\0';
-    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) {
+    if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) {
         SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
         return 0;
     }
@@ -3765,13 +3728,13 @@ INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID,
 BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
                                 UINT wHilite )
 {
-    LPPOPUPMENU menu;
+    LPPOPUPMENU menu = MENU_GetMenu(hMenu);
+    MENUITEM *item;
     TRACE("(%p, %p, %04x, %04x);\n", hWnd, hMenu, wItemID, wHilite);
-    if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE;
-    if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
+    if (!(item = MENU_FindItem( &menu, &wItemID, wHilite ))) return FALSE;
     if (menu->FocusedItem == wItemID) return TRUE;
-    MENU_HideSubPopups( hWnd, hMenu, FALSE, 0 );
-    MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 );
+    MENU_HideSubPopups( hWnd, menu, FALSE, 0 );
+    MENU_SelectItem( hWnd, menu, wItemID, TRUE, 0 );
     return TRUE;
 }
 
@@ -3781,13 +3744,14 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
  */
 UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags )
 {
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
     MENUITEM *item;
     TRACE("(menu=%p, id=%04x, flags=%04x);\n", hMenu, wItemID, wFlags);
-    if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
+    if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) return -1;
     debug_print_menuitem ("  item: ", item, "");
     if (item->fType & MF_POPUP)
     {
-	POPUPMENU *menu = MENU_GetMenu( item->hSubMenu );
+	menu = item->submenu;
 	if (!menu) return -1;
 	else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff);
     }
@@ -3819,8 +3783,9 @@ INT WINAPI GetMenuItemCount( HMENU hMenu )
 UINT WINAPI GetMenuItemID( HMENU hMenu, INT nPos )
 {
     MENUITEM * lpmi;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
 
-    if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return -1;
+    if (!(lpmi = MENU_FindItem(&menu, (UINT*)&nPos, MF_BYPOSITION))) return -1;
     if (lpmi->fType & MF_POPUP) return -1;
     return lpmi->wID;
 
@@ -3947,15 +3912,17 @@ BOOL WINAPI AppendMenuW( HMENU hMenu, UINT flags,
  */
 BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
 {
-    LPPOPUPMENU	menu;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
     MENUITEM *item;
 
     TRACE("(menu=%p pos=%04x flags=%04x)\n",hMenu, nPos, wFlags);
-    if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
-    if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
+    if (!(item = MENU_FindItem( &menu, &nPos, wFlags ))) return FALSE;
 
       /* Remove item */
 
+    if(item->fType & MF_POPUP)
+        MENU_ReleaseMenu(item->submenu);
+
     MENU_FreeItemData( item );
 
     if (--menu->nItems == 0)
@@ -3983,11 +3950,12 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
  */
 BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags )
 {
-    MENUITEM *item = MENU_FindItem( &hMenu, &nPos, wFlags );
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
+    MENUITEM *item = MENU_FindItem( &menu, &nPos, wFlags );
     if (!item) return FALSE;
-    if (item->fType & MF_POPUP) DestroyMenu( item->hSubMenu );
+    if (item->fType & MF_POPUP) DestroyMenu( MENU_GetHandle(item->submenu) );
       /* nPos is now the position of the item */
-    RemoveMenu( hMenu, nPos, wFlags | MF_BYPOSITION );
+    RemoveMenu( MENU_GetHandle(menu), nPos, wFlags | MF_BYPOSITION );
     return TRUE;
 }
 
@@ -3998,6 +3966,7 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags )
 BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
                          UINT_PTR id, LPCWSTR str )
 {
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
     MENUITEM *item;
     MENUITEMINFOW mii;
 
@@ -4006,8 +3975,8 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
     else
         TRACE("%p %d %04x %04lx %p\n", hMenu, pos, flags, id, str );
 
-    if (!(item = MENU_FindItem( &hMenu, &pos, flags ))) return FALSE;
-    MENU_GetMenu(hMenu)->Height = 0; /* force size recalculate */
+    if (!(item = MENU_FindItem( &menu, &pos, flags ))) return FALSE;
+    menu->Height = 0; /* force size recalculate */
     MENU_mnu2mnuii( flags, id, str, &mii);
     return SetMenuItemInfo_common( item, &mii, TRUE);
 }
@@ -4070,8 +4039,9 @@ BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags,
                                     HBITMAP hNewUnCheck, HBITMAP hNewCheck)
 {
     MENUITEM *item;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
 
-    if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+    if (!(item = MENU_FindItem( &menu, &nPos, wFlags ))) return FALSE;
 
     if (!hNewCheck && !hNewUnCheck)
     {
@@ -4098,6 +4068,7 @@ HMENU WINAPI CreateMenu(void)
     if (!(menu = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*menu) ))) return 0;
     menu->FocusedItem = NO_SELECTED_ITEM;
     menu->bTimeToHide = FALSE;
+    menu->refcount = 1;
 
     if (!(hMenu = alloc_user_handle( &menu->obj, USER_MENU ))) HeapFree( GetProcessHeap(), 0, menu );
 
@@ -4106,18 +4077,13 @@ HMENU WINAPI CreateMenu(void)
     return hMenu;
 }
 
-
-/**********************************************************************
- *         DestroyMenu    (USER32.@)
- */
-BOOL WINAPI DestroyMenu( HMENU hMenu )
+static BOOL MENU_ReleaseMenu( POPUPMENU *lppop )
 {
-    LPPOPUPMENU lppop;
+    LONG ref;
 
-    TRACE("(%p)\n", hMenu);
-
-    if (!(lppop = free_user_handle( hMenu, USER_MENU ))) return FALSE;
-    if (lppop == OBJ_OTHER_PROCESS) return FALSE;
+    ref = InterlockedDecrement(&lppop->refcount);
+    if(ref)
+        return TRUE;
 
     /* DestroyMenu should not destroy system menu popup owner */
     if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd)
@@ -4132,15 +4098,31 @@ BOOL WINAPI DestroyMenu( HMENU hMenu )
         MENUITEM *item = lppop->items;
         for (i = lppop->nItems; i > 0; i--, item++)
         {
-            if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu);
+            if (item->fType & MF_POPUP) MENU_ReleaseMenu(item->submenu);
             MENU_FreeItemData( item );
         }
         HeapFree( GetProcessHeap(), 0, lppop->items );
     }
     HeapFree( GetProcessHeap(), 0, lppop );
+
     return TRUE;
 }
 
+/**********************************************************************
+ *         DestroyMenu    (USER32.@)
+ */
+BOOL WINAPI DestroyMenu( HMENU hMenu )
+{
+    POPUPMENU *lppop;
+
+    TRACE("(%p)\n", hMenu);
+
+    if (!(lppop = free_user_handle( hMenu, USER_MENU ))) return FALSE;
+    if (lppop == OBJ_OTHER_PROCESS) return FALSE;
+
+    return MENU_ReleaseMenu(lppop);
+}
+
 
 /**********************************************************************
  *         GetSystemMenu    (USER32.@)
@@ -4279,13 +4261,13 @@ BOOL WINAPI GetMenuBarInfo( HWND hwnd, LONG idObject, LONG idItem, PMENUBARINFO
 
     pmbi->hMenu = hmenu;
     pmbi->hwndMenu = NULL;
-    pmbi->fBarFocused = top_popup_hmenu == hmenu;
+    pmbi->fBarFocused = (top_popup_menu == menu);
     if (idItem)
     {
         pmbi->fFocused = menu->FocusedItem == idItem - 1;
         if (pmbi->fFocused && (menu->items[idItem - 1].fType & MF_POPUP))
         {
-            menu = MENU_GetMenu(menu->items[idItem - 1].hSubMenu);
+            menu = menu->items[idItem - 1].submenu;
             if (menu)
                 pmbi->hwndMenu = menu->hWnd;
         }
@@ -4354,10 +4336,11 @@ BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
 HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos )
 {
     MENUITEM * lpmi;
+    POPUPMENU *menu = MENU_GetMenu(hMenu);
 
-    if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return 0;
+    if (!(lpmi = MENU_FindItem(&menu, (UINT*)&nPos, MF_BYPOSITION))) return 0;
     if (!(lpmi->fType & MF_POPUP)) return 0;
-    return lpmi->hSubMenu;
+    return MENU_GetHandle(lpmi->submenu);
 }
 
 
@@ -4435,7 +4418,7 @@ DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFO
 
     for (i = 0; i < lppop->nItems; i++)
     {
-        MENU_DrawMenuItem( hwnd, hMenu, hwnd,
+        MENU_DrawMenuItem( hwnd, lppop, hwnd,
                            hDC, &lppop->items[i], lppop->Height, TRUE, ODA_DRAWENTIRE );
     }
     retvalue = lppop->Height;
@@ -4561,7 +4544,8 @@ BOOL WINAPI IsMenu(HMENU hmenu)
 static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
 					LPMENUITEMINFOW lpmii, BOOL unicode)
 {
-    MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos ? MF_BYPOSITION : 0);
+    POPUPMENU *popup = MENU_GetMenu(hmenu);
+    MENUITEM *menu = MENU_FindItem (&popup, &item, bypos ? MF_BYPOSITION : 0);
 
     debug_print_menuitem("GetMenuItemInfo_common: ", menu, "");
 
@@ -4644,7 +4628,7 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos,
 	lpmii->wID = menu->wID;
 
     if (lpmii->fMask & MIIM_SUBMENU)
-	lpmii->hSubMenu = menu->hSubMenu;
+        lpmii->hSubMenu = MENU_GetHandle(menu->submenu);
     else {
         /* hSubMenu is always cleared 
          * (not on Win9x/ME ) */
@@ -4741,13 +4725,12 @@ static int MENU_depth( POPUPMENU *pmenu, int depth)
     item = pmenu->items;
     subdepth = depth;
     for( i = 0; i < pmenu->nItems && subdepth <= MAXMENUDEPTH; i++, item++){
-        POPUPMENU *psubmenu =  item->hSubMenu ? MENU_GetMenu( item->hSubMenu) : NULL;
-        if( psubmenu){
-            int bdepth = MENU_depth( psubmenu, depth);
+        if( item->submenu){
+            int bdepth = MENU_depth( item->submenu, depth);
             if( bdepth > subdepth) subdepth = bdepth;
         }
         if( subdepth > MAXMENUDEPTH)
-            TRACE("<- hmenu %p\n", item->hSubMenu);
+            TRACE("<- menu %p\n", item->submenu);
     }
     return subdepth;
 }
@@ -4787,24 +4770,29 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu,
 	menu->wID = lpmii->wID;
 
     if (lpmii->fMask & MIIM_SUBMENU) {
-	menu->hSubMenu = lpmii->hSubMenu;
-	if (menu->hSubMenu) {
-	    POPUPMENU *subMenu = MENU_GetMenu(menu->hSubMenu);
-	    if (subMenu) {
-                if( MENU_depth( subMenu, 0) > MAXMENUDEPTH) {
+        if(menu->fType & MF_POPUP){
+            if(menu->submenu)
+                InterlockedDecrement(&menu->submenu->refcount);
+        }
+
+        if (lpmii->hSubMenu) {
+            menu->submenu = MENU_GetMenu(lpmii->hSubMenu);
+            if (menu->submenu) {
+                if( MENU_depth( menu->submenu, 0) > MAXMENUDEPTH) {
                     ERR( "Loop detected in menu hierarchy or maximum menu depth exceeded!\n");
-                    menu->hSubMenu = 0;
+                    menu->submenu = NULL;
                     return FALSE;
                 }
-		subMenu->wFlags |= MF_POPUP;
-		menu->fType |= MF_POPUP;
-	    } else {
+                menu->submenu->wFlags |= MF_POPUP;
+                menu->fType |= MF_POPUP;
+                InterlockedIncrement(&menu->submenu->refcount);
+            } else {
                 SetLastError( ERROR_INVALID_PARAMETER);
                 return FALSE;
             }
-	}
-	else
-	    menu->fType &= ~MF_POPUP;
+        }
+        else
+            menu->fType &= ~MF_POPUP;
     }
 
     if (lpmii->fMask & MIIM_CHECKMARKS)
@@ -4876,12 +4864,13 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
                                  const MENUITEMINFOA *lpmii)
 {
     MENUITEMINFOW mii;
+    POPUPMENU *menu = MENU_GetMenu(hmenu);
 
     TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
 
     if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE;
 
-    return SetMenuItemInfo_common(MENU_FindItem(&hmenu, &item, bypos? MF_BYPOSITION : 0),
+    return SetMenuItemInfo_common(MENU_FindItem(&menu, &item, bypos? MF_BYPOSITION : 0),
                                   &mii, FALSE);
 }
 
@@ -4892,11 +4881,12 @@ BOOL WINAPI SetMenuItemInfoW(HMENU hmenu, UINT item, BOOL bypos,
                                  const MENUITEMINFOW *lpmii)
 {
     MENUITEMINFOW mii;
+    POPUPMENU *menu = MENU_GetMenu(hmenu);
 
     TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
 
     if (!MENU_NormalizeMenuItemInfoStruct( lpmii, &mii )) return FALSE;
-    return SetMenuItemInfo_common(MENU_FindItem(&hmenu,
+    return SetMenuItemInfo_common(MENU_FindItem(&menu,
                 &item, bypos? MF_BYPOSITION : 0), &mii, TRUE);
 }
 
@@ -4977,11 +4967,11 @@ UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags)
 	/* default: don't return disabled items */
 	if ( (!(GMDI_USEDISABLED & flags)) && (item->fState & MFS_DISABLED )) return -1;
 
-	/* search rekursiv when needed */
+	/* search recursively when needed */
 	if ( (item->fType & MF_POPUP) &&  (flags & GMDI_GOINTOPOPUPS) )
 	{
 	    UINT ret;
-	    ret = GetMenuDefaultItem( item->hSubMenu, bypos, flags );
+	    ret = GetMenuDefaultItem( MENU_GetHandle(item->submenu), bypos, flags );
 	    if ( -1 != ret ) return ret;
 
 	    /* when item not found in submenu, return the popup item */
@@ -5037,7 +5027,7 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
     BOOL done = FALSE;
     UINT i;
     MENUITEM *mi_first = NULL, *mi_check;
-    HMENU m_first, m_check;
+    POPUPMENU *m_first, *m_check;
 
     for (i = first; i <= last; i++)
     {
@@ -5045,7 +5035,7 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
 
         if (!mi_first)
         {
-            m_first = hMenu;
+            m_first = MENU_GetMenu(hMenu);
             mi_first = MENU_FindItem(&m_first, &pos, bypos);
             if (!mi_first) continue;
             mi_check = mi_first;
@@ -5053,7 +5043,7 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
         }
         else
         {
-            m_check = hMenu;
+            m_check = MENU_GetMenu(hMenu);
             mi_check = MENU_FindItem(&m_check, &pos, bypos);
             if (!mi_check) continue;
         }
@@ -5089,18 +5079,17 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
 BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
 				 LPRECT rect)
 {
-     POPUPMENU *itemMenu;
+     POPUPMENU *itemMenu = MENU_GetMenu(hMenu);
      MENUITEM *item;
      HWND referenceHwnd;
 
      TRACE("(%p,%p,%d,%p)\n", hwnd, hMenu, uItem, rect);
 
-     item = MENU_FindItem (&hMenu, &uItem, MF_BYPOSITION);
+     item = MENU_FindItem (&itemMenu, &uItem, MF_BYPOSITION);
      referenceHwnd = hwnd;
 
      if(!hwnd)
      {
-	 itemMenu = MENU_GetMenu(hMenu);
 	 if (itemMenu == NULL)
 	     return FALSE;
 
@@ -5126,10 +5115,9 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem,
  *	actually use the items to draw the menu
  *      (recalculate and/or redraw)
  */
-static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi)
+static BOOL menu_SetMenuInfo( POPUPMENU *menu, LPCMENUINFO lpmi)
 {
-    POPUPMENU *menu;
-    if( !(menu = MENU_GetMenu(hMenu))) return FALSE;
+    if( !menu ) return FALSE;
 
     if (lpmi->fMask & MIM_BACKGROUND)
         menu->hbrBack = lpmi->hbrBack;
@@ -5151,7 +5139,7 @@ static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi)
         MENUITEM *item = menu->items;
         for( i = menu->nItems; i; i--, item++)
             if( item->fType & MF_POPUP)
-                menu_SetMenuInfo( item->hSubMenu, lpmi);
+                menu_SetMenuInfo( item->submenu, lpmi);
     }
     return TRUE;
 }
@@ -5159,7 +5147,7 @@ static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi)
 BOOL WINAPI SetMenuInfo (HMENU hMenu, LPCMENUINFO lpmi)
 {
     TRACE("(%p %p)\n", hMenu, lpmi);
-    if( lpmi && (lpmi->cbSize == sizeof( MENUINFO)) && (menu_SetMenuInfo( hMenu, lpmi))) {
+    if( lpmi && (lpmi->cbSize == sizeof( MENUINFO)) && (menu_SetMenuInfo( MENU_GetMenu(hMenu), lpmi))) {
 	if( lpmi->fMask & MIM_STYLE) {
 	    if (lpmi->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented\n");
 	    if (lpmi->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented\n");
@@ -5309,17 +5297,20 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
         mesg = 1;
     else
     {
-        HMENU hMenu, hSubMenu, hSysMenu;
+        HMENU hMenu, hSysMenu;
+        POPUPMENU *menu, *subMenu, *sysMenu;
         UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
 
         hMenu = (GetWindowLongW( hWnd, GWL_STYLE ) & WS_CHILD) ? 0 : GetMenu(hWnd);
+        menu = MENU_GetMenu(hMenu);
         hSysMenu = get_win_sys_menu( hWnd );
+        sysMenu = MENU_GetMenu(hSysMenu);
 
         /* find menu item and ask application to initialize it */
         /* 1. in the system menu */
-        hSubMenu = hSysMenu;
+        subMenu = sysMenu;
         nPos = cmd;
-        if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
+        if(MENU_FindItem(&subMenu, &nPos, MF_BYCOMMAND))
         {
             if (GetCapture())
                 mesg = 2;
@@ -5328,20 +5319,20 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
             else
             {
                 SendMessageW(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L);
-                if(hSubMenu != hSysMenu)
+                if(subMenu != sysMenu)
                 {
-                    nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu);
-                    TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos);
-                    SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE));
+                    nPos = MENU_FindSubMenu(&sysMenu, subMenu);
+                    TRACE_(accel)("sysMenu = %p, subMenu = %p, nPos = %d\n", sysMenu, subMenu, nPos);
+                    SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)MENU_GetHandle(subMenu), MAKELPARAM(nPos, TRUE));
                 }
                 uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND);
             }
         }
         else /* 2. in the window's menu */
         {
-            hSubMenu = hMenu;
+            subMenu = menu;
             nPos = cmd;
-            if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND))
+            if(MENU_FindItem(&subMenu, &nPos, MF_BYCOMMAND))
             {
                 if (GetCapture())
                     mesg = 2;
@@ -5350,11 +5341,12 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA
                 else
                 {
                     SendMessageW(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L);
-                    if(hSubMenu != hMenu)
+                    if(subMenu != menu)
                     {
-                        nPos = MENU_FindSubMenu(&hMenu, hSubMenu);
-                        TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos);
-                        SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE));
+                        nPos = MENU_FindSubMenu(&menu, subMenu);
+                        hMenu = MENU_GetHandle(menu);
+                        TRACE_(accel)("hMenu = %p, subMenu = %p, nPos = %d\n", hMenu, subMenu, nPos);
+                        SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)MENU_GetHandle(subMenu), MAKELPARAM(nPos, FALSE));
                     }
                     uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND);
                 }
diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c
index 593292d..9cf8af6 100644
--- a/dlls/user32/tests/menu.c
+++ b/dlls/user32/tests/menu.c
@@ -526,9 +526,7 @@ static void test_subpopup_locked_by_menu(void)
         SetLastError( 0xdeadbeef);
         ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
         gle = GetLastError();
-        todo_wine {
-            ok( ret == itemid , "TrackPopupMenu returned %d error is %d\n", ret, gle);
-        }
+        ok( ret == itemid , "TrackPopupMenu returned %d error is %d\n", ret, gle);
         ok( gle == 0 ||
             broken(gle == 0xdeadbeef) || /* wow64 */
             broken(gle == ERROR_INVALID_PARAMETER), /* win2k0 */
-- 
1.9.2




More information about the wine-patches mailing list