[PATCH 3/3] user32: Use NtUserThunkedMenuItemInfo for GetSubMenu implementation.

Jacek Caban wine at gitlab.winehq.org
Fri Jun 24 07:31:52 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

---
 dlls/user32/menu.c | 104 ++-------------------------------------------
 dlls/win32u/menu.c |  41 +++++++++---------
 include/ntuser.h   |   1 +
 3 files changed, 26 insertions(+), 120 deletions(-)

diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 043af437356..6fb381ea617 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -115,32 +115,6 @@ static POPUPMENU *MENU_GetMenu(HMENU hMenu)
     return menu;
 }
 
-static POPUPMENU *grab_menu_ptr(HMENU hMenu)
-{
-    POPUPMENU *menu = get_user_handle_ptr( hMenu, NTUSER_OBJ_MENU );
-
-    if (menu == OBJ_OTHER_PROCESS)
-    {
-        WARN("other process menu %p?\n", hMenu);
-        return NULL;
-    }
-
-    if (menu)
-        menu->refcount++;
-    else
-        WARN("invalid menu handle=%p\n", hMenu);
-    return menu;
-}
-
-static void release_menu_ptr(POPUPMENU *menu)
-{
-    if (menu)
-    {
-        menu->refcount--;
-        release_user_handle_ptr(menu);
-    }
-}
-
 /***********************************************************************
  *           MENU_CopySysPopup
  *
@@ -232,66 +206,6 @@ HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu )
 }
 
 
-static POPUPMENU *find_menu_item(HMENU hmenu, UINT id, UINT flags, UINT *pos)
-{
-    UINT fallback_pos = ~0u, i;
-    POPUPMENU *menu;
-
-    menu = grab_menu_ptr(hmenu);
-    if (!menu)
-        return NULL;
-
-    if (flags & MF_BYPOSITION)
-    {
-        if (id >= menu->nItems)
-        {
-            release_menu_ptr(menu);
-            return NULL;
-        }
-
-        if (pos) *pos = id;
-        return menu;
-    }
-    else
-    {
-        MENUITEM *item = menu->items;
-	for (i = 0; i < menu->nItems; i++, item++)
-	{
-	    if (item->fType & MF_POPUP)
-	    {
-                POPUPMENU *submenu = find_menu_item(item->hSubMenu, id, flags, pos);
-
-                if (submenu)
-                {
-                    release_menu_ptr(menu);
-                    return submenu;
-                }
-                else if (item->wID == id)
-		{
-		    /* fallback to this item if nothing else found */
-		    fallback_pos = i;
-		}
-	    }
-	    else if (item->wID == id)
-	    {
-                if (pos) *pos = i;
-                return menu;
-	    }
-	}
-    }
-
-    if (fallback_pos != ~0u)
-        *pos = fallback_pos;
-    else
-    {
-        release_menu_ptr(menu);
-        menu = NULL;
-    }
-
-    return menu;
-}
-
-
 /**********************************************************************
  *         MENU_ParseResource
  *
@@ -755,22 +669,10 @@ HMENU WINAPI GetMenu( HWND hWnd )
 /**********************************************************************
  *         GetSubMenu    (USER32.@)
  */
-HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos )
+HMENU WINAPI GetSubMenu( HMENU menu, INT pos )
 {
-    POPUPMENU *menu;
-    HMENU submenu;
-    UINT pos;
-
-    if (!(menu = find_menu_item(hMenu, nPos, MF_BYPOSITION, &pos)))
-        return 0;
-
-    if (menu->items[pos].fType & MF_POPUP)
-        submenu = menu->items[pos].hSubMenu;
-    else
-        submenu = 0;
-
-    release_menu_ptr(menu);
-    return submenu;
+    UINT ret = NtUserThunkedMenuItemInfo( menu, pos, MF_BYPOSITION, NtUserGetSubMenu, NULL, NULL );
+    return UlongToHandle( ret );
 }
 
 
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c
index 4ba5b42ec9d..598576437c6 100644
--- a/dlls/win32u/menu.c
+++ b/dlls/win32u/menu.c
@@ -1151,6 +1151,25 @@ static BOOL check_menu_radio_item( HMENU handle, UINT first, UINT last, UINT che
     return done;
 }
 
+/* see GetSubMenu */
+static HMENU get_sub_menu( HMENU handle, INT pos )
+{
+    POPUPMENU *menu;
+    HMENU submenu;
+    UINT i;
+
+    if (!(menu = find_menu_item( handle, pos, MF_BYPOSITION, &i )))
+        return 0;
+
+    if (menu->items[i].fType & MF_POPUP)
+        submenu = menu->items[i].hSubMenu;
+    else
+        submenu = 0;
+
+    release_menu_ptr(menu);
+    return submenu;
+}
+
 /**********************************************************************
  *           NtUserThunkedMenuItemInfo    (win32u.@)
  */
@@ -1178,6 +1197,9 @@ UINT WINAPI NtUserThunkedMenuItemInfo( HMENU handle, UINT pos, UINT flags, UINT
     case NtUserGetMenuItemInfoW:
         return get_menu_item_info( handle, pos, flags, info, FALSE );
 
+    case NtUserGetSubMenu:
+        return HandleToUlong( get_sub_menu( handle, pos ));
+
     case NtUserInsertMenuItem:
         if (!info || info->cbSize != sizeof(*info))
         {
@@ -1314,25 +1336,6 @@ BOOL WINAPI NtUserSetMenuContextHelpId( HMENU handle, DWORD id )
     return TRUE;
 }
 
-/* see GetSubMenu */
-static HMENU get_sub_menu( HMENU handle, INT pos )
-{
-    POPUPMENU *menu;
-    HMENU submenu;
-    UINT i;
-
-    if (!(menu = find_menu_item( handle, pos, MF_BYPOSITION, &i )))
-        return 0;
-
-    if (menu->items[i].fType & MF_POPUP)
-        submenu = menu->items[i].hSubMenu;
-    else
-        submenu = 0;
-
-    release_menu_ptr(menu);
-    return submenu;
-}
-
 /**********************************************************************
  *           NtUserMenuItemFromPoint    (win32u.@)
  */
diff --git a/include/ntuser.h b/include/ntuser.h
index e15345bb7d6..bf4e9f4b13a 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -229,6 +229,7 @@ enum
     NtUserGetMenuItemInfoA,
     NtUserGetMenuItemInfoW,
     NtUserGetMenuState,
+    NtUserGetSubMenu,
 };
 
 struct send_message_timeout_params
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/311



More information about the wine-devel mailing list