From 01bf37d81016486af4bd46e4c1c712bd8eac154f Mon Sep 17 00:00:00 2001 From: Michael Kaufmann Date: Tue, 18 Apr 2006 16:35:51 +0200 Subject: [PATCH] user: Find popup menus by ID. - 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. --- dlls/user/menu.c | 13 +++++++-- dlls/user/tests/menu.c | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/dlls/user/menu.c b/dlls/user/menu.c index a487347fd9d..11a02d82166 100644 --- a/dlls/user/menu.c +++ b/dlls/user/menu.c @@ -580,6 +580,7 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) { 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 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) *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 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) } } } + + if (fallback) + *nPos = fallback_pos; + return fallback; } diff --git a/dlls/user/tests/menu.c b/dlls/user/tests/menu.c index 22e48bf6396..c2fd8f387ac 100644 --- a/dlls/user/tests/menu.c +++ b/dlls/user/tests/menu.c @@ -1410,6 +1410,69 @@ void test_menu_search_bycommand( void ) 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)