[PATCH 09/11] user: even more menu item client changes
Thomas Kho
tkho at ucla.edu
Thu Jun 29 15:34:24 CDT 2006
user: even more menu item client changes
Thomas Kho
---
dlls/user/menu.c | 153 +++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 105 insertions(+), 48 deletions(-)
diff --git a/dlls/user/menu.c b/dlls/user/menu.c
index a0b70d1..7cfd934 100644
--- a/dlls/user/menu.c
+++ b/dlls/user/menu.c
@@ -2277,32 +2277,42 @@ static void MENU_MoveSelection( HWND hwn
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
LOCALPOPUPMENU *lpm;
+ MENUITEM *items;
TRACE("hwnd=%p hmenu=%p off=0x%04x\n", hwndOwner, hmenu, offset);
- if ((MENU_GetMenu(hmenu, menu)) || (!menu->items)) return;
+ if ((MENU_GetMenu(hmenu, menu))
+ || (MENU_GetAllMenuItems(hmenu, &items)) || (!items)) return;
lpm = MENU_GetLocalMenu(hmenu);
if ( lpm->FocusedItem != NO_SELECTED_ITEM )
{
- if( menu->nItems == 1 ) return; else
+ if( menu->nItems == 1 )
+ {
+ MENU_ReleaseMenuItem(items);
+ return;
+ }
+ else
for (i = lpm->FocusedItem + offset ; i >= 0 && i < menu->nItems
; i += offset)
- if (!(menu->items[i].fType & MF_SEPARATOR))
+ if (!(items[i].fType & MF_SEPARATOR))
{
MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 );
+ MENU_ReleaseMenuItem(items);
return;
}
}
for ( i = (offset > 0) ? 0 : menu->nItems - 1;
i >= 0 && i < menu->nItems ; i += offset)
- if (!(menu->items[i].fType & MF_SEPARATOR))
+ if (!(items[i].fType & MF_SEPARATOR))
{
MENU_SelectItem( hwndOwner, hmenu, i, TRUE, 0 );
+ MENU_ReleaseMenuItem(items);
return;
}
+ MENU_ReleaseMenuItem(items);
}
@@ -2312,9 +2322,12 @@ static void MENU_MoveSelection( HWND hwn
* Set an item's flags, id and text ptr. Called by InsertMenu() and
* ModifyMenu().
*/
-static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT_PTR id,
+static BOOL MENU_SetItemData( HMENU hmenu, UINT pos, UINT flags, UINT_PTR id,
LPCWSTR str )
{
+ MENUITEM *item;
+ if (MENU_GetMenuItem(hmenu, pos, &item))
+ return FALSE;
debug_print_menuitem("MENU_SetItemData from: ", item, "");
TRACE("flags=%x str=%p\n", flags, str);
@@ -2336,7 +2349,10 @@ static BOOL MENU_SetItemData( MENUITEM *
str++;
}
if (!(text = HeapAlloc( GetProcessHeap(), 0, (strlenW(str)+1) * sizeof(WCHAR) )))
+ {
+ MENU_ReleaseMenuItem(item);
return FALSE;
+ }
strcpyW( text, str );
item->text = text;
}
@@ -2373,6 +2389,8 @@ static BOOL MENU_SetItemData( MENUITEM *
item->hSubMenu = 0;
item->fType = 0;
item->fState = 0;
+ MENU_UpdateMenuItem(hmenu, pos, item);
+ MENU_ReleaseMenuItem(item);
return FALSE;
}
}
@@ -2390,6 +2408,8 @@ static BOOL MENU_SetItemData( MENUITEM *
/* Don't call SetRectEmpty here! */
debug_print_menuitem("MENU_SetItemData to : ", item, "");
+ MENU_UpdateMenuItem(hmenu, pos, item);
+ MENU_ReleaseMenuItem(item);
return TRUE;
}
@@ -3259,13 +3279,16 @@ static void MENU_KeyRight( MTRACKER* pmt
POPUPMENU tmpmenu, tmpcurmenu;
POPUPMENU *menu = &tmpmenu, *curmenu = &tmpcurmenu;
UINT nextcol;
+ MENUITEM *item;
MENU_GetMenu( pmt->hTopMenu, menu);
MENU_GetMenu(pmt->hCurrentMenu, curmenu);
+ MENU_GetMenuItem(pmt->hCurrentMenu, 0, &item);
TRACE("MENU_KeyRight called, cur %p (%s), top %p (%s).\n",
pmt->hCurrentMenu,
- debugstr_w(curmenu->items[0].text),
- pmt->hTopMenu, debugstr_w(menu->items[0].text) );
+ debugstr_w(item->text),
+ pmt->hTopMenu, debugstr_w(item->text) );
+ MENU_ReleaseMenuItem(item);
if ( (menu->wFlags & MF_POPUP) || (pmt->hCurrentMenu != pmt->hTopMenu))
{
@@ -3508,12 +3531,18 @@ static BOOL MENU_TrackMenu( HMENU hmenu,
case VK_F1:
{
HELPINFO hi;
+ UINT focuseditem = MENU_GetLocalMenu(hmenu)->FocusedItem;
hi.cbSize = sizeof(HELPINFO);
hi.iContextType = HELPINFO_MENUITEM;
- if (MENU_GetLocalMenu(hmenu)->FocusedItem == NO_SELECTED_ITEM)
+ if (focuseditem == NO_SELECTED_ITEM)
hi.iCtrlId = 0;
else
- hi.iCtrlId = menu->items[MENU_GetLocalMenu(hmenu)->FocusedItem].wID;
+ {
+ MENUITEM *item;
+ MENU_GetMenuItem(hmenu, focuseditem, &item);
+ hi.iCtrlId = item->wID;
+ MENU_ReleaseMenuItem(item);
+ }
hi.hItemHandle = hmenu;
hi.dwContextId = menu->dwContextHelpID;
hi.MousePos = msg.pt;
@@ -4092,27 +4121,36 @@ UINT WINAPI GetMenuState( HMENU hMenu, U
{
MENUITEM *item;
UINT pos;
- POPUPMENU menu;
TRACE("(menu=%p, id=%04x, flags=%04x);\n", hMenu, wItemID, wFlags);
if ((pos = MENU_FindItem( &hMenu, &wItemID, wFlags )) == ITEM_NOT_FOUND)
return -1;
- MENU_GetMenu(hMenu, &menu);
- item = &menu.items[pos];
+ MENU_GetMenuItem(hMenu, pos, &item);
debug_print_menuitem (" item: ", item, "");
if (item->fType & MF_POPUP)
{
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
- if (MENU_GetMenu( item->hSubMenu, menu )) return -1;
- else return (menu->nItems << 8) | ((item->fState|item->fType) & 0xff);
+ if (MENU_GetMenu( item->hSubMenu, menu ))
+ {
+ MENU_ReleaseMenuItem(item);
+ return -1;
+ }
+ else
+ {
+ UINT ret = (menu->nItems << 8) | ((item->fState|item->fType) & 0xff);
+ MENU_ReleaseMenuItem(item);
+ return ret;
+ }
}
else
{
/* We used to (from way back then) mask the result to 0xff. */
/* I don't know why and it seems wrong as the documented */
/* return flag MF_SEPARATOR is outside that mask. */
- return (item->fType | item->fState);
+ UINT ret = (item->fType | item->fState);
+ MENU_ReleaseMenuItem(item);
+ return ret;
}
}
@@ -4170,14 +4208,8 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UI
if ((i = MENU_InsertItem( hMenu, pos, flags )) == ITEM_NOT_FOUND)
return FALSE;
- else
- {
- POPUPMENU menu;
- MENU_GetMenu(hMenu, &menu);
- item = &menu.items[i];
- }
- if (!(MENU_SetItemData( item, flags, id, str )))
+ if (!(MENU_SetItemData( hMenu, i, flags, id, str )))
{
RemoveMenu( hMenu, pos, flags );
return FALSE;
@@ -4192,7 +4224,10 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UI
MENU_UpdateMenu((HMENU)id, menu, SET_MI_FLAGS);
}
+ MENU_GetMenuItem(hMenu, i, &item);
item->hCheckBit = item->hUnCheckBit = 0;
+ MENU_UpdateMenuItem(hMenu, i, item);
+ MENU_ReleaseMenuItem(item);
return TRUE;
}
@@ -4293,9 +4328,10 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UIN
if ((pos = MENU_FindItem( &hMenu, &nPos, wFlags )) == ITEM_NOT_FOUND)
return FALSE;
MENU_GetMenu(hMenu, &menu);
- item = &menu.items[pos];
+ MENU_GetMenuItem(hMenu, pos, &item);
if (item->fType & MF_POPUP) DestroyMenu( item->hSubMenu );
/* nPos is now the position of the item */
+ MENU_ReleaseMenuItem(item);
RemoveMenu( hMenu, nPos, wFlags | MF_BYPOSITION );
return TRUE;
}
@@ -4307,7 +4343,6 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UIN
BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
UINT_PTR id, LPCWSTR str )
{
- MENUITEM *item;
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
UINT i;
@@ -4320,10 +4355,9 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UI
if ((i = MENU_FindItem( &hMenu, &pos, flags )) == ITEM_NOT_FOUND)
return FALSE;
MENU_GetMenu(hMenu, menu);
- item = &menu->items[i];
menu->Height = 0; /* force size recalculate */
MENU_UpdateMenu(hMenu, menu, SET_MI_HEIGHT);
- return MENU_SetItemData( item, flags, id, str );
+ return MENU_SetItemData( hMenu, i, flags, id, str );
}
@@ -4386,14 +4420,12 @@ BOOL WINAPI SetMenuItemBitmaps( HMENU hM
HBITMAP hNewUnCheck, HBITMAP hNewCheck)
{
MENUITEM *item;
- POPUPMENU menu;
UINT pos;
TRACE("(%p, %04x, %04x, %p, %p)\n",
hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
if ((pos = MENU_FindItem( &hMenu, &nPos, wFlags )) == ITEM_NOT_FOUND)
return FALSE;
- MENU_GetMenu(hMenu, &menu);
- item = &menu.items[pos];
+ MENU_GetMenuItem(hMenu, pos, &item);
if (!hNewCheck && !hNewUnCheck)
{
@@ -4405,6 +4437,7 @@ BOOL WINAPI SetMenuItemBitmaps( HMENU hM
item->hUnCheckBit = hNewUnCheck;
item->fState |= MF_USECHECKBITMAPS;
}
+ MENU_ReleaseMenuItem(item);
return TRUE;
}
@@ -4918,7 +4951,10 @@ static BOOL GetMenuItemInfo_common ( HME
pos = MENU_FindItem (&hmenu, &item, bypos? MF_BYPOSITION : 0);
MENU_GetMenu(hmenu, &pm);
- menu = (pos == ITEM_NOT_FOUND) ? NULL : &pm.items[pos];
+ if (pos == ITEM_NOT_FOUND)
+ menu = NULL;
+ else
+ MENU_GetMenuItem(hmenu, pos, &menu);
debug_print_menuitem("GetMenuItemInfo_common: ", menu, "");
@@ -4928,6 +4964,7 @@ static BOOL GetMenuItemInfo_common ( HME
if( lpmii->fMask & MIIM_TYPE) {
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
WARN("invalid combination of fMask bits used\n");
+ MENU_ReleaseMenuItem(menu);
/* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
@@ -5013,6 +5050,7 @@ static BOOL GetMenuItemInfo_common ( HME
if (lpmii->fMask & MIIM_DATA)
lpmii->dwItemData = menu->dwItemData;
+ MENU_ReleaseMenuItem(menu);
return TRUE;
}
@@ -5088,12 +5126,10 @@ static BOOL SetMenuItemInfo_common(HMENU
const MENUITEMINFOW *lpmii,
BOOL unicode)
{
- POPUPMENU pm;
MENUITEM *menu;
if (pos == ITEM_NOT_FOUND) return FALSE;
- if (MENU_GetMenu(hmenu, &pm)) return FALSE;
- if (!pm.items) return FALSE;
- menu = &pm.items[pos];
+ if (MENU_GetMenuItem(hmenu, pos, &menu)) return FALSE;
+ if (!menu) return FALSE;
debug_print_menuitem("SetmenuItemInfo_common from: ", menu, "");
@@ -5102,7 +5138,7 @@ static BOOL SetMenuItemInfo_common(HMENU
WARN("invalid combination of fMask bits used\n");
/* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto returnfalse;
}
/* make only MENU_ITEM_TYPE bits in menu->fType equal lpmii->fType */
menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
@@ -5118,7 +5154,7 @@ static BOOL SetMenuItemInfo_common(HMENU
if (lpmii->fMask & MIIM_FTYPE ) {
if(( lpmii->fType & MFT_BITMAP)) {
SetLastError( ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto returnfalse;
}
menu->fType &= ~MENU_ITEM_TYPE(menu->fType);
menu->fType |= MENU_ITEM_TYPE(lpmii->fType);
@@ -5151,7 +5187,7 @@ static BOOL SetMenuItemInfo_common(HMENU
}
else {
SetLastError( ERROR_INVALID_PARAMETER);
- return FALSE;
+ goto returnfalse;
}
}
else
@@ -5176,7 +5212,14 @@ static BOOL SetMenuItemInfo_common(HMENU
menu->fType |= MFT_SEPARATOR;
debug_print_menuitem("SetMenuItemInfo_common to : ", menu, "");
+ MENU_UpdateMenuItem(hmenu, pos, menu);
+ MENU_ReleaseMenuItem(menu);
return TRUE;
+
+returnfalse:
+ MENU_UpdateMenuItem(hmenu, pos, menu);
+ MENU_ReleaseMenuItem(menu);
+ return FALSE;
}
/**********************************************************************
@@ -5233,30 +5276,39 @@ BOOL WINAPI SetMenuDefaultItem(HMENU hme
UINT i;
POPUPMENU tmpmenu;
POPUPMENU *menu = &tmpmenu;
- MENUITEM *item;
+ MENUITEM *item, *items;
TRACE("(%p,%d,%d)\n", hmenu, uItem, bypos);
if (MENU_GetMenu(hmenu, menu)) return FALSE;
/* reset all default-item flags */
- item = menu->items;
+ MENU_GetAllMenuItems(hmenu, &items);
+ item = items;
for (i = 0; i < menu->nItems; i++, item++)
{
item->fState &= ~MFS_DEFAULT;
+ MENU_UpdateMenuItem(hmenu, i, item);
}
/* no default item */
if ( -1 == uItem)
{
+ MENU_ReleaseMenuItem(items);
return TRUE;
}
- item = menu->items;
+ item = items;
if ( bypos )
{
- if ( uItem >= menu->nItems ) return FALSE;
+ if ( uItem >= menu->nItems )
+ {
+ MENU_ReleaseMenuItem(items);
+ return FALSE;
+ }
item[uItem].fState |= MFS_DEFAULT;
+ MENU_UpdateMenuItem(hmenu, uItem, &item[uItem]);
+ MENU_ReleaseMenuItem(items);
return TRUE;
}
else
@@ -5266,11 +5318,14 @@ BOOL WINAPI SetMenuDefaultItem(HMENU hme
if (item->wID == uItem)
{
item->fState |= MFS_DEFAULT;
+ MENU_UpdateMenuItem(hmenu, i, item);
+ MENU_ReleaseMenuItem(items);
return TRUE;
}
}
}
+ MENU_ReleaseMenuItem(items);
return FALSE;
}
@@ -5397,7 +5452,7 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMe
{
UINT posfirst, poslast, poscheck;
HMENU mfirst = hMenu, mlast = hMenu, mcheck = hMenu;
- POPUPMENU menu;
+ MENUITEM *items;
TRACE("%p: %d-%d, check %d, bypos=%d\n", hMenu, first, last, check, bypos);
@@ -5411,19 +5466,21 @@ BOOL WINAPI CheckMenuRadioItem(HMENU hMe
|| poscheck > poslast || poscheck < posfirst)
return FALSE;
- MENU_GetMenu(mfirst, &menu);
+ MENU_GetAllMenuItems(mfirst, &items);
while (posfirst <= poslast)
{
if (posfirst == poscheck)
{
- menu.items[posfirst].fType |= MFT_RADIOCHECK;
- menu.items[posfirst].fState |= MFS_CHECKED;
+ items[posfirst].fType |= MFT_RADIOCHECK;
+ items[posfirst].fState |= MFS_CHECKED;
} else {
- menu.items[posfirst].fType &= ~MFT_RADIOCHECK;
- menu.items[posfirst].fState &= ~MFS_CHECKED;
- }
+ items[posfirst].fType &= ~MFT_RADIOCHECK;
+ items[posfirst].fState &= ~MFS_CHECKED;
+ }
+ MENU_UpdateMenuItem(mfirst, posfirst, &items[posfirst]);
posfirst++;
}
+ MENU_ReleaseMenuItem(items);
return TRUE;
}
More information about the wine-patches
mailing list