Find Popup Menus by ID
Michael Kaufmann
hallo at michael-kaufmann.ch
Tue Apr 18 06:18:39 CDT 2006
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 10:51:38 -0000
@@ -4,7 +4,7 @@
* Copyright 1993 Martin Ayotte
* Copyright 1994 Alexandre Julliard
* Copyright 1997 Morten Welinder
- * Copyright 2005 Maxime Bellengé
+ * Copyright 2005 Maxime Belleng
* Copyright 2006 Phil Krylov
*
* This library is free software; you can redistribute it and/or
@@ -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 10:51:40 -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