Index: dlls/user/menu.c =================================================================== RCS file: /home/wine/wine/dlls/user/menu.c,v retrieving revision 1.64 diff -u -r1.64 menu.c --- dlls/user/menu.c 9 Jun 2006 16:18:26 -0000 1.64 +++ dlls/user/menu.c 10 Jun 2006 00:34:48 -0000 @@ -6,6 +6,7 @@ * Copyright 1997 Morten Welinder * Copyright 2005 Maxime Bellengé * Copyright 2006 Phil Krylov + * Copyright 2006 Google (Thomas Kho) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -45,6 +46,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -68,6 +70,7 @@ #define MM_SETMENUHANDLE (WM_USER + 0) #define MM_GETMENUHANDLE (WM_USER + 1) +/* MENUITEM and POPUPMENU duplicated in server/menu.c */ /* Menu item structure */ typedef struct { /* ----------- MENUITEMINFO Stuff ----------- */ @@ -282,19 +285,55 @@ /*********************************************************************** - * MENU_GetMenu + * SERVER_GetMenu * - * Validate the given menu handle and returns the menu structure pointer. + * Get a local copy of menu for given hMenu + * Return non-zero on success */ -static POPUPMENU *MENU_GetMenu(HMENU hMenu) +static int SERVER_GetMenu(HMENU hMenu, POPUPMENU *menu) { - POPUPMENU *menu = USER_HEAP_LIN_ADDR(hMenu); - if (!menu || menu->wMagic != MENU_MAGIC) + int ret = 0; + if (!menu) { - WARN("invalid menu handle=%p, ptr=%p, magic=%x\n", hMenu, menu, menu? menu->wMagic:0); - menu = NULL; + WARN("null pointer, hMenu=0x%x, menu=0x%x\n", hMenu, menu); + return 0; + } + SERVER_START_REQ( menu_info ) + { + req->handle = hMenu; + req->mask = 0; + wine_server_set_reply(req, menu, sizeof(POPUPMENU)); + if (!wine_server_call_err( req )) + { + assert(wine_server_reply_size(reply) == sizeof(POPUPMENU)); + if (!(ret = reply->status)) + WARN("invalid menu handle %p\n", hMenu); + } } - return menu; + SERVER_END_REQ; + return ret; +} + +/*********************************************************************** + * SERVER_SetMenu + * + * Update specific fields in server's copy of menu + */ +static void SERVER_SetMenu(HMENU hMenu, POPUPMENU *menu, unsigned int mask) +{ + if (!menu) + { + WARN("null pointer, hMenu=0x%x, menu=0x%x\n", hMenu, menu); + return; + } + SERVER_START_REQ( menu_info ) + { + req->handle = hMenu; + req->mask = mask; + wine_server_add_data(req, menu, sizeof(POPUPMENU)); + wine_server_call( req ); + } + SERVER_END_REQ; } /*********************************************************************** @@ -415,8 +454,10 @@ HMENU hMenu = LoadMenuW(user32_module, sysmenuW); if( hMenu ) { - POPUPMENU* menu = MENU_GetMenu(hMenu); - menu->wFlags |= MF_SYSMENU | MF_POPUP; + POPUPMENU menu; + SERVER_GetMenu(hMenu, &menu); + menu.wFlags |= MF_SYSMENU | MF_POPUP; + SERVER_SetMenu(hMenu, &menu, SET_MI_FLAGS); SetMenuDefaultItem(hMenu, SC_CLOSE, FALSE); } else @@ -444,10 +485,12 @@ TRACE("loading system menu, hWnd %p, hPopupMenu %p\n", hWnd, hPopupMenu); if ((hMenu = CreateMenu())) { - POPUPMENU *menu = MENU_GetMenu(hMenu); - menu->wFlags = MF_SYSMENU; - menu->hWnd = WIN_GetFullHandle( hWnd ); - TRACE("hWnd %p (hMenu %p)\n", menu->hWnd, hMenu); + POPUPMENU menu; + SERVER_GetMenu(hMenu, &menu); + menu.wFlags = MF_SYSMENU; + menu.hWnd = WIN_GetFullHandle( hWnd ); + SERVER_SetMenu(hMenu, &menu, SET_MI_FLAGS|SET_MI_HWND); + TRACE("hWnd %p (hMenu %p)\n", menu.hWnd, hMenu); if (!hPopupMenu) hPopupMenu = MENU_CopySysPopup(); @@ -455,14 +498,21 @@ if (hPopupMenu) { if (GetClassLongW(hWnd, GCL_STYLE) & CS_NOCLOSE) + { DeleteMenu(hPopupMenu, SC_CLOSE, MF_BYCOMMAND); + } InsertMenuW( hMenu, -1, MF_SYSMENU | MF_POPUP | MF_BYPOSITION, (UINT_PTR)hPopupMenu, NULL ); - menu->items[0].fType = MF_SYSMENU | MF_POPUP; - menu->items[0].fState = 0; - if ((menu = MENU_GetMenu(hPopupMenu))) menu->wFlags |= MF_SYSMENU; + SERVER_GetMenu(hMenu, &menu); + menu.items[0].fType = MF_SYSMENU | MF_POPUP; + menu.items[0].fState = 0; + if ((SERVER_GetMenu(hPopupMenu, &menu))) + { + menu.wFlags |= MF_SYSMENU; + SERVER_SetMenu(hPopupMenu, &menu, SET_MI_FLAGS); + } TRACE("hMenu=%p (hPopup %p)\n", hMenu, hPopupMenu ); return hMenu; @@ -511,18 +561,18 @@ static UINT MENU_GetStartOfNextColumn( HMENU hMenu ) { - POPUPMENU *menu = MENU_GetMenu(hMenu); + POPUPMENU menu; UINT i; - if(!menu) + if(!SERVER_GetMenu(hMenu, &menu)) return NO_SELECTED_ITEM; - i = menu->FocusedItem + 1; + i = menu.FocusedItem + 1; if( i == NO_SELECTED_ITEM ) return i; - for( ; i < menu->nItems; ++i ) { - if (menu->items[i].fType & MF_MENUBARBREAK) + for( ; i < menu.nItems; ++i ) { + if (menu.items[i].fType & MF_MENUBARBREAK) return i; } @@ -540,26 +590,26 @@ static UINT MENU_GetStartOfPrevColumn( HMENU hMenu ) { - POPUPMENU *menu = MENU_GetMenu(hMenu); + POPUPMENU menu; UINT i; - if( !menu ) + if( !SERVER_GetMenu(hMenu, &menu) ) return NO_SELECTED_ITEM; - if( menu->FocusedItem == 0 || menu->FocusedItem == NO_SELECTED_ITEM ) + if( menu.FocusedItem == 0 || menu.FocusedItem == NO_SELECTED_ITEM ) return NO_SELECTED_ITEM; /* Find the start of the column */ - for(i = menu->FocusedItem; i != 0 && - !(menu->items[i].fType & MF_MENUBARBREAK); + for(i = menu.FocusedItem; i != 0 && + !(menu.items[i].fType & MF_MENUBARBREAK); --i); /* empty */ if(i == 0) return NO_SELECTED_ITEM; for(--i; i != 0; --i) { - if (menu->items[i].fType & MF_MENUBARBREAK) + if (menu.items[i].fType & MF_MENUBARBREAK) break; } @@ -578,21 +628,22 @@ */ static MENUITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) { - POPUPMENU *menu; + POPUPMENU menu; MENUITEM *fallback = NULL; UINT fallback_pos = 0; UINT i; - if ((*hmenu == (HMENU)0xffff) || (!(menu = MENU_GetMenu(*hmenu)))) return NULL; + if ((*hmenu == (HMENU)0xffff) || (!(SERVER_GetMenu(*hmenu, &menu)))) + return NULL; if (wFlags & MF_BYPOSITION) { - if (*nPos >= menu->nItems) return NULL; - return &menu->items[*nPos]; + if (*nPos >= menu.nItems) return NULL; + return &menu.items[*nPos]; } else { - MENUITEM *item = menu->items; - for (i = 0; i < menu->nItems; i++, item++) + MENUITEM *item = menu.items; + for (i = 0; i < menu.nItems; i++, item++) { if (item->fType & MF_POPUP) { @@ -633,14 +684,14 @@ */ UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget ) { - POPUPMENU *menu; + POPUPMENU menu; UINT i; MENUITEM *item; if (((*hmenu)==(HMENU)0xffff) || - (!(menu = MENU_GetMenu(*hmenu)))) + (!SERVER_GetMenu(*hmenu, &menu))) return NO_SELECTED_ITEM; - item = menu->items; - for (i = 0; i < menu->nItems; i++, item++) { + item = menu.items; + for (i = 0; i < menu.nItems; i++, item++) { if(!(item->fType & MF_POPUP)) continue; if (item->hSubMenu == hSubTarget) { return i; @@ -736,15 +787,16 @@ if (hmenu) { - POPUPMENU *menu = MENU_GetMenu( hmenu ); - MENUITEM *item = menu->items; + POPUPMENU menu; + SERVER_GetMenu(hmenu, &menu); + MENUITEM *item = menu.items; LRESULT menuchar; if( !forceMenuChar ) { UINT i; - for (i = 0; i < menu->nItems; i++, item++) + for (i = 0; i < menu.nItems; i++, item++) { if( item->text) { @@ -759,7 +811,7 @@ } } menuchar = SendMessageW( hwndOwner, WM_MENUCHAR, - MAKEWPARAM( key, menu->wFlags ), (LPARAM)hmenu ); + MAKEWPARAM( key, menu.wFlags ), (LPARAM)hmenu ); if (HIWORD(menuchar) == 2) return LOWORD(menuchar); if (HIWORD(menuchar) == 1) return (UINT)(-2); } @@ -1338,7 +1390,7 @@ BOOL flat_menu = FALSE; int bkgnd; UINT arrow_bitmap_width = 0, arrow_bitmap_height = 0; - POPUPMENU *menu = MENU_GetMenu(hmenu); + POPUPMENU menu; RECT bmprc; debug_print_menuitem("MENU_DrawMenuItem: ", lpitem, ""); @@ -1386,7 +1438,8 @@ TRACE("rect=%s\n", wine_dbgstr_rect( &lpitem->rect)); rect = lpitem->rect; - MENU_AdjustMenuItemRect(MENU_GetMenu(hmenu), &rect); + SERVER_GetMenu(hmenu, &menu); + MENU_AdjustMenuItemRect(&menu, &rect); if (lpitem->fType & MF_OWNERDRAW) { @@ -1506,7 +1559,7 @@ bmprc.left = lpitem->text ? menucharsize.cx : 0; } else { bmprc.left = 4; - if( !(menu->dwStyle & ( MNS_CHECKORBMP | MNS_NOCHECK))) + if( !(menu.dwStyle & ( MNS_CHECKORBMP | MNS_NOCHECK))) bmprc.left += GetSystemMetrics( SM_CXMENUCHECK); } bmprc.right = bmprc.left + lpitem->bmpsize.cx; @@ -1531,7 +1584,8 @@ * FIXME: * Custom checkmark bitmaps are monochrome but not always 1bpp. */ - if( !(menu->dwStyle & MNS_NOCHECK)) { + if( !(menu.dwStyle & MNS_NOCHECK)) + { bm = (lpitem->fState & MF_CHECKED) ? lpitem->hCheckBit : lpitem->hUnCheckBit; if (bm) /* we have a custom bitmap */ @@ -1565,7 +1619,7 @@ } } if( lpitem->hbmpItem && - !( checked && (menu->dwStyle & MNS_CHECKORBMP))) { + !( checked && (menu.dwStyle & MNS_CHECKORBMP))) { POINT origorg; /* some applications make this assumption on the DC's origin */ SetViewportOrgEx( hdc, lpitem->rect.left, lpitem->rect.top, &origorg); @@ -1578,7 +1632,7 @@ draw_popup_arrow( hdc, rect, arrow_bitmap_width, arrow_bitmap_height); rect.left += 4; - if( !(menu->dwStyle & MNS_NOCHECK)) + if( !(menu.dwStyle & MNS_NOCHECK)) rect.left += check_bitmap_width; rect.right -= arrow_bitmap_width; } @@ -1601,8 +1655,8 @@ DT_CENTER | DT_VCENTER | DT_SINGLELINE : DT_LEFT | DT_VCENTER | DT_SINGLELINE; - if( !(menu->dwStyle & MNS_CHECKORBMP)) - rect.left += menu->maxBmpSize.cx; + if( !(menu.dwStyle & MNS_CHECKORBMP)) + rect.left += menu.maxBmpSize.cx; if ( lpitem->fState & MFS_DEFAULT ) { @@ -1693,7 +1747,7 @@ hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) ); if( hPrevPen ) { - POPUPMENU *menu; + POPUPMENU menu; BOOL flat_menu = FALSE; SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0); @@ -1702,22 +1756,22 @@ else DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT); - if( (menu = MENU_GetMenu( hmenu ))) + if( (SERVER_GetMenu( hmenu, &menu ))) { /* draw menu items */ - if( menu->nItems) + if( menu.nItems) { MENUITEM *item; UINT u; - item = menu->items; - for( u = menu->nItems; u > 0; u--, item++) - MENU_DrawMenuItem( hwnd, hmenu, menu->hwndOwner, hdc, - item, menu->Height, FALSE, ODA_DRAWENTIRE ); + item = menu.items; + for( u = menu.nItems; u > 0; u--, item++) + MENU_DrawMenuItem( hwnd, hmenu, menu.hwndOwner, hdc, + item, menu.Height, FALSE, ODA_DRAWENTIRE ); } /* draw scroll arrows */ - if (menu->bScrolling) - MENU_DrawScrollArrows(menu, hdc); + if (menu.bScrolling) + MENU_DrawScrollArrows(&menu, hdc); } } else { @@ -1735,12 +1789,11 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd, BOOL suppress_draw) { - LPPOPUPMENU lppop; + POPUPMENU pop; HFONT hfontOld = 0; HMENU hMenu = GetMenu(hwnd); - lppop = MENU_GetMenu( hMenu ); - if (lppop == NULL || lprect == NULL) + if (!SERVER_GetMenu(hMenu, &pop) || lprect == NULL) { return GetSystemMetrics(SM_CYMENU); } @@ -1749,13 +1802,16 @@ { hfontOld = SelectObject( hDC, get_menu_font(FALSE)); - if (lppop->Height == 0) - MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd); + if (pop.Height == 0) + { + MENU_MenuBarCalcSize(hDC, lprect, &pop, hwnd); + SERVER_SetMenu(hMenu, &pop, SET_MI_MAXBMPSIZE); + } - lprect->bottom = lprect->top + lppop->Height; + lprect->bottom = lprect->top + pop.Height; if (hfontOld) SelectObject( hDC, hfontOld); - return lppop->Height; + return pop.Height; } else return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL); @@ -1770,29 +1826,31 @@ static BOOL MENU_ShowPopup( HWND hwndOwner, HMENU hmenu, UINT id, INT x, INT y, INT xanchor, INT yanchor ) { - POPUPMENU *menu; + POPUPMENU menu; UINT width, 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); - if (!(menu = MENU_GetMenu( hmenu ))) return FALSE; - if (menu->FocusedItem != NO_SELECTED_ITEM) + if (!(SERVER_GetMenu( hmenu, &menu ))) return FALSE; + if (menu.FocusedItem != NO_SELECTED_ITEM) { - menu->items[menu->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); - menu->FocusedItem = NO_SELECTED_ITEM; + menu.items[menu.FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); + menu.FocusedItem = NO_SELECTED_ITEM; + SERVER_SetMenu(hmenu, &menu, SET_MI_FOCUSITEM); } /* store the owner for DrawItem */ - menu->hwndOwner = hwndOwner; + menu.hwndOwner = hwndOwner; - menu->nScrollPos = 0; - MENU_PopupMenuCalcSize( menu, hwndOwner ); + menu.nScrollPos = 0; + MENU_PopupMenuCalcSize( &menu, hwndOwner ); + SERVER_SetMenu(hmenu, &menu, SET_MI_WIDTH|SET_MI_HEIGHT|SET_MI_MAXBMPSIZE|SET_MI_TOTALHEIGHT|SET_MI_SCROLLING|SET_MI_SCROLLPOS|SET_MI_OWNER); /* adjust popup menu pos so that it fits within the desktop */ - width = menu->Width + GetSystemMetrics(SM_CXBORDER); - height = menu->Height + GetSystemMetrics(SM_CYBORDER); + width = menu.Width + GetSystemMetrics(SM_CXBORDER); + height = menu.Height + GetSystemMetrics(SM_CYBORDER); if( x + width > GetSystemMetrics(SM_CXSCREEN )) { @@ -1815,18 +1873,19 @@ if( y < 0 ) y = 0; /* NOTE: In Windows, top menu popup is not owned. */ - menu->hWnd = CreateWindowExW( 0, POPUPMENU_CLASS_ATOMW, NULL, + menu.hWnd = CreateWindowExW( 0, POPUPMENU_CLASS_ATOMW, NULL, WS_POPUP, x, y, width, height, hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE), (LPVOID)hmenu ); - if( !menu->hWnd ) return FALSE; - if (!top_popup) top_popup = menu->hWnd; + SERVER_SetMenu( hmenu, &menu, SET_MI_HWND ); + if( !menu.hWnd ) return FALSE; + if (!top_popup) top_popup = menu.hWnd; /* Display the window */ - SetWindowPos( menu->hWnd, HWND_TOP, 0, 0, 0, 0, + SetWindowPos( menu.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE ); - UpdateWindow( menu->hWnd ); + UpdateWindow( menu.hWnd ); return TRUE; } @@ -1878,63 +1937,66 @@ static void MENU_SelectItem( HWND hwndOwner, HMENU hmenu, UINT wIndex, BOOL sendMenuSelect, HMENU topmenu ) { - LPPOPUPMENU lppop; + POPUPMENU pop; HDC hdc; TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect); - lppop = MENU_GetMenu( hmenu ); - if ((!lppop) || (!lppop->nItems) || (!lppop->hWnd)) return; + if (!SERVER_GetMenu( hmenu, &pop ) || (!pop.nItems) + || (!pop.hWnd)) return; - if (lppop->FocusedItem == wIndex) return; - if (lppop->wFlags & MF_POPUP) hdc = GetDC( lppop->hWnd ); - else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW); - if (!top_popup) top_popup = lppop->hWnd; + if (pop.FocusedItem == wIndex) return; + if (pop.wFlags & MF_POPUP) hdc = GetDC( pop.hWnd ); + else hdc = GetDCEx( pop.hWnd, 0, DCX_CACHE | DCX_WINDOW); + if (!top_popup) top_popup = pop.hWnd; SelectObject( hdc, get_menu_font(FALSE)); /* Clear previous highlighted item */ - if (lppop->FocusedItem != NO_SELECTED_ITEM) + if (pop.FocusedItem != NO_SELECTED_ITEM) { - lppop->items[lppop->FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); - MENU_DrawMenuItem(lppop->hWnd, hmenu, hwndOwner, hdc,&lppop->items[lppop->FocusedItem], - lppop->Height, !(lppop->wFlags & MF_POPUP), + pop.items[pop.FocusedItem].fState &= ~(MF_HILITE|MF_MOUSESELECT); + MENU_DrawMenuItem(pop.hWnd, hmenu, hwndOwner, hdc,&pop.items[pop.FocusedItem], + pop.Height, !(pop.wFlags & MF_POPUP), ODA_SELECT ); } /* Highlight new item (if any) */ - lppop->FocusedItem = wIndex; - if (lppop->FocusedItem != NO_SELECTED_ITEM) + pop.FocusedItem = wIndex; + SERVER_SetMenu(hmenu, &pop, SET_MI_FOCUSITEM); + if (pop.FocusedItem != NO_SELECTED_ITEM) { - if(!(lppop->items[wIndex].fType & MF_SEPARATOR)) { - lppop->items[wIndex].fState |= MF_HILITE; - MENU_EnsureMenuItemVisible(lppop, wIndex, hdc); - MENU_DrawMenuItem( lppop->hWnd, hmenu, hwndOwner, hdc, - &lppop->items[wIndex], lppop->Height, - !(lppop->wFlags & MF_POPUP), ODA_SELECT ); + if(!(pop.items[wIndex].fType & MF_SEPARATOR)) + { + pop.items[wIndex].fState |= MF_HILITE; + MENU_EnsureMenuItemVisible(&pop, wIndex, hdc); + MENU_DrawMenuItem( pop.hWnd, hmenu, hwndOwner, hdc, + &pop.items[wIndex], pop.Height, + !(pop.wFlags & MF_POPUP), ODA_SELECT ); } if (sendMenuSelect) { - MENUITEM *ip = &lppop->items[lppop->FocusedItem]; + MENUITEM *ip = &pop.items[pop.FocusedItem]; SendMessageW( hwndOwner, WM_MENUSELECT, MAKELONG(ip->fType & MF_POPUP ? wIndex: ip->wID, ip->fType | ip->fState | - (lppop->wFlags & MF_SYSMENU)), (LPARAM)hmenu); + (pop.wFlags & MF_SYSMENU)), (LPARAM)hmenu); } } else if (sendMenuSelect) { if(topmenu){ int pos; if((pos=MENU_FindSubMenu(&topmenu, hmenu))!=NO_SELECTED_ITEM){ - POPUPMENU *ptm = MENU_GetMenu( topmenu ); - MENUITEM *ip = &ptm->items[pos]; + POPUPMENU ptm; + SERVER_GetMenu( topmenu, &ptm ); + MENUITEM *ip = &ptm.items[pos]; SendMessageW( hwndOwner, WM_MENUSELECT, MAKELONG(pos, ip->fType | ip->fState | - (ptm->wFlags & MF_SYSMENU)), (LPARAM)topmenu); + (ptm.wFlags & MF_SYSMENU)), (LPARAM)topmenu); } } } - ReleaseDC( lppop->hWnd, hdc ); + ReleaseDC( pop.hWnd, hdc ); } @@ -1948,28 +2010,27 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset ) { INT i; - POPUPMENU *menu; + POPUPMENU menu; TRACE("hwnd=%p hmenu=%p off=0x%04x\n", hwndOwner, hmenu, offset); - menu = MENU_GetMenu( hmenu ); - if ((!menu) || (!menu->items)) return; + if ((!SERVER_GetMenu(hmenu, &menu)) || (!menu.items)) return; - if ( menu->FocusedItem != NO_SELECTED_ITEM ) + if ( menu.FocusedItem != NO_SELECTED_ITEM ) { - if( menu->nItems == 1 ) return; else - for (i = menu->FocusedItem + offset ; i >= 0 && i < menu->nItems + if( menu.nItems == 1 ) return; else + for (i = menu.FocusedItem + offset ; i >= 0 && i < menu.nItems ; i += offset) - if (!(menu->items[i].fType & MF_SEPARATOR)) + if (!(menu.items[i].fType & MF_SEPARATOR)) { MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 ); return; } } - for ( i = (offset > 0) ? 0 : menu->nItems - 1; - i >= 0 && i < menu->nItems ; i += offset) - if (!(menu->items[i].fType & MF_SEPARATOR)) + for ( i = (offset > 0) ? 0 : menu.nItems - 1; + i >= 0 && i < menu.nItems ; i += offset) + if (!(menu.items[i].fType & MF_SEPARATOR)) { MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 ); return; @@ -2031,8 +2092,12 @@ if (flags & MF_POPUP) { - POPUPMENU *menu = MENU_GetMenu((HMENU)id); - if (menu) menu->wFlags |= MF_POPUP; + POPUPMENU menu; + if (SERVER_GetMenu((HMENU)id, &menu)) + { + menu.wFlags |= MF_POPUP; + SERVER_SetMenu((HMENU)id, &menu, SET_MI_FLAGS); + } else { item->wID = 0; @@ -2068,45 +2133,46 @@ static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags ) { MENUITEM *newItems; - POPUPMENU *menu; + POPUPMENU menu; - if (!(menu = MENU_GetMenu(hMenu))) + if (!SERVER_GetMenu(hMenu, &menu)) return NULL; /* Find where to insert new item */ if (flags & MF_BYPOSITION) { - if (pos > menu->nItems) - pos = menu->nItems; + if (pos > menu.nItems) + pos = menu.nItems; } else { if (!MENU_FindItem( &hMenu, &pos, flags )) - pos = menu->nItems; + pos = menu.nItems; else { - if (!(menu = MENU_GetMenu( hMenu ))) + if (!SERVER_GetMenu(hMenu, &menu)) return NULL; } } /* Create new items array */ - newItems = HeapAlloc( GetProcessHeap(), 0, sizeof(MENUITEM) * (menu->nItems+1) ); + newItems = HeapAlloc( GetProcessHeap(), 0, sizeof(MENUITEM) * (menu.nItems+1) ); if (!newItems) { WARN("allocation failed\n" ); return NULL; } - if (menu->nItems > 0) + if (menu.nItems > 0) { /* Copy the old array into the new one */ - if (pos > 0) memcpy( newItems, menu->items, pos * sizeof(MENUITEM) ); - if (pos < menu->nItems) memcpy( &newItems[pos+1], &menu->items[pos], - (menu->nItems-pos)*sizeof(MENUITEM) ); - HeapFree( GetProcessHeap(), 0, menu->items ); + if (pos > 0) memcpy( newItems, menu.items, pos * sizeof(MENUITEM) ); + if (pos < menu.nItems) memcpy( &newItems[pos+1], &menu.items[pos], + (menu.nItems-pos)*sizeof(MENUITEM) ); + HeapFree( GetProcessHeap(), 0, menu.items ); } - menu->items = newItems; - menu->nItems++; + menu.items = newItems; + menu.nItems++; memset( &newItems[pos], 0, sizeof(*newItems) ); - menu->Height = 0; /* force size recalculate */ + menu.Height = 0; /* force size recalculate */ + SERVER_SetMenu(hMenu, &menu, SET_MI_ITEMS|SET_MI_NITEMS|SET_MI_HEIGHT); return &newItems[pos]; } @@ -2220,14 +2286,13 @@ */ static HMENU MENU_GetSubPopup( HMENU hmenu ) { - POPUPMENU *menu; + POPUPMENU menu; MENUITEM *item; - menu = MENU_GetMenu( hmenu ); - - if ((!menu) || (menu->FocusedItem == NO_SELECTED_ITEM)) return 0; + if (!SERVER_GetMenu( hmenu, &menu ) + || (menu.FocusedItem == NO_SELECTED_ITEM)) return 0; - item = &menu->items[menu->FocusedItem]; + item = &menu.items[menu.FocusedItem]; if ((item->fType & MF_POPUP) && (item->fState & MF_MOUSESELECT)) return item->hSubMenu; return 0; @@ -2242,30 +2307,31 @@ static void MENU_HideSubPopups( HWND hwndOwner, HMENU hmenu, BOOL sendMenuSelect ) { - POPUPMENU *menu = MENU_GetMenu( hmenu ); + POPUPMENU menu; TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, sendMenuSelect); - if (menu && top_popup) + if (SERVER_GetMenu( hmenu, &menu ) && top_popup) { HMENU hsubmenu; - POPUPMENU *submenu; + POPUPMENU submenu; MENUITEM *item; - if (menu->FocusedItem != NO_SELECTED_ITEM) + if (menu.FocusedItem != NO_SELECTED_ITEM) { - item = &menu->items[menu->FocusedItem]; + item = &menu.items[menu.FocusedItem]; if (!(item->fType & MF_POPUP) || !(item->fState & MF_MOUSESELECT)) return; item->fState &= ~MF_MOUSESELECT; hsubmenu = item->hSubMenu; } else return; - submenu = MENU_GetMenu( hsubmenu ); + SERVER_GetMenu( hsubmenu, &submenu ); MENU_HideSubPopups( hwndOwner, hsubmenu, FALSE ); MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, sendMenuSelect, 0 ); - DestroyWindow( submenu->hWnd ); - submenu->hWnd = 0; + DestroyWindow( submenu.hWnd ); + submenu.hWnd = 0; + SERVER_SetMenu(hsubmenu, &submenu, SET_MI_HWND); } } @@ -2280,17 +2346,17 @@ BOOL selectFirst, UINT wFlags ) { RECT rect; - POPUPMENU *menu; + POPUPMENU menu; MENUITEM *item; HDC hdc; TRACE("owner=%p hmenu=%p 0x%04x\n", hwndOwner, hmenu, selectFirst); - if (!(menu = MENU_GetMenu( hmenu ))) return hmenu; + if (!(SERVER_GetMenu( hmenu, &menu ))) return hmenu; - if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu; + if (menu.FocusedItem == NO_SELECTED_ITEM) return hmenu; - item = &menu->items[menu->FocusedItem]; + item = &menu.items[menu.FocusedItem]; if (!(item->fType & MF_POPUP) || (item->fState & (MF_GRAYED | MF_DISABLED))) return hmenu; @@ -2300,47 +2366,47 @@ /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */ if (!(wFlags & TPM_NONOTIFY)) SendMessageW( hwndOwner, WM_INITMENUPOPUP, (WPARAM)item->hSubMenu, - MAKELONG( menu->FocusedItem, IS_SYSTEM_MENU(menu) )); + MAKELONG( menu.FocusedItem, IS_SYSTEM_MENU(&menu) )); - item = &menu->items[menu->FocusedItem]; + item = &menu.items[menu.FocusedItem]; rect = item->rect; /* correct item if modified as a reaction to WM_INITMENUPOPUP message */ if (!(item->fState & MF_HILITE)) { - if (menu->wFlags & MF_POPUP) hdc = GetDC( menu->hWnd ); - else hdc = GetDCEx( menu->hWnd, 0, DCX_CACHE | DCX_WINDOW); + if (menu.wFlags & MF_POPUP) hdc = GetDC( menu.hWnd ); + else hdc = GetDCEx( menu.hWnd, 0, DCX_CACHE | DCX_WINDOW); SelectObject( hdc, get_menu_font(FALSE)); item->fState |= MF_HILITE; - MENU_DrawMenuItem( menu->hWnd, hmenu, hwndOwner, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP), ODA_DRAWENTIRE ); - ReleaseDC( menu->hWnd, hdc ); + MENU_DrawMenuItem( menu.hWnd, hmenu, hwndOwner, hdc, item, menu.Height, !(menu.wFlags & MF_POPUP), ODA_DRAWENTIRE ); + ReleaseDC( menu.hWnd, hdc ); } if (!item->rect.top && !item->rect.left && !item->rect.bottom && !item->rect.right) item->rect = rect; item->fState |= MF_MOUSESELECT; - if (IS_SYSTEM_MENU(menu)) + if (IS_SYSTEM_MENU(&menu)) { MENU_InitSysMenuPopup(item->hSubMenu, - GetWindowLongW( menu->hWnd, GWL_STYLE ), - GetClassLongW( menu->hWnd, GCL_STYLE)); + GetWindowLongW( menu.hWnd, GWL_STYLE ), + GetClassLongW( menu.hWnd, GCL_STYLE)); - NC_GetSysPopupPos( menu->hWnd, &rect ); + NC_GetSysPopupPos( menu.hWnd, &rect ); rect.top = rect.bottom; rect.right = GetSystemMetrics(SM_CXSIZE); rect.bottom = GetSystemMetrics(SM_CYSIZE); } else { - GetWindowRect( menu->hWnd, &rect ); - if (menu->wFlags & MF_POPUP) + GetWindowRect( menu.hWnd, &rect ); + if (menu.wFlags & MF_POPUP) { RECT rc = item->rect; - MENU_AdjustMenuItemRect(menu, &rc); + MENU_AdjustMenuItemRect(&menu, &rc); /* The first item in the popup menu has to be at the same y position as the focused menu item */ @@ -2359,7 +2425,7 @@ } } - MENU_ShowPopup( hwndOwner, item->hSubMenu, menu->FocusedItem, + MENU_ShowPopup( hwndOwner, item->hSubMenu, menu.FocusedItem, rect.left, rect.top, rect.right, rect.bottom ); if (selectFirst) MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT ); @@ -2383,27 +2449,28 @@ */ static HMENU MENU_PtMenu( HMENU hMenu, POINT pt ) { - POPUPMENU *menu = MENU_GetMenu( hMenu ); - UINT item = menu->FocusedItem; + POPUPMENU menu; + SERVER_GetMenu( hMenu, &menu ); + UINT item = menu.FocusedItem; HMENU 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.items[item].fType & MF_POPUP) && + (menu.items[item].fState & MF_MOUSESELECT)) + ? MENU_PtMenu(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 ) + INT ht = NC_HandleNCHitTest( menu.hWnd, pt ); + if( menu.wFlags & MF_POPUP ) { if (ht != HTNOWHERE && ht != HTERROR) ret = hMenu; } else if (ht == HTSYSMENU) - ret = get_win_sys_menu( menu->hWnd ); + ret = get_win_sys_menu( menu.hWnd ); else if (ht == HTMENU) - ret = GetMenu( menu->hWnd ); + ret = GetMenu( menu.hWnd ); } return ret; } @@ -2421,14 +2488,14 @@ static INT MENU_ExecFocusedItem( MTRACKER* pmt, HMENU hMenu, UINT wFlags ) { MENUITEM *item; - POPUPMENU *menu = MENU_GetMenu( hMenu ); + POPUPMENU menu; TRACE("%p hmenu=%p\n", pmt, hMenu); - if (!menu || !menu->nItems || - (menu->FocusedItem == NO_SELECTED_ITEM)) return -1; + if (!SERVER_GetMenu( hMenu, &menu ) || !menu.nItems || + (menu.FocusedItem == NO_SELECTED_ITEM)) return -1; - item = &menu->items[menu->FocusedItem]; + item = &menu.items[menu.FocusedItem]; TRACE("%p %08x %p\n", hMenu, item->wID, item->hSubMenu); @@ -2440,7 +2507,7 @@ do not send a message to the owner */ if(!(wFlags & TPM_RETURNCMD)) { - if( menu->wFlags & MF_SYSMENU ) + if( menu.wFlags & MF_SYSMENU ) PostMessageW( pmt->hOwnerWnd, WM_SYSCOMMAND, item->wID, MAKELPARAM((INT16)pmt->pt.x, (INT16)pmt->pt.y) ); else @@ -2465,13 +2532,14 @@ */ static void MENU_SwitchTracking( MTRACKER* pmt, HMENU hPtMenu, UINT id ) { - POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); - POPUPMENU *topmenu = MENU_GetMenu( pmt->hTopMenu ); + POPUPMENU ptmenu, topmenu; + SERVER_GetMenu( hPtMenu, &ptmenu ); + SERVER_GetMenu( pmt->hTopMenu, &topmenu ); TRACE("%p hmenu=%p 0x%04x\n", pmt, hPtMenu, id); if( pmt->hTopMenu != hPtMenu && - !((ptmenu->wFlags | topmenu->wFlags) & MF_POPUP) ) + !((ptmenu.wFlags | topmenu.wFlags) & MF_POPUP) ) { /* both are top level menus (system and menu-bar) */ MENU_HideSubPopups( pmt->hOwnerWnd, pmt->hTopMenu, FALSE ); @@ -2495,17 +2563,18 @@ if (hPtMenu) { UINT id = 0; - POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); + POPUPMENU ptmenu; MENUITEM *item; + SERVER_GetMenu( hPtMenu, &ptmenu ); - if( IS_SYSTEM_MENU(ptmenu) ) - item = ptmenu->items; + if( IS_SYSTEM_MENU(&ptmenu) ) + item = ptmenu.items; else - item = MENU_FindItemByCoords( ptmenu, pmt->pt, &id ); + item = MENU_FindItemByCoords( &ptmenu, pmt->pt, &id ); if( item ) { - if( ptmenu->FocusedItem != id ) + if( ptmenu.FocusedItem != id ) MENU_SwitchTracking( pmt, hPtMenu, id ); /* If the popup menu is not already "popped" */ @@ -2536,15 +2605,16 @@ if (hPtMenu) { UINT id = 0; - POPUPMENU *ptmenu = MENU_GetMenu( hPtMenu ); MENUITEM *item; + POPUPMENU ptmenu; + SERVER_GetMenu( hPtMenu, &ptmenu ); - if( IS_SYSTEM_MENU(ptmenu) ) - item = ptmenu->items; + if( IS_SYSTEM_MENU(&ptmenu) ) + item = ptmenu.items; else - item = MENU_FindItemByCoords( ptmenu, pmt->pt, &id ); + item = MENU_FindItemByCoords( &ptmenu, pmt->pt, &id ); - if( item && (ptmenu->FocusedItem == id )) + if( item && (ptmenu.FocusedItem == id )) { if( !(item->fType & MF_POPUP) ) { @@ -2555,10 +2625,11 @@ /* If we are dealing with the top-level menu */ /* and this is a click on an already "popped" item: */ /* Stop the menu tracking and close the opened submenus */ - if((pmt->hTopMenu == hPtMenu) && ptmenu->bTimeToHide) + if((pmt->hTopMenu == hPtMenu) && ptmenu.bTimeToHide) return 0; } - ptmenu->bTimeToHide = TRUE; + ptmenu.bTimeToHide = TRUE; + SERVER_SetMenu( hPtMenu, &ptmenu, SET_MI_TIMETOHIDE ); } return -1; } @@ -2572,15 +2643,15 @@ static BOOL MENU_MouseMove( MTRACKER* pmt, HMENU hPtMenu, UINT wFlags ) { UINT id = NO_SELECTED_ITEM; - POPUPMENU *ptmenu = NULL; + POPUPMENU ptmenu; if( hPtMenu ) { - ptmenu = MENU_GetMenu( hPtMenu ); - if( IS_SYSTEM_MENU(ptmenu) ) + SERVER_GetMenu( hPtMenu, &ptmenu ); + if( IS_SYSTEM_MENU(&ptmenu) ) id = 0; else - MENU_FindItemByCoords( ptmenu, pmt->pt, &id ); + MENU_FindItemByCoords( &ptmenu, pmt->pt, &id ); } if( id == NO_SELECTED_ITEM ) @@ -2589,7 +2660,7 @@ NO_SELECTED_ITEM, TRUE, pmt->hTopMenu); } - else if( ptmenu->FocusedItem != id ) + else if( ptmenu.FocusedItem != id ) { MENU_SwitchTracking( pmt, hPtMenu, id ); pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hPtMenu, FALSE, wFlags); @@ -2629,17 +2700,18 @@ */ static LRESULT MENU_DoNextMenu( MTRACKER* pmt, UINT vk ) { - POPUPMENU *menu = MENU_GetMenu( pmt->hTopMenu ); + POPUPMENU menu; + SERVER_GetMenu( pmt->hTopMenu, &menu ); - if( (vk == VK_LEFT && menu->FocusedItem == 0 ) || - (vk == VK_RIGHT && menu->FocusedItem == menu->nItems - 1)) + if( (vk == VK_LEFT && menu.FocusedItem == 0 ) || + (vk == VK_RIGHT && menu.FocusedItem == menu.nItems - 1)) { MDINEXTMENU next_menu; HMENU hNewMenu; HWND hNewWnd; UINT id = 0; - next_menu.hmenuIn = (IS_SYSTEM_MENU(menu)) ? GetSubMenu(pmt->hTopMenu,0) : pmt->hTopMenu; + next_menu.hmenuIn = (IS_SYSTEM_MENU(&menu)) ? GetSubMenu(pmt->hTopMenu,0) : pmt->hTopMenu; next_menu.hmenuNext = 0; next_menu.hwndNext = 0; SendMessageW( pmt->hOwnerWnd, WM_NEXTMENU, vk, (LPARAM)&next_menu ); @@ -2651,7 +2723,7 @@ { DWORD style = GetWindowLongW( pmt->hOwnerWnd, GWL_STYLE ); hNewWnd = pmt->hOwnerWnd; - if( IS_SYSTEM_MENU(menu) ) + if( IS_SYSTEM_MENU(&menu) ) { /* switch to the menu bar */ @@ -2659,8 +2731,8 @@ if( vk == VK_LEFT ) { - menu = MENU_GetMenu( hNewMenu ); - id = menu->nItems - 1; + SERVER_GetMenu( hNewMenu, &menu ); + id = menu.nItems - 1; } } else if (style & WS_SYSMENU ) @@ -2768,9 +2840,10 @@ if (pmt->hCurrentMenu != pmt->hTopMenu) { - POPUPMENU *menu = MENU_GetMenu(pmt->hCurrentMenu); + POPUPMENU menu; + SERVER_GetMenu(pmt->hCurrentMenu, &menu); - if (menu->wFlags & MF_POPUP) + if (menu.wFlags & MF_POPUP) { HMENU hmenutmp, hmenuprev; @@ -2799,12 +2872,12 @@ */ static void MENU_KeyLeft( MTRACKER* pmt, UINT wFlags ) { - POPUPMENU *menu; + POPUPMENU menu; HMENU hmenutmp, hmenuprev; UINT prevcol; hmenuprev = hmenutmp = pmt->hTopMenu; - menu = MENU_GetMenu( hmenutmp ); + SERVER_GetMenu( hmenutmp, &menu ); /* Try to move 1 column left (if possible) */ if( (prevcol = MENU_GetStartOfPrevColumn( pmt->hCurrentMenu )) != @@ -2825,7 +2898,7 @@ MENU_HideSubPopups( pmt->hOwnerWnd, hmenuprev, TRUE ); pmt->hCurrentMenu = hmenuprev; - if ( (hmenuprev == pmt->hTopMenu) && !(menu->wFlags & MF_POPUP) ) + if ( (hmenuprev == pmt->hTopMenu) && !(menu.wFlags & MF_POPUP) ) { /* move menu bar selection if no more popups are left */ @@ -2853,15 +2926,17 @@ static void MENU_KeyRight( MTRACKER* pmt, UINT wFlags ) { HMENU hmenutmp; - POPUPMENU *menu = MENU_GetMenu( pmt->hTopMenu ); + POPUPMENU menu, tmpmenu; + SERVER_GetMenu( pmt->hTopMenu, &menu); UINT nextcol; + SERVER_GetMenu(pmt->hCurrentMenu, &tmpmenu); 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) ); + debugstr_w(tmpmenu.items[0].text), + pmt->hTopMenu, debugstr_w(menu.items[0].text) ); - if ( (menu->wFlags & MF_POPUP) || (pmt->hCurrentMenu != pmt->hTopMenu)) + if ( (menu.wFlags & MF_POPUP) || (pmt->hCurrentMenu != pmt->hTopMenu)) { /* If already displaying a popup, try to display sub-popup */ @@ -2881,7 +2956,7 @@ return; } - if (!(menu->wFlags & MF_POPUP)) /* menu bar tracking */ + if (!(menu.wFlags & MF_POPUP)) /* menu bar tracking */ { if( pmt->hCurrentMenu != pmt->hTopMenu ) { @@ -2909,7 +2984,7 @@ HWND hwnd, const RECT *lprect ) { MSG msg; - POPUPMENU *menu; + POPUPMENU menu; BOOL fRemove; INT executedMenuId = -1; MTRACKER mt; @@ -2926,7 +3001,7 @@ hmenu, wFlags, x, y, hwnd, wine_dbgstr_rect( lprect)); fEndMenu = FALSE; - if (!(menu = MENU_GetMenu( hmenu ))) + if (!SERVER_GetMenu( hmenu, &menu )) { WARN("Invalid menu handle %p\n", hmenu); SetLastError(ERROR_INVALID_MENU_HANDLE); @@ -2946,9 +3021,11 @@ while (!fEndMenu) { - menu = MENU_GetMenu( mt.hCurrentMenu ); - if (!menu) /* sometimes happens if I do a window manager close */ + if (!SERVER_GetMenu( mt.hCurrentMenu, &menu )) + { + /* sometimes happens if I do a window manager close */ break; + } /* we have to keep the message in the queue until it's * clear that menu loop is not over yet. */ @@ -2965,7 +3042,7 @@ { if (!enterIdleSent) { - HWND win = (wFlags & TPM_ENTERIDLEEX && menu->wFlags & MF_POPUP) ? menu->hWnd : 0; + HWND win = (wFlags & TPM_ENTERIDLEEX && menu.wFlags & MF_POPUP) ? menu.hWnd : 0; enterIdleSent = TRUE; SendMessageW( mt.hOwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM)win ); } @@ -2989,7 +3066,7 @@ TranslateMessage( &msg ); mt.pt = msg.pt; - if ( (msg.hwnd==menu->hWnd) || (msg.message!=WM_TIMER) ) + if ( (msg.hwnd==menu.hWnd) || (msg.message!=WM_TIMER) ) enterIdleSent=FALSE; fRemove = FALSE; @@ -3076,8 +3153,8 @@ case VK_UP: case VK_DOWN: /* If on menu bar, pull-down the menu */ - menu = MENU_GetMenu( mt.hCurrentMenu ); - if (!(menu->wFlags & MF_POPUP)) + SERVER_GetMenu( mt.hCurrentMenu, &menu ); + 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, @@ -3101,12 +3178,12 @@ HELPINFO hi; hi.cbSize = sizeof(HELPINFO); hi.iContextType = HELPINFO_MENUITEM; - if (menu->FocusedItem == NO_SELECTED_ITEM) + if (menu.FocusedItem == NO_SELECTED_ITEM) hi.iCtrlId = 0; else - hi.iCtrlId = menu->items[menu->FocusedItem].wID; + hi.iCtrlId = menu.items[menu.FocusedItem].wID; hi.hItemHandle = hmenu; - hi.dwContextId = menu->dwContextHelpID; + hi.dwContextId = menu.dwContextHelpID; hi.MousePos = msg.pt; SendMessageW(hwnd, WM_HELP, 0, (LPARAM)&hi); break; @@ -3173,23 +3250,28 @@ check for this first. */ if( IsMenu( mt.hTopMenu ) ) { - menu = MENU_GetMenu( mt.hTopMenu ); + int ret = SERVER_GetMenu( mt.hTopMenu, &menu ); if( IsWindow( mt.hOwnerWnd ) ) { MENU_HideSubPopups( mt.hOwnerWnd, mt.hTopMenu, FALSE ); - if (menu && (menu->wFlags & MF_POPUP)) + if (ret && (menu.wFlags & MF_POPUP)) { - DestroyWindow( menu->hWnd ); - menu->hWnd = 0; + DestroyWindow( menu.hWnd ); + menu.hWnd = 0; + SERVER_SetMenu(mt.hTopMenu, &menu, SET_MI_HWND); } MENU_SelectItem( mt.hOwnerWnd, mt.hTopMenu, NO_SELECTED_ITEM, FALSE, 0 ); SendMessageW( mt.hOwnerWnd, WM_MENUSELECT, MAKELONG(0,0xffff), 0 ); } /* Reset the variable for hiding menu */ - if( menu ) menu->bTimeToHide = FALSE; + if( ret ) + { + menu.bTimeToHide = FALSE; + SERVER_SetMenu(mt.hTopMenu, &menu, SET_MI_TIMETOHIDE); + } } /* The return value is only used by TrackPopupMenu */ @@ -3203,7 +3285,7 @@ */ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags) { - POPUPMENU *menu; + POPUPMENU menu; TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu); @@ -3227,7 +3309,11 @@ * It also enables menus to be displayed in more than one window, * but there are some bugs left that need to be fixed in this case. */ - if ((menu = MENU_GetMenu( hMenu ))) menu->hWnd = hWnd; + if (SERVER_GetMenu( hMenu, &menu )) + { + menu.hWnd = hWnd; + SERVER_SetMenu( hMenu, &menu, SET_MI_HWND ); + } return TRUE; } @@ -3440,18 +3526,19 @@ { HDC hdc; RECT rectBar; - LPPOPUPMENU lppop; + POPUPMENU pop; TRACE("HWND %p, width %d, at (%d, %d).\n", hwnd, menubarWidth, orgX, orgY ); - if (!(lppop = MENU_GetMenu( GetMenu(hwnd) ))) return 0; + if (!SERVER_GetMenu( GetMenu(hwnd), &pop )) return 0; hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW ); SelectObject( hdc, get_menu_font(FALSE)); SetRect(&rectBar, orgX, orgY, orgX+menubarWidth, orgY+GetSystemMetrics(SM_CYMENU)); - MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd ); + MENU_MenuBarCalcSize( hdc, &rectBar, &pop, hwnd ); + SERVER_SetMenu( GetMenu(hwnd), &pop, SET_MI_WIDTH|SET_MI_HEIGHT|SET_MI_MAXBMPSIZE|SET_MI_TOTALHEIGHT|SET_MI_SCROLLING); ReleaseDC( hwnd, hdc ); - return lppop->Height; + return pop.Height; } @@ -3519,12 +3606,12 @@ { UINT oldflags; MENUITEM *item; - POPUPMENU *menu; + POPUPMENU menu; TRACE("(%p, %04x, %04x) !\n", hMenu, wItemID, wFlags); /* Get the Popupmenu to access the owner menu */ - if (!(menu = MENU_GetMenu(hMenu))) + if (!SERVER_GetMenu(hMenu, &menu)) return (UINT)-1; if (!(item = MENU_FindItem( &hMenu, &wItemID, wFlags ))) @@ -3536,20 +3623,20 @@ /* If the close item in the system menu change update the close button */ if((item->wID == SC_CLOSE) && (oldflags != wFlags)) { - if (menu->hSysMenuOwner != 0) + if (menu.hSysMenuOwner != 0) { RECT rc; - POPUPMENU* parentMenu; + POPUPMENU parentMenu; /* Get the parent menu to access*/ - if (!(parentMenu = MENU_GetMenu(menu->hSysMenuOwner))) + if (!SERVER_GetMenu(menu.hSysMenuOwner, &parentMenu)) return (UINT)-1; /* Refresh the frame to reflect the change */ - GetWindowRect(parentMenu->hWnd, &rc); - MapWindowPoints(0, parentMenu->hWnd, (POINT *)&rc, 2); + GetWindowRect(parentMenu.hWnd, &rc); + MapWindowPoints(0, parentMenu.hWnd, (POINT *)&rc, 2); rc.bottom = 0; - RedrawWindow(parentMenu->hWnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN); + RedrawWindow(parentMenu.hWnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN); } } @@ -3614,11 +3701,11 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID, UINT wHilite ) { - LPPOPUPMENU menu; + POPUPMENU 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; - if (menu->FocusedItem == wItemID) return TRUE; + if (!SERVER_GetMenu(hMenu, &menu)) return FALSE; + if (menu.FocusedItem == wItemID) return TRUE; MENU_HideSubPopups( hWnd, hMenu, FALSE ); MENU_SelectItem( hWnd, hMenu, wItemID, TRUE, 0 ); return TRUE; @@ -3636,9 +3723,9 @@ debug_print_menuitem (" item: ", item, ""); if (item->fType & MF_POPUP) { - POPUPMENU *menu = MENU_GetMenu( item->hSubMenu ); - if (!menu) return -1; - else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff); + POPUPMENU menu; + if (!SERVER_GetMenu( item->hSubMenu, &menu )) return -1; + else return (menu.nItems << 8) | ((item->fState|item->fType) & 0xff); } else { @@ -3655,10 +3742,10 @@ */ INT WINAPI GetMenuItemCount( HMENU hMenu ) { - LPPOPUPMENU menu = MENU_GetMenu(hMenu); - if (!menu) return -1; - TRACE("(%p) returning %d\n", hMenu, menu->nItems ); - return menu->nItems; + POPUPMENU menu; + if (!SERVER_GetMenu(hMenu, &menu)) return -1; + TRACE("(%p) returning %d\n", hMenu, menu.nItems ); + return menu.nItems; } @@ -3690,16 +3777,26 @@ else TRACE("hMenu %p, pos %d, flags %08x, id %04x, str %p (not a string)\n", hMenu, pos, flags, id, str ); - if (!(item = MENU_InsertItem( hMenu, pos, flags ))) return FALSE; + if (!(item = MENU_InsertItem( hMenu, pos, flags ))) + { + TRACE("can't insert\n"); + return FALSE; + } if (!(MENU_SetItemData( item, flags, id, str ))) { + TRACE("removing menu\n"); RemoveMenu( hMenu, pos, flags ); return FALSE; } if (flags & MF_POPUP) /* Set the MF_POPUP flag on the popup-menu */ - (MENU_GetMenu((HMENU)id))->wFlags |= MF_POPUP; + { + POPUPMENU menu; + SERVER_GetMenu((HMENU)id, &menu); + menu.wFlags |= MF_POPUP; + SERVER_SetMenu((HMENU)id, &menu, SET_MI_FLAGS); + } item->hCheckBit = item->hUnCheckBit = 0; return TRUE; @@ -3755,32 +3852,32 @@ */ BOOL WINAPI RemoveMenu( HMENU hMenu, UINT nPos, UINT wFlags ) { - LPPOPUPMENU menu; + POPUPMENU menu; 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 (!SERVER_GetMenu(hMenu, &menu)) return FALSE; /* Remove item */ MENU_FreeItemData( item ); - if (--menu->nItems == 0) + if (--menu.nItems == 0) { - HeapFree( GetProcessHeap(), 0, menu->items ); - menu->items = NULL; + HeapFree( GetProcessHeap(), 0, menu.items ); + menu.items = NULL; } else { - while(nPos < menu->nItems) + while(nPos < menu.nItems) { *item = *(item+1); item++; nPos++; } - menu->items = HeapReAlloc( GetProcessHeap(), 0, menu->items, - menu->nItems * sizeof(MENUITEM) ); + menu.items = HeapReAlloc( GetProcessHeap(), 0, menu.items, + menu.nItems * sizeof(MENUITEM) ); } return TRUE; } @@ -3807,6 +3904,7 @@ UINT_PTR id, LPCWSTR str ) { MENUITEM *item; + POPUPMENU menu; if (IS_STRING_ITEM(flags)) TRACE("%p %d %04x %04x %s\n", hMenu, pos, flags, id, debugstr_w(str) ); @@ -3814,7 +3912,9 @@ TRACE("%p %d %04x %04x %p\n", hMenu, pos, flags, id, str ); if (!(item = MENU_FindItem( &hMenu, &pos, flags ))) return FALSE; - MENU_GetMenu(hMenu)->Height = 0; /* force size recalculate */ + SERVER_GetMenu(hMenu, &menu); + menu.Height = 0; /* force size recalculate */ + SERVER_SetMenu(hMenu, &menu, SET_MI_HEIGHT); return MENU_SetItemData( item, flags, id, str ); } @@ -3849,12 +3949,13 @@ HMENU WINAPI CreatePopupMenu(void) { HMENU hmenu; - POPUPMENU *menu; + POPUPMENU menu; if (!(hmenu = CreateMenu())) return 0; - menu = MENU_GetMenu( hmenu ); - menu->wFlags |= MF_POPUP; - menu->bTimeToHide = FALSE; + SERVER_GetMenu(hmenu, &menu); + menu.wFlags |= MF_POPUP; + menu.bTimeToHide = FALSE; + SERVER_SetMenu(hmenu, &menu, SET_MI_FLAGS|SET_MI_TIMETOHIDE); return hmenu; } @@ -3899,15 +4000,14 @@ */ HMENU WINAPI CreateMenu(void) { - HMENU hMenu; - LPPOPUPMENU menu; - if (!(hMenu = USER_HEAP_ALLOC( sizeof(POPUPMENU) ))) return 0; - menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu); - - ZeroMemory(menu, sizeof(POPUPMENU)); - menu->wMagic = MENU_MAGIC; - menu->FocusedItem = NO_SELECTED_ITEM; - menu->bTimeToHide = FALSE; + HMENU hMenu = 0; + + SERVER_START_REQ( create_menu ) + { + if (!wine_server_call_err( req )) + hMenu = reply->handle; + } + SERVER_END_REQ; TRACE("return %p\n", hMenu ); @@ -3920,34 +4020,41 @@ */ BOOL WINAPI DestroyMenu( HMENU hMenu ) { - LPPOPUPMENU lppop = MENU_GetMenu(hMenu); + POPUPMENU pop; TRACE("(%p)\n", hMenu); + if (!SERVER_GetMenu(hMenu, &pop)) return FALSE; - if (!lppop) return FALSE; - - lppop->wMagic = 0; /* Mark it as destroyed */ + pop.wMagic = 0; /* Mark it as destroyed */ /* DestroyMenu should not destroy system menu popup owner */ - if ((lppop->wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && lppop->hWnd) + if ((pop.wFlags & (MF_POPUP | MF_SYSMENU)) == MF_POPUP && pop.hWnd) { - DestroyWindow( lppop->hWnd ); - lppop->hWnd = 0; + DestroyWindow( pop.hWnd ); + pop.hWnd = 0; } - if (lppop->items) /* recursively destroy submenus */ + if (pop.items) /* recursively destroy submenus */ { int i; - MENUITEM *item = lppop->items; - for (i = lppop->nItems; i > 0; i--, item++) + MENUITEM *item = pop.items; + for (i = pop.nItems; i > 0; i--, item++) { if (item->fType & MF_POPUP) DestroyMenu(item->hSubMenu); MENU_FreeItemData( item ); } - HeapFree( GetProcessHeap(), 0, lppop->items ); + HeapFree( GetProcessHeap(), 0, pop.items ); } - USER_HEAP_FREE( hMenu ); + + SERVER_START_REQ( destroy_menu ) + { + req->handle = hMenu; + if (!wine_server_call_err( req )) + { + } + } + SERVER_END_REQ; return TRUE; } @@ -3978,14 +4085,16 @@ if( wndPtr->hSysMenu ) { - POPUPMENU *menu; + POPUPMENU menu; retvalue = GetSubMenu(wndPtr->hSysMenu, 0); /* Store the dummy sysmenu handle to facilitate the refresh */ /* of the close button if the SC_CLOSE item change */ - menu = MENU_GetMenu(retvalue); - if ( menu ) - menu->hSysMenuOwner = wndPtr->hSysMenu; + if (SERVER_GetMenu(retvalue, &menu)) + { + menu.hSysMenuOwner = wndPtr->hSysMenu; + SERVER_SetMenu(retvalue, &menu, SET_MI_OWNER); + } } WIN_ReleasePtr( wndPtr ); } @@ -4054,12 +4163,13 @@ if (hMenu != 0) { - LPPOPUPMENU lpmenu; + POPUPMENU menu; - if (!(lpmenu = MENU_GetMenu(hMenu))) return FALSE; + if (!SERVER_GetMenu(hMenu, &menu)) return FALSE; - lpmenu->hWnd = hWnd; - lpmenu->Height = 0; /* Make sure we recalculate the size */ + menu.hWnd = hWnd; + menu.Height = 0; /* Make sure we recalculate the size */ + SERVER_SetMenu(hMenu, &menu, SET_MI_HWND|SET_MI_HEIGHT); } SetWindowLongPtrW( hWnd, GWLP_ID, (LONG_PTR)hMenu ); return TRUE; @@ -4098,15 +4208,16 @@ */ BOOL WINAPI DrawMenuBar( HWND hWnd ) { - LPPOPUPMENU lppop; + POPUPMENU pop; HMENU hMenu = GetMenu(hWnd); if (!WIN_ALLOWED_MENU(GetWindowLongW( hWnd, GWL_STYLE ))) return FALSE; - if (!hMenu || !(lppop = MENU_GetMenu( hMenu ))) return FALSE; + if (!hMenu || !SERVER_GetMenu( hMenu, &pop )) return FALSE; - lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */ - lppop->hwndOwner = hWnd; + pop.Height = 0; /* Make sure we call MENU_MenuBarCalcSize */ + pop.hwndOwner = hWnd; + SERVER_SetMenu( hMenu, &pop, SET_MI_HEIGHT|SET_MI_OWNER ); SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); return TRUE; @@ -4123,7 +4234,7 @@ */ DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont) { - LPPOPUPMENU lppop; + POPUPMENU pop; UINT i,retvalue; HFONT hfontOld = 0; BOOL flat_menu = FALSE; @@ -4136,8 +4247,7 @@ if (!hFont) hFont = get_menu_font(FALSE); - lppop = MENU_GetMenu( hMenu ); - if (lppop == NULL || lprect == NULL) + if (!SERVER_GetMenu(hMenu, &pop) || lprect == NULL) { retvalue = GetSystemMetrics(SM_CYMENU); goto END; @@ -4147,10 +4257,13 @@ hfontOld = SelectObject( hDC, hFont); - if (lppop->Height == 0) - MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd); + if (pop.Height == 0) + { + MENU_MenuBarCalcSize(hDC, lprect, &pop, hwnd); + SERVER_SetMenu(hMenu, &pop, SET_MI_MAXBMPSIZE); + } - lprect->bottom = lprect->top + lppop->Height; + lprect->bottom = lprect->top + pop.Height; FillRect(hDC, lprect, GetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU) ); @@ -4158,18 +4271,18 @@ MoveToEx( hDC, lprect->left, lprect->bottom, NULL ); LineTo( hDC, lprect->right, lprect->bottom ); - if (lppop->nItems == 0) + if (pop.nItems == 0) { retvalue = GetSystemMetrics(SM_CYMENU); goto END; } - for (i = 0; i < lppop->nItems; i++) + for (i = 0; i < pop.nItems; i++) { MENU_DrawMenuItem( hwnd, hMenu, hwnd, - hDC, &lppop->items[i], lppop->Height, TRUE, ODA_DRAWENTIRE ); + hDC, &pop.items[i], pop.Height, TRUE, ODA_DRAWENTIRE ); } - retvalue = lppop->Height; + retvalue = pop.Height; END: if (hfontOld) SelectObject (hDC, hfontOld); @@ -4336,9 +4449,9 @@ */ BOOL WINAPI IsMenu(HMENU hmenu) { - LPPOPUPMENU menu = MENU_GetMenu(hmenu); - - if (!menu) + POPUPMENU menu; + + if (!SERVER_GetMenu(hmenu, &menu)) { SetLastError(ERROR_INVALID_MENU_HANDLE); return FALSE; @@ -4568,15 +4681,20 @@ if (lpmii->fMask & MIIM_ID) menu->wID = lpmii->wID; - if (lpmii->fMask & MIIM_SUBMENU) { + if (lpmii->fMask & MIIM_SUBMENU) + { menu->hSubMenu = lpmii->hSubMenu; - if (menu->hSubMenu) { - POPUPMENU *subMenu = MENU_GetMenu(menu->hSubMenu); - if (subMenu) { - subMenu->wFlags |= MF_POPUP; + if (menu->hSubMenu) + { + POPUPMENU subMenu; + if (SERVER_GetMenu(menu->hSubMenu, &subMenu)) + { + subMenu.wFlags |= MF_POPUP; + SERVER_SetMenu(menu->hSubMenu, &subMenu, SET_MI_FLAGS); menu->fType |= MF_POPUP; } - else { + else + { SetLastError( ERROR_INVALID_PARAMETER); return FALSE; } @@ -4655,16 +4773,16 @@ BOOL WINAPI SetMenuDefaultItem(HMENU hmenu, UINT uItem, UINT bypos) { UINT i; - POPUPMENU *menu; + POPUPMENU menu; MENUITEM *item; TRACE("(%p,%d,%d)\n", hmenu, uItem, bypos); - if (!(menu = MENU_GetMenu(hmenu))) return FALSE; + if (!SERVER_GetMenu(hmenu, &menu)) return FALSE; /* reset all default-item flags */ - item = menu->items; - for (i = 0; i < menu->nItems; i++, item++) + item = menu.items; + for (i = 0; i < menu.nItems; i++, item++) { item->fState &= ~MFS_DEFAULT; } @@ -4675,16 +4793,16 @@ return TRUE; } - item = menu->items; + item = menu.items; if ( bypos ) { - if ( uItem >= menu->nItems ) return FALSE; + if ( uItem >= menu.nItems ) return FALSE; item[uItem].fState |= MFS_DEFAULT; return TRUE; } else { - for (i = 0; i < menu->nItems; i++, item++) + for (i = 0; i < menu.nItems; i++, item++) { if (item->wID == uItem) { @@ -4702,16 +4820,16 @@ */ UINT WINAPI GetMenuDefaultItem(HMENU hmenu, UINT bypos, UINT flags) { - POPUPMENU *menu; + POPUPMENU menu; MENUITEM * item; UINT i = 0; TRACE("(%p,%d,%d)\n", hmenu, bypos, flags); - if (!(menu = MENU_GetMenu(hmenu))) return -1; + if (!SERVER_GetMenu(hmenu, &menu)) return -1; /* find default item */ - item = menu->items; + item = menu.items; /* empty menu */ if (! item) return -1; @@ -4719,7 +4837,7 @@ while ( !( item->fState & MFS_DEFAULT ) ) { i++; item++; - if (i >= menu->nItems ) return -1; + if (i >= menu.nItems ) return -1; } /* default: don't return disabled items */ @@ -4832,7 +4950,7 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd, HMENU hMenu, UINT uItem, LPRECT rect) { - POPUPMENU *itemMenu; + POPUPMENU itemMenu; MENUITEM *item; HWND referenceHwnd; @@ -4843,13 +4961,12 @@ if(!hwnd) { - itemMenu = MENU_GetMenu(hMenu); - if (itemMenu == NULL) + if (!SERVER_GetMenu(hMenu, &itemMenu)) return FALSE; - if(itemMenu->hWnd == 0) + if(itemMenu.hWnd == 0) return FALSE; - referenceHwnd = itemMenu->hWnd; + referenceHwnd = itemMenu.hWnd; } if ((rect == NULL) || (item == NULL)) @@ -4872,34 +4989,36 @@ */ BOOL WINAPI SetMenuInfo (HMENU hMenu, LPCMENUINFO lpmi) { - POPUPMENU *menu; + POPUPMENU menu; TRACE("(%p %p)\n", hMenu, lpmi); - if (lpmi && (lpmi->cbSize==sizeof(MENUINFO)) && (menu = MENU_GetMenu(hMenu))) + if (lpmi && (lpmi->cbSize==sizeof(MENUINFO)) && SERVER_GetMenu(hMenu, &menu)) { if (lpmi->fMask & MIM_BACKGROUND) - menu->hbrBack = lpmi->hbrBack; + menu.hbrBack = lpmi->hbrBack; if (lpmi->fMask & MIM_HELPID) - menu->dwContextHelpID = lpmi->dwContextHelpID; + menu.dwContextHelpID = lpmi->dwContextHelpID; if (lpmi->fMask & MIM_MAXHEIGHT) - menu->cyMax = lpmi->cyMax; + menu.cyMax = lpmi->cyMax; if (lpmi->fMask & MIM_MENUDATA) - menu->dwMenuData = lpmi->dwMenuData; + menu.dwMenuData = lpmi->dwMenuData; if (lpmi->fMask & MIM_STYLE) { - menu->dwStyle = lpmi->dwStyle; - if (menu->dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented\n"); - if (menu->dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented\n"); - if (menu->dwStyle & MNS_MODELESS) FIXME("MNS_MODELESS unimplemented\n"); - if (menu->dwStyle & MNS_NOTIFYBYPOS) FIXME("MNS_NOTIFYBYPOS unimplemented\n"); + menu.dwStyle = lpmi->dwStyle; + if (menu.dwStyle & MNS_AUTODISMISS) FIXME("MNS_AUTODISMISS unimplemented\n"); + if (menu.dwStyle & MNS_DRAGDROP) FIXME("MNS_DRAGDROP unimplemented\n"); + if (menu.dwStyle & MNS_MODELESS) FIXME("MNS_MODELESS unimplemented\n"); + if (menu.dwStyle & MNS_NOTIFYBYPOS) FIXME("MNS_NOTIFYBYPOS unimplemented\n"); } + SERVER_SetMenu(hMenu, &menu, lpmi->fMask & (MIM_BACKGROUND|MIM_HELPID|MIM_MAXHEIGHT|MIM_MENUDATA|MIM_STYLE)); + return TRUE; } return FALSE; @@ -4913,27 +5032,27 @@ * */ BOOL WINAPI GetMenuInfo (HMENU hMenu, LPMENUINFO lpmi) -{ POPUPMENU *menu; +{ POPUPMENU menu; TRACE("(%p %p)\n", hMenu, lpmi); - if (lpmi && (menu = MENU_GetMenu(hMenu))) + if (lpmi && SERVER_GetMenu(hMenu, &menu)) { if (lpmi->fMask & MIM_BACKGROUND) - lpmi->hbrBack = menu->hbrBack; + lpmi->hbrBack = menu.hbrBack; if (lpmi->fMask & MIM_HELPID) - lpmi->dwContextHelpID = menu->dwContextHelpID; + lpmi->dwContextHelpID = menu.dwContextHelpID; if (lpmi->fMask & MIM_MAXHEIGHT) - lpmi->cyMax = menu->cyMax; + lpmi->cyMax = menu.cyMax; if (lpmi->fMask & MIM_MENUDATA) - lpmi->dwMenuData = menu->dwMenuData; + lpmi->dwMenuData = menu.dwMenuData; if (lpmi->fMask & MIM_STYLE) - lpmi->dwStyle = menu->dwStyle; + lpmi->dwStyle = menu.dwStyle; return TRUE; } @@ -4946,13 +5065,13 @@ */ BOOL WINAPI SetMenuContextHelpId( HMENU hMenu, DWORD dwContextHelpID) { - LPPOPUPMENU menu; + POPUPMENU menu; TRACE("(%p 0x%08lx)\n", hMenu, dwContextHelpID); - if ((menu = MENU_GetMenu(hMenu))) + if (SERVER_GetMenu(hMenu, &menu)) { - menu->dwContextHelpID = dwContextHelpID; + menu.dwContextHelpID = dwContextHelpID; return TRUE; } return FALSE; @@ -4964,13 +5083,13 @@ */ DWORD WINAPI GetMenuContextHelpId( HMENU hMenu ) { - LPPOPUPMENU menu; + POPUPMENU menu; TRACE("(%p)\n", hMenu); - if ((menu = MENU_GetMenu(hMenu))) + if (SERVER_GetMenu(hMenu, &menu)) { - return menu->dwContextHelpID; + return menu.dwContextHelpID; } return 0; } @@ -4980,12 +5099,12 @@ */ INT WINAPI MenuItemFromPoint(HWND hWnd, HMENU hMenu, POINT ptScreen) { - POPUPMENU *menu = MENU_GetMenu(hMenu); + POPUPMENU menu; UINT pos; /*FIXME: Do we have to handle hWnd here? */ - if (!menu) return -1; - if (!MENU_FindItemByCoords(menu, ptScreen, &pos)) return -1; + if (!SERVER_GetMenu(hMenu, &menu)) return -1; + if (!MENU_FindItemByCoords(&menu, ptScreen, &pos)) return -1; return pos; } Index: include/wine/server_protocol.h =================================================================== RCS file: /home/wine/wine/include/wine/server_protocol.h,v retrieving revision 1.200 diff -u -r1.200 server_protocol.h --- include/wine/server_protocol.h 7 Jun 2006 12:51:16 -0000 1.200 +++ include/wine/server_protocol.h 10 Jun 2006 00:34:48 -0000 @@ -3492,6 +3492,58 @@ #define SET_GLOBAL_TASKMAN_WINDOW 0x04 +struct menu_info_request +{ + struct request_header __header; + user_handle_t handle; + unsigned int mask; + /* VARARG(data,bytes); */ +}; +struct menu_info_reply +{ + struct reply_header __header; + unsigned int status; + /* VARARG(data,bytes); */ +}; + + +struct create_menu_request +{ + struct request_header __header; +}; +struct create_menu_reply +{ + struct reply_header __header; + user_handle_t handle; +}; + + +struct destroy_menu_request +{ + struct request_header __header; + user_handle_t handle; +}; +struct destroy_menu_reply +{ + struct reply_header __header; +}; + +#define SET_MI_FLAGS 0x80000000 +#define SET_MI_HWND 0x40000000 +#define SET_MI_SYSMENU 0x20000000 +#define SET_MI_OWNER 0x10000000 +#define SET_MI_FOCUSITEM 0x08000000 +#define SET_MI_TIMETOHIDE 0x04000000 +#define SET_MI_WIDTH 0x02000000 +#define SET_MI_HEIGHT 0x01000000 +#define SET_MI_SCROLLING 0x00800000 +#define SET_MI_SCROLLPOS 0x00400000 +#define SET_MI_TOTALHEIGHT 0x00200000 +#define SET_MI_MAXBMPSIZE 0x00100000 +#define SET_MI_ITEMS 0x00080000 +#define SET_MI_NITEMS 0x00040000 + + struct adjust_token_privileges_request { struct request_header __header; @@ -3927,6 +3979,9 @@ REQ_set_clipboard_info, REQ_open_token, REQ_set_global_windows, + REQ_menu_info, + REQ_create_menu, + REQ_destroy_menu, REQ_adjust_token_privileges, REQ_get_token_privileges, REQ_check_token_privileges, @@ -4147,6 +4202,9 @@ struct set_clipboard_info_request set_clipboard_info_request; struct open_token_request open_token_request; struct set_global_windows_request set_global_windows_request; + struct menu_info_request menu_info_request; + struct create_menu_request create_menu_request; + struct destroy_menu_request destroy_menu_request; struct adjust_token_privileges_request adjust_token_privileges_request; struct get_token_privileges_request get_token_privileges_request; struct check_token_privileges_request check_token_privileges_request; @@ -4365,6 +4423,9 @@ struct set_clipboard_info_reply set_clipboard_info_reply; struct open_token_reply open_token_reply; struct set_global_windows_reply set_global_windows_reply; + struct menu_info_reply menu_info_reply; + struct create_menu_reply create_menu_reply; + struct destroy_menu_reply destroy_menu_reply; struct adjust_token_privileges_reply adjust_token_privileges_reply; struct get_token_privileges_reply get_token_privileges_reply; struct check_token_privileges_reply check_token_privileges_reply; @@ -4382,6 +4443,6 @@ struct query_symlink_reply query_symlink_reply; }; -#define SERVER_PROTOCOL_VERSION 236 +#define SERVER_PROTOCOL_VERSION 11 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ Index: server/Makefile.in =================================================================== RCS file: /home/wine/wine/server/Makefile.in,v retrieving revision 1.62 diff -u -r1.62 Makefile.in --- server/Makefile.in 20 Feb 2006 11:43:12 -0000 1.62 +++ server/Makefile.in 10 Jun 2006 00:34:48 -0000 @@ -26,6 +26,7 @@ mailslot.c \ main.c \ mapping.c \ + menu.c \ mutex.c \ named_pipe.c \ object.c \ Index: server/protocol.def =================================================================== RCS file: /home/wine/wine/server/protocol.def,v retrieving revision 1.200 diff -u -r1.200 protocol.def --- server/protocol.def 7 Jun 2006 12:51:16 -0000 1.200 +++ server/protocol.def 10 Jun 2006 00:34:48 -0000 @@ -2456,6 +2456,43 @@ #define SET_GLOBAL_PROGMAN_WINDOW 0x02 #define SET_GLOBAL_TASKMAN_WINDOW 0x04 +/* Set/get menu info */ +@REQ(menu_info) + user_handle_t handle; + unsigned int mask; + VARARG(data,bytes); +@REPLY + unsigned int status; + VARARG(data,bytes); +@END + +/* create a menu */ +@REQ(create_menu) +@REPLY + user_handle_t handle; +@END + +/* destroy menu */ +@REQ(destroy_menu) + user_handle_t handle; +@REPLY +@END + +#define SET_MI_FLAGS 0x80000000 +#define SET_MI_HWND 0x40000000 +#define SET_MI_SYSMENU 0x20000000 +#define SET_MI_OWNER 0x10000000 +#define SET_MI_FOCUSITEM 0x08000000 +#define SET_MI_TIMETOHIDE 0x04000000 +#define SET_MI_WIDTH 0x02000000 +#define SET_MI_HEIGHT 0x01000000 +#define SET_MI_SCROLLING 0x00800000 +#define SET_MI_SCROLLPOS 0x00400000 +#define SET_MI_TOTALHEIGHT 0x00200000 +#define SET_MI_MAXBMPSIZE 0x00100000 +#define SET_MI_ITEMS 0x00080000 +#define SET_MI_NITEMS 0x00040000 + /* Adjust the privileges held by a token */ @REQ(adjust_token_privileges) obj_handle_t handle; /* handle to the token */ Index: server/request.h =================================================================== RCS file: /home/wine/wine/server/request.h,v retrieving revision 1.132 diff -u -r1.132 request.h --- server/request.h 23 May 2006 12:49:34 -0000 1.132 +++ server/request.h 10 Jun 2006 00:34:48 -0000 @@ -308,6 +308,9 @@ DECL_HANDLER(set_clipboard_info); DECL_HANDLER(open_token); DECL_HANDLER(set_global_windows); +DECL_HANDLER(menu_info); +DECL_HANDLER(create_menu); +DECL_HANDLER(destroy_menu); DECL_HANDLER(adjust_token_privileges); DECL_HANDLER(get_token_privileges); DECL_HANDLER(check_token_privileges); @@ -527,6 +530,9 @@ (req_handler)req_set_clipboard_info, (req_handler)req_open_token, (req_handler)req_set_global_windows, + (req_handler)req_menu_info, + (req_handler)req_create_menu, + (req_handler)req_destroy_menu, (req_handler)req_adjust_token_privileges, (req_handler)req_get_token_privileges, (req_handler)req_check_token_privileges, Index: server/trace.c =================================================================== RCS file: /home/wine/wine/server/trace.c,v retrieving revision 1.313 diff -u -r1.313 trace.c --- server/trace.c 8 Jun 2006 10:07:22 -0000 1.313 +++ server/trace.c 10 Jun 2006 00:34:49 -0000 @@ -3044,6 +3044,35 @@ fprintf( stderr, " old_taskman_window=%p", req->old_taskman_window ); } +static void dump_menu_info_request( const struct menu_info_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " mask=%08x,", req->mask ); + fprintf( stderr, " data=" ); + dump_varargs_bytes( cur_size ); +} + +static void dump_menu_info_reply( const struct menu_info_reply *req ) +{ + fprintf( stderr, " status=%08x,", req->status ); + fprintf( stderr, " data=" ); + dump_varargs_bytes( cur_size ); +} + +static void dump_create_menu_request( const struct create_menu_request *req ) +{ +} + +static void dump_create_menu_reply( const struct create_menu_reply *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_destroy_menu_request( const struct destroy_menu_request *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + static void dump_adjust_token_privileges_request( const struct adjust_token_privileges_request *req ) { fprintf( stderr, " handle=%p,", req->handle ); @@ -3462,6 +3491,9 @@ (dump_func)dump_set_clipboard_info_request, (dump_func)dump_open_token_request, (dump_func)dump_set_global_windows_request, + (dump_func)dump_menu_info_request, + (dump_func)dump_create_menu_request, + (dump_func)dump_destroy_menu_request, (dump_func)dump_adjust_token_privileges_request, (dump_func)dump_get_token_privileges_request, (dump_func)dump_check_token_privileges_request, @@ -3678,6 +3710,9 @@ (dump_func)dump_set_clipboard_info_reply, (dump_func)dump_open_token_reply, (dump_func)dump_set_global_windows_reply, + (dump_func)dump_menu_info_reply, + (dump_func)dump_create_menu_reply, + (dump_func)0, (dump_func)dump_adjust_token_privileges_reply, (dump_func)dump_get_token_privileges_reply, (dump_func)dump_check_token_privileges_reply, @@ -3894,6 +3929,9 @@ "set_clipboard_info", "open_token", "set_global_windows", + "menu_info", + "create_menu", + "destroy_menu", "adjust_token_privileges", "get_token_privileges", "check_token_privileges", Index: server/user.h =================================================================== RCS file: /home/wine/wine/server/user.h,v retrieving revision 1.43 diff -u -r1.43 user.h --- server/user.h 8 Jun 2006 10:07:25 -0000 1.43 +++ server/user.h 10 Jun 2006 00:34:49 -0000 @@ -35,7 +35,8 @@ enum user_object { USER_WINDOW = 1, - USER_HOOK + USER_MENU = 2, + USER_HOOK = 5 }; #define DESKTOP_ATOM ((atom_t)32769) --- /dev/null 2006-05-31 09:29:03.272380500 -0700 +++ server/menu.c 2006-06-09 16:15:43.000000000 -0700 @@ -0,0 +1,207 @@ +/* + * Server-side menu handling + * + * Copyright (C) 2004 Ulrich Czekalla for CodeWeavers Inc. + * Copyright (C) 2006 Google (Thomas Kho) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winternl.h" + +#include "object.h" +#include "request.h" +#include "user.h" +#include "unicode.h" + +/* MENUITEM and POPUPMENU duplicated in dlls/user/menu.c */ +/* 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. */ + HBITMAP hCheckBit; /* Bitmap when checked. */ + HBITMAP hUnCheckBit; /* Bitmap when unchecked. */ + LPWSTR text; /* Item text. */ + ULONG_PTR dwItemData; /* Application defined. */ + LPWSTR dwTypeData; /* depends on fMask */ + HBITMAP hbmpItem; /* bitmap */ + /* ----------- Wine stuff ----------- */ + RECT rect; /* Item area (relative to menu window) */ + UINT xTab; /* X position of text after Tab */ + SIZE bmpsize; /* size needed for the HBMMENU_CALLBACK + * bitmap */ +} MENUITEM; + +/* Popup menu structure */ +typedef struct { + WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ + WORD wMagic; /* Magic number */ + WORD Width; /* Width of the whole menu */ + WORD Height; /* Height of the whole menu */ + UINT nItems; /* Number of items in the menu */ + HWND hWnd; /* Window containing the menu */ + MENUITEM *items; /* Array of menu items */ + UINT FocusedItem; /* Currently focused item */ + HWND hwndOwner; /* window receiving the messages for ownerdraw */ + BOOL bTimeToHide; /* Request hiding when receiving a second click in the top-level menu item */ + BOOL bScrolling; /* Scroll arrows are active */ + UINT nScrollPos; /* Current scroll position */ + UINT nTotalHeight; /* Total height of menu items inside menu */ + /* ------------ MENUINFO members ------ */ + DWORD dwStyle; /* Extended menu style */ + UINT cyMax; /* max height of the whole menu, 0 is screen height */ + HBRUSH hbrBack; /* brush for menu background */ + DWORD dwContextHelpID; + DWORD dwMenuData; /* application defined value */ + HMENU hSysMenuOwner; /* Handle to the dummy sys menu holder */ + SIZE maxBmpSize; /* Maximum size of the bitmap items */ +} POPUPMENU, *LPPOPUPMENU; + +struct menu +{ + user_handle_t handle; + POPUPMENU p; +}; + + +/* (other menu->FocusedItem values give the position of the focused item) */ +#define NO_SELECTED_ITEM 0xffff + + +/* retrive a pointer to a menu given its handle */ +static struct menu *get_menu(user_handle_t handle) +{ + struct menu *ret = get_user_object(handle, USER_MENU); + if (!ret) set_error(STATUS_INVALID_HANDLE); + return ret; +} + + +/* create a new menu structure */ +static struct menu *create_menu() +{ + struct menu *pmenu; + + if (!(pmenu = mem_alloc(sizeof(struct menu)))) + return NULL; + + ZeroMemory(pmenu, sizeof(struct menu)); + + if (!(pmenu->handle = alloc_user_handle(pmenu, USER_MENU))) + { + free(pmenu); + return NULL; + } + + return pmenu; +} + + +/* destroy a menu */ +static void destroy_menu(struct menu *pmenu) +{ + free_user_handle(pmenu->handle); + free(pmenu); +} + + +/* create a menu */ +DECL_HANDLER(create_menu) +{ + struct menu *pmenu; + + reply->handle = 0; + + if ((pmenu = create_menu())) + { + pmenu->p.FocusedItem = NO_SELECTED_ITEM; + pmenu->p.bTimeToHide = FALSE; + reply->handle = pmenu->handle; + } +} + + +/* destroy a menu */ +DECL_HANDLER(destroy_menu) +{ + struct menu *pmenu = get_menu(req->handle); + + if (pmenu) + destroy_menu(pmenu); +} + + +/* validate the given menu handle and set/get menu info */ +DECL_HANDLER(menu_info) +{ + struct menu *pmenu = get_menu(req->handle); + + if (pmenu) + { + if (req->mask && get_req_data_size() == sizeof(POPUPMENU)) + { + const POPUPMENU *p = get_req_data(); + + if (req->mask & SET_MI_FLAGS) pmenu->p.wFlags = p->wFlags; + if (req->mask & SET_MI_WIDTH) pmenu->p.Width = p->Width; + if (req->mask & SET_MI_HEIGHT) pmenu->p.Height = p->Height; + if (req->mask & SET_MI_NITEMS) pmenu->p.nItems = p->nItems; + if (req->mask & SET_MI_HWND) pmenu->p.hWnd = p->hWnd; + if (req->mask & SET_MI_ITEMS) pmenu->p.items = p->items; + if (req->mask & SET_MI_FOCUSITEM) + pmenu->p.FocusedItem = p->FocusedItem; + if (req->mask & SET_MI_OWNER) pmenu->p.hwndOwner = p->hwndOwner; + if (req->mask & SET_MI_TIMETOHIDE) + pmenu->p.bTimeToHide = p->bTimeToHide; + if (req->mask & SET_MI_SCROLLING) + pmenu->p.bScrolling = p->bScrolling; + if (req->mask & SET_MI_SCROLLPOS) + pmenu->p.nScrollPos = p->nScrollPos; + if (req->mask & SET_MI_TOTALHEIGHT) + pmenu->p.nTotalHeight = p->nTotalHeight; + + if (req->mask & MIM_STYLE) pmenu->p.dwStyle = p->dwStyle; + if (req->mask & MIM_MAXHEIGHT) pmenu->p.cyMax = p->cyMax; + if (req->mask & MIM_BACKGROUND) pmenu->p.hbrBack = p->hbrBack; + if (req->mask & MIM_HELPID) + pmenu->p.dwContextHelpID= p->dwContextHelpID; + if (req->mask & MIM_MENUDATA) pmenu->p.dwMenuData = p->dwMenuData; + if (req->mask & SET_MI_SYSMENU) + pmenu->p.hSysMenuOwner = p->hSysMenuOwner; + if (req->mask & SET_MI_MAXBMPSIZE) + pmenu->p.maxBmpSize = p->maxBmpSize; + } + + if (get_reply_max_size() == sizeof(POPUPMENU)) + { + set_reply_data(&pmenu->p, sizeof(POPUPMENU)); + } + } + reply->status = (int) pmenu; +}