[PATCH 3/3] user32: Avoid HMENU internally for showing popups

Andrew Eikum aeikum at codeweavers.com
Fri Sep 12 10:46:21 CDT 2014


This is the first in a series of about 7 patches which removes
needless pointer->HMENU->pointer conversions.
---
 dlls/user32/menu.c | 141 ++++++++++++++++++++++++-----------------------------
 1 file changed, 63 insertions(+), 78 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 969c441..6002e24 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -1436,14 +1436,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, "");
@@ -1459,7 +1458,6 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
     {
 	if( !IsIconic(hwnd) )
 	    NC_DrawSysButton( hwnd, hdc, lpitem->fState & (MF_HILITE | MF_MOUSESELECT) );
-	MENU_ReleaseMenu(menu);
 	return;
     }
 
@@ -1516,7 +1514,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, "
@@ -1528,14 +1526,11 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         if (lpitem->fType & MF_POPUP)
             draw_popup_arrow( hdc, rect, arrow_bitmap_width,
                     arrow_bitmap_height);
-        MENU_ReleaseMenu(menu);
         return;
     }
 
-    if (menuBar && (lpitem->fType & MF_SEPARATOR)) {
-        MENU_ReleaseMenu(menu);
+    if (menuBar && (lpitem->fType & MF_SEPARATOR))
         return;
-    }
 
     if (lpitem->fState & MF_HILITE)
     {
@@ -1597,7 +1592,6 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
         }
         else
             DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
-        MENU_ReleaseMenu(menu);
         return;
     }
 
@@ -1683,7 +1677,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_GetHandle(menu), hwndOwner,
                     odaction, FALSE);
             SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
         }
@@ -1701,7 +1695,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_GetHandle(menu), hwndOwner,
                 odaction, menuBar);
         SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
     }
@@ -1780,8 +1774,6 @@ static void MENU_DrawMenuItem( HWND hwnd, HMENU hmenu, HWND hwndOwner, HDC hdc,
 	if (hfontOld)
 	    SelectObject (hdc, hfontOld);
     }
-
-    MENU_ReleaseMenu(menu);
 }
 
 
@@ -1829,7 +1821,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 */
@@ -1868,20 +1860,18 @@ 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 hmenu=%p\n", hwndOwner, MENU_GetHandle(menu));
 
-    if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+    if (!menu) return FALSE;
 
     /* store the owner for DrawItem */
     if (!IsWindow( hwndOwner ))
     {
         SetLastError( ERROR_INVALID_WINDOW_HANDLE );
-        MENU_ReleaseMenu(menu);
         return FALSE;
     }
     menu->hwndOwner = hwndOwner;
@@ -1893,13 +1883,10 @@ 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 );
-    if( !menu->hWnd ) {
-        MENU_ReleaseMenu(menu);
+                                (LPVOID)MENU_GetHandle(menu) );
+    if( !menu->hWnd )
         return FALSE;
-    }
 
-    MENU_ReleaseMenu(menu);
     return TRUE;
 }
 
@@ -1909,19 +1896,18 @@ 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);
+          hwndOwner, MENU_GetHandle(menu), id, x, y, xanchor, yanchor);
 
-    if (!(menu = MENU_GetMenu( hmenu ))) return FALSE;
+    if (!menu) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
     {
 	menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
@@ -1974,14 +1960,13 @@ 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_hmenu = MENU_GetHandle(menu);
     }
     /* Display the window */
 
     SetWindowPos( menu->hWnd, HWND_TOPMOST, x, y, width, height,
                   SWP_SHOWWINDOW | SWP_NOACTIVATE );
     UpdateWindow( menu->hWnd );
-    MENU_ReleaseMenu(menu);
     return TRUE;
 }
 
@@ -2060,7 +2045,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 );
     }
@@ -2072,7 +2057,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 );
         }
@@ -2358,50 +2343,40 @@ 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 hmenu=%p 0x%04x\n", hwndOwner, MENU_GetHandle(menu), sendMenuSelect);
 
     if (!menu)
         return;
 
     if (top_popup)
     {
-	HMENU hsubmenu;
-	POPUPMENU *submenu;
-	MENUITEM *item;
+        HMENU hsubmenu;
+        MENUITEM *item;
 
-	if (menu->FocusedItem != NO_SELECTED_ITEM)
-	{
-	    item = &menu->items[menu->FocusedItem];
-	    if (!(item->fType & MF_POPUP) ||
-		!(item->fState & MF_MOUSESELECT)) return;
-	    item->fState &= ~MF_MOUSESELECT;
-	    submenu = item->submenu;
-	    hsubmenu = MENU_GetHandle(item->submenu);
-	} else {
-	    MENU_ReleaseMenu(menu);
-	    return;
-	}
+        if (menu->FocusedItem == NO_SELECTED_ITEM)
+            return;
 
-	if (!submenu) {
-	    MENU_ReleaseMenu(menu);
-	    return;
-	}
-	MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE, wFlags );
-	MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
-        DestroyWindow( submenu->hWnd );
-        submenu->hWnd = 0;
+        item = &menu->items[menu->FocusedItem];
+        if (!(item->fType & MF_POPUP) ||
+            !(item->fState & MF_MOUSESELECT)) return;
+        item->fState &= ~MF_MOUSESELECT;
+        if (!item->submenu)
+            return;
+        hsubmenu = MENU_GetHandle(item->submenu);
+
+        MENU_HideSubPopups( hwndOwner, item->submenu, FALSE, wFlags );
+        MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 );
+        DestroyWindow( item->submenu->hWnd );
+        item->submenu->hWnd = 0;
 
         if (!(wFlags & TPM_NONOTIFY))
            SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)hsubmenu,
-                         MAKELPARAM(0, IS_SYSTEM_MENU(submenu)) );
+                         MAKELPARAM(0, IS_SYSTEM_MENU(item->submenu)) );
     }
-
-    MENU_ReleaseMenu(menu);
 }
 
 
@@ -2454,7 +2429,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)
@@ -2509,9 +2484,9 @@ 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, MENU_GetHandle(item->submenu), wFlags );
+    MENU_InitPopup( hwndOwner, item->submenu, wFlags );
 
-    MENU_ShowPopup( hwndOwner, MENU_GetHandle(item->submenu), menu->FocusedItem, wFlags,
+    MENU_ShowPopup( hwndOwner, item->submenu, menu->FocusedItem, wFlags,
 		    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
         MENU_MoveSelection( hwndOwner, MENU_GetHandle(item->submenu), ITEM_NEXT );
@@ -2663,11 +2638,11 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFl
 	!((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) )
     {
 	/* both are top level menus (system and menu-bar) */
-	MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+	MENU_HideSubPopups( pmt->hOwnerWnd, topmenu, FALSE, wFlags );
 	MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 );
         pmt->hTopMenu = hPtMenu;
     }
-    else MENU_HideSubPopups( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags );
+    else MENU_HideSubPopups( pmt->hOwnerWnd, ptmenu, FALSE, wFlags );
     MENU_SelectItem( pmt->hOwnerWnd, hPtMenu, id, TRUE, 0 );
     MENU_ReleaseMenu(ptmenu);
     MENU_ReleaseMenu(topmenu);
@@ -2929,9 +2904,12 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
 	if( hNewMenu != pmt->hTopMenu )
 	{
 	    MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM,
-                    FALSE, 0 );
-	    if( pmt->hCurrentMenu != pmt->hTopMenu )
-		MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+		    FALSE, 0 );
+	    if( pmt->hCurrentMenu != pmt->hTopMenu ) {
+		POPUPMENU *topmenu = MENU_GetMenu(pmt->hTopMenu);
+		MENU_HideSubPopups( pmt->hOwnerWnd, topmenu, FALSE, wFlags );
+		MENU_ReleaseMenu(topmenu);
+	    }
 	}
 
 	if( hNewWnd != pmt->hOwnerWnd )
@@ -3002,6 +2980,7 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
         if (menu->wFlags & MF_POPUP)
         {
             HMENU hmenutmp, hmenuprev;
+            POPUPMENU *menuprev;
 
             hmenuprev = hmenutmp = pmt->hTopMenu;
 
@@ -3012,7 +2991,9 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
                 hmenutmp = MENU_GetSubPopup( hmenuprev );
             }
 
-            MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
+            menuprev = MENU_GetMenu(hmenuprev);
+            MENU_HideSubPopups( pmt->hOwnerWnd, menuprev, TRUE, wFlags );
+            MENU_ReleaseMenu(menuprev);
             pmt->hCurrentMenu = hmenuprev;
             bEndMenu = FALSE;
         }
@@ -3029,7 +3010,7 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
  */
 static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
 {
-    POPUPMENU *menu;
+    POPUPMENU *menu, *menuprev;
     HMENU hmenutmp, hmenuprev;
     UINT  prevcol;
 
@@ -3053,7 +3034,9 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
 	hmenutmp = MENU_GetSubPopup( hmenuprev );
     }
 
-    MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
+    menuprev = MENU_GetMenu(hmenuprev);
+    MENU_HideSubPopups( pmt->hOwnerWnd, menuprev, TRUE, wFlags );
+    MENU_ReleaseMenu(menuprev);
     pmt->hCurrentMenu = hmenuprev;
 
     if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) )
@@ -3125,7 +3108,9 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags )
     {
 	if( pmt->hCurrentMenu != pmt->hTopMenu )
 	{
-	    MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+	    POPUPMENU *topmenu = MENU_GetMenu( pmt->hTopMenu);
+	    MENU_HideSubPopups( pmt->hOwnerWnd, topmenu, FALSE, wFlags );
+	    MENU_ReleaseMenu(topmenu);
 	    hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu;
 	} else hmenutmp = 0;
 
@@ -3429,7 +3414,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
 
         if( IsWindow( mt.hOwnerWnd ) )
         {
-	    MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE, wFlags );
+	    MENU_HideSubPopups( mt.hOwnerWnd, menu, FALSE, wFlags );
 
 	    if (menu && (menu->wFlags & MF_POPUP))
 	    {
@@ -3633,7 +3618,7 @@ 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);
 
@@ -3641,7 +3626,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
         if (!(wFlags & TPM_NONOTIFY))
             SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
 
-        if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
+        if (MENU_ShowPopup( hWnd, menu, 0, wFlags, x, y, 0, 0 ))
             ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
                                   lpTpm ? &lpTpm->rcExclude : NULL );
         MENU_ExitTracking(hWnd, TRUE);
@@ -3943,7 +3928,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
         MENU_ReleaseMenu(menu);
         return TRUE;
     }
-    MENU_HideSubPopups( hWnd, hMenu, FALSE, 0 );
+    MENU_HideSubPopups( hWnd, menu, FALSE, 0 );
     MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 );
     MENU_ReleaseMenu(menu);
     return TRUE;
@@ -4656,7 +4641,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;
-- 
2.1.0




More information about the wine-patches mailing list