From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/menu.c | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 99a99c0395..0aa4fb7ee5 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -98,6 +98,7 @@ typedef struct { UINT nScrollPos; /* Current scroll position */ UINT nTotalHeight; /* Total height of menu items inside menu */ RECT items_rect; /* Rectangle within which the items lie. Excludes margins and scroll arrows */ + LONG refcount; /* ------------ MENUINFO members ------ */ DWORD dwStyle; /* Extended menu style */ UINT cyMax; /* max height of the whole menu, 0 is screen height */ @@ -180,6 +181,7 @@ static BOOL fEndMenu = FALSE; DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont);
static BOOL SetMenuItemInfo_common( MENUITEM *, const MENUITEMINFOW *, BOOL); +static BOOL MENU_ReleaseMenu( POPUPMENU *lppop );
/********************************************************************* * menu class descriptor @@ -3978,7 +3980,9 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags ) if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE; if (!(menu = MENU_GetMenu(hMenu))) return FALSE;
- /* Remove item */ + /* Remove item */ + if ((item->fType & MF_POPUP) && item->hSubMenu) + MENU_ReleaseMenu(MENU_GetMenu(item->hSubMenu));
MENU_FreeItemData( item );
@@ -4127,6 +4131,7 @@ HMENU WINAPI CreateMenu(void)
if (!(menu = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*menu) ))) return 0; menu->FocusedItem = NO_SELECTED_ITEM; + menu->refcount = 1;
if (!(hMenu = alloc_user_handle( &menu->obj, USER_MENU ))) HeapFree( GetProcessHeap(), 0, menu );
@@ -4135,18 +4140,16 @@ HMENU WINAPI CreateMenu(void) return hMenu; }
- -/********************************************************************** - * DestroyMenu (USER32.@) - */ -BOOL WINAPI DestroyMenu( HMENU hMenu ) +static BOOL MENU_ReleaseMenu( POPUPMENU *lppop ) { - LPPOPUPMENU lppop; + LONG ref;
- TRACE("(%p)\n", hMenu); + if (!lppop) + return FALSE;
- if (!(lppop = free_user_handle( hMenu, USER_MENU ))) return FALSE; - if (lppop == OBJ_OTHER_PROCESS) return FALSE; + ref = InterlockedDecrement(&lppop->refcount); + if (ref) + return FALSE;
/* DestroyMenu should not destroy system menu popup owner */ if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd) @@ -4161,15 +4164,37 @@ BOOL WINAPI DestroyMenu( HMENU hMenu ) MENUITEM *item = lppop->items; for (i = lppop->nItems; i > 0; i--, item++) { - if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu); + if (item->fType & MF_POPUP) + { + /* Release handle if it hasn't already been released. */ + if (!MENU_ReleaseMenu(MENU_GetMenu(item->hSubMenu))) + DestroyMenu(item->hSubMenu); + } MENU_FreeItemData( item ); } HeapFree( GetProcessHeap(), 0, lppop->items ); } HeapFree( GetProcessHeap(), 0, lppop ); + return TRUE; }
+/********************************************************************** + * DestroyMenu (USER32.@) + */ +BOOL WINAPI DestroyMenu( HMENU hMenu ) +{ + POPUPMENU *lppop; + + TRACE("(%p)\n", hMenu); + + if (!(lppop = free_user_handle( hMenu, USER_MENU ))) return FALSE; + if (lppop == OBJ_OTHER_PROCESS) return FALSE; + + MENU_ReleaseMenu(lppop); + + return TRUE; +}
/********************************************************************** * GetSystemMenu (USER32.@) @@ -4817,6 +4842,8 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu, menu->wID = lpmii->wID;
if (lpmii->fMask & MIIM_SUBMENU) { + if ((menu->fType & MF_POPUP) && menu->hSubMenu) + MENU_ReleaseMenu(MENU_GetMenu(menu->hSubMenu)); menu->hSubMenu = lpmii->hSubMenu; if (menu->hSubMenu) { POPUPMENU *subMenu = MENU_GetMenu(menu->hSubMenu); @@ -4828,6 +4855,7 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu, } subMenu->wFlags |= MF_POPUP; menu->fType |= MF_POPUP; + InterlockedIncrement(&subMenu->refcount); } else { SetLastError( ERROR_INVALID_PARAMETER); return FALSE;
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/menu.c | 69 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 33 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 0aa4fb7ee5..71bd5dd51a 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -196,6 +196,10 @@ const struct builtin_class_descr MENU_builtin_class = (HBRUSH)(COLOR_MENU+1) /* brush */ };
+static HMENU MENU_GetHandle(const POPUPMENU *menu) +{ + return menu ? menu->obj.handle : NULL; +}
/*********************************************************************** * debug_print_menuitem @@ -1837,14 +1841,14 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd ) * * Popup menu initialization before WM_ENTERMENULOOP. */ -static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags ) +static BOOL MENU_InitPopup( HWND hwndOwner, POPUPMENU *menu, UINT flags ) { - POPUPMENU *menu; DWORD ex_style = 0;
- TRACE("owner=%p hmenu=%p\n", hwndOwner, hmenu); + TRACE("owner=%p menu=%p\n", hwndOwner, menu);
- if (!(menu = MENU_GetMenu( hmenu ))) return FALSE; + if (!menu) + return FALSE;
/* store the owner for DrawItem */ if (!IsWindow( hwndOwner )) @@ -1861,7 +1865,7 @@ static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags ) menu->hWnd = CreateWindowExW( ex_style, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL, WS_POPUP, 0, 0, 0, 0, hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE), - (LPVOID)hmenu ); + (void *)MENU_GetHandle(menu) ); if( !menu->hWnd ) return FALSE; return TRUE; } @@ -1872,19 +1876,20 @@ static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags ) * * Display a popup menu. */ -static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags, +static BOOL MENU_ShowPopup( HWND hwndOwner, POPUPMENU *menu, UINT id, UINT flags, INT x, INT y, INT xanchor, INT yanchor ) { - POPUPMENU *menu; POINT pt; HMONITOR monitor; MONITORINFO info; UINT max_height;
- TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", - hwndOwner, hmenu, id, x, y, xanchor, yanchor); + TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", + hwndOwner, menu, id, x, y, xanchor, yanchor); + + if (!menu) + return FALSE;
- if (!(menu = MENU_GetMenu( hmenu ))) return FALSE; if (menu->FocusedItem != NO_SELECTED_ITEM) { menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); @@ -1939,7 +1944,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
if (!top_popup) { top_popup = menu->hWnd; - top_popup_hmenu = hmenu; + top_popup_hmenu = MENU_GetHandle(menu); } /* Display the window */
@@ -2290,16 +2295,13 @@ static HMENU MENU_GetSubPopup( HMENU hmenu ) * * Hide the sub-popup menus of this menu. */ -static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu, +static void MENU_HideSubPopups( HWND hwndOwner, POPUPMENU *menu, BOOL sendMenuSelect, UINT wFlags ) { - POPUPMENU *menu = MENU_GetMenu( hmenu ); - - TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, sendMenuSelect); + TRACE("owner=%p menu=%p 0x%04x\n", hwndOwner, menu, sendMenuSelect);
if (menu && top_popup) { - HMENU hsubmenu; POPUPMENU *submenu; MENUITEM *item;
@@ -2309,17 +2311,17 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu, if (!(item->fType & MF_POPUP) || !(item->fState & MF_MOUSESELECT)) return; item->fState &= ~MF_MOUSESELECT; - hsubmenu = item->hSubMenu; + submenu = MENU_GetMenu(item->hSubMenu); } else return;
- if (!(submenu = MENU_GetMenu( hsubmenu ))) return; - MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE, wFlags ); - MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 ); + if (!submenu) return; + MENU_HideSubPopups( hwndOwner, submenu, FALSE, wFlags ); + MENU_SelectItem( hwndOwner, MENU_GetHandle(submenu), NO_SELECTED_ITEM, sendMenuSelect, 0 ); DestroyWindow( submenu->hWnd ); submenu->hWnd = 0;
if (!(wFlags & TPM_NONOTIFY)) - SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)hsubmenu, + SendMessageW( hwndOwner, WM_UNINITMENUPOPUP, (WPARAM)MENU_GetHandle(submenu), MAKELPARAM(0, IS_SYSTEM_MENU(submenu)) ); } } @@ -2423,9 +2425,9 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, /* use default alignment for submenus */ wFlags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
- MENU_InitPopup( hwndOwner, item->hSubMenu, wFlags ); + MENU_InitPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), wFlags );
- MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, wFlags, + MENU_ShowPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), menu->FocusedItem, wFlags, rect.left, rect.top, rect.right, rect.bottom ); if (selectFirst) MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT ); @@ -2563,11 +2565,12 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFl !((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) ) { /* both are top level menus (system and menu-bar) */ - MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags ); + MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); pmt->hTopMenu = hPtMenu; } - else MENU_HideSubPopups( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags ); + else + MENU_HideSubPopups( pmt->hOwnerWnd, ptmenu, FALSE, wFlags ); MENU_SelectItem( pmt->hOwnerWnd, hPtMenu, id, TRUE, 0 ); }
@@ -2811,7 +2814,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags ) MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); if( pmt->hCurrentMenu != pmt->hTopMenu ) - MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags ); + MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); }
if( hNewWnd != pmt->hOwnerWnd ) @@ -2892,7 +2895,7 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags) hmenutmp = MENU_GetSubPopup( hmenuprev ); }
- MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags ); + MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags ); pmt->hCurrentMenu = hmenuprev; bEndMenu = FALSE; } @@ -2931,7 +2934,7 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags, UINT msg ) hmenutmp = MENU_GetSubPopup( hmenuprev ); }
- MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE, wFlags ); + MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags ); pmt->hCurrentMenu = hmenuprev;
if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) ) @@ -2994,7 +2997,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags, UINT msg ) { if( pmt->hCurrentMenu != pmt->hTopMenu ) { - MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE, wFlags ); + MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu; } else hmenutmp = 0;
@@ -3297,7 +3300,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
if( IsWindow( mt.hOwnerWnd ) ) { - MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE, wFlags ); + MENU_HideSubPopups( mt.hOwnerWnd, menu, FALSE, wFlags );
if (menu && (menu->wFlags & MF_POPUP)) { @@ -3494,7 +3497,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y, return FALSE; }
- if (MENU_InitPopup( hWnd, hMenu, wFlags )) + if (MENU_InitPopup( hWnd, menu, wFlags )) { MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
@@ -3506,7 +3509,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y, MENU_InitSysMenuPopup( hMenu, GetWindowLongW( hWnd, GWL_STYLE ), GetClassLongW( hWnd, GCL_STYLE));
- if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 )) + if (MENU_ShowPopup( hWnd, MENU_GetMenu(hMenu), 0, wFlags, x, y, 0, 0 )) ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, lpTpm ? &lpTpm->rcExclude : NULL ); MENU_ExitTracking(hWnd, TRUE); @@ -3796,7 +3799,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID, if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE; if (!(menu = MENU_GetMenu(hMenu))) return FALSE; if (menu->FocusedItem == wItemID) return TRUE; - MENU_HideSubPopups( hWnd, hMenu, FALSE, 0 ); + MENU_HideSubPopups( hWnd, menu, FALSE, 0 ); MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 ); return TRUE; }
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/menu.c | 174 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 76 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 71bd5dd51a..f5176fdeca 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -565,17 +565,19 @@ static UINT MENU_GetStartOfPrevColumn( /*********************************************************************** * MENU_FindItem * - * Find a menu item. Return a pointer on the item, and modifies *hmenu + * Find a menu item. Return a pointer on the item, and modifies *pmenu * in case the item was in a sub-menu. */ -static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) +static MENUITEM *MENU_FindItem( POPUPMENU **pmenu, UINT *nPos, UINT wFlags ) { - POPUPMENU *menu; + POPUPMENU *menu = *pmenu; MENUITEM *fallback = NULL; UINT fallback_pos = 0; UINT i;
- if ((*hmenu == (HMENU)0xffff) || (!(menu = MENU_GetMenu(*hmenu)))) return NULL; + if (!menu) + return NULL; + if (wFlags & MF_BYPOSITION) { if (*nPos >= menu->nItems) return NULL; @@ -588,11 +590,11 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) { if (item->fType & MF_POPUP) { - HMENU hsubmenu = item->hSubMenu; - MENUITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags ); + POPUPMENU *submenu = MENU_GetMenu(item->hSubMenu); + MENUITEM *subitem = MENU_FindItem( &submenu, nPos, wFlags ); if (subitem) { - *hmenu = hsubmenu; + *pmenu = submenu; return subitem; } else if (item->wID == *nPos) @@ -623,25 +625,27 @@ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) * *hmenu in case it is found in another sub-menu. * If the submenu cannot be found, NO_SELECTED_ITEM is returned. */ -static UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget ) +static UINT MENU_FindSubMenu( POPUPMENU **pmenu, POPUPMENU *subTarget ) { - POPUPMENU *menu; + POPUPMENU *menu = *pmenu; UINT i; MENUITEM *item; - if (((*hmenu)==(HMENU)0xffff) || - (!(menu = MENU_GetMenu(*hmenu)))) + + if (!menu) return NO_SELECTED_ITEM; + item = menu->items; for (i = 0; i < menu->nItems; i++, item++) { if(!(item->fType & MF_POPUP)) continue; - if (item->hSubMenu == hSubTarget) { + if (item->hSubMenu == MENU_GetHandle(subTarget)) + { return i; } else { - HMENU hsubmenu = item->hSubMenu; - UINT pos = MENU_FindSubMenu( &hsubmenu, hSubTarget ); + POPUPMENU *submenu = MENU_GetMenu(item->hSubMenu); + UINT pos = MENU_FindSubMenu( &submenu, subTarget ); if (pos != NO_SELECTED_ITEM) { - *hmenu = hsubmenu; + *pmenu = submenu; return pos; } } @@ -750,16 +754,16 @@ static enum hittest MENU_FindItemByCoords( const POPUPMENU *menu, POINT pt, UINT * Find the menu item selected by a key press. * Return item id, -1 if none, -2 if we should close the menu. */ -static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, +static UINT MENU_FindItemByKey( HWND hwndOwner, POPUPMENU *menu, WCHAR key, BOOL forceMenuChar ) { - TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)key, key, hmenu ); + TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char)key, key, menu );
- if (!IsMenu( hmenu )) hmenu = GetSubMenu( get_win_sys_menu(hwndOwner), 0); + if (!menu) + menu = MENU_GetMenu(GetSubMenu( get_win_sys_menu(hwndOwner), 0));
- if (hmenu) + if (menu) { - POPUPMENU *menu = MENU_GetMenu( hmenu ); MENUITEM *item = menu->items; LRESULT menuchar;
@@ -785,7 +789,7 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, } } menuchar = SendMessageW( hwndOwner, WM_MENUCHAR, - MAKEWPARAM( key, menu->wFlags ), (LPARAM)hmenu ); + MAKEWPARAM( key, menu->wFlags ), (LPARAM)MENU_GetHandle(menu) ); if (HIWORD(menuchar) == MNC_EXECUTE) return LOWORD(menuchar); if (HIWORD(menuchar) == MNC_CLOSE) return (UINT)(-2); } @@ -2005,7 +2009,7 @@ MENU_EnsureMenuItemVisible(LPPOPUPMENU lppop, UINT wIndex, HDC hdc) * MENU_SelectItem */ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, - BOOL sendMenuSelect, HMENU topmenu ) + BOOL sendMenuSelect, HMENU htopmenu ) { LPPOPUPMENU lppop; HDC hdc; @@ -2053,14 +2057,17 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, } } else if (sendMenuSelect) { - if(topmenu){ + POPUPMENU *topmenu; + + if (htopmenu && (topmenu = MENU_GetMenu(htopmenu))) + { int pos; - if((pos=MENU_FindSubMenu(&topmenu, hmenu))!=NO_SELECTED_ITEM){ - POPUPMENU *ptm = MENU_GetMenu( topmenu ); - MENUITEM *ip = &ptm->items[pos]; + if ((pos=MENU_FindSubMenu(&topmenu, lppop)) != NO_SELECTED_ITEM) + { + MENUITEM *ip = &topmenu->items[pos]; SendMessageW( hwndOwner, WM_MENUSELECT, MAKEWPARAM(pos, ip->fType | ip->fState | - (ptm->wFlags & MF_SYSMENU)), (LPARAM)topmenu); + (topmenu->wFlags & MF_SYSMENU)), (LPARAM)htopmenu); } } } @@ -2126,7 +2133,7 @@ static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags ) if (pos > menu->nItems) pos = menu->nItems; } else { - if (!MENU_FindItem( &hMenu, &pos, flags )) + if (!MENU_FindItem( &menu, &pos, flags )) pos = menu->nItems; else { if (!(menu = MENU_GetMenu( hMenu ))) @@ -3258,7 +3265,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, /* We will find a better way real soon... */ if (msg.wParam < 32) break;
- pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.hCurrentMenu, + pos = MENU_FindItemByKey( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), LOWORD(msg.wParam), FALSE ); if (pos == (UINT)-2) fEndMenu = TRUE; else if (pos == (UINT)-1) MessageBeep(0); @@ -3444,7 +3451,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar)
if( wChar && wChar != ' ' ) { - uItem = MENU_FindItemByKey( hwnd, hTrackMenu, wChar, (wParam & HTSYSMENU) ); + uItem = MENU_FindItemByKey( hwnd, MENU_GetMenu(hTrackMenu), wChar, (wParam & HTSYSMENU) ); if ( uItem >= (UINT)(-2) ) { if( uItem == (UINT)(-1) ) MessageBeep(0); @@ -3681,10 +3688,11 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UINT pos, LPCWSTR data, */ DWORD WINAPI CheckMenuItem( HMENU hMenu, UINT id, UINT flags ) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item; DWORD ret;
- if (!(item = MENU_FindItem( &hMenu, &id, flags ))) return -1; + if (!(item = MENU_FindItem( &menu, &id, flags ))) return -1; ret = item->fState & MF_CHECKED; if (flags & MF_CHECKED) item->fState |= MF_CHECKED; else item->fState &= ~MF_CHECKED; @@ -3707,7 +3715,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags ) if (!(menu = MENU_GetMenu(hMenu))) return (UINT)-1;
- if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) + if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) return (UINT)-1;
oldflags = item->fState & (MF_GRAYED | MF_DISABLED); @@ -3745,12 +3753,14 @@ INT WINAPI GetMenuStringA( LPSTR str, /* [out] outbuffer. If NULL, func returns entry length*/ INT nMaxSiz, /* [in] length of buffer. if 0, func returns entry len*/ UINT wFlags /* [in] MF_ flags */ -) { +) +{ + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item;
TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags ); if (str && nMaxSiz) str[0] = '\0'; - if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) { + if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) { SetLastError( ERROR_MENU_ITEM_NOT_FOUND); return 0; } @@ -3769,11 +3779,12 @@ INT WINAPI GetMenuStringA( INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID, LPWSTR str, INT nMaxSiz, UINT wFlags ) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item;
TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, wItemID, str, nMaxSiz, wFlags ); if (str && nMaxSiz) str[0] = '\0'; - if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) { + if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) { SetLastError( ERROR_MENU_ITEM_NOT_FOUND); return 0; } @@ -3794,13 +3805,15 @@ INT WINAPI GetMenuStringW( HMENU hMenu, UINT wItemID, BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID, UINT wHilite ) { - LPPOPUPMENU menu; - TRACE("(%p, %p, %04x, %04x);\n", hWnd, hMenu, wItemID, wHilite); - if (!MENU_FindItem( &hMenu, &wItemID, wHilite )) return FALSE; - if (!(menu = MENU_GetMenu(hMenu))) return FALSE; + POPUPMENU *menu = MENU_GetMenu(hMenu); + MENUITEM *item; + + TRACE("(%p, %p, %04x, %04x)\n", hWnd, hMenu, wItemID, wHilite); + + if (!(item = MENU_FindItem( &menu, &wItemID, wHilite ))) return FALSE; if (menu->FocusedItem == wItemID) return TRUE; MENU_HideSubPopups( hWnd, menu, FALSE, 0 ); - MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 ); + MENU_SelectItem( hWnd, MENU_GetHandle(menu), wItemID, TRUE, 0 ); return TRUE; }
@@ -3810,13 +3823,15 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID, */ UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags ) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item; + TRACE("(menu=%p, id=%04x, flags=%04x);\n", hMenu, wItemID, wFlags); - if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1; + if (!(item = MENU_FindItem( &menu, &wItemID, wFlags ))) return -1; debug_print_menuitem (" item: ", item, ""); if (item->fType & MF_POPUP) { - POPUPMENU *menu = MENU_GetMenu( item->hSubMenu ); + menu = MENU_GetMenu( item->hSubMenu ); if (!menu) return -1; else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff); } @@ -3847,9 +3862,10 @@ INT WINAPI GetMenuItemCount( HMENU hMenu ) */ UINT WINAPI GetMenuItemID( HMENU hMenu, INT nPos ) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM * lpmi;
- if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return -1; + if (!(lpmi = MENU_FindItem(&menu, (UINT *)&nPos, MF_BYPOSITION))) return -1; if (lpmi->fType & MF_POPUP) return -1; return lpmi->wID;
@@ -3976,15 +3992,14 @@ BOOL WINAPI AppendMenuW( HMENU hMenu, UINT flags, */ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags ) { - LPPOPUPMENU menu; + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item;
TRACE("(menu=%p pos=%04x flags=%04x)\n",hMenu, nPos, wFlags); - if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE; - if (!(menu = MENU_GetMenu(hMenu))) return FALSE; + if (!(item = MENU_FindItem( &menu, &nPos, wFlags ))) return FALSE;
/* Remove item */ - if ((item->fType & MF_POPUP) && item->hSubMenu) + if (item->fType & MF_POPUP) MENU_ReleaseMenu(MENU_GetMenu(item->hSubMenu));
MENU_FreeItemData( item ); @@ -4016,7 +4031,8 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags ) */ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags ) { - MENUITEM *item = MENU_FindItem( &hMenu, &nPos, wFlags ); + POPUPMENU *menu = MENU_GetMenu(hMenu); + MENUITEM *item = MENU_FindItem( &menu, &nPos, wFlags ); if (!item) return FALSE; if (item->fType & MF_POPUP) DestroyMenu( item->hSubMenu ); /* nPos is now the position of the item */ @@ -4031,6 +4047,7 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags ) BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags, UINT_PTR id, LPCWSTR str ) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item; MENUITEMINFOW mii;
@@ -4039,13 +4056,13 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags, else TRACE("%p %d %04x %04lx %p\n", hMenu, pos, flags, id, str );
- if (!(item = MENU_FindItem( &hMenu, &pos, flags ))) + if (!(item = MENU_FindItem( &menu, &pos, flags ))) { /* workaround for Word 95: pretend that SC_TASKLIST item exists */ if (pos == SC_TASKLIST && !(flags & MF_BYPOSITION)) return TRUE; return FALSE; } - MENU_GetMenu(hMenu)->Height = 0; /* force size recalculate */ + menu->Height = 0; /* force size recalculation */ MENU_mnu2mnuii( flags, id, str, &mii); return SetMenuItemInfo_common( item, &mii, TRUE); } @@ -4106,9 +4123,10 @@ DWORD WINAPI GetMenuCheckMarkDimensions(void) BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags, HBITMAP hNewUnCheck, HBITMAP hNewCheck) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item;
- if (!(item = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE; + if (!(item = MENU_FindItem( &menu, &nPos, wFlags ))) return FALSE;
if (!hNewCheck && !hNewUnCheck) { @@ -4410,9 +4428,10 @@ BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu ) */ HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos ) { + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM * lpmi;
- if (!(lpmi = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))) return 0; + if (!(lpmi = MENU_FindItem(&menu, (UINT *)&nPos, MF_BYPOSITION))) return 0; if (!(lpmi->fType & MF_POPUP)) return 0; return lpmi->hSubMenu; } @@ -4618,7 +4637,8 @@ BOOL WINAPI IsMenu(HMENU hmenu) static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos, LPMENUITEMINFOW lpmii, BOOL unicode) { - MENUITEM *menu = MENU_FindItem (&hmenu, &item, bypos ? MF_BYPOSITION : 0); + POPUPMENU *popup = MENU_GetMenu(hmenu); + MENUITEM *menu = MENU_FindItem (&popup, &item, bypos ? MF_BYPOSITION : 0);
debug_print_menuitem("GetMenuItemInfo_common: ", menu, "");
@@ -4936,6 +4956,7 @@ static BOOL MENU_NormalizeMenuItemInfoStruct( const MENUITEMINFOW *pmii_in, BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos, const MENUITEMINFOA *lpmii) { + POPUPMENU *menu = MENU_GetMenu(hmenu); MENUITEM *menuitem; MENUITEMINFOW mii;
@@ -4943,7 +4964,7 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE;
- if (!(menuitem = MENU_FindItem( &hmenu, &item, bypos? MF_BYPOSITION : 0 ))) + if (!(menuitem = MENU_FindItem( &menu, &item, bypos? MF_BYPOSITION : 0 ))) { /* workaround for Word 95: pretend that SC_TASKLIST item exists */ if (item == SC_TASKLIST && !bypos) return TRUE; @@ -4958,13 +4979,14 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos, BOOL WINAPI SetMenuItemInfoW(HMENU hmenu, UINT item, BOOL bypos, const MENUITEMINFOW *lpmii) { + POPUPMENU *menu = MENU_GetMenu(hmenu); MENUITEM *menuitem; MENUITEMINFOW mii;
TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
if (!MENU_NormalizeMenuItemInfoStruct( lpmii, &mii )) return FALSE; - if (!(menuitem = MENU_FindItem( &hmenu, &item, bypos? MF_BYPOSITION : 0 ))) + if (!(menuitem = MENU_FindItem( &menu, &item, bypos? MF_BYPOSITION : 0 ))) { /* workaround for Word 95: pretend that SC_TASKLIST item exists */ if (item == SC_TASKLIST && !bypos) return TRUE; @@ -5107,10 +5129,10 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu, UINT first, UINT last, UINT check, UINT bypos) { + POPUPMENU *m_first, *m_check; BOOL done = FALSE; UINT i; MENUITEM *mi_first = NULL, *mi_check; - HMENU m_first, m_check;
for (i = first; i <= last; i++) { @@ -5118,7 +5140,7 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu,
if (!mi_first) { - m_first = hMenu; + m_first = MENU_GetMenu(hMenu); mi_first = MENU_FindItem(&m_first, &pos, bypos); if (!mi_first) continue; mi_check = mi_first; @@ -5126,7 +5148,7 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu, } else { - m_check = hMenu; + m_check = MENU_GetMenu(hMenu); mi_check = MENU_FindItem(&m_check, &pos, bypos); if (!mi_check) continue; } @@ -5161,18 +5183,15 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMenu, */ BOOL WINAPI GetMenuItemRect(HWND hwnd, HMENU hMenu, UINT uItem, RECT *rect) { - POPUPMENU *menu; + POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item;
TRACE("(%p,%p,%d,%p)\n", hwnd, hMenu, uItem, rect);
- item = MENU_FindItem (&hMenu, &uItem, MF_BYPOSITION); + item = MENU_FindItem (&menu, &uItem, MF_BYPOSITION); if ((rect == NULL) || (item == NULL)) return FALSE;
- menu = MENU_GetMenu(hMenu); - if (!menu) return FALSE; - if (!hwnd) hwnd = menu->hWnd; if (!hwnd) return FALSE;
@@ -5384,17 +5403,20 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA mesg = 1; else { - HMENU hMenu, hSubMenu, hSysMenu; + HMENU hMenu, hSysMenu; + POPUPMENU *menu, *subMenu, *sysMenu; UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos;
hMenu = (GetWindowLongW( hWnd, GWL_STYLE ) & WS_CHILD) ? 0 : GetMenu(hWnd); + menu = MENU_GetMenu(hMenu); hSysMenu = get_win_sys_menu( hWnd ); + sysMenu = MENU_GetMenu(hSysMenu);
/* find menu item and ask application to initialize it */ /* 1. in the system menu */ - hSubMenu = hSysMenu; + subMenu = sysMenu; nPos = cmd; - if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) + if (MENU_FindItem(&subMenu, &nPos, MF_BYCOMMAND)) { if (GetCapture()) mesg = 2; @@ -5403,20 +5425,20 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA else { SendMessageW(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L); - if(hSubMenu != hSysMenu) + if (subMenu != sysMenu) { - nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu); - TRACE_(accel)("hSysMenu = %p, hSubMenu = %p, nPos = %d\n", hSysMenu, hSubMenu, nPos); - SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); + nPos = MENU_FindSubMenu(&sysMenu, subMenu); + TRACE_(accel)("sysMenu = %p, subMenu = %p, nPos = %d\n", sysMenu, subMenu, nPos); + SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)MENU_GetHandle(subMenu), MAKELPARAM(nPos, TRUE)); } uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND); } } else /* 2. in the window's menu */ { - hSubMenu = hMenu; + subMenu = menu; nPos = cmd; - if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) + if (MENU_FindItem(&subMenu, &nPos, MF_BYCOMMAND)) { if (GetCapture()) mesg = 2; @@ -5425,11 +5447,11 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA else { SendMessageW(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); - if(hSubMenu != hMenu) + if (subMenu != menu) { - nPos = MENU_FindSubMenu(&hMenu, hSubMenu); - TRACE_(accel)("hMenu = %p, hSubMenu = %p, nPos = %d\n", hMenu, hSubMenu, nPos); - SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE)); + nPos = MENU_FindSubMenu(&menu, subMenu); + TRACE_(accel)("hMenu = %p, subMenu = %p, nPos = %d\n", hMenu, subMenu, nPos); + SendMessageW(hWnd, WM_INITMENUPOPUP, (WPARAM)MENU_GetHandle(subMenu), MAKELPARAM(nPos, FALSE)); } uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND); }
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/menu.c | 79 ++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 44 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index f5176fdeca..9a786dbb85 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -2008,15 +2008,13 @@ MENU_EnsureMenuItemVisible(LPPOPUPMENU lppop, UINT wIndex, HDC hdc) /*********************************************************************** * MENU_SelectItem */ -static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, - BOOL sendMenuSelect, HMENU htopmenu ) +static void MENU_SelectItem( HWND hwndOwner, POPUPMENU *lppop, UINT wIndex, + BOOL sendMenuSelect, POPUPMENU *topmenu ) { - LPPOPUPMENU lppop; HDC hdc;
- TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect); + TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, lppop, wIndex, sendMenuSelect);
- lppop = MENU_GetMenu( hmenu ); if ((!lppop) || (!lppop->nItems) || (!lppop->hWnd)) return;
if (lppop->FocusedItem == wIndex) return; @@ -2024,7 +2022,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW); if (!top_popup) { top_popup = lppop->hWnd; - top_popup_hmenu = hmenu; + top_popup_hmenu = MENU_GetHandle(lppop); }
SelectObject( hdc, get_menu_font(FALSE)); @@ -2053,13 +2051,12 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, SendMessageW( hwndOwner, WM_MENUSELECT, MAKEWPARAM(ip->fType & MF_POPUP ? wIndex: ip->wID, ip->fType | ip->fState | - (lppop->wFlags & MF_SYSMENU)), (LPARAM)hmenu); + (lppop->wFlags & MF_SYSMENU)), (LPARAM)MENU_GetHandle(lppop)); } } - else if (sendMenuSelect) { - POPUPMENU *topmenu; - - if (htopmenu && (topmenu = MENU_GetMenu(htopmenu))) + else if (sendMenuSelect) + { + if (topmenu) { int pos; if ((pos=MENU_FindSubMenu(&topmenu, lppop)) != NO_SELECTED_ITEM) @@ -2067,7 +2064,7 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, MENUITEM *ip = &topmenu->items[pos]; SendMessageW( hwndOwner, WM_MENUSELECT, MAKEWPARAM(pos, ip->fType | ip->fState | - (topmenu->wFlags & MF_SYSMENU)), (LPARAM)htopmenu); + (topmenu->wFlags & MF_SYSMENU)), (LPARAM)MENU_GetHandle(topmenu)); } } } @@ -2082,14 +2079,12 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, * If there is no selection then it should select the last item if * offset is ITEM_PREV or the first item if offset is ITEM_NEXT. */ -static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset ) +static void MENU_MoveSelection( HWND hwndOwner, POPUPMENU *menu, INT offset ) { INT i; - POPUPMENU *menu;
- TRACE("hwnd=%p hmenu=%p off=0x%04x\n", hwndOwner, hmenu, offset); + TRACE("hwnd=%p menu=%p off=0x%04x\n", hwndOwner, menu, offset);
- menu = MENU_GetMenu( hmenu ); if ((!menu) || (!menu->items)) return;
if ( menu->FocusedItem != NO_SELECTED_ITEM ) @@ -2099,7 +2094,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset ) ; i += offset) if (!(menu->items[i].fType & MF_SEPARATOR)) { - MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 ); + MENU_SelectItem( hwndOwner, menu, i, TRUE, 0 ); return; } } @@ -2108,7 +2103,7 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset ) i >= 0 && i < menu->nItems ; i += offset) if (!(menu->items[i].fType & MF_SEPARATOR)) { - MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 ); + MENU_SelectItem( hwndOwner, menu, i, TRUE, 0 ); return; } } @@ -2323,7 +2318,7 @@ static void MENU_HideSubPopups( HWND hwndOwner, POPUPMENU *menu,
if (!submenu) return; MENU_HideSubPopups( hwndOwner, submenu, FALSE, wFlags ); - MENU_SelectItem( hwndOwner, MENU_GetHandle(submenu), NO_SELECTED_ITEM, sendMenuSelect, 0 ); + MENU_SelectItem( hwndOwner, submenu, NO_SELECTED_ITEM, sendMenuSelect, 0 ); DestroyWindow( submenu->hWnd ); submenu->hWnd = 0;
@@ -2437,7 +2432,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, MENU_ShowPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), menu->FocusedItem, wFlags, rect.left, rect.top, rect.right, rect.bottom ); if (selectFirst) - MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT ); + MENU_MoveSelection( hwndOwner, MENU_GetMenu(item->hSubMenu), ITEM_NEXT ); return item->hSubMenu; }
@@ -2571,14 +2566,14 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFl if( pmt->hTopMenu != hPtMenu && !((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) ) { - /* both are top level menus (system and menu-bar) */ - MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); - MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); + /* both are top level menus (system and menu-bar) */ + MENU_HideSubPopups( pmt->hOwnerWnd, topmenu, FALSE, wFlags ); + MENU_SelectItem( pmt->hOwnerWnd, topmenu, NO_SELECTED_ITEM, FALSE, 0 ); pmt->hTopMenu = hPtMenu; } else MENU_HideSubPopups( pmt->hOwnerWnd, ptmenu, FALSE, wFlags ); - MENU_SelectItem( pmt->hOwnerWnd, hPtMenu, id, TRUE, 0 ); + MENU_SelectItem( pmt->hOwnerWnd, ptmenu, id, TRUE, 0 ); }
@@ -2692,9 +2687,8 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
if( id == NO_SELECTED_ITEM ) { - MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, - NO_SELECTED_ITEM, TRUE, pmt->hTopMenu); - + MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hCurrentMenu), + NO_SELECTED_ITEM, TRUE, MENU_GetMenu(pmt->hTopMenu)); } else if( ptmenu->FocusedItem != id ) { @@ -2818,7 +2812,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
if( hNewMenu != pmt->hTopMenu ) { - MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, NO_SELECTED_ITEM, + MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), NO_SELECTED_ITEM, FALSE, 0 ); if( pmt->hCurrentMenu != pmt->hTopMenu ) MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); @@ -2831,7 +2825,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags ) }
pmt->hTopMenu = pmt->hCurrentMenu = hNewMenu; /* all subpopups are hidden */ - MENU_SelectItem( pmt->hOwnerWnd, pmt->hTopMenu, id, TRUE, 0 ); + MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), id, TRUE, 0 );
return TRUE; } @@ -2929,8 +2923,7 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags, UINT msg ) if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) != NO_SELECTED_ITEM ) {
- MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, - prevcol, TRUE, 0 ); + MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hCurrentMenu), prevcol, TRUE, 0 ); return; }
@@ -2949,7 +2942,7 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags, UINT msg ) /* move menu bar selection if no more popups are left */
if( !MENU_DoNextMenu( pmt, VK_LEFT, wFlags ) ) - MENU_MoveSelection( pmt->hOwnerWnd, pmt->hTopMenu, ITEM_PREV ); + MENU_MoveSelection( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), ITEM_PREV );
if ( hmenuprev != hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) { @@ -2995,8 +2988,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags, UINT msg ) if( (nextcol = MENU_GetStartOfNextColumn( pmt->hCurrentMenu )) != NO_SELECTED_ITEM ) { TRACE("Going to %d.\n", nextcol ); - MENU_SelectItem( pmt->hOwnerWnd, pmt->hCurrentMenu, - nextcol, TRUE, 0 ); + MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hCurrentMenu), nextcol, TRUE, 0 ); return; }
@@ -3010,7 +3002,7 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags, UINT msg )
/* try to move to the next item */ if( !MENU_DoNextMenu( pmt, VK_RIGHT, wFlags ) ) - MENU_MoveSelection( pmt->hOwnerWnd, pmt->hTopMenu, ITEM_NEXT ); + MENU_MoveSelection( pmt->hOwnerWnd, menu, ITEM_NEXT );
if( hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) if( !MENU_SuspendPopup( pmt, msg ) ) @@ -3197,9 +3189,9 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
case VK_HOME: case VK_END: - MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu, + MENU_SelectItem( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), NO_SELECTED_ITEM, FALSE, 0 ); - MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu, + MENU_MoveSelection( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV ); break;
@@ -3210,7 +3202,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, if (!(menu->wFlags & MF_POPUP)) mt.hCurrentMenu = MENU_ShowSubPopup(mt.hOwnerWnd, mt.hTopMenu, TRUE, wFlags); else /* otherwise try to move selection */ - MENU_MoveSelection( mt.hOwnerWnd, mt.hCurrentMenu, + MENU_MoveSelection( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT ); break;
@@ -3271,8 +3263,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, else if (pos == (UINT)-1) MessageBeep(0); else { - MENU_SelectItem( mt.hOwnerWnd, mt.hCurrentMenu, pos, - TRUE, 0 ); + MENU_SelectItem( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), pos, TRUE, 0 ); executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags); fEndMenu = (executedMenuId != -2); } @@ -3318,7 +3309,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, SendMessageW( mt.hOwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.hTopMenu, MAKELPARAM(0, IS_SYSTEM_MENU(menu)) ); } - MENU_SelectItem( mt.hOwnerWnd, mt.hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); + MENU_SelectItem( mt.hOwnerWnd, MENU_GetMenu(mt.hTopMenu), NO_SELECTED_ITEM, FALSE, 0 ); SendMessageW( mt.hOwnerWnd, WM_MENUSELECT, MAKEWPARAM(0,0xffff), 0 ); } } @@ -3461,12 +3452,12 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar) } }
- MENU_SelectItem( hwnd, hTrackMenu, uItem, TRUE, 0 ); + MENU_SelectItem( hwnd, MENU_GetMenu(hTrackMenu), uItem, TRUE, 0 );
if (!(wParam & HTSYSMENU) || wChar == ' ') { if( uItem == NO_SELECTED_ITEM ) - MENU_MoveSelection( hwnd, hTrackMenu, ITEM_NEXT ); + MENU_MoveSelection( hwnd, MENU_GetMenu(hTrackMenu), ITEM_NEXT ); else PostMessageW( hwnd, WM_KEYDOWN, VK_RETURN, 0 ); } @@ -3813,7 +3804,7 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID, if (!(item = MENU_FindItem( &menu, &wItemID, wHilite ))) return FALSE; if (menu->FocusedItem == wItemID) return TRUE; MENU_HideSubPopups( hWnd, menu, FALSE, 0 ); - MENU_SelectItem( hWnd, MENU_GetHandle(menu), wItemID, TRUE, 0 ); + MENU_SelectItem( hWnd, menu, wItemID, TRUE, 0 ); return TRUE; }
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/menu.c | 395 +++++++++++++++++++++++------------------------------ 1 file changed, 172 insertions(+), 223 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 9a786dbb85..c8d30eba17 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -118,11 +118,11 @@ typedef struct {
typedef struct { - UINT trackFlags; - HMENU hCurrentMenu; /* current submenu (can be equal to hTopMenu)*/ - HMENU hTopMenu; /* initial menu */ - HWND hOwnerWnd; /* where notifications are sent */ - POINT pt; + UINT trackFlags; + POPUPMENU *current_menu; /* current submenu (can be equal to hTopMenu)*/ + POPUPMENU *top_menu; /* initial menu */ + HWND hOwnerWnd; /* where notifications are sent */ + POINT pt; } MTRACKER;
#define ITEM_PREV -1 @@ -492,18 +492,8 @@ static void MENU_InitSysMenuPopup( HMENU hmenu, DWORD style, DWORD clsStyle ) EnableMenuItem( hmenu, SC_CLOSE, MF_GRAYED); }
- -/****************************************************************************** - * - * UINT MENU_GetStartOfNextColumn( - * HMENU hMenu ) - * - *****************************************************************************/ - -static UINT MENU_GetStartOfNextColumn( - HMENU hMenu ) +static UINT MENU_GetStartOfNextColumn( POPUPMENU *menu ) { - POPUPMENU *menu = MENU_GetMenu(hMenu); UINT i;
if(!menu) @@ -521,18 +511,8 @@ static UINT MENU_GetStartOfNextColumn( return NO_SELECTED_ITEM; }
- -/****************************************************************************** - * - * UINT MENU_GetStartOfPrevColumn( - * HMENU hMenu ) - * - *****************************************************************************/ - -static UINT MENU_GetStartOfPrevColumn( - HMENU hMenu ) +static UINT MENU_GetStartOfPrevColumn( POPUPMENU *menu ) { - POPUPMENU *menu = MENU_GetMenu(hMenu); UINT i;
if( !menu ) @@ -2276,19 +2256,17 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu) * * Return the handle of the selected sub-popup menu (if any). */ -static HMENU MENU_GetSubPopup( HMENU hmenu ) +static POPUPMENU *MENU_GetSubPopup( POPUPMENU *menu ) { - POPUPMENU *menu; MENUITEM *item;
- menu = MENU_GetMenu( hmenu ); - if ((!menu) || (menu->FocusedItem == NO_SELECTED_ITEM)) return 0;
item = &menu->items[menu->FocusedItem]; if ((item->fType & MF_POPUP) && (item->fState & MF_MOUSESELECT)) - return item->hSubMenu; - return 0; + return MENU_GetMenu(item->hSubMenu); + + return NULL; }
@@ -2333,25 +2311,25 @@ static void MENU_HideSubPopups( HWND hwndOwner, POPUPMENU *menu, * MENU_ShowSubPopup * * Display the sub-menu of the selected item of this menu. - * Return the handle of the submenu, or hmenu if no submenu to display. + * Return the submenu, or menu if no submenu to display. */ -static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, +static POPUPMENU *MENU_ShowSubPopup( HWND hwndOwner, POPUPMENU *menu, BOOL selectFirst, UINT wFlags ) { RECT rect; - POPUPMENU *menu; MENUITEM *item; HDC hdc;
- TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, selectFirst); + TRACE("owner=%p menu=%p 0x%04x\n", hwndOwner, menu, selectFirst);
- if (!(menu = MENU_GetMenu( hmenu ))) return hmenu; + if (!menu) + return NULL;
- if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu; + if (menu->FocusedItem == NO_SELECTED_ITEM) return menu;
item = &menu->items[menu->FocusedItem]; if (!(item->fType & MF_POPUP) || (item->fState & (MF_GRAYED | MF_DISABLED))) - return hmenu; + return menu;
/* message must be sent before using item, because nearly everything may be changed by the application ! */ @@ -2433,7 +2411,7 @@ static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, rect.left, rect.top, rect.right, rect.bottom ); if (selectFirst) MENU_MoveSelection( hwndOwner, MENU_GetMenu(item->hSubMenu), ITEM_NEXT ); - return item->hSubMenu; + return MENU_GetMenu(item->hSubMenu); }
@@ -2465,29 +2443,28 @@ void MENU_EndMenu( HWND hwnd ) * * Walks menu chain trying to find a menu pt maps to. */ -static HMENU MENU_PtMenu( HMENU hMenu, POINT pt ) +static POPUPMENU *MENU_PtMenu( POPUPMENU *menu, POINT pt ) { - POPUPMENU *menu = MENU_GetMenu( hMenu ); UINT item = menu->FocusedItem; - HMENU ret; + POPUPMENU *ret;
/* try subpopup first (if any) */ ret = (item != NO_SELECTED_ITEM && (menu->items[item].fType & MF_POPUP) && (menu->items[item].fState & MF_MOUSESELECT)) - ? MENU_PtMenu(menu->items[item].hSubMenu, pt) : 0; + ? MENU_PtMenu(MENU_GetMenu(menu->items[item].hSubMenu), pt) : 0;
if (!ret) /* check the current window (avoiding WM_HITTEST) */ { INT ht = NC_HandleNCHitTest( menu->hWnd, pt ); if( menu->wFlags & MF_POPUP ) { - if (ht != HTNOWHERE && ht != HTERROR) ret = hMenu; + if (ht != HTNOWHERE && ht != HTERROR) ret = menu; } else if (ht == HTSYSMENU) - ret = get_win_sys_menu( menu->hWnd ); + ret = MENU_GetMenu(get_win_sys_menu( menu->hWnd )); else if (ht == HTMENU) - ret = GetMenu( menu->hWnd ); + ret = MENU_GetMenu(GetMenu( menu->hWnd )); } return ret; } @@ -2502,19 +2479,18 @@ static HMENU MENU_PtMenu( HMENU hMenu, POINT pt ) * sending unwanted message. * */ -static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags ) +static INT MENU_ExecFocusedItem( MTRACKER* pmt, POPUPMENU *menu, UINT wFlags ) { MENUITEM *item; - POPUPMENU *menu = MENU_GetMenu( hMenu );
- TRACE("%p hmenu=%p\n", pmt, hMenu); + TRACE("%p menu=%p\n", pmt, menu);
if (!menu || !menu->nItems || (menu->FocusedItem == NO_SELECTED_ITEM)) return -1;
item = &menu->items[menu->FocusedItem];
- TRACE("hMenu %p wID %08lx hSubMenu %p fType %04x\n", hMenu, item->wID, item->hSubMenu, item->fType); + TRACE("menu %p wID %08lx hSubMenu %p fType %04x\n", menu, item->wID, item->hSubMenu, item->fType);
if (!(item->fType & MF_POPUP)) { @@ -2529,12 +2505,11 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags ) MAKELPARAM((INT16)pmt->pt.x, (INT16)pmt->pt.y) ); else { - POPUPMENU *topmenu = MENU_GetMenu( pmt->hTopMenu ); - DWORD dwStyle = menu->dwStyle | (topmenu ? topmenu->dwStyle : 0); + DWORD dwStyle = menu->dwStyle | (pmt->top_menu ? pmt->top_menu->dwStyle : 0);
if (dwStyle & MNS_NOTIFYBYPOS) PostMessageW( pmt->hOwnerWnd, WM_MENUCOMMAND, menu->FocusedItem, - (LPARAM)hMenu); + (LPARAM)MENU_GetHandle(menu)); else PostMessageW( pmt->hOwnerWnd, WM_COMMAND, item->wID, 0 ); } @@ -2544,8 +2519,8 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags ) } else { - pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hMenu, TRUE, wFlags); - return -2; + pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, menu, TRUE, wFlags); + return -2; }
return -1; @@ -2556,20 +2531,17 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags ) * * Helper function for menu navigation routines. */ -static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFlags ) +static void MENU_SwitchTracking( MTRACKER* pmt, POPUPMENU *ptmenu, UINT id, UINT wFlags ) { - POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); - POPUPMENU *topmenu = MENU_GetMenu( pmt->hTopMenu ); - - TRACE("%p hmenu=%p 0x%04x\n", pmt, hPtMenu, id); + TRACE("%p ptmenu=%p 0x%04x\n", pmt, ptmenu, id);
- if( pmt->hTopMenu != hPtMenu && - !((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) ) + if (pmt->top_menu != ptmenu && + !((ptmenu->wFlags | pmt->top_menu->wFlags) & MF_POPUP)) { /* both are top level menus (system and menu-bar) */ - MENU_HideSubPopups( pmt->hOwnerWnd, topmenu, FALSE, wFlags ); - MENU_SelectItem( pmt->hOwnerWnd, topmenu, NO_SELECTED_ITEM, FALSE, 0 ); - pmt->hTopMenu = hPtMenu; + MENU_HideSubPopups( pmt->hOwnerWnd, pmt->top_menu, FALSE, wFlags ); + MENU_SelectItem( pmt->hOwnerWnd, pmt->top_menu, NO_SELECTED_ITEM, FALSE, 0 ); + pmt->top_menu = ptmenu; } else MENU_HideSubPopups( pmt->hOwnerWnd, ptmenu, FALSE, wFlags ); @@ -2582,14 +2554,13 @@ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id, UINT wFl * * Return TRUE if we can go on with menu tracking. */ -static BOOL MENU_ButtonDown( MTRACKER* pmt, UINT message, HMENU hPtMenu, UINT wFlags ) +static BOOL MENU_ButtonDown( MTRACKER* pmt, UINT message, POPUPMENU *ptmenu, UINT wFlags ) { - TRACE("%p hPtMenu=%p\n", pmt, hPtMenu); + TRACE("%p ptmenu=%p\n", pmt, ptmenu);
- if (hPtMenu) + if (ptmenu) { UINT pos; - POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); enum hittest ht = ht_item;
if( IS_SYSTEM_MENU(ptmenu) ) @@ -2603,11 +2574,11 @@ static BOOL MENU_ButtonDown( MTRACKER* pmt, UINT message, HMENU hPtMenu, UINT wF if (pos != NO_SELECTED_ITEM) { if (ptmenu->FocusedItem != pos) - MENU_SwitchTracking( pmt, hPtMenu, pos, wFlags ); + MENU_SwitchTracking( pmt, ptmenu, pos, wFlags );
/* If the popup menu is not already "popped" */ if (!(ptmenu->items[pos].fState & MF_MOUSESELECT)) - pmt->hCurrentMenu = MENU_ShowSubPopup( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags ); + pmt->current_menu = MENU_ShowSubPopup( pmt->hOwnerWnd, ptmenu, FALSE, wFlags ); }
/* A click on an item or anywhere on a popup keeps tracking going */ @@ -2625,14 +2596,13 @@ static BOOL MENU_ButtonDown( MTRACKER* pmt, UINT message, HMENU hPtMenu, UINT wF * A -1 return value indicates that we go on with menu tracking. * */ -static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags) +static INT MENU_ButtonUp( MTRACKER* pmt, POPUPMENU *ptmenu, UINT wFlags) { - TRACE("%p hmenu=%p\n", pmt, hPtMenu); + TRACE("%p ptmenu=%p\n", pmt, ptmenu);
- if (hPtMenu) + if (ptmenu) { UINT pos; - POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu );
if( IS_SYSTEM_MENU(ptmenu) ) pos = 0; @@ -2645,7 +2615,7 @@ static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags)
if (!(ptmenu->items[pos].fType & MF_POPUP)) { - INT executedMenuId = MENU_ExecFocusedItem( pmt, hPtMenu, wFlags); + INT executedMenuId = MENU_ExecFocusedItem( pmt, ptmenu, wFlags); if (executedMenuId == -1 || executedMenuId == -2) return -1; return executedMenuId; } @@ -2653,10 +2623,10 @@ static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags) /* If we are dealing with the menu bar */ /* and this is a click on an already "popped" item: */ /* Stop the menu tracking and close the opened submenus */ - if(((pmt->hTopMenu == hPtMenu) || IS_SYSTEM_MENU(ptmenu)) && (pmt->trackFlags & TF_RCVD_BTN_UP)) + if (((pmt->top_menu == ptmenu) || IS_SYSTEM_MENU(ptmenu)) && (pmt->trackFlags & TF_RCVD_BTN_UP)) return 0; } - if( GetMenu(ptmenu->hWnd) == hPtMenu || IS_SYSTEM_MENU(ptmenu) ) + if ( GetMenu(ptmenu->hWnd) == MENU_GetHandle(ptmenu) || IS_SYSTEM_MENU(ptmenu) ) { if (pos == NO_SELECTED_ITEM) return 0; pmt->trackFlags |= TF_RCVD_BTN_UP; @@ -2671,14 +2641,12 @@ static INT MENU_ButtonUp( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags) * * Return TRUE if we can go on with menu tracking. */ -static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags ) +static BOOL MENU_MouseMove( MTRACKER* pmt, POPUPMENU *ptmenu, UINT wFlags ) { UINT id = NO_SELECTED_ITEM; - POPUPMENU *ptmenu = NULL;
- if( hPtMenu ) + if (ptmenu) { - ptmenu = MENU_GetMenu( hPtMenu ); if( IS_SYSTEM_MENU(ptmenu) ) id = 0; else if (MENU_FindItemByCoords( ptmenu, pmt->pt, &id ) != ht_item) @@ -2687,13 +2655,12 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags )
if( id == NO_SELECTED_ITEM ) { - MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hCurrentMenu), - NO_SELECTED_ITEM, TRUE, MENU_GetMenu(pmt->hTopMenu)); + MENU_SelectItem( pmt->hOwnerWnd, pmt->current_menu, NO_SELECTED_ITEM, TRUE, pmt->top_menu); } else if( ptmenu->FocusedItem != id ) { - MENU_SwitchTracking( pmt, hPtMenu, id, wFlags ); - pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hPtMenu, FALSE, wFlags); + MENU_SwitchTracking( pmt, ptmenu, id, wFlags ); + pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, ptmenu, FALSE, wFlags); } return TRUE; } @@ -2706,35 +2673,34 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags ) */ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags ) { - POPUPMENU *menu = MENU_GetMenu( pmt->hTopMenu ); BOOL atEnd = FALSE;
/* When skipping left, we need to do something special after the first menu. */ - if (vk == VK_LEFT && menu->FocusedItem == 0) + if (vk == VK_LEFT && pmt->top_menu->FocusedItem == 0) { atEnd = TRUE; } /* When skipping right, for the non-system menu, we need to handle the last non-special menu item (ie skip any window icons such as MDI maximize, restore or close) */ - else if ((vk == VK_RIGHT) && !IS_SYSTEM_MENU(menu)) + else if ((vk == VK_RIGHT) && !IS_SYSTEM_MENU(pmt->top_menu)) { - UINT i = menu->FocusedItem + 1; - while (i < menu->nItems) { - if ((menu->items[i].wID >= SC_SIZE && - menu->items[i].wID <= SC_RESTORE)) { + UINT i = pmt->top_menu->FocusedItem + 1; + while (i < pmt->top_menu->nItems) { + if ((pmt->top_menu->items[i].wID >= SC_SIZE && + pmt->top_menu->items[i].wID <= SC_RESTORE)) { i++; } else break; } - if (i == menu->nItems) { + if (i == pmt->top_menu->nItems) { atEnd = TRUE; } } /* When skipping right, we need to cater for the system menu */ - else if ((vk == VK_RIGHT) && IS_SYSTEM_MENU(menu)) + else if ((vk == VK_RIGHT) && IS_SYSTEM_MENU(pmt->top_menu)) { - if (menu->FocusedItem == (menu->nItems - 1)) { + if (pmt->top_menu->FocusedItem == (pmt->top_menu->nItems - 1)) { atEnd = TRUE; } } @@ -2746,19 +2712,19 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags ) HWND hNewWnd; UINT id = 0;
- next_menu.hmenuIn = (IS_SYSTEM_MENU(menu)) ? GetSubMenu(pmt->hTopMenu,0) : pmt->hTopMenu; + next_menu.hmenuIn = (IS_SYSTEM_MENU(pmt->top_menu)) ? GetSubMenu(MENU_GetHandle(pmt->top_menu), 0) : MENU_GetHandle(pmt->top_menu); next_menu.hmenuNext = 0; next_menu.hwndNext = 0; SendMessageW( pmt->hOwnerWnd, WM_NEXTMENU, vk, (LPARAM)&next_menu );
TRACE("%p [%p] -> %p [%p]\n", - pmt->hCurrentMenu, pmt->hOwnerWnd, next_menu.hmenuNext, next_menu.hwndNext ); + pmt->current_menu, pmt->hOwnerWnd, next_menu.hmenuNext, next_menu.hwndNext );
if (!next_menu.hmenuNext || !next_menu.hwndNext) { DWORD style = GetWindowLongW( pmt->hOwnerWnd, GWL_STYLE ); hNewWnd = pmt->hOwnerWnd; - if( IS_SYSTEM_MENU(menu) ) + if (IS_SYSTEM_MENU(pmt->top_menu)) { /* switch to the menu bar */
@@ -2766,7 +2732,7 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags )
if( vk == VK_LEFT ) { - menu = MENU_GetMenu( hNewMenu ); + POPUPMENU *menu = MENU_GetMenu( hNewMenu ); id = menu->nItems - 1;
/* Skip backwards over any system predefined icons, @@ -2810,13 +2776,12 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags ) else return FALSE; }
- if( hNewMenu != pmt->hTopMenu ) - { - MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), NO_SELECTED_ITEM, - FALSE, 0 ); - if( pmt->hCurrentMenu != pmt->hTopMenu ) - MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); - } + if (pmt->top_menu && hNewMenu != MENU_GetHandle(pmt->top_menu)) + { + MENU_SelectItem( pmt->hOwnerWnd, pmt->top_menu, NO_SELECTED_ITEM, FALSE, 0 ); + if (pmt->current_menu != pmt->top_menu) + MENU_HideSubPopups( pmt->hOwnerWnd, pmt->top_menu, FALSE, wFlags ); + }
if( hNewWnd != pmt->hOwnerWnd ) { @@ -2824,8 +2789,8 @@ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk, UINT wFlags ) set_capture_window( pmt->hOwnerWnd, GUI_INMENUMODE, NULL ); }
- pmt->hTopMenu = pmt->hCurrentMenu = hNewMenu; /* all subpopups are hidden */ - MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), id, TRUE, 0 ); + pmt->top_menu = pmt->current_menu = MENU_GetMenu(hNewMenu); /* all subpopups are hidden */ + MENU_SelectItem( pmt->hOwnerWnd, pmt->top_menu, id, TRUE, 0 );
return TRUE; } @@ -2879,25 +2844,23 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags) { BOOL bEndMenu = TRUE;
- if (pmt->hCurrentMenu != pmt->hTopMenu) + if (pmt->current_menu != pmt->top_menu) { - POPUPMENU *menu = MENU_GetMenu(pmt->hCurrentMenu); - - if (menu->wFlags & MF_POPUP) + if (pmt->current_menu->wFlags & MF_POPUP) { - HMENU hmenutmp, hmenuprev; + POPUPMENU *menutmp, *menuprev;
- hmenuprev = hmenutmp = pmt->hTopMenu; + menuprev = menutmp = pmt->top_menu;
/* close topmost popup */ - while (hmenutmp != pmt->hCurrentMenu) + while (menutmp != pmt->current_menu) { - hmenuprev = hmenutmp; - hmenutmp = MENU_GetSubPopup( hmenuprev ); + menuprev = menutmp; + menutmp = MENU_GetSubPopup( menuprev ); }
- MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags ); - pmt->hCurrentMenu = hmenuprev; + MENU_HideSubPopups( pmt->hOwnerWnd, menuprev, TRUE, wFlags ); + pmt->current_menu = menuprev; bEndMenu = FALSE; } } @@ -2912,46 +2875,42 @@ static BOOL MENU_KeyEscape(MTRACKER* pmt, UINT wFlags) */ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags, UINT msg ) { - POPUPMENU *menu; - HMENU hmenutmp, hmenuprev; + POPUPMENU *menu, *menutmp, *menuprev; UINT prevcol;
- hmenuprev = hmenutmp = pmt->hTopMenu; - menu = MENU_GetMenu( hmenutmp ); + menu = menuprev = menutmp = pmt->top_menu;
/* Try to move 1 column left (if possible) */ - if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) != - NO_SELECTED_ITEM ) { - - MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hCurrentMenu), prevcol, TRUE, 0 ); - return; + if ((prevcol = MENU_GetStartOfPrevColumn( pmt->current_menu )) != NO_SELECTED_ITEM ) + { + MENU_SelectItem( pmt->hOwnerWnd, pmt->current_menu, prevcol, TRUE, 0 ); + return; }
/* close topmost popup */ - while (hmenutmp != pmt->hCurrentMenu) + while (menutmp != pmt->current_menu) { - hmenuprev = hmenutmp; - hmenutmp = MENU_GetSubPopup( hmenuprev ); + menuprev = menutmp; + menutmp = MENU_GetSubPopup( menuprev ); }
- MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(hmenuprev), TRUE, wFlags ); - pmt->hCurrentMenu = hmenuprev; + MENU_HideSubPopups( pmt->hOwnerWnd, menuprev, TRUE, wFlags ); + pmt->current_menu = menuprev;
- if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) ) + if ((menuprev == pmt->top_menu) && !(menu->wFlags & MF_POPUP)) { /* move menu bar selection if no more popups are left */
if( !MENU_DoNextMenu( pmt, VK_LEFT, wFlags ) ) - MENU_MoveSelection( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), ITEM_PREV ); + MENU_MoveSelection( pmt->hOwnerWnd, pmt->top_menu, ITEM_PREV );
- if ( hmenuprev != hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) + if ( menuprev != menutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) { /* A sublevel menu was displayed - display the next one * unless there is another displacement coming up */
if( !MENU_SuspendPopup( pmt, msg ) ) - pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, - pmt->hTopMenu, TRUE, wFlags); + pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, pmt->top_menu, TRUE, wFlags); } } } @@ -2964,50 +2923,50 @@ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags, UINT msg ) */ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags, UINT msg ) { - HMENU hmenutmp; - POPUPMENU *menu = MENU_GetMenu( pmt->hTopMenu ); + POPUPMENU *menutmp; UINT nextcol;
TRACE("MENU_KeyRight called, cur %p (%s), top %p (%s).\n", - pmt->hCurrentMenu, - debugstr_w((MENU_GetMenu(pmt->hCurrentMenu))->items[0].text), - pmt->hTopMenu, debugstr_w(menu->items[0].text) ); + pmt->current_menu, + debugstr_w(pmt->current_menu->items[0].text), + pmt->top_menu, debugstr_w(pmt->top_menu->items[0].text) );
- if ( (menu->wFlags & MF_POPUP) || (pmt->hCurrentMenu != pmt->hTopMenu)) + if ((pmt->top_menu->wFlags & MF_POPUP) || (pmt->current_menu != pmt->top_menu)) { - /* If already displaying a popup, try to display sub-popup */ + /* If already displaying a popup, try to display sub-popup */
- hmenutmp = pmt->hCurrentMenu; - pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hmenutmp, TRUE, wFlags); + menutmp = pmt->current_menu; + pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, menutmp, TRUE, wFlags);
- /* if subpopup was displayed then we are done */ - if (hmenutmp != pmt->hCurrentMenu) return; + /* if subpopup was displayed then we are done */ + if (menutmp != pmt->current_menu) return; }
/* Check to see if there's another column */ - if( (nextcol = MENU_GetStartOfNextColumn( pmt->hCurrentMenu )) != - NO_SELECTED_ITEM ) { + if ( (nextcol = MENU_GetStartOfNextColumn( pmt->current_menu )) != NO_SELECTED_ITEM ) + { TRACE("Going to %d.\n", nextcol ); - MENU_SelectItem( pmt->hOwnerWnd, MENU_GetMenu(pmt->hCurrentMenu), nextcol, TRUE, 0 ); + MENU_SelectItem( pmt->hOwnerWnd, pmt->current_menu, nextcol, TRUE, 0 ); return; }
- if (!(menu->wFlags & MF_POPUP)) /* menu bar tracking */ + if (!(pmt->top_menu->wFlags & MF_POPUP)) /* menu bar tracking */ { - if( pmt->hCurrentMenu != pmt->hTopMenu ) - { - MENU_HideSubPopups( pmt->hOwnerWnd, MENU_GetMenu(pmt->hTopMenu), FALSE, wFlags ); - hmenutmp = pmt->hCurrentMenu = pmt->hTopMenu; - } else hmenutmp = 0; + if ( pmt->current_menu != pmt->top_menu ) + { + MENU_HideSubPopups( pmt->hOwnerWnd, pmt->top_menu, FALSE, wFlags ); + menutmp = pmt->current_menu = pmt->top_menu; + } + else + menutmp = NULL;
/* try to move to the next item */ if( !MENU_DoNextMenu( pmt, VK_RIGHT, wFlags ) ) - MENU_MoveSelection( pmt->hOwnerWnd, menu, ITEM_NEXT ); + MENU_MoveSelection( pmt->hOwnerWnd, pmt->top_menu, ITEM_NEXT );
- if( hmenutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) + if ( menutmp || pmt->trackFlags & TF_SUSPENDPOPUP ) if( !MENU_SuspendPopup( pmt, msg ) ) - pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, - pmt->hTopMenu, TRUE, wFlags); + pmt->current_menu = MENU_ShowSubPopup(pmt->hOwnerWnd, pmt->top_menu, TRUE, wFlags); } }
@@ -3021,11 +2980,10 @@ static void CALLBACK release_capture( BOOL __normal ) * * Menu tracking code. */ -static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, +static BOOL MENU_TrackMenu( POPUPMENU *menu, UINT wFlags, INT x, INT y, HWND hwnd, const RECT *lprect ) { MSG msg; - POPUPMENU *menu; BOOL fRemove; INT executedMenuId = -1; MTRACKER mt; @@ -3033,18 +2991,15 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, HWND capture_win;
mt.trackFlags = 0; - mt.hCurrentMenu = hmenu; - mt.hTopMenu = hmenu; + mt.current_menu = mt.top_menu = menu; mt.hOwnerWnd = WIN_GetFullHandle( hwnd ); mt.pt.x = x; mt.pt.y = y;
- TRACE("hmenu=%p flags=0x%08x (%d,%d) hwnd=%p %s\n", - hmenu, wFlags, x, y, hwnd, wine_dbgstr_rect( lprect)); + TRACE("menu=%p flags=0x%08x (%d,%d) hwnd=%p %s\n", menu, wFlags, x, y, hwnd, wine_dbgstr_rect( lprect));
- if (!(menu = MENU_GetMenu( hmenu ))) + if (!menu) { - WARN("Invalid menu handle %p\n", hmenu); SetLastError(ERROR_INVALID_MENU_HANDLE); return FALSE; } @@ -3052,7 +3007,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, if (wFlags & TPM_BUTTONDOWN) { /* Get the result in order to start the tracking or not */ - fRemove = MENU_ButtonDown( &mt, WM_LBUTTONDOWN, hmenu, wFlags ); + fRemove = MENU_ButtonDown( &mt, WM_LBUTTONDOWN, menu, wFlags ); fEndMenu = !fRemove; }
@@ -3067,7 +3022,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
__TRY while (!fEndMenu) { - menu = MENU_GetMenu( mt.hCurrentMenu ); + menu = mt.current_menu; if (!menu) /* sometimes happens if I do a window manager close */ break;
@@ -3124,7 +3079,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, mt.pt.y = (short)HIWORD(msg.lParam);
/* Find a menu for this mouse event */ - hmenu = MENU_PtMenu( mt.hTopMenu, mt.pt ); + menu = MENU_PtMenu( mt.top_menu, mt.pt );
switch(msg.message) { @@ -3138,7 +3093,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, case WM_LBUTTONDOWN: /* If the message belongs to the menu, removes it from the queue */ /* Else, end menu tracking */ - fRemove = MENU_ButtonDown( &mt, msg.message, hmenu, wFlags ); + fRemove = MENU_ButtonDown( &mt, msg.message, menu, wFlags ); fEndMenu = !fRemove; break;
@@ -3147,9 +3102,9 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, /* fall through */ case WM_LBUTTONUP: /* Check if a menu was selected by the mouse */ - if (hmenu) + if (menu) { - executedMenuId = MENU_ButtonUp( &mt, hmenu, wFlags); + executedMenuId = MENU_ButtonUp(&mt, menu, wFlags); TRACE("executedMenuId %d\n", executedMenuId);
/* End the loop if executedMenuId is an item ID */ @@ -3168,8 +3123,8 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, /* the selected menu item must be changed every time */ /* the mouse moves. */
- if (hmenu) - fEndMenu |= !MENU_MouseMove( &mt, hmenu, wFlags ); + if (menu) + fEndMenu |= !MENU_MouseMove( &mt, menu, wFlags );
} /* switch(msg.message) - mouse */ } @@ -3189,21 +3144,18 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
case VK_HOME: case VK_END: - MENU_SelectItem( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), - NO_SELECTED_ITEM, FALSE, 0 ); - MENU_MoveSelection( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), - (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV ); + MENU_SelectItem( mt.hOwnerWnd, mt.current_menu, NO_SELECTED_ITEM, FALSE, 0 ); + MENU_MoveSelection( mt.hOwnerWnd, mt.current_menu, (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV ); break;
case VK_UP: case VK_DOWN: /* If on menu bar, pull-down the menu */
- menu = MENU_GetMenu( mt.hCurrentMenu ); + menu = mt.current_menu; if (!(menu->wFlags & MF_POPUP)) - mt.hCurrentMenu = MENU_ShowSubPopup(mt.hOwnerWnd, mt.hTopMenu, TRUE, wFlags); + mt.current_menu = MENU_ShowSubPopup(mt.hOwnerWnd, mt.top_menu, TRUE, wFlags); else /* otherwise try to move selection */ - MENU_MoveSelection( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), - (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT ); + MENU_MoveSelection( mt.hOwnerWnd, mt.current_menu, (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT ); break;
case VK_LEFT: @@ -3227,7 +3179,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, hi.iCtrlId = 0; else hi.iCtrlId = menu->items[menu->FocusedItem].wID; - hi.hItemHandle = hmenu; + hi.hItemHandle = MENU_GetHandle(menu); hi.dwContextId = menu->dwContextHelpID; hi.MousePos = msg.pt; SendMessageW(hwnd, WM_HELP, 0, (LPARAM)&hi); @@ -3247,7 +3199,7 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y,
if (msg.wParam == '\r' || msg.wParam == ' ') { - executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags); + executedMenuId = MENU_ExecFocusedItem(&mt, mt.current_menu, wFlags); fEndMenu = (executedMenuId != -2);
break; @@ -3257,14 +3209,13 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, /* We will find a better way real soon... */ if (msg.wParam < 32) break;
- pos = MENU_FindItemByKey( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), - LOWORD(msg.wParam), FALSE ); + pos = MENU_FindItemByKey( mt.hOwnerWnd, mt.current_menu, LOWORD(msg.wParam), FALSE ); if (pos == (UINT)-2) fEndMenu = TRUE; else if (pos == (UINT)-1) MessageBeep(0); else { - MENU_SelectItem( mt.hOwnerWnd, MENU_GetMenu(mt.hCurrentMenu), pos, TRUE, 0 ); - executedMenuId = MENU_ExecFocusedItem(&mt,mt.hCurrentMenu, wFlags); + MENU_SelectItem( mt.hOwnerWnd, mt.current_menu, pos, TRUE, 0 ); + executedMenuId = MENU_ExecFocusedItem(&mt, mt.current_menu, wFlags); fEndMenu = (executedMenuId != -2); } } @@ -3292,24 +3243,22 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, then the menu will be destroyed as part of the DispatchMessage above. This will then invalidate the menu handle in mt.hTopMenu. We should check for this first. */ - if( IsMenu( mt.hTopMenu ) ) + if (mt.top_menu) { - menu = MENU_GetMenu( mt.hTopMenu ); - if( IsWindow( mt.hOwnerWnd ) ) { - MENU_HideSubPopups( mt.hOwnerWnd, menu, FALSE, wFlags ); + MENU_HideSubPopups( mt.hOwnerWnd, mt.top_menu, FALSE, wFlags );
- if (menu && (menu->wFlags & MF_POPUP)) + if (mt.top_menu && (mt.top_menu->wFlags & MF_POPUP)) { - DestroyWindow( menu->hWnd ); - menu->hWnd = 0; + DestroyWindow( mt.top_menu->hWnd ); + mt.top_menu->hWnd = 0;
if (!(wFlags & TPM_NONOTIFY)) - SendMessageW( mt.hOwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.hTopMenu, - MAKELPARAM(0, IS_SYSTEM_MENU(menu)) ); + SendMessageW( mt.hOwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.top_menu, + MAKELPARAM(0, IS_SYSTEM_MENU(mt.top_menu)) ); } - MENU_SelectItem( mt.hOwnerWnd, MENU_GetMenu(mt.hTopMenu), NO_SELECTED_ITEM, FALSE, 0 ); + MENU_SelectItem( mt.hOwnerWnd, mt.top_menu, NO_SELECTED_ITEM, FALSE, 0 ); SendMessageW( mt.hOwnerWnd, WM_MENUSELECT, MAKEWPARAM(0,0xffff), 0 ); } } @@ -3324,15 +3273,14 @@ static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, INT x, INT y, /*********************************************************************** * MENU_InitTracking */ -static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags) +static BOOL MENU_InitTracking(HWND hWnd, POPUPMENU *menu, BOOL bPopup, UINT wFlags) { - POPUPMENU *menu; - - TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu); + TRACE("hwnd=%p menu=%p\n", hWnd, menu);
HideCaret(0);
- if (!(menu = MENU_GetMenu( hMenu ))) return FALSE; + if (!menu) + return FALSE;
/* This makes the menus of applications built with Delphi work. * It also enables menus to be displayed in more than one window, @@ -3342,7 +3290,7 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags) if (!top_popup) { top_popup = menu->hWnd; - top_popup_hmenu = hMenu; + top_popup_hmenu = MENU_GetHandle(menu); }
fEndMenu = FALSE; @@ -3355,7 +3303,7 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
if (!(wFlags & TPM_NONOTIFY)) { - SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 ); + SendMessageW( hWnd, WM_INITMENU, (WPARAM)MENU_GetHandle(menu), 0 ); /* If an app changed/recreated menu bar entries in WM_INITMENU * menu sizes will be recalculated once the menu created/shown. */ @@ -3393,11 +3341,11 @@ void MENU_TrackMouseMenuBar( HWND hWnd, INT ht, POINT pt ) if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL; if (IsMenu(hMenu)) { - MENU_InitTracking( hWnd, hMenu, FALSE, wFlags ); + MENU_InitTracking( hWnd, MENU_GetMenu(hMenu), FALSE, wFlags );
/* fetch the window menu again, it may have changed */ hMenu = (ht == HTSYSMENU) ? get_win_sys_menu( hWnd ) : GetMenu( hWnd ); - MENU_TrackMenu( hMenu, wFlags, pt.x, pt.y, hWnd, NULL ); + MENU_TrackMenu( MENU_GetMenu(hMenu), wFlags, pt.x, pt.y, hWnd, NULL ); MENU_ExitTracking(hWnd, FALSE); } } @@ -3413,6 +3361,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar) UINT uItem = NO_SELECTED_ITEM; HMENU hTrackMenu; UINT wFlags = TPM_LEFTALIGN | TPM_LEFTBUTTON; + POPUPMENU *trackmenu;
TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hwnd, wParam, wChar);
@@ -3433,16 +3382,18 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar) } if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
- if (!IsMenu( hTrackMenu )) return; + trackmenu = MENU_GetMenu(hTrackMenu); + if (!trackmenu) return;
- MENU_InitTracking( hwnd, hTrackMenu, FALSE, wFlags ); + MENU_InitTracking( hwnd, trackmenu, FALSE, wFlags );
/* fetch the window menu again, it may have changed */ hTrackMenu = (wParam & HTSYSMENU) ? get_win_sys_menu( hwnd ) : GetMenu( hwnd ); + trackmenu = MENU_GetMenu(hTrackMenu);
if( wChar && wChar != ' ' ) { - uItem = MENU_FindItemByKey( hwnd, MENU_GetMenu(hTrackMenu), wChar, (wParam & HTSYSMENU) ); + uItem = MENU_FindItemByKey( hwnd, trackmenu, wChar, (wParam & HTSYSMENU) ); if ( uItem >= (UINT)(-2) ) { if( uItem == (UINT)(-1) ) MessageBeep(0); @@ -3463,7 +3414,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar) }
track_menu: - MENU_TrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL ); + MENU_TrackMenu( trackmenu, wFlags, 0, 0, hwnd, NULL ); MENU_ExitTracking( hwnd, FALSE ); }
@@ -3481,8 +3432,6 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y, lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" );
/* Parameter check */ - /* FIXME: this check is performed several times, here and in the called - functions. That could be optimized */ if (!(menu = MENU_GetMenu( hMenu ))) { SetLastError( ERROR_INVALID_MENU_HANDLE ); @@ -3497,7 +3446,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
if (MENU_InitPopup( hWnd, menu, wFlags )) { - MENU_InitTracking(hWnd, hMenu, TRUE, wFlags); + MENU_InitTracking(hWnd, menu, TRUE, wFlags);
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */ if (!(wFlags & TPM_NONOTIFY)) @@ -3507,8 +3456,8 @@ BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y, MENU_InitSysMenuPopup( hMenu, GetWindowLongW( hWnd, GWL_STYLE ), GetClassLongW( hWnd, GCL_STYLE));
- if (MENU_ShowPopup( hWnd, MENU_GetMenu(hMenu), 0, wFlags, x, y, 0, 0 )) - ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, + if (MENU_ShowPopup( hWnd, menu, 0, wFlags, x, y, 0, 0 )) + ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, lpTpm ? &lpTpm->rcExclude : NULL ); MENU_ExitTracking(hWnd, TRUE);
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/menu.c | 141 +++++++++++++++++++++++++---------------------- dlls/user32/tests/menu.c | 4 +- 2 files changed, 77 insertions(+), 68 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index c8d30eba17..284e48fab5 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -62,13 +62,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu); WINE_DECLARE_DEBUG_CHANNEL(accel);
+typedef struct _POPUPMENU POPUPMENU; + /* Menu item structure */ typedef struct { /* ----------- MENUITEMINFO Stuff ----------- */ UINT fType; /* Item type. */ UINT fState; /* Item state. */ UINT_PTR wID; /* Item id. */ - HMENU hSubMenu; /* Pop-up menu. */ + POPUPMENU *submenu; /* Pop-up menu. */ HBITMAP hCheckBit; /* Bitmap when checked. */ HBITMAP hUnCheckBit; /* Bitmap when unchecked. */ LPWSTR text; /* Item text. */ @@ -84,7 +86,8 @@ typedef struct { } MENUITEM;
/* Popup menu structure */ -typedef struct { +struct _POPUPMENU +{ struct user_object obj; WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ WORD Width; /* Width of the whole menu */ @@ -107,7 +110,7 @@ typedef struct { DWORD dwMenuData; /* application defined value */ HMENU hSysMenuOwner; /* Handle to the dummy sys menu holder */ WORD textOffset; /* Offset of text when items have both bitmaps and text */ -} POPUPMENU, *LPPOPUPMENU; +};
/* internal flags for menu tracking */
@@ -229,8 +232,8 @@ static void do_debug_print_menuitem(const char *prefix, const MENUITEM *mp, if (mp) { UINT flags = mp->fType; TRACE( "{ ID=0x%lx", mp->wID); - if ( mp->hSubMenu) - TRACE( ", Sub=%p", mp->hSubMenu); + if ( mp->submenu) + TRACE( ", Sub=%p", mp->submenu); if (flags) { int count = 0; TRACE( ", fType="); @@ -570,7 +573,7 @@ static MENUITEM *MENU_FindItem( POPUPMENU **pmenu, UINT *nPos, UINT wFlags ) { if (item->fType & MF_POPUP) { - POPUPMENU *submenu = MENU_GetMenu(item->hSubMenu); + POPUPMENU *submenu = item->submenu; MENUITEM *subitem = MENU_FindItem( &submenu, nPos, wFlags ); if (subitem) { @@ -617,12 +620,12 @@ static UINT MENU_FindSubMenu( POPUPMENU **pmenu, POPUPMENU *subTarget ) item = menu->items; for (i = 0; i < menu->nItems; i++, item++) { if(!(item->fType & MF_POPUP)) continue; - if (item->hSubMenu == MENU_GetHandle(subTarget)) + if (item->submenu == subTarget) { return i; } else { - POPUPMENU *submenu = MENU_GetMenu(item->hSubMenu); + POPUPMENU *submenu = item->submenu; UINT pos = MENU_FindSubMenu( &submenu, subTarget ); if (pos != NO_SELECTED_ITEM) { *pmenu = submenu; @@ -1131,7 +1134,7 @@ static void MENU_CalcItemSize( HDC hdc, MENUITEM *lpitem, HWND hwndOwner, * * Calculate the size of a popup menu. */ -static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, UINT max_height ) +static void MENU_PopupMenuCalcSize( POPUPMENU *lppop, UINT max_height ) { MENUITEM *lpitem; HDC hdc; @@ -1237,7 +1240,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, UINT max_height ) * Calculate the size of the menu bar. */ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, - LPPOPUPMENU lppop, HWND hwndOwner ) + POPUPMENU *lppop, HWND hwndOwner ) { MENUITEM *lpitem; UINT start, i, helpPos; @@ -1807,7 +1810,7 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu ) */ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd ) { - LPPOPUPMENU lppop; + POPUPMENU *lppop; HMENU hMenu = GetMenu(hwnd);
lppop = MENU_GetMenu( hMenu ); @@ -1943,7 +1946,7 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, POPUPMENU *menu, UINT id, UINT flags * MENU_EnsureMenuItemVisible */ static void -MENU_EnsureMenuItemVisible(LPPOPUPMENU lppop, UINT wIndex, HDC hdc) +MENU_EnsureMenuItemVisible(POPUPMENU *lppop, UINT wIndex, HDC hdc) { if (lppop->bScrolling) { @@ -2254,7 +2257,7 @@ static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu) /*********************************************************************** * MENU_GetSubPopup * - * Return the handle of the selected sub-popup menu (if any). + * Return the selected sub-popup menu (if any). */ static POPUPMENU *MENU_GetSubPopup( POPUPMENU *menu ) { @@ -2264,7 +2267,7 @@ static POPUPMENU *MENU_GetSubPopup( POPUPMENU *menu )
item = &menu->items[menu->FocusedItem]; if ((item->fType & MF_POPUP) && (item->fState & MF_MOUSESELECT)) - return MENU_GetMenu(item->hSubMenu); + return item->submenu;
return NULL; } @@ -2291,7 +2294,7 @@ static void MENU_HideSubPopups( HWND hwndOwner, POPUPMENU *menu, if (!(item->fType & MF_POPUP) || !(item->fState & MF_MOUSESELECT)) return; item->fState &= ~MF_MOUSESELECT; - submenu = MENU_GetMenu(item->hSubMenu); + submenu = item->submenu; } else return;
if (!submenu) return; @@ -2336,7 +2339,7 @@ static POPUPMENU *MENU_ShowSubPopup( HWND hwndOwner, POPUPMENU *menu,
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */ if (!(wFlags & TPM_NONOTIFY)) - SendMessageW( hwndOwner, WM_INITMENUPOPUP, (WPARAM)item->hSubMenu, + SendMessageW( hwndOwner, WM_INITMENUPOPUP, (WPARAM)MENU_GetHandle(item->submenu), MAKELPARAM( menu->FocusedItem, IS_SYSTEM_MENU(menu) ));
item = &menu->items[menu->FocusedItem]; @@ -2361,7 +2364,7 @@ static POPUPMENU *MENU_ShowSubPopup( HWND hwndOwner, POPUPMENU *menu,
if (IS_SYSTEM_MENU(menu)) { - MENU_InitSysMenuPopup(item->hSubMenu, + MENU_InitSysMenuPopup(MENU_GetHandle(item->submenu), GetWindowLongW( menu->hWnd, GWL_STYLE ), GetClassLongW( menu->hWnd, GCL_STYLE));
@@ -2405,13 +2408,13 @@ static POPUPMENU *MENU_ShowSubPopup( HWND hwndOwner, POPUPMENU *menu, /* use default alignment for submenus */ wFlags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
- MENU_InitPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), wFlags ); + MENU_InitPopup( hwndOwner, item->submenu, wFlags );
- MENU_ShowPopup( hwndOwner, MENU_GetMenu(item->hSubMenu), menu->FocusedItem, wFlags, + MENU_ShowPopup( hwndOwner, item->submenu, menu->FocusedItem, wFlags, rect.left, rect.top, rect.right, rect.bottom ); if (selectFirst) - MENU_MoveSelection( hwndOwner, MENU_GetMenu(item->hSubMenu), ITEM_NEXT ); - return MENU_GetMenu(item->hSubMenu); + MENU_MoveSelection( hwndOwner, item->submenu, ITEM_NEXT ); + return item->submenu; }
@@ -2452,7 +2455,7 @@ static POPUPMENU *MENU_PtMenu( POPUPMENU *menu, POINT pt ) ret = (item != NO_SELECTED_ITEM && (menu->items[item].fType & MF_POPUP) && (menu->items[item].fState & MF_MOUSESELECT)) - ? MENU_PtMenu(MENU_GetMenu(menu->items[item].hSubMenu), pt) : 0; + ? MENU_PtMenu(menu->items[item].submenu, pt) : 0;
if (!ret) /* check the current window (avoiding WM_HITTEST) */ { @@ -2490,7 +2493,7 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, POPUPMENU *menu, UINT wFlags )
item = &menu->items[menu->FocusedItem];
- TRACE("menu %p wID %08lx hSubMenu %p fType %04x\n", menu, item->wID, item->hSubMenu, item->fType); + TRACE("menu %p wID %08lx hSubMenu %p fType %04x\n", menu, item->wID, item->submenu, item->fType);
if (!(item->fType & MF_POPUP)) { @@ -3568,7 +3571,7 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, { HDC hdc; RECT rectBar; - LPPOPUPMENU lppop; + POPUPMENU *lppop;
TRACE("HWND %p, width %d, at (%d, %d).\n", hwnd, menubarWidth, orgX, orgY );
@@ -3771,7 +3774,7 @@ UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags ) debug_print_menuitem (" item: ", item, ""); if (item->fType & MF_POPUP) { - menu = MENU_GetMenu( item->hSubMenu ); + menu = item->submenu; if (!menu) return -1; else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff); } @@ -3790,7 +3793,7 @@ UINT WINAPI GetMenuState( HMENU hMenu, UINT wItemID, UINT wFlags ) */ INT WINAPI GetMenuItemCount( HMENU hMenu ) { - LPPOPUPMENU menu = MENU_GetMenu(hMenu); + POPUPMENU *menu = MENU_GetMenu(hMenu); if (!menu) return -1; TRACE("(%p) returning %d\n", hMenu, menu->nItems ); return menu->nItems; @@ -3940,7 +3943,7 @@ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags )
/* Remove item */ if (item->fType & MF_POPUP) - MENU_ReleaseMenu(MENU_GetMenu(item->hSubMenu)); + MENU_ReleaseMenu(item->submenu);
MENU_FreeItemData( item );
@@ -3974,9 +3977,9 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT nPos, UINT wFlags ) POPUPMENU *menu = MENU_GetMenu(hMenu); MENUITEM *item = MENU_FindItem( &menu, &nPos, wFlags ); if (!item) return FALSE; - if (item->fType & MF_POPUP) DestroyMenu( item->hSubMenu ); + if (item->fType & MF_POPUP) DestroyMenu( MENU_GetHandle(item->submenu) ); /* nPos is now the position of the item */ - RemoveMenu( hMenu, nPos, wFlags | MF_BYPOSITION ); + RemoveMenu( MENU_GetHandle(menu), nPos, wFlags | MF_BYPOSITION ); return TRUE; }
@@ -4088,7 +4091,7 @@ BOOL WINAPI SetMenuItemBitmaps( HMENU hMenu, UINT nPos, UINT wFlags, HMENU WINAPI CreateMenu(void) { HMENU hMenu; - LPPOPUPMENU menu; + POPUPMENU *menu;
if (!(menu = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*menu) ))) return 0; menu->FocusedItem = NO_SELECTED_ITEM; @@ -4128,8 +4131,8 @@ static BOOL MENU_ReleaseMenu( POPUPMENU *lppop ) if (item->fType & MF_POPUP) { /* Release handle if it hasn't already been released. */ - if (!MENU_ReleaseMenu(MENU_GetMenu(item->hSubMenu))) - DestroyMenu(item->hSubMenu); + if (!MENU_ReleaseMenu(item->submenu)) + DestroyMenu(MENU_GetHandle(item->submenu)); } MENU_FreeItemData( item ); } @@ -4300,7 +4303,7 @@ BOOL WINAPI GetMenuBarInfo( HWND hwnd, LONG idObject, LONG idItem, PMENUBARINFO pmbi->fFocused = menu->FocusedItem == idItem - 1; if (pmbi->fFocused && (menu->items[idItem - 1].fType & MF_POPUP)) { - menu = MENU_GetMenu(menu->items[idItem - 1].hSubMenu); + menu = menu->items[idItem - 1].submenu; if (menu) pmbi->hwndMenu = menu->hWnd; } @@ -4337,7 +4340,7 @@ BOOL MENU_SetMenu( HWND hWnd, HMENU hMenu )
if (hMenu != 0) { - LPPOPUPMENU lpmenu; + POPUPMENU *lpmenu;
if (!(lpmenu = MENU_GetMenu(hMenu))) return FALSE;
@@ -4373,7 +4376,7 @@ HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos )
if (!(lpmi = MENU_FindItem(&menu, (UINT *)&nPos, MF_BYPOSITION))) return 0; if (!(lpmi->fType & MF_POPUP)) return 0; - return lpmi->hSubMenu; + return MENU_GetHandle(lpmi->submenu); }
@@ -4382,7 +4385,7 @@ HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos ) */ BOOL WINAPI DrawMenuBar( HWND hWnd ) { - LPPOPUPMENU lppop; + POPUPMENU *lppop; HMENU hMenu;
if (!IsWindow( hWnd )) @@ -4410,7 +4413,7 @@ BOOL WINAPI DrawMenuBar( HWND hWnd ) */ DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont) { - LPPOPUPMENU lppop; + POPUPMENU *lppop; UINT i,retvalue; HFONT hfontOld = 0; BOOL flat_menu = FALSE; @@ -4560,7 +4563,7 @@ HMENU WINAPI LoadMenuIndirectA( LPCVOID template ) */ BOOL WINAPI IsMenu(HMENU hmenu) { - LPPOPUPMENU menu = MENU_GetMenu(hmenu); + POPUPMENU *menu = MENU_GetMenu(hmenu);
if (!menu) { @@ -4662,7 +4665,7 @@ static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT item, BOOL bypos, lpmii->wID = menu->wID;
if (lpmii->fMask & MIIM_SUBMENU) - lpmii->hSubMenu = menu->hSubMenu; + lpmii->hSubMenu = MENU_GetHandle(menu->submenu); else { /* hSubMenu is always cleared * (not on Win9x/ME ) */ @@ -4759,13 +4762,13 @@ static int MENU_depth( POPUPMENU *pmenu, int depth) item = pmenu->items; subdepth = depth; for( i = 0; i < pmenu->nItems && subdepth <= MAXMENUDEPTH; i++, item++){ - POPUPMENU *psubmenu = item->hSubMenu ? MENU_GetMenu( item->hSubMenu) : NULL; - if( psubmenu){ - int bdepth = MENU_depth( psubmenu, depth); + if (item->submenu) + { + int bdepth = MENU_depth(item->submenu, depth); if( bdepth > subdepth) subdepth = bdepth; } if( subdepth > MAXMENUDEPTH) - TRACE("<- hmenu %p\n", item->hSubMenu); + TRACE("<- menu %p\n", item->submenu); } return subdepth; } @@ -4804,22 +4807,30 @@ static BOOL SetMenuItemInfo_common(MENUITEM * menu, if (lpmii->fMask & MIIM_ID) menu->wID = lpmii->wID;
- if (lpmii->fMask & MIIM_SUBMENU) { - if ((menu->fType & MF_POPUP) && menu->hSubMenu) - MENU_ReleaseMenu(MENU_GetMenu(menu->hSubMenu)); - menu->hSubMenu = lpmii->hSubMenu; - if (menu->hSubMenu) { - POPUPMENU *subMenu = MENU_GetMenu(menu->hSubMenu); - if (subMenu) { - if( MENU_depth( subMenu, 0) > MAXMENUDEPTH) { + if (lpmii->fMask & MIIM_SUBMENU) + { + if ((menu->fType & MF_POPUP) && menu->submenu) + { + MENU_ReleaseMenu(menu->submenu); + menu->submenu = NULL; + } + if (lpmii->hSubMenu) + { + menu->submenu = MENU_GetMenu(lpmii->hSubMenu); + if (menu->submenu) + { + if (MENU_depth( menu->submenu, 0) > MAXMENUDEPTH) + { ERR( "Loop detected in menu hierarchy or maximum menu depth exceeded!\n"); - menu->hSubMenu = 0; + menu->submenu = NULL; return FALSE; } - subMenu->wFlags |= MF_POPUP; - menu->fType |= MF_POPUP; - InterlockedIncrement(&subMenu->refcount); - } else { + menu->submenu->wFlags |= MF_POPUP; + menu->fType |= MF_POPUP; + InterlockedIncrement(&menu->submenu->refcount); + } + else + { SetLastError( ERROR_INVALID_PARAMETER); return FALSE; } @@ -5012,11 +5023,11 @@ UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags) /* default: don't return disabled items */ if ( (!(GMDI_USEDISABLED & flags)) && (item->fState & MFS_DISABLED )) return -1;
- /* search rekursiv when needed */ + /* search recursively when needed */ if ( (item->fType & MF_POPUP) && (flags & GMDI_GOINTOPOPUPS) ) { UINT ret; - ret = GetMenuDefaultItem( item->hSubMenu, bypos, flags ); + ret = GetMenuDefaultItem( MENU_GetHandle(item->submenu), bypos, flags ); if ( -1 != ret ) return ret;
/* when item not found in submenu, return the popup item */ @@ -5150,10 +5161,10 @@ BOOL WINAPI GetMenuItemRect(HWND hwnd, HMENU hMenu, UINT uItem, RECT *rect) * actually use the items to draw the menu * (recalculate and/or redraw) */ -static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi) +static BOOL menu_SetMenuInfo( POPUPMENU *menu, LPCMENUINFO lpmi) { - POPUPMENU *menu; - if( !(menu = MENU_GetMenu(hMenu))) return FALSE; + if (!menu) + return FALSE;
if (lpmi->fMask & MIM_BACKGROUND) menu->hbrBack = lpmi->hbrBack; @@ -5175,7 +5186,7 @@ static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi) MENUITEM *item = menu->items; for( i = menu->nItems; i; i--, item++) if( item->fType & MF_POPUP) - menu_SetMenuInfo( item->hSubMenu, lpmi); + menu_SetMenuInfo( item->submenu, lpmi); } return TRUE; } @@ -5183,7 +5194,7 @@ static BOOL menu_SetMenuInfo( HMENU hMenu, LPCMENUINFO lpmi) BOOL WINAPI SetMenuInfo (HMENU hMenu, LPCMENUINFO lpmi) { TRACE("(%p %p)\n", hMenu, lpmi); - if( lpmi && (lpmi->cbSize == sizeof( MENUINFO)) && (menu_SetMenuInfo( hMenu, lpmi))) { + if( lpmi && (lpmi->cbSize == sizeof( MENUINFO)) && (menu_SetMenuInfo( MENU_GetMenu(hMenu), lpmi))) { if( lpmi->fMask & MIM_STYLE) { if (lpmi->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented\n"); if (lpmi->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented\n"); @@ -5237,7 +5248,7 @@ BOOL WINAPI GetMenuInfo (HMENU hMenu, LPMENUINFO lpmi) */ BOOL WINAPI SetMenuContextHelpId( HMENU hMenu, DWORD dwContextHelpID) { - LPPOPUPMENU menu; + POPUPMENU *menu;
TRACE("(%p 0x%08x)\n", hMenu, dwContextHelpID);
@@ -5255,7 +5266,7 @@ BOOL WINAPI SetMenuContextHelpId( HMENU hMenu, DWORD dwContextHelpID) */ DWORD WINAPI GetMenuContextHelpId( HMENU hMenu ) { - LPPOPUPMENU menu; + POPUPMENU *menu;
TRACE("(%p)\n", hMenu);
diff --git a/dlls/user32/tests/menu.c b/dlls/user32/tests/menu.c index 0f6e8618a6..6a6de9de8c 100644 --- a/dlls/user32/tests/menu.c +++ b/dlls/user32/tests/menu.c @@ -634,9 +634,7 @@ static void test_subpopup_locked_by_menu(void)
/* but TrackPopupMenu still works! */ ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL); - todo_wine { - ok( ret == itemid , "TrackPopupMenu returned %d error is %d\n", ret, GetLastError()); - } + ok( ret == itemid , "TrackPopupMenu returned %#x error is %d\n", ret, GetLastError());
/* clean up */ DestroyMenu( hmenu);
Nikolay Sivov nsivov@codeweavers.com writes:
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/user32/menu.c | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-)
I still think you need to increase the refcount while holding a pointer, cf. https://www.winehq.org/pipermail/wine-devel/2014-May/104347.html