Find Popup Menus by ID (2nd try)

Michael Kaufmann hallo at michael-kaufmann.ch
Tue Apr 18 09:35:51 CDT 2006


2nd try: Don't remove the "é" in the copyright header.

This fixes the menu of PE Explorer.

Changelog:
- Find menus by ID: Proper fallback to popup menus
- Use the menu ID, not the handle for the fallback
- Save the fallback menu's position
-------------- next part --------------
Index: dlls/user/menu.c
===================================================================
RCS file: /home/wine/wine/dlls/user/menu.c,v
retrieving revision 1.59
diff -u -r1.59 menu.c
--- dlls/user/menu.c	13 Apr 2006 10:18:13 -0000	1.59
+++ dlls/user/menu.c	18 Apr 2006 14:25:58 -0000
@@ -580,6 +580,7 @@
 {
     POPUPMENU *menu;
     MENUITEM *fallback = NULL;
+    UINT fallback_pos = 0;
     UINT i;
 
     if ((*hmenu == (HMENU)0xffff) || (!(menu = MENU_GetMenu(*hmenu)))) return NULL;
@@ -602,8 +603,12 @@
 		    *hmenu = hsubmenu;
 		    return subitem;
 		}
-		if ((UINT_PTR)item->hSubMenu == *nPos)
-		    fallback = item; /* fallback to this item if nothing else found */
+		else if (item->wID == *nPos)
+		{
+		    /* fallback to this item if nothing else found */
+		    fallback_pos = i;
+		    fallback = item;
+		}
 	    }
 	    else if (item->wID == *nPos)
 	    {
@@ -612,6 +617,10 @@
 	    }
 	}
     }
+
+    if (fallback)
+        *nPos = fallback_pos;
+
     return fallback;
 }
 
Index: dlls/user/tests/menu.c
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/menu.c,v
retrieving revision 1.19
diff -u -r1.19 menu.c
--- dlls/user/tests/menu.c	10 Apr 2006 18:49:40 -0000	1.19
+++ dlls/user/tests/menu.c	18 Apr 2006 14:26:00 -0000
@@ -1410,6 +1410,69 @@
     ok (rc, "Getting the menus info failed\n");
     ok (info.wID == (UINT)hmenuSub2, "IDs differ for popup menu\n");
     ok (!strcmp(info.dwTypeData, "Submenu2"), "Returned item has wrong label (%s)\n", info.dwTypeData);
+
+    DestroyMenu( hmenu );
+    DestroyMenu( hmenuSub );
+    DestroyMenu( hmenuSub2 );
+
+
+    /* 
+        Case 5: Menu containing a popup menu which in turn
+           contains an item with a different id than the popup menu.
+           This tests the fallback to a popup menu ID.
+     */
+
+    hmenu = CreateMenu();
+    hmenuSub = CreateMenu();
+
+    rc = AppendMenu(hmenu, MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, "Submenu");
+    ok (rc, "Appending the popup menu to the main menu failed\n");
+
+    rc = AppendMenu(hmenuSub, MF_STRING, 102, "Item");
+    ok (rc, "Appending the item to the popup menu failed\n");
+
+    /* Set the ID for hmenuSub */
+    info.cbSize = sizeof(info);
+    info.fMask = MIIM_ID;
+    info.wID = 101;
+
+    rc = SetMenuItemInfo(hmenu, 0, TRUE, &info);
+    ok(rc, "Setting the ID for the popup menu failed\n");
+
+    /* Check if the ID has been set */
+    info.wID = 0;
+    rc = GetMenuItemInfo(hmenu, 0, TRUE, &info);
+    ok(rc, "Getting the ID for the popup menu failed\n");
+    ok(info.wID == 101, "The ID for the popup menu has not been set\n");
+
+    /* Prove getting the item info via ID returns the popup menu */
+    memset( &info, 0, sizeof(info));
+    strback[0] = 0x00;
+    info.cbSize = sizeof(MENUITEMINFO);
+    info.fMask = MIIM_STRING | MIIM_ID;
+    info.dwTypeData = strback;
+    info.cch = sizeof(strback);
+
+    rc = GetMenuItemInfo(hmenu, 101, FALSE, &info);
+    ok (rc, "Getting the menu info failed\n");
+    ok (info.wID == 101, "IDs differ\n");
+    ok (!strcmp(info.dwTypeData, "Submenu"), "Returned item has wrong label (%s)\n", info.dwTypeData);
+
+    /* Also look for the menu item  */
+    memset( &info, 0, sizeof(info));
+    strback[0] = 0x00;
+    info.cbSize = sizeof(MENUITEMINFO);
+    info.fMask = MIIM_STRING | MIIM_ID;
+    info.dwTypeData = strback;
+    info.cch = sizeof(strback);
+
+    rc = GetMenuItemInfo(hmenu, 102, FALSE, &info);
+    ok (rc, "Getting the menu info failed\n");
+    ok (info.wID == 102, "IDs differ\n");
+    ok (!strcmp(info.dwTypeData, "Item"), "Returned item has wrong label (%s)\n", info.dwTypeData);
+
+    DestroyMenu(hmenu);
+    DestroyMenu(hmenuSub);
 }
 
 START_TEST(menu)


More information about the wine-patches mailing list