[PATCH 3/3] user32: Don't rely on HMENU for showing popups

Andrew Eikum aeikum at codeweavers.com
Fri May 16 10:55:18 CDT 2014


The idea here is to push the conversions from HMENU to struct pointer
up the call stack until eventually we are only converting to/from
HMENUs near the client code border, so we don't depend on HMENU
internally at all.

This is the first in a sequence of about 8 patches converting HMENUs
to raw pointers.

---
 dlls/user32/menu.c | 85 +++++++++++++++++++++++++++---------------------------
 1 file changed, 42 insertions(+), 43 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 6f064de..851e40d 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -195,6 +195,10 @@ const struct builtin_class_descr MENU_builtin_class =
     (HBRUSH)(COLOR_MENU+1)         /* brush */
 };
 
+static HMENU MENU_GetHandle(const POPUPMENU *menu)
+{
+    return menu ? menu->obj.handle : NULL;
+}
 
 /***********************************************************************
  *           debug_print_menuitem
@@ -1391,14 +1395,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, "");
@@ -1446,7 +1449,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)
     {
@@ -1470,7 +1473,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, "
@@ -1632,7 +1635,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);
         }
@@ -1650,7 +1653,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);
     }
@@ -1776,7 +1779,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 */
@@ -1816,14 +1819,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 ))
@@ -1840,7 +1842,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;
 }
@@ -1851,19 +1853,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);
+    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)
     {
 	menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT);
@@ -1916,7 +1917,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_hmenu = MENU_GetHandle(menu);
     }
     /* Display the window */
 
@@ -1996,7 +1997,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 );
     }
@@ -2008,7 +2009,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 );
         }
@@ -2264,16 +2265,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;
 
@@ -2283,17 +2282,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 = MENU_GetMenu(item->hSubMenu);
 	} 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, MENU_GetHandle(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)) );
     }
 }
@@ -2343,7 +2342,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)
@@ -2398,9 +2397,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, item->hSubMenu, wFlags );
+    MENU_InitPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), wFlags );
 
-    MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, wFlags,
+    MENU_ShowPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), menu->FocusedItem, wFlags,
 		    rect.left, rect.top, rect.right, rect.bottom );
     if (selectFirst)
         MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
@@ -2538,11 +2537,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, MENU_GetMenu(pmt->hTopMenu), 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 );
 }
 
@@ -2781,7 +2780,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
 	    MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM,
                     FALSE, 0 );
 	    if( pmt->hCurrentMenu != pmt->hTopMenu )
-		MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+		MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags );
 	}
 
 	if( hNewWnd != pmt->hOwnerWnd )
@@ -2862,7 +2861,7 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags)
                 hmenutmp = MENU_GetSubPopup( hmenuprev );
             }
 
-            MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
+            MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags );
             pmt->hCurrentMenu = hmenuprev;
             bEndMenu = FALSE;
         }
@@ -2901,7 +2900,7 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags )
 	hmenutmp = MENU_GetSubPopup( hmenuprev );
     }
 
-    MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags );
+    MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags );
     pmt->hCurrentMenu = hmenuprev;
 
     if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) )
@@ -2964,7 +2963,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags )
     {
 	if( pmt->hCurrentMenu != pmt->hTopMenu )
 	{
-	    MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags );
+	    MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags );
 	    hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu;
 	} else hmenutmp = 0;
 
@@ -3264,7 +3263,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))
 	    {
@@ -3463,7 +3462,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);
 
@@ -3471,7 +3470,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_GetMenu(hMenu), 0, wFlags, x, y, 0, 0 ))
             ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
                                   lpTpm ? &lpTpm->rcExclude : NULL );
         MENU_ExitTracking(hWnd, TRUE);
@@ -3760,7 +3759,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID,
     if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE;
     if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
     if (menu->FocusedItem == wItemID) return TRUE;
-    MENU_HideSubPopups( hWnd, hMenu, FALSE, 0 );
+    MENU_HideSubPopups( hWnd, menu, FALSE, 0 );
     MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 );
     return TRUE;
 }
@@ -4450,7 +4449,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;
-- 
1.9.2




More information about the wine-patches mailing list