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);