From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/menu.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 76144706771..342ee08a89b 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -714,30 +714,21 @@ DWORD WINAPI GetMenuCheckMarkDimensions(void) /********************************************************************** * SetMenuItemBitmaps (USER32.@) */ -BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags, - HBITMAP hNewUnCheck, HBITMAP hNewCheck) +BOOL WINAPI SetMenuItemBitmaps( HMENU menu, UINT pos, UINT flags, HBITMAP uncheck, HBITMAP check ) { - POPUPMENU *menu; - MENUITEM *item; - UINT pos; + MENUITEMINFOW info;
- if (!(menu = find_menu_item(hMenu, nPos, wFlags, &pos))) + info.cbSize = sizeof(info); + info.fMask = MIIM_STATE; + if (!NtUserThunkedMenuItemInfo( menu, pos, flags, NtUserGetMenuItemInfoW, &info, NULL )) return FALSE;
- item = &menu->items[pos]; - if (!hNewCheck && !hNewUnCheck) - { - item->fState &= ~MF_USECHECKBITMAPS; - } - else /* Install new bitmaps */ - { - item->hCheckBit = hNewCheck; - item->hUnCheckBit = hNewUnCheck; - item->fState |= MF_USECHECKBITMAPS; - } - release_menu_ptr(menu); - - return TRUE; + info.fMask = MIIM_STATE | MIIM_CHECKMARKS; + info.hbmpChecked = check; + info.hbmpUnchecked = uncheck; + if (check || uncheck) info.fState |= MF_USECHECKBITMAPS; + else info.fState &= ~MF_USECHECKBITMAPS; + return NtUserThunkedMenuItemInfo( menu, pos, flags, NtUserSetMenuItemInfo, &info, NULL ); }
From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/menu.c | 49 +++++----------------------------------------- dlls/win32u/menu.c | 45 ++++++++++++++++++++++++++++++++++++++++++ include/ntuser.h | 1 + 3 files changed, 51 insertions(+), 44 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 342ee08a89b..043af437356 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -1098,51 +1098,12 @@ BOOL WINAPI InsertMenuItemW(HMENU hMenu, UINT uItem, BOOL bypos, /********************************************************************** * CheckMenuRadioItem (USER32.@) */ - -BOOL WINAPI CheckMenuRadioItem(HMENU hMenu, UINT first, UINT last, - UINT check, UINT flags) +BOOL WINAPI CheckMenuRadioItem( HMENU menu, UINT first, UINT last, UINT check, UINT flags ) { - POPUPMENU *first_menu = NULL, *check_menu; - UINT i, check_pos; - BOOL done = FALSE; - - for (i = first; i <= last; i++) - { - MENUITEM *item; - - if (!(check_menu = find_menu_item(hMenu, i, flags, &check_pos))) - continue; - - if (!first_menu) - first_menu = grab_menu_ptr(check_menu->obj.handle); - - if (first_menu != check_menu) - { - release_menu_ptr(check_menu); - continue; - } - - item = &check_menu->items[check_pos]; - if (item->fType != MFT_SEPARATOR) - { - if (i == check) - { - item->fType |= MFT_RADIOCHECK; - item->fState |= MFS_CHECKED; - done = TRUE; - } - else - { - /* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */ - item->fState &= ~MFS_CHECKED; - } - } - - release_menu_ptr(check_menu); - } - release_menu_ptr(first_menu); - - return done; + MENUITEMINFOW info; /* abuse to pass last and check */ + info.cch = last; + info.fMask = check; + return NtUserThunkedMenuItemInfo( menu, first, flags, NtUserCheckMenuRadioItem, &info, NULL ); }
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index eab97e58d39..4ba5b42ec9d 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -1109,6 +1109,48 @@ static BOOL get_menu_item_info( HMENU handle, UINT id, UINT flags, MENUITEMINFOW return TRUE; }
+static BOOL check_menu_radio_item( HMENU handle, UINT first, UINT last, UINT check, UINT flags ) +{ + POPUPMENU *first_menu = NULL, *check_menu; + UINT i, check_pos; + BOOL done = FALSE; + + for (i = first; i <= last; i++) + { + MENUITEM *item; + + if (!(check_menu = find_menu_item( handle, i, flags, &check_pos ))) continue; + if (!first_menu) first_menu = grab_menu_ptr( check_menu->obj.handle ); + + if (first_menu != check_menu) + { + release_menu_ptr(check_menu); + continue; + } + + item = &check_menu->items[check_pos]; + if (item->fType != MFT_SEPARATOR) + { + if (i == check) + { + item->fType |= MFT_RADIOCHECK; + item->fState |= MFS_CHECKED; + done = TRUE; + } + else + { + /* Windows does not remove MFT_RADIOCHECK */ + item->fState &= ~MFS_CHECKED; + } + } + + release_menu_ptr( check_menu ); + } + + release_menu_ptr( first_menu ); + return done; +} + /********************************************************************** * NtUserThunkedMenuItemInfo (win32u.@) */ @@ -1121,6 +1163,9 @@ UINT WINAPI NtUserThunkedMenuItemInfo( HMENU handle, UINT pos, UINT flags, UINT
switch (method) { + case NtUserCheckMenuRadioItem: + return check_menu_radio_item( handle, pos, info->cch, info->fMask, flags ); + case NtUserGetMenuItemID: if (!(menu = find_menu_item( handle, pos, flags, &i ))) return -1; ret = menu->items[i].fType & MF_POPUP ? -1 : menu->items[i].wID; diff --git a/include/ntuser.h b/include/ntuser.h index 41b328376a9..e15345bb7d6 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -224,6 +224,7 @@ enum NtUserSetMenuItemInfo, NtUserInsertMenuItem, /* Wine extensions */ + NtUserCheckMenuRadioItem, NtUserGetMenuItemID, NtUserGetMenuItemInfoA, NtUserGetMenuItemInfoW,
From: Jacek Caban jacek@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
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=117584
Your paranoid android.
=== debian11 (64 bit WoW report) ===
user32: win.c:10982: Test failed: Expected foreground window 00000000001A0124, got 0000000001430052 win.c:10985: Test failed: Received WM_ACTIVATEAPP(0), did not expect it. win.c:10992: Test failed: Expected foreground window 00000000001A0124, got 0000000000000000
This merge request was approved by Huw Davies.