[PATCH 08/11] user: more menu item client changes
Thomas Kho
tkho at ucla.edu
Thu Jun 29 15:34:22 CDT 2006
user: more menu item client changes
Thomas Kho
---
dlls/user/menu.c | 207 +++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 151 insertions(+), 56 deletions(-)
diff --git a/dlls/user/menu.c b/dlls/user/menu.c
index 557d2af..a0b70d1 100644
--- a/dlls/user/menu.c
+++ b/dlls/user/menu.c
@@ -1468,9 +1468,10 @@ static void MENU_PopupMenuCalcSize( HMEN
* Calculate the size of the menu bar.
*/
static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect,
- LPPOPUPMENU lppop, HWND hwndOwner )
+ LPPOPUPMENU lppop, HMENU hmenu,
+ HWND hwndOwner )
{
- MENUITEM *lpitem;
+ MENUITEM *lpitem, *items;
int start, i, orgX, orgY, maxY, helpPos;
if ((lprect == NULL) || (lppop == NULL)) return;
@@ -1483,9 +1484,10 @@ static void MENU_MenuBarCalcSize( HDC hd
helpPos = -1;
lppop->maxBmpSize.cx = 0;
lppop->maxBmpSize.cy = 0;
+ MENU_GetAllMenuItems(hmenu, &items);
while (start < lppop->nItems)
{
- lpitem = &lppop->items[start];
+ lpitem = &items[start];
orgX = lprect->left;
orgY = maxY;
@@ -1499,18 +1501,28 @@ static void MENU_MenuBarCalcSize( HDC hd
TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY );
debug_print_menuitem (" item: ", lpitem, "");
MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, TRUE, lppop );
+ MENU_UpdateMenuItem(hmenu, i, lpitem);
if (lpitem->rect.right > lprect->right)
{
if (i != start) break;
- else lpitem->rect.right = lprect->right;
+ else
+ {
+ lpitem->rect.right = lprect->right;
+ MENU_UpdateMenuItem(hmenu, i, lpitem);
+ }
}
maxY = max( maxY, lpitem->rect.bottom );
orgX = lpitem->rect.right;
}
/* Finish the line (set all items to the largest height found) */
- while (start < i) lppop->items[start++].rect.bottom = maxY;
+ while (start < i)
+ {
+ items[start].rect.bottom = maxY;
+ MENU_UpdateMenuItem(hmenu, start, &items[start]);
+ start++;
+ }
}
lprect->bottom = maxY;
@@ -1518,7 +1530,7 @@ static void MENU_MenuBarCalcSize( HDC hd
/* Flush right all items between the MF_RIGHTJUSTIFY and */
/* the last item (if several lines, only move the last line) */
- lpitem = &lppop->items[lppop->nItems-1];
+ lpitem = &items[lppop->nItems-1];
orgY = lpitem->rect.top;
orgX = lprect->right;
for (i = lppop->nItems - 1; i >= helpPos; i--, lpitem--) {
@@ -1528,8 +1540,10 @@ static void MENU_MenuBarCalcSize( HDC hd
if (lpitem->rect.right >= orgX) break; /* Too far right already */
lpitem->rect.left += orgX - lpitem->rect.right;
lpitem->rect.right = orgX;
+ MENU_UpdateMenuItem(hmenu, i, lpitem);
orgX = lpitem->rect.left;
}
+ MENU_ReleaseMenuItem(items);
}
@@ -2032,7 +2046,7 @@ UINT MENU_DrawMenuBar( HDC hDC, LPRECT l
if (lppop->Height == 0)
{
- MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd);
+ MENU_MenuBarCalcSize(hDC, lprect, lppop, hMenu, hwnd);
MENU_UpdateMenu(hMenu, lppop, SET_MI_MAXBMPSIZE);
}
@@ -2580,15 +2594,18 @@ static void MENU_HideSubPopups( HWND hwn
HMENU hsubmenu;
POPUPMENU tmpsubmenu;
POPUPMENU *submenu = &tmpsubmenu;
- MENUITEM *item;
+ UINT focuseditem = MENU_GetLocalMenu(hmenu)->FocusedItem;
- if (MENU_GetLocalMenu(hmenu)->FocusedItem != NO_SELECTED_ITEM)
+ if (focuseditem != NO_SELECTED_ITEM)
{
- item = &menu->items[MENU_GetLocalMenu(hmenu)->FocusedItem];
+ MENUITEM *item;
+ MENU_GetMenuItem(hmenu, focuseditem, &item);
if (!(item->fType & MF_POPUP) ||
!(item->fState & MF_MOUSESELECT)) return;
item->fState &= ~MF_MOUSESELECT;
+ MENU_UpdateMenuItem(hmenu, focuseditem, item);
hsubmenu = item->hSubMenu;
+ MENU_ReleaseMenuItem(item);
} else return;
MENU_GetMenu( hsubmenu, submenu );
@@ -2610,6 +2627,8 @@ static void MENU_HideSubPopups( HWND hwn
static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu,
BOOL selectFirst, UINT wFlags )
{
+ UINT focuseditem;
+ HMENU hm;
RECT rect;
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
@@ -2620,11 +2639,16 @@ static HMENU MENU_ShowSubPopup( HWND hwn
if (MENU_GetMenu( hmenu, menu )) return hmenu;
- if (MENU_GetLocalMenu(hmenu)->FocusedItem == NO_SELECTED_ITEM) return hmenu;
+ focuseditem = MENU_GetLocalMenu(hmenu)->FocusedItem;
+ if (focuseditem == NO_SELECTED_ITEM) return hmenu;
- item = &menu->items[MENU_GetLocalMenu(hmenu)->FocusedItem];
+ MENU_GetMenuItem(hmenu, focuseditem, &item);
if (!(item->fType & MF_POPUP) || (item->fState & (MF_GRAYED | MF_DISABLED)))
+ {
+ MENU_ReleaseMenuItem(item);
return hmenu;
+ }
+ MENU_ReleaseMenuItem(item);
/* message must be sent before using item,
because nearly everything may be changed by the application ! */
@@ -2632,10 +2656,9 @@ static HMENU MENU_ShowSubPopup( HWND hwn
/* 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_GetLocalMenu(hmenu)->FocusedItem,
- IS_SYSTEM_MENU(menu) ));
+ MAKELONG( focuseditem, IS_SYSTEM_MENU(menu) ));
- item = &menu->items[MENU_GetLocalMenu(hmenu)->FocusedItem];
+ MENU_GetMenuItem(hmenu, focuseditem, &item);
rect = item->rect;
/* correct item if modified as a reaction to WM_INITMENUPOPUP message */
@@ -2692,12 +2715,15 @@ static HMENU MENU_ShowSubPopup( HWND hwn
}
}
- MENU_ShowPopup( hwndOwner, item->hSubMenu,
- MENU_GetLocalMenu(hmenu)->FocusedItem,
+ MENU_UpdateMenuItem(hmenu, focuseditem, item);
+ MENU_ShowPopup( hwndOwner, item->hSubMenu, focuseditem,
rect.left, rect.top, rect.right, rect.bottom );
if (selectFirst)
MENU_MoveSelection( hwndOwner, item->hSubMenu, ITEM_NEXT );
- return item->hSubMenu;
+
+ hm = item->hSubMenu;
+ MENU_ReleaseMenuItem(item);
+ return hm;
}
@@ -2717,6 +2743,7 @@ HWND MENU_IsMenuActive(void)
*/
static HMENU MENU_PtMenu( HMENU hMenu, POINT pt )
{
+ MENUITEM *mi;
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
UINT item;
@@ -2725,10 +2752,13 @@ static HMENU MENU_PtMenu( HMENU hMenu, P
item = MENU_GetLocalMenu(hMenu)->FocusedItem;
/* try subpopup first (if any) */
+ if (item != NO_SELECTED_ITEM)
+ MENU_GetMenuItem(hMenu, item, &mi);
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;
+ (mi->fType & MF_POPUP) &&
+ (mi->fState & MF_MOUSESELECT))
+ ? MENU_PtMenu(mi->hSubMenu, pt) : 0;
+ MENU_ReleaseMenuItem(mi);
if (!ret) /* check the current window (avoiding WM_HITTEST) */
{
@@ -2766,7 +2796,7 @@ static INT MENU_ExecFocusedItem( MTRACKE
if (MENU_GetMenu( hMenu, menu ) || !menu->nItems ||
(MENU_GetLocalMenu(hMenu)->FocusedItem == NO_SELECTED_ITEM)) return -1;
- item = &menu->items[MENU_GetLocalMenu(hMenu)->FocusedItem];
+ MENU_GetMenuItem(hMenu, MENU_GetLocalMenu(hMenu)->FocusedItem, &item);
TRACE("%p %08x %p\n", hMenu, item->wID, item->hSubMenu);
@@ -2784,15 +2814,18 @@ static INT MENU_ExecFocusedItem( MTRACKE
else
PostMessageW( pmt->hOwnerWnd, WM_COMMAND, item->wID, 0 );
}
+ MENU_ReleaseMenuItem(item);
return item->wID;
}
}
else
{
pmt->hCurrentMenu = MENU_ShowSubPopup(pmt->hOwnerWnd, hMenu, TRUE, wFlags);
+ MENU_ReleaseMenuItem(item);
return -2;
}
+ MENU_ReleaseMenuItem(item);
return -1;
}
@@ -2841,13 +2874,15 @@ static BOOL MENU_ButtonDown( MTRACKER* p
MENU_GetMenu( hPtMenu, ptmenu );
if( IS_SYSTEM_MENU(ptmenu) )
- item = ptmenu->items;
+ MENU_GetMenuItem(hPtMenu, 0, &item);
else
{
POPUPMENU menu;
MENU_FindItemByCoords( hPtMenu, pmt->pt, &id );
MENU_GetMenu(hPtMenu, &menu);
- item = (id == ITEM_NOT_FOUND) ? NULL : &menu.items[id];
+ if (id == ITEM_NOT_FOUND) item = NULL;
+ else
+ MENU_GetMenuItem(hPtMenu, id, &item);
}
if( item )
@@ -2861,6 +2896,7 @@ static BOOL MENU_ButtonDown( MTRACKER* p
pmt->hCurrentMenu = MENU_ShowSubPopup( pmt->hOwnerWnd, hPtMenu, FALSE, wFlags );
}
+ MENU_ReleaseMenuItem(item);
return TRUE;
}
/* Else the click was on the menu bar, finish the tracking */
@@ -2889,13 +2925,15 @@ static INT MENU_ButtonUp( MTRACKER* pmt,
MENU_GetMenu( hPtMenu, ptmenu );
if( IS_SYSTEM_MENU(ptmenu) )
- item = ptmenu->items;
+ MENU_GetMenuItem(hPtMenu, 0, &item);
else
{
POPUPMENU menu;
MENU_FindItemByCoords( hPtMenu, pmt->pt, &id );
MENU_GetMenu(hPtMenu, &menu);
- item = (id == ITEM_NOT_FOUND) ? NULL : &menu.items[id];
+ if (id == ITEM_NOT_FOUND) item = NULL;
+ else
+ MENU_GetMenuItem(hPtMenu, id, &item);
}
if( item && (MENU_GetLocalMenu(hPtMenu)->FocusedItem == id ))
@@ -2903,6 +2941,7 @@ static INT MENU_ButtonUp( MTRACKER* pmt,
if( !(item->fType & MF_POPUP) )
{
INT executedMenuId = MENU_ExecFocusedItem( pmt, hPtMenu, wFlags);
+ MENU_ReleaseMenuItem(item);
return (executedMenuId < 0) ? -1 : executedMenuId;
}
@@ -2910,8 +2949,12 @@ static INT MENU_ButtonUp( MTRACKER* pmt,
/* and this is a click on an already "popped" item: */
/* Stop the menu tracking and close the opened submenus */
if((pmt->hTopMenu == hPtMenu) && MENU_GetLocalMenu(hPtMenu)->bTimeToHide)
+ {
+ MENU_ReleaseMenuItem(item);
return 0;
+ }
}
+ MENU_ReleaseMenuItem(item);
MENU_GetLocalMenu(hPtMenu)->bTimeToHide = TRUE;
}
return -1;
@@ -3823,7 +3866,7 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, U
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, lppop, GetMenu(hwnd), hwnd );
MENU_UpdateMenu( GetMenu(hwnd), lppop, SET_MI_WIDTH|SET_MI_HEIGHT|SET_MI_MAXBMPSIZE|SET_MI_TOTALHEIGHT);
ReleaseDC( hwnd, hdc );
return lppop->Height;
@@ -3876,18 +3919,18 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UI
DWORD WINAPI CheckMenuItem( HMENU hMenu, UINT id, UINT flags )
{
MENUITEM *item;
- POPUPMENU menu;
DWORD ret;
UINT pos;
TRACE("menu=%p id=%04x flags=%04x\n", hMenu, id, flags );
if ((pos = MENU_FindItem( &hMenu, &id, flags )) == ITEM_NOT_FOUND)
return -1;
- MENU_GetMenu(hMenu, &menu);
- item = &menu.items[pos];
+ MENU_GetMenuItem(hMenu, pos, &item);
ret = item->fState & MF_CHECKED;
if (flags & MF_CHECKED) item->fState |= MF_CHECKED;
else item->fState &= ~MF_CHECKED;
+ MENU_UpdateMenuItem(hMenu, pos, item);
+ MENU_ReleaseMenuItem(item);
return ret;
}
@@ -3912,10 +3955,11 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu,
if ((pos = MENU_FindItem( &hMenu, &wItemID, wFlags )) == ITEM_NOT_FOUND)
return (UINT)-1;
MENU_GetMenu(hMenu, menu);
- item = &menu->items[pos];
+ MENU_GetMenuItem(hMenu, pos, &item);
oldflags = item->fState & (MF_GRAYED | MF_DISABLED);
item->fState ^= (oldflags ^ wFlags) & (MF_GRAYED | MF_DISABLED);
+ MENU_UpdateMenuItem(hMenu, pos, item);
/* If the close item in the system menu change update the close button */
if((item->wID == SC_CLOSE) && (oldflags != wFlags))
@@ -3928,7 +3972,10 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu,
/* Get the parent menu to access*/
if (MENU_GetMenu(menu->hSysMenuOwner, parentMenu))
+ {
+ MENU_ReleaseMenuItem(item);
return (UINT)-1;
+ }
/* Refresh the frame to reflect the change */
GetWindowRect(parentMenu->hWnd, &rc);
@@ -3938,6 +3985,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu,
}
}
+ MENU_ReleaseMenuItem(item);
return oldflags;
}
@@ -3963,11 +4011,17 @@ INT WINAPI GetMenuStringA(
return 0;
}
MENU_GetMenu(hMenu, &menu);
- item = &menu.items[pos];
+ MENU_GetMenuItem(hMenu, pos, &item);
if (!item->text) return 0;
- if (!str || !nMaxSiz) return strlenW(item->text);
+ if (!str || !nMaxSiz)
+ {
+ UINT len = strlenW(item->text);
+ MENU_ReleaseMenuItem(item);
+ return len;
+ }
if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1, str, nMaxSiz, NULL, NULL ))
str[nMaxSiz-1] = 0;
+ MENU_ReleaseMenuItem(item);
TRACE("returning '%s'\n", str );
return strlen(str);
}
@@ -3990,13 +4044,24 @@ INT WINAPI GetMenuStringW( HMENU hMenu,
return 0;
}
MENU_GetMenu(hMenu, &menu);
- item = &menu.items[pos];
- if (!str || !nMaxSiz) return item->text ? strlenW(item->text) : 0;
+ MENU_GetMenuItem(hMenu, pos, &item);
+ if (!str || !nMaxSiz)
+ {
+ if (item->text)
+ {
+ UINT len = strlenW(item->text);
+ MENU_ReleaseMenuItem(item);
+ return len;
+ }
+ else return 0;
+ }
if( !(item->text)) {
str[0] = 0;
+ MENU_ReleaseMenuItem(item);
return 0;
}
lstrcpynW( str, item->text, nMaxSiz );
+ MENU_ReleaseMenuItem(item);
return strlenW(str);
}
@@ -4070,17 +4135,21 @@ INT WINAPI GetMenuItemCount( HMENU hMenu
*/
UINT WINAPI GetMenuItemID( HMENU hMenu, INT nPos )
{
+ WORD id;
MENUITEM * lpmi;
- POPUPMENU menu;
UINT pos;
if ((pos = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))
== ITEM_NOT_FOUND) return -1;
- MENU_GetMenu(hMenu, &menu);
- lpmi = &menu.items[pos];
- if (lpmi->fType & MF_POPUP) return -1;
- return lpmi->wID;
-
+ MENU_GetMenuItem(hMenu, pos, &lpmi);
+ if (lpmi->fType & MF_POPUP)
+ {
+ MENU_ReleaseMenuItem(lpmi);
+ return -1;
+ }
+ id = lpmi->wID;
+ MENU_ReleaseMenuItem(lpmi);
+ return id;
}
@@ -4555,16 +4624,21 @@ BOOL WINAPI SetMenu( HWND hWnd, HMENU hM
*/
HMENU WINAPI GetSubMenu( HMENU hMenu, INT nPos )
{
+ HMENU hsubmenu;
MENUITEM * lpmi;
- POPUPMENU menu;
UINT pos;
if ((pos = MENU_FindItem(&hMenu,(UINT*)&nPos,MF_BYPOSITION))
== ITEM_NOT_FOUND) return 0;
- MENU_GetMenu(hMenu, &menu);
- lpmi = &menu.items[pos];
- if (!(lpmi->fType & MF_POPUP)) return 0;
- return lpmi->hSubMenu;
+ MENU_GetMenuItem(hMenu, pos, &lpmi);
+ if (!(lpmi->fType & MF_POPUP))
+ {
+ MENU_ReleaseMenuItem(lpmi);
+ return 0;
+ }
+ hsubmenu = lpmi->hSubMenu;
+ MENU_ReleaseMenuItem(lpmi);
+ return hsubmenu;
}
@@ -4600,6 +4674,7 @@ BOOL WINAPI DrawMenuBar( HWND hWnd )
*/
DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont)
{
+ MENUITEM *items;
POPUPMENU tmppop;
LPPOPUPMENU lppop = &tmppop;
UINT i,retvalue;
@@ -4626,7 +4701,7 @@ DWORD WINAPI DrawMenuBarTemp(HWND hwnd,
if (lppop->Height == 0)
{
- MENU_MenuBarCalcSize(hDC, lprect, lppop, hwnd);
+ MENU_MenuBarCalcSize(hDC, lprect, lppop, hMenu, hwnd);
MENU_UpdateMenu(hMenu, lppop, SET_MI_MAXBMPSIZE);
}
@@ -4644,11 +4719,14 @@ DWORD WINAPI DrawMenuBarTemp(HWND hwnd,
goto END;
}
+ MENU_GetAllMenuItems(hMenu, &items);
for (i = 0; i < lppop->nItems; i++)
{
MENU_DrawMenuItem( hwnd, hMenu, hwnd,
- hDC, &lppop->items[i], lppop->Height, TRUE, ODA_DRAWENTIRE );
+ hDC, &items[i], lppop->Height, TRUE, ODA_DRAWENTIRE );
+ MENU_UpdateMenuItem(hMenu, i, &items[i]);
}
+ MENU_ReleaseMenuItem(items);
retvalue = lppop->Height;
END:
@@ -5203,15 +5281,17 @@ UINT WINAPI GetMenuDefaultItem(HMENU hme
{
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
- MENUITEM * item;
+ MENUITEM * item, *items;
UINT i = 0;
+ WORD id;
TRACE("(%p,%d,%d)\n", hmenu, bypos, flags);
if (MENU_GetMenu(hmenu, menu)) return -1;
/* find default item */
- item = menu->items;
+ MENU_GetAllMenuItems(hmenu, &items);
+ item = items;
/* empty menu */
if (! item) return -1;
@@ -5219,22 +5299,36 @@ UINT WINAPI GetMenuDefaultItem(HMENU hme
while ( !( item->fState & MFS_DEFAULT ) )
{
i++; item++;
- if (i >= menu->nItems ) return -1;
+ if (i >= menu->nItems )
+ {
+ MENU_ReleaseMenuItem(items);
+ return -1;
+ }
}
/* default: don't return disabled items */
- if ( (!(GMDI_USEDISABLED & flags)) && (item->fState & MFS_DISABLED )) return -1;
+ if ( (!(GMDI_USEDISABLED & flags)) && (item->fState & MFS_DISABLED ))
+ {
+ MENU_ReleaseMenuItem(items);
+ return -1;
+ }
/* search rekursiv when needed */
if ( (item->fType & MF_POPUP) && (flags & GMDI_GOINTOPOPUPS) )
{
UINT ret;
ret = GetMenuDefaultItem( item->hSubMenu, bypos, flags );
- if ( -1 != ret ) return ret;
+ if ( -1 != ret )
+ {
+ MENU_ReleaseMenuItem(items);
+ return ret;
+ }
/* when item not found in submenu, return the popup item */
}
- return ( bypos ) ? i : item->wID;
+ id = item->wID;
+ MENU_ReleaseMenuItem(items);
+ return ( bypos ) ? i : id;
}
@@ -5356,7 +5450,6 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd,
pos = MENU_FindItem (&hMenu, &uItem, MF_BYPOSITION);
MENU_GetMenu(hMenu, itemMenu);
- item = (pos == ITEM_NOT_FOUND) ? NULL : &itemMenu->items[pos];
referenceHwnd = hwnd;
if(!hwnd)
@@ -5369,10 +5462,12 @@ BOOL WINAPI GetMenuItemRect (HWND hwnd,
referenceHwnd = itemMenu->hWnd;
}
- if ((rect == NULL) || (item == NULL))
+ if ((rect == NULL) || (pos == ITEM_NOT_FOUND))
return FALSE;
+ MENU_GetMenuItem(hMenu, pos, &item);
*rect = item->rect;
+ MENU_ReleaseMenuItem(item);
MapWindowPoints(referenceHwnd, 0, (LPPOINT)rect, 2);
More information about the wine-patches
mailing list