win32u: Move menu item info management from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
75c297f2b8
commit
77ab51019f
|
@ -120,7 +120,6 @@ extern void MENU_TrackMouseMenuBar( HWND hwnd, INT ht, POINT pt ) DECLSPEC_HIDDE
|
|||
extern void MENU_TrackKbdMenuBar( HWND hwnd, UINT wParam, WCHAR wChar ) DECLSPEC_HIDDEN;
|
||||
extern UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern void MENU_EndMenu(HWND) DECLSPEC_HIDDEN;
|
||||
extern void free_menu_items( void *ptr ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* nonclient area */
|
||||
extern LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -417,7 +417,7 @@ static LRESULT MDI_RefreshMenu(MDICLIENTINFO *ci)
|
|||
if (mii.wID == ci->idFirstChild)
|
||||
{
|
||||
TRACE("removing %u items including separator\n", count - i);
|
||||
while (RemoveMenu(ci->hWindowMenu, i, MF_BYPOSITION))
|
||||
while (NtUserRemoveMenu( ci->hWindowMenu, i, MF_BYPOSITION ))
|
||||
/* nothing */;
|
||||
|
||||
break;
|
||||
|
@ -935,7 +935,7 @@ static BOOL MDI_RestoreFrameMenu( HWND frame, HWND hChild )
|
|||
TRUE,
|
||||
&menuInfo);
|
||||
|
||||
RemoveMenu(menu,0,MF_BYPOSITION);
|
||||
NtUserRemoveMenu( menu, 0, MF_BYPOSITION );
|
||||
|
||||
if ( (menuInfo.fType & MFT_BITMAP) &&
|
||||
(LOWORD(menuInfo.dwTypeData)!=0) &&
|
||||
|
|
|
@ -88,11 +88,6 @@ typedef struct
|
|||
/* Margins for popup menus */
|
||||
#define MENU_MARGIN 3
|
||||
|
||||
/* maximum allowed depth of any branch in the menu tree.
|
||||
* This value is slightly larger than in windows (25) to
|
||||
* stay on the safe side. */
|
||||
#define MAXMENUDEPTH 30
|
||||
|
||||
/* (other menu->FocusedItem values give the position of the focused item) */
|
||||
#define NO_SELECTED_ITEM 0xffff
|
||||
|
||||
|
@ -127,8 +122,6 @@ static BOOL fEndMenu = FALSE;
|
|||
|
||||
DWORD WINAPI DrawMenuBarTemp(HWND hwnd, HDC hDC, LPRECT lprect, HMENU hMenu, HFONT hFont);
|
||||
|
||||
static BOOL SetMenuItemInfo_common( MENUITEM *, const MENUITEMINFOW * );
|
||||
|
||||
static BOOL is_win_menu_disallowed(HWND hwnd)
|
||||
{
|
||||
return (GetWindowLongW(hwnd, GWL_STYLE) & (WS_CHILD | WS_POPUP)) == WS_CHILD;
|
||||
|
@ -623,15 +616,6 @@ static UINT MENU_FindSubMenu( HMENU *hmenu, HMENU hSubTarget )
|
|||
return NO_SELECTED_ITEM;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MENU_FreeItemData
|
||||
*/
|
||||
static void MENU_FreeItemData( MENUITEM* item )
|
||||
{
|
||||
/* delete text */
|
||||
HeapFree( GetProcessHeap(), 0, item->text );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MENU_AdjustMenuItemRect
|
||||
*
|
||||
|
@ -2078,62 +2062,6 @@ static void MENU_MoveSelection( HWND hwndOwner, HMENU hmenu, INT offset )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* insert_menu_item
|
||||
*
|
||||
* Insert (allocate) a new item into a menu.
|
||||
*/
|
||||
static POPUPMENU *insert_menu_item(HMENU hMenu, UINT id, UINT flags, UINT *ret_pos)
|
||||
{
|
||||
MENUITEM *newItems;
|
||||
POPUPMENU *menu;
|
||||
UINT pos = id;
|
||||
|
||||
/* Find where to insert new item */
|
||||
if (!(menu = find_menu_item(hMenu, id, flags, &pos)))
|
||||
{
|
||||
if (!(menu = grab_menu_ptr(hMenu)))
|
||||
return NULL;
|
||||
pos = menu->nItems;
|
||||
}
|
||||
|
||||
/* Make sure that MDI system buttons stay on the right side.
|
||||
* Note: XP treats only bitmap handles 1 - 6 as "magic" ones
|
||||
* regardless of their id.
|
||||
*/
|
||||
while (pos > 0 && (INT_PTR)menu->items[pos - 1].hbmpItem >= (INT_PTR)HBMMENU_SYSTEM &&
|
||||
(INT_PTR)menu->items[pos - 1].hbmpItem <= (INT_PTR)HBMMENU_MBAR_CLOSE_D)
|
||||
pos--;
|
||||
|
||||
TRACE("inserting at %u flags %x\n", pos, flags);
|
||||
|
||||
/* Create new items array */
|
||||
|
||||
newItems = HeapAlloc( GetProcessHeap(), 0, sizeof(MENUITEM) * (menu->nItems+1) );
|
||||
if (!newItems)
|
||||
{
|
||||
release_menu_ptr(menu);
|
||||
WARN("allocation failed\n" );
|
||||
return NULL;
|
||||
}
|
||||
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 );
|
||||
}
|
||||
menu->items = newItems;
|
||||
menu->nItems++;
|
||||
memset( &newItems[pos], 0, sizeof(*newItems) );
|
||||
menu->Height = 0; /* force size recalculate */
|
||||
|
||||
*ret_pos = pos;
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MENU_ParseResource
|
||||
*
|
||||
|
@ -3616,9 +3544,9 @@ BOOL WINAPI ChangeMenuA( HMENU hMenu, UINT pos, LPCSTR data,
|
|||
if (flags & MF_DELETE) return DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
|
||||
if (flags & MF_CHANGE) return ModifyMenuA(hMenu, pos, flags & ~MF_CHANGE,
|
||||
id, data );
|
||||
if (flags & MF_REMOVE) return RemoveMenu( hMenu,
|
||||
flags & MF_BYPOSITION ? pos : id,
|
||||
flags & ~MF_REMOVE );
|
||||
if (flags & MF_REMOVE) return NtUserRemoveMenu( hMenu,
|
||||
flags & MF_BYPOSITION ? pos : id,
|
||||
flags & ~MF_REMOVE );
|
||||
/* Default: MF_INSERT */
|
||||
return InsertMenuA( hMenu, pos, flags, id, data );
|
||||
}
|
||||
|
@ -3636,9 +3564,9 @@ BOOL WINAPI ChangeMenuW( HMENU hMenu, UINT pos, LPCWSTR data,
|
|||
if (flags & MF_DELETE) return DeleteMenu(hMenu, pos, flags & ~MF_DELETE);
|
||||
if (flags & MF_CHANGE) return ModifyMenuW(hMenu, pos, flags & ~MF_CHANGE,
|
||||
id, data );
|
||||
if (flags & MF_REMOVE) return RemoveMenu( hMenu,
|
||||
flags & MF_BYPOSITION ? pos : id,
|
||||
flags & ~MF_REMOVE );
|
||||
if (flags & MF_REMOVE) return NtUserRemoveMenu( hMenu,
|
||||
flags & MF_BYPOSITION ? pos : id,
|
||||
flags & ~MF_REMOVE );
|
||||
/* Default: MF_INSERT */
|
||||
return InsertMenuW( hMenu, pos, flags, id, data );
|
||||
}
|
||||
|
@ -3877,10 +3805,6 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UINT pos, UINT flags,
|
|||
UINT_PTR id, LPCWSTR str )
|
||||
{
|
||||
MENUITEMINFOW mii;
|
||||
POPUPMENU *menu;
|
||||
MENUITEM *item;
|
||||
UINT newpos;
|
||||
BOOL ret;
|
||||
|
||||
if (IS_STRING_ITEM(flags) && str)
|
||||
TRACE("hMenu %p, pos %d, flags %08x, id %04lx, str %s\n",
|
||||
|
@ -3888,19 +3812,9 @@ BOOL WINAPI InsertMenuW( HMENU hMenu, UINT pos, UINT flags,
|
|||
else TRACE("hMenu %p, pos %d, flags %08x, id %04lx, str %p (not a string)\n",
|
||||
hMenu, pos, flags, id, str );
|
||||
|
||||
if (!(menu = insert_menu_item(hMenu, pos, flags, &newpos)))
|
||||
return FALSE;
|
||||
|
||||
MENU_mnu2mnuii( flags, id, str, &mii);
|
||||
mii.fMask |= MIIM_CHECKMARKS;
|
||||
|
||||
item = &menu->items[newpos];
|
||||
ret = SetMenuItemInfo_common( item, &mii );
|
||||
if (!ret)
|
||||
RemoveMenu( hMenu, pos, flags );
|
||||
release_menu_ptr(menu);
|
||||
|
||||
return ret;
|
||||
return NtUserThunkedMenuItemInfo( hMenu, pos, flags, NtUserInsertMenuItem, &mii, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
@ -3948,46 +3862,6 @@ BOOL WINAPI AppendMenuW( HMENU hMenu, UINT flags,
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* RemoveMenu (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI RemoveMenu( HMENU hMenu, UINT id, UINT flags )
|
||||
{
|
||||
POPUPMENU *menu;
|
||||
UINT pos;
|
||||
|
||||
TRACE("(menu=%p id=%#x flags=%04x)\n", hMenu, id, flags);
|
||||
|
||||
if (!(menu = find_menu_item(hMenu, id, flags, &pos)))
|
||||
return FALSE;
|
||||
|
||||
/* Remove item */
|
||||
MENU_FreeItemData( &menu->items[pos] );
|
||||
|
||||
if (--menu->nItems == 0)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, menu->items );
|
||||
menu->items = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MENUITEM *new_items, *item = &menu->items[pos];
|
||||
|
||||
while (pos < menu->nItems)
|
||||
{
|
||||
*item = *(item+1);
|
||||
item++;
|
||||
pos++;
|
||||
}
|
||||
new_items = HeapReAlloc( GetProcessHeap(), 0, menu->items, menu->nItems * sizeof(MENUITEM) );
|
||||
if (new_items) menu->items = new_items;
|
||||
}
|
||||
release_menu_ptr(menu);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* DeleteMenu (USER32.@)
|
||||
*/
|
||||
|
@ -4002,7 +3876,7 @@ BOOL WINAPI DeleteMenu( HMENU hMenu, UINT id, UINT flags )
|
|||
if (menu->items[pos].fType & MF_POPUP)
|
||||
NtUserDestroyMenu( menu->items[pos].hSubMenu );
|
||||
|
||||
RemoveMenu(menu->obj.handle, pos, flags | MF_BYPOSITION);
|
||||
NtUserRemoveMenu( menu->obj.handle, pos, flags | MF_BYPOSITION );
|
||||
release_menu_ptr(menu);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -4015,26 +3889,14 @@ BOOL WINAPI ModifyMenuW( HMENU hMenu, UINT pos, UINT flags,
|
|||
UINT_PTR id, LPCWSTR str )
|
||||
{
|
||||
MENUITEMINFOW mii;
|
||||
POPUPMENU *menu;
|
||||
UINT item_pos;
|
||||
BOOL ret;
|
||||
|
||||
if (IS_STRING_ITEM(flags))
|
||||
TRACE("%p %d %04x %04lx %s\n", hMenu, pos, flags, id, debugstr_w(str) );
|
||||
else
|
||||
TRACE("%p %d %04x %04lx %p\n", hMenu, pos, flags, id, str );
|
||||
|
||||
if (!(menu = find_menu_item(hMenu, pos, flags, &item_pos)))
|
||||
{
|
||||
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
|
||||
if (pos == SC_TASKLIST && !(flags & MF_BYPOSITION)) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
menu->Height = 0; /* force size recalculate */
|
||||
MENU_mnu2mnuii( flags, id, str, &mii);
|
||||
ret = SetMenuItemInfo_common( &menu->items[item_pos], &mii );
|
||||
release_menu_ptr(menu);
|
||||
return ret;
|
||||
return NtUserThunkedMenuItemInfo( hMenu, pos, flags, NtUserSetMenuItemInfo, &mii, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
@ -4120,21 +3982,6 @@ HMENU WINAPI CreateMenu(void)
|
|||
}
|
||||
|
||||
|
||||
void free_menu_items( void *ptr )
|
||||
{
|
||||
POPUPMENU *menu = ptr;
|
||||
MENUITEM *item = menu->items;
|
||||
int i;
|
||||
|
||||
for (i = menu->nItems; i > 0; i--, item++)
|
||||
{
|
||||
if (item->fType & MF_POPUP) NtUserDestroyMenu( item->hSubMenu );
|
||||
MENU_FreeItemData( item );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, menu->items );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* GetSystemMenu (USER32.@)
|
||||
*/
|
||||
|
@ -4654,108 +4501,6 @@ BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos,
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* MENU_depth
|
||||
*
|
||||
* detect if there are loops in the menu tree (or the depth is too large)
|
||||
*/
|
||||
static int MENU_depth( POPUPMENU *pmenu, int depth)
|
||||
{
|
||||
UINT i;
|
||||
MENUITEM *item;
|
||||
int subdepth;
|
||||
|
||||
depth++;
|
||||
if( depth > MAXMENUDEPTH) return depth;
|
||||
item = pmenu->items;
|
||||
subdepth = depth;
|
||||
for( i = 0; i < pmenu->nItems && subdepth <= MAXMENUDEPTH; i++, item++){
|
||||
POPUPMENU *psubmenu = item->hSubMenu ? MENU_GetMenu( item->hSubMenu) : NULL;
|
||||
if( psubmenu){
|
||||
int bdepth = MENU_depth( psubmenu, depth);
|
||||
if( bdepth > subdepth) subdepth = bdepth;
|
||||
}
|
||||
if( subdepth > MAXMENUDEPTH)
|
||||
TRACE("<- hmenu %p\n", item->hSubMenu);
|
||||
}
|
||||
return subdepth;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SetMenuItemInfo_common
|
||||
*
|
||||
* Note: does not support the MIIM_TYPE flag. Use the MIIM_FTYPE,
|
||||
* MIIM_BITMAP and MIIM_STRING flags instead.
|
||||
*/
|
||||
|
||||
static BOOL SetMenuItemInfo_common( MENUITEM *menu, const MENUITEMINFOW *lpmii )
|
||||
{
|
||||
if (!menu) return FALSE;
|
||||
|
||||
debug_print_menuitem("SetMenuItemInfo_common from: ", menu, "");
|
||||
|
||||
if (lpmii->fMask & MIIM_FTYPE ) {
|
||||
menu->fType &= ~MENUITEMINFO_TYPE_MASK;
|
||||
menu->fType |= lpmii->fType & MENUITEMINFO_TYPE_MASK;
|
||||
}
|
||||
if (lpmii->fMask & MIIM_STRING ) {
|
||||
const WCHAR *text = lpmii->dwTypeData;
|
||||
/* free the string when used */
|
||||
HeapFree(GetProcessHeap(), 0, menu->text);
|
||||
if (!text)
|
||||
menu->text = NULL;
|
||||
else if ((menu->text = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(text)+1) * sizeof(WCHAR) )))
|
||||
lstrcpyW( menu->text, text );
|
||||
}
|
||||
|
||||
if (lpmii->fMask & MIIM_STATE)
|
||||
/* Other menu items having MFS_DEFAULT are not converted
|
||||
to normal items */
|
||||
menu->fState = lpmii->fState & MENUITEMINFO_STATE_MASK;
|
||||
|
||||
if (lpmii->fMask & MIIM_ID)
|
||||
menu->wID = lpmii->wID;
|
||||
|
||||
if (lpmii->fMask & MIIM_SUBMENU) {
|
||||
menu->hSubMenu = lpmii->hSubMenu;
|
||||
if (menu->hSubMenu) {
|
||||
POPUPMENU *subMenu = MENU_GetMenu(menu->hSubMenu);
|
||||
if (subMenu) {
|
||||
if( MENU_depth( subMenu, 0) > MAXMENUDEPTH) {
|
||||
ERR( "Loop detected in menu hierarchy or maximum menu depth exceeded!\n");
|
||||
menu->hSubMenu = 0;
|
||||
return FALSE;
|
||||
}
|
||||
subMenu->wFlags |= MF_POPUP;
|
||||
menu->fType |= MF_POPUP;
|
||||
} else {
|
||||
SetLastError( ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
menu->fType &= ~MF_POPUP;
|
||||
}
|
||||
|
||||
if (lpmii->fMask & MIIM_CHECKMARKS)
|
||||
{
|
||||
menu->hCheckBit = lpmii->hbmpChecked;
|
||||
menu->hUnCheckBit = lpmii->hbmpUnchecked;
|
||||
}
|
||||
if (lpmii->fMask & MIIM_DATA)
|
||||
menu->dwItemData = lpmii->dwItemData;
|
||||
|
||||
if (lpmii->fMask & MIIM_BITMAP)
|
||||
menu->hbmpItem = lpmii->hbmpItem;
|
||||
|
||||
if( !menu->text && !(menu->fType & MFT_OWNERDRAW) && !menu->hbmpItem)
|
||||
menu->fType |= MFT_SEPARATOR;
|
||||
|
||||
debug_print_menuitem("SetMenuItemInfo_common to : ", menu, "");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* MENU_NormalizeMenuItemInfoStruct
|
||||
*
|
||||
|
@ -4808,8 +4553,6 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
|
|||
{
|
||||
WCHAR *strW = NULL;
|
||||
MENUITEMINFOW mii;
|
||||
POPUPMENU *menu;
|
||||
UINT pos;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
|
||||
|
@ -4825,15 +4568,9 @@ BOOL WINAPI SetMenuItemInfoA(HMENU hmenu, UINT item, BOOL bypos,
|
|||
mii.dwTypeData = strW;
|
||||
}
|
||||
|
||||
if (!(menu = find_menu_item(hmenu, item, bypos ? MF_BYPOSITION : 0, &pos)))
|
||||
{
|
||||
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
|
||||
HeapFree( GetProcessHeap(), 0, strW );
|
||||
if (item == SC_TASKLIST && !bypos) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
ret = SetMenuItemInfo_common( &menu->items[pos], &mii );
|
||||
release_menu_ptr(menu);
|
||||
ret = NtUserThunkedMenuItemInfo( hmenu, item, bypos ? MF_BYPOSITION : 0,
|
||||
NtUserSetMenuItemInfo, &mii, NULL );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, strW );
|
||||
return ret;
|
||||
}
|
||||
|
@ -4845,24 +4582,13 @@ BOOL WINAPI SetMenuItemInfoW(HMENU hmenu, UINT item, BOOL bypos,
|
|||
const MENUITEMINFOW *lpmii)
|
||||
{
|
||||
MENUITEMINFOW mii;
|
||||
POPUPMENU *menu;
|
||||
BOOL ret;
|
||||
UINT pos;
|
||||
|
||||
TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii);
|
||||
|
||||
if (!MENU_NormalizeMenuItemInfoStruct( lpmii, &mii )) return FALSE;
|
||||
|
||||
if (!(menu = find_menu_item(hmenu, item, bypos ? MF_BYPOSITION : 0, &pos)))
|
||||
{
|
||||
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
|
||||
if (item == SC_TASKLIST && !bypos) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = SetMenuItemInfo_common(&menu->items[pos], &mii);
|
||||
release_menu_ptr(menu);
|
||||
return ret;
|
||||
return NtUserThunkedMenuItemInfo( hmenu, item, bypos ? MF_BYPOSITION : 0,
|
||||
NtUserSetMenuItemInfo, &mii, NULL );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -4915,8 +4641,6 @@ BOOL WINAPI InsertMenuItemA(HMENU hMenu, UINT uItem, BOOL bypos,
|
|||
{
|
||||
WCHAR *strW = NULL;
|
||||
MENUITEMINFOW mii;
|
||||
POPUPMENU *menu;
|
||||
UINT pos;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("hmenu %p, item %04x, by pos %d, info %p\n", hMenu, uItem, bypos, lpmii);
|
||||
|
@ -4932,14 +4656,9 @@ BOOL WINAPI InsertMenuItemA(HMENU hMenu, UINT uItem, BOOL bypos,
|
|||
mii.dwTypeData = strW;
|
||||
}
|
||||
|
||||
if (!(menu = insert_menu_item(hMenu, uItem, bypos ? MF_BYPOSITION : 0, &pos)))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, strW );
|
||||
return FALSE;
|
||||
}
|
||||
ret = NtUserThunkedMenuItemInfo( hMenu, uItem, bypos ? MF_BYPOSITION : 0,
|
||||
NtUserInsertMenuItem, &mii, NULL );
|
||||
|
||||
ret = SetMenuItemInfo_common( &menu->items[pos], &mii );
|
||||
release_menu_ptr(menu);
|
||||
HeapFree( GetProcessHeap(), 0, strW );
|
||||
return ret;
|
||||
}
|
||||
|
@ -4952,20 +4671,13 @@ BOOL WINAPI InsertMenuItemW(HMENU hMenu, UINT uItem, BOOL bypos,
|
|||
const MENUITEMINFOW *lpmii)
|
||||
{
|
||||
MENUITEMINFOW mii;
|
||||
POPUPMENU *menu;
|
||||
UINT pos;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("hmenu %p, item %04x, by pos %d, info %p\n", hMenu, uItem, bypos, lpmii);
|
||||
|
||||
if (!MENU_NormalizeMenuItemInfoStruct( lpmii, &mii )) return FALSE;
|
||||
|
||||
if (!(menu = insert_menu_item(hMenu, uItem, bypos ? MF_BYPOSITION : 0, &pos)))
|
||||
return FALSE;
|
||||
|
||||
ret = SetMenuItemInfo_common( &menu->items[pos], &mii );
|
||||
release_menu_ptr(menu);
|
||||
return ret;
|
||||
return NtUserThunkedMenuItemInfo( hMenu, uItem, bypos ? MF_BYPOSITION : 0,
|
||||
NtUserInsertMenuItem, &mii, NULL );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
|
@ -619,7 +619,7 @@
|
|||
@ stdcall ReleaseCapture()
|
||||
@ stdcall ReleaseDC(long long) NtUserReleaseDC
|
||||
@ stdcall RemoveClipboardFormatListener(long) NtUserRemoveClipboardFormatListener
|
||||
@ stdcall RemoveMenu(long long long)
|
||||
@ stdcall RemoveMenu(long long long) NtUserRemoveMenu
|
||||
@ stdcall RemovePropA(long str)
|
||||
@ stdcall RemovePropW(long wstr)
|
||||
@ stdcall ReplyMessage(long)
|
||||
|
|
|
@ -165,7 +165,6 @@ static const struct user_callbacks user_funcs =
|
|||
ImmProcessKey,
|
||||
ImmTranslateMessage,
|
||||
SetSystemMenu,
|
||||
free_menu_items,
|
||||
free_win_ptr,
|
||||
MENU_IsMenuActive,
|
||||
notify_ime,
|
||||
|
|
|
@ -39,9 +39,26 @@ struct accelerator
|
|||
ACCEL table[1];
|
||||
};
|
||||
|
||||
/* maximum allowed depth of any branch in the menu tree.
|
||||
* This value is slightly larger than in windows (25) to
|
||||
* stay on the safe side. */
|
||||
#define MAXMENUDEPTH 30
|
||||
|
||||
/* (other menu->FocusedItem values give the position of the focused item) */
|
||||
#define NO_SELECTED_ITEM 0xffff
|
||||
|
||||
/* macro to test that flags do not indicate bitmap, ownerdraw or separator */
|
||||
#define IS_STRING_ITEM(flags) (MENU_ITEM_TYPE ((flags)) == MF_STRING)
|
||||
#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
|
||||
|
||||
#define MENUITEMINFO_TYPE_MASK \
|
||||
(MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \
|
||||
MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \
|
||||
MFT_RIGHTORDER | MFT_RIGHTJUSTIFY /* same as MF_HELP */ )
|
||||
#define TYPE_MASK (MENUITEMINFO_TYPE_MASK | MF_POPUP | MF_SYSMENU)
|
||||
#define STATE_MASK (~TYPE_MASK)
|
||||
#define MENUITEMINFO_STATE_MASK (STATE_MASK & ~(MF_BYPOSITION | MF_MOUSESELECT))
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserCopyAcceleratorTable (win32u.@)
|
||||
*/
|
||||
|
@ -111,6 +128,73 @@ BOOL WINAPI NtUserDestroyAcceleratorTable( HACCEL handle )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#define MENUFLAG(bit,text) \
|
||||
do { \
|
||||
if (flags & (bit)) { flags &= ~(bit); strcat(buf, (text)); } \
|
||||
} while (0)
|
||||
|
||||
static const char *debugstr_menuitem( const MENUITEM *item )
|
||||
{
|
||||
static const char *const hbmmenus[] = { "HBMMENU_CALLBACK", "", "HBMMENU_SYSTEM",
|
||||
"HBMMENU_MBAR_RESTORE", "HBMMENU_MBAR_MINIMIZE", "UNKNOWN BITMAP", "HBMMENU_MBAR_CLOSE",
|
||||
"HBMMENU_MBAR_CLOSE_D", "HBMMENU_MBAR_MINIMIZE_D", "HBMMENU_POPUP_CLOSE",
|
||||
"HBMMENU_POPUP_RESTORE", "HBMMENU_POPUP_MAXIMIZE", "HBMMENU_POPUP_MINIMIZE" };
|
||||
char buf[256];
|
||||
UINT flags;
|
||||
|
||||
if (!item) return "NULL";
|
||||
|
||||
sprintf( buf, "{ ID=0x%lx", item->wID );
|
||||
if (item->hSubMenu) sprintf( buf + strlen(buf), ", Sub=%p", item->hSubMenu );
|
||||
|
||||
flags = item->fType;
|
||||
if (flags)
|
||||
{
|
||||
strcat( buf, ", fType=" );
|
||||
MENUFLAG( MFT_SEPARATOR, "sep" );
|
||||
MENUFLAG( MFT_OWNERDRAW, "own" );
|
||||
MENUFLAG( MFT_BITMAP, "bit" );
|
||||
MENUFLAG( MF_POPUP, "pop" );
|
||||
MENUFLAG( MFT_MENUBARBREAK, "barbrk" );
|
||||
MENUFLAG( MFT_MENUBREAK, "brk");
|
||||
MENUFLAG( MFT_RADIOCHECK, "radio" );
|
||||
MENUFLAG( MFT_RIGHTORDER, "rorder" );
|
||||
MENUFLAG( MF_SYSMENU, "sys" );
|
||||
MENUFLAG( MFT_RIGHTJUSTIFY, "right" ); /* same as MF_HELP */
|
||||
if (flags) sprintf( buf + strlen(buf), "+0x%x", flags );
|
||||
}
|
||||
|
||||
flags = item->fState;
|
||||
if (flags)
|
||||
{
|
||||
strcat( buf, ", State=" );
|
||||
MENUFLAG( MFS_GRAYED, "grey" );
|
||||
MENUFLAG( MFS_DEFAULT, "default" );
|
||||
MENUFLAG( MFS_DISABLED, "dis" );
|
||||
MENUFLAG( MFS_CHECKED, "check" );
|
||||
MENUFLAG( MFS_HILITE, "hi" );
|
||||
MENUFLAG( MF_USECHECKBITMAPS, "usebit" );
|
||||
MENUFLAG( MF_MOUSESELECT, "mouse" );
|
||||
if (flags) sprintf( buf + strlen(buf), "+0x%x", flags );
|
||||
}
|
||||
|
||||
if (item->hCheckBit) sprintf( buf + strlen(buf), ", Chk=%p", item->hCheckBit );
|
||||
if (item->hUnCheckBit) sprintf( buf + strlen(buf), ", Unc=%p", item->hUnCheckBit );
|
||||
if (item->text) sprintf( buf + strlen(buf), ", Text=%s", debugstr_w(item->text) );
|
||||
if (item->dwItemData) sprintf( buf + strlen(buf), ", ItemData=0x%08lx", item->dwItemData );
|
||||
|
||||
if (item->hbmpItem)
|
||||
{
|
||||
if (IS_MAGIC_BITMAP( item->hbmpItem ))
|
||||
sprintf( buf + strlen(buf), ", hbitmap=%s", hbmmenus[(INT_PTR)item->hbmpItem + 1] );
|
||||
else
|
||||
sprintf( buf + strlen(buf), ", hbitmap=%p", item->hbmpItem );
|
||||
}
|
||||
return wine_dbg_sprintf( "%s }", buf );
|
||||
}
|
||||
|
||||
#undef MENUFLAG
|
||||
|
||||
static POPUPMENU *grab_menu_ptr( HMENU handle )
|
||||
{
|
||||
POPUPMENU *menu = get_user_handle_ptr( handle, NTUSER_OBJ_MENU );
|
||||
|
@ -210,6 +294,53 @@ static POPUPMENU *find_menu_item( HMENU handle, UINT id, UINT flags, UINT *pos )
|
|||
return menu;
|
||||
}
|
||||
|
||||
static POPUPMENU *insert_menu_item( HMENU handle, UINT id, UINT flags, UINT *ret_pos )
|
||||
{
|
||||
MENUITEM *new_items;
|
||||
POPUPMENU *menu;
|
||||
UINT pos = id;
|
||||
|
||||
/* Find where to insert new item */
|
||||
if (!(menu = find_menu_item(handle, id, flags, &pos)))
|
||||
{
|
||||
if (!(menu = grab_menu_ptr(handle)))
|
||||
return NULL;
|
||||
pos = menu->nItems;
|
||||
}
|
||||
|
||||
/* Make sure that MDI system buttons stay on the right side.
|
||||
* Note: XP treats only bitmap handles 1 - 6 as "magic" ones
|
||||
* regardless of their id.
|
||||
*/
|
||||
while (pos > 0 && (INT_PTR)menu->items[pos - 1].hbmpItem >= (INT_PTR)HBMMENU_SYSTEM &&
|
||||
(INT_PTR)menu->items[pos - 1].hbmpItem <= (INT_PTR)HBMMENU_MBAR_CLOSE_D)
|
||||
pos--;
|
||||
|
||||
TRACE( "inserting at %u flags %x\n", pos, flags );
|
||||
|
||||
new_items = malloc( sizeof(MENUITEM) * (menu->nItems + 1) );
|
||||
if (!new_items)
|
||||
{
|
||||
release_menu_ptr( menu );
|
||||
return NULL;
|
||||
}
|
||||
if (menu->nItems > 0)
|
||||
{
|
||||
/* Copy the old array into the new one */
|
||||
if (pos > 0) memcpy( new_items, menu->items, pos * sizeof(MENUITEM) );
|
||||
if (pos < menu->nItems) memcpy( &new_items[pos + 1], &menu->items[pos],
|
||||
(menu->nItems - pos) * sizeof(MENUITEM) );
|
||||
free( menu->items );
|
||||
}
|
||||
menu->items = new_items;
|
||||
menu->nItems++;
|
||||
memset( &new_items[pos], 0, sizeof(*new_items) );
|
||||
menu->Height = 0; /* force size recalculate */
|
||||
|
||||
*ret_pos = pos;
|
||||
return menu;
|
||||
}
|
||||
|
||||
static BOOL is_win_menu_disallowed( HWND hwnd )
|
||||
{
|
||||
return (get_window_long(hwnd, GWL_STYLE) & (WS_CHILD | WS_POPUP)) == WS_CHILD;
|
||||
|
@ -257,8 +388,19 @@ BOOL WINAPI NtUserDestroyMenu( HMENU handle )
|
|||
menu->hWnd = 0;
|
||||
}
|
||||
|
||||
if (menu->items && user_callbacks) /* recursively destroy submenus */
|
||||
user_callbacks->free_menu_items( menu );
|
||||
/* recursively destroy submenus */
|
||||
if (menu->items)
|
||||
{
|
||||
MENUITEM *item = menu->items;
|
||||
int i;
|
||||
|
||||
for (i = menu->nItems; i > 0; i--, item++)
|
||||
{
|
||||
if (item->fType & MF_POPUP) NtUserDestroyMenu( item->hSubMenu );
|
||||
free( item->text );
|
||||
}
|
||||
free( menu->items );
|
||||
}
|
||||
|
||||
free( menu );
|
||||
return TRUE;
|
||||
|
@ -527,6 +669,206 @@ BOOL get_menu_info( HMENU handle, MENUINFO *info )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* menu_depth
|
||||
*
|
||||
* detect if there are loops in the menu tree (or the depth is too large)
|
||||
*/
|
||||
static int menu_depth( POPUPMENU *pmenu, int depth)
|
||||
{
|
||||
int i, subdepth;
|
||||
MENUITEM *item;
|
||||
|
||||
if (++depth > MAXMENUDEPTH) return depth;
|
||||
item = pmenu->items;
|
||||
subdepth = depth;
|
||||
for (i = 0; i < pmenu->nItems && subdepth <= MAXMENUDEPTH; i++, item++)
|
||||
{
|
||||
POPUPMENU *submenu = item->hSubMenu ? grab_menu_ptr( item->hSubMenu ) : NULL;
|
||||
if (submenu)
|
||||
{
|
||||
int bdepth = menu_depth( submenu, depth);
|
||||
if (bdepth > subdepth) subdepth = bdepth;
|
||||
release_menu_ptr( submenu );
|
||||
}
|
||||
if (subdepth > MAXMENUDEPTH)
|
||||
TRACE( "<- hmenu %p\n", item->hSubMenu );
|
||||
}
|
||||
|
||||
return subdepth;
|
||||
}
|
||||
|
||||
static BOOL set_menu_item_info( MENUITEM *menu, const MENUITEMINFOW *info )
|
||||
{
|
||||
if (!menu) return FALSE;
|
||||
|
||||
TRACE( "%s\n", debugstr_menuitem( menu ));
|
||||
|
||||
if (info->fMask & MIIM_FTYPE )
|
||||
{
|
||||
menu->fType &= ~MENUITEMINFO_TYPE_MASK;
|
||||
menu->fType |= info->fType & MENUITEMINFO_TYPE_MASK;
|
||||
}
|
||||
if (info->fMask & MIIM_STRING )
|
||||
{
|
||||
const WCHAR *text = info->dwTypeData;
|
||||
/* free the string when used */
|
||||
free( menu->text );
|
||||
if (!text)
|
||||
menu->text = NULL;
|
||||
else if ((menu->text = malloc( (lstrlenW(text) + 1) * sizeof(WCHAR) )))
|
||||
lstrcpyW( menu->text, text );
|
||||
}
|
||||
|
||||
if (info->fMask & MIIM_STATE)
|
||||
/* Other menu items having MFS_DEFAULT are not converted
|
||||
to normal items */
|
||||
menu->fState = info->fState & MENUITEMINFO_STATE_MASK;
|
||||
|
||||
if (info->fMask & MIIM_ID)
|
||||
menu->wID = info->wID;
|
||||
|
||||
if (info->fMask & MIIM_SUBMENU)
|
||||
{
|
||||
menu->hSubMenu = info->hSubMenu;
|
||||
if (menu->hSubMenu)
|
||||
{
|
||||
POPUPMENU *submenu = grab_menu_ptr( menu->hSubMenu );
|
||||
if (!submenu)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (menu_depth( submenu, 0 ) > MAXMENUDEPTH)
|
||||
{
|
||||
ERR( "Loop detected in menu hierarchy or maximum menu depth exceeded\n" );
|
||||
menu->hSubMenu = 0;
|
||||
release_menu_ptr( submenu );
|
||||
return FALSE;
|
||||
}
|
||||
submenu->wFlags |= MF_POPUP;
|
||||
menu->fType |= MF_POPUP;
|
||||
release_menu_ptr( submenu );
|
||||
}
|
||||
else
|
||||
menu->fType &= ~MF_POPUP;
|
||||
}
|
||||
|
||||
if (info->fMask & MIIM_CHECKMARKS)
|
||||
{
|
||||
menu->hCheckBit = info->hbmpChecked;
|
||||
menu->hUnCheckBit = info->hbmpUnchecked;
|
||||
}
|
||||
if (info->fMask & MIIM_DATA)
|
||||
menu->dwItemData = info->dwItemData;
|
||||
|
||||
if (info->fMask & MIIM_BITMAP)
|
||||
menu->hbmpItem = info->hbmpItem;
|
||||
|
||||
if (!menu->text && !(menu->fType & MFT_OWNERDRAW) && !menu->hbmpItem)
|
||||
menu->fType |= MFT_SEPARATOR;
|
||||
|
||||
TRACE( "to: %s\n", debugstr_menuitem( menu ));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserThunkedMenuItemInfo (win32u.@)
|
||||
*/
|
||||
UINT WINAPI NtUserThunkedMenuItemInfo( HMENU handle, UINT pos, UINT flags, UINT method,
|
||||
MENUITEMINFOW *info, UNICODE_STRING *str )
|
||||
{
|
||||
POPUPMENU *menu;
|
||||
UINT i;
|
||||
BOOL ret;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case NtUserInsertMenuItem:
|
||||
if (!info || info->cbSize != sizeof(*info))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(menu = insert_menu_item( handle, pos, flags, &i )))
|
||||
{
|
||||
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
|
||||
if (pos == SC_TASKLIST && !(flags & MF_BYPOSITION)) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = set_menu_item_info( &menu->items[i], info );
|
||||
if (!ret) NtUserRemoveMenu( handle, pos, flags );
|
||||
release_menu_ptr(menu);
|
||||
break;
|
||||
|
||||
case NtUserSetMenuItemInfo:
|
||||
if (!info || info->cbSize != sizeof(*info))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(menu = find_menu_item( handle, pos, flags, &i )))
|
||||
{
|
||||
/* workaround for Word 95: pretend that SC_TASKLIST item exists */
|
||||
if (pos == SC_TASKLIST && !(flags & MF_BYPOSITION)) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = set_menu_item_info( &menu->items[i], info );
|
||||
if (ret) menu->Height = 0; /* force size recalculate */
|
||||
release_menu_ptr(menu);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "unsupported method %u\n", method );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserRemoveMenu (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtUserRemoveMenu( HMENU handle, UINT id, UINT flags )
|
||||
{
|
||||
POPUPMENU *menu;
|
||||
UINT pos;
|
||||
|
||||
TRACE( "(menu=%p id=%#x flags=%04x)\n", handle, id, flags );
|
||||
|
||||
if (!(menu = find_menu_item( handle, id, flags, &pos )))
|
||||
return FALSE;
|
||||
|
||||
/* Remove item */
|
||||
free( menu->items[pos].text );
|
||||
|
||||
if (--menu->nItems == 0)
|
||||
{
|
||||
free( menu->items );
|
||||
menu->items = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MENUITEM *new_items, *item = &menu->items[pos];
|
||||
|
||||
while (pos < menu->nItems)
|
||||
{
|
||||
*item = item[1];
|
||||
item++;
|
||||
pos++;
|
||||
}
|
||||
new_items = realloc( menu->items, menu->nItems * sizeof(MENUITEM) );
|
||||
if (new_items) menu->items = new_items;
|
||||
}
|
||||
|
||||
release_menu_ptr(menu);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserSetMenuContextHelpId (win32u.@)
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,6 @@ struct user_callbacks
|
|||
BOOL (WINAPI *pImmProcessKey)(HWND, HKL, UINT, LPARAM, DWORD);
|
||||
BOOL (WINAPI *pImmTranslateMessage)(HWND, UINT, WPARAM, LPARAM);
|
||||
BOOL (WINAPI *pSetSystemMenu)( HWND hwnd, HMENU menu );
|
||||
void (CDECL *free_menu_items)( void *ptr );
|
||||
void (CDECL *free_win_ptr)( struct tagWND *win );
|
||||
HWND (CDECL *is_menu_active)(void);
|
||||
void (CDECL *notify_ime)( HWND hwnd, UINT param );
|
||||
|
|
|
@ -156,6 +156,7 @@ static void * const syscalls[] =
|
|||
NtUserOpenInputDesktop,
|
||||
NtUserOpenWindowStation,
|
||||
NtUserRemoveClipboardFormatListener,
|
||||
NtUserRemoveMenu,
|
||||
NtUserRemoveProp,
|
||||
NtUserSetKeyboardState,
|
||||
NtUserSetMenuContextHelpId,
|
||||
|
@ -170,6 +171,7 @@ static void * const syscalls[] =
|
|||
NtUserSetWinEventHook,
|
||||
NtUserSetWindowsHookEx,
|
||||
NtUserThunkedMenuInfo,
|
||||
NtUserThunkedMenuItemInfo,
|
||||
NtUserUnhookWinEvent,
|
||||
NtUserUnhookWindowsHookEx,
|
||||
NtUserWindowFromDC,
|
||||
|
|
|
@ -1147,7 +1147,7 @@
|
|||
@ stub NtUserRemoteStopScreenUpdates
|
||||
@ stdcall -syscall NtUserRemoveClipboardFormatListener(long)
|
||||
@ stub NtUserRemoveInjectionDevice
|
||||
@ stub NtUserRemoveMenu
|
||||
@ stdcall -syscall NtUserRemoveMenu(long long long)
|
||||
@ stdcall -syscall NtUserRemoveProp(long wstr)
|
||||
@ stub NtUserRemoveVisualIdentifier
|
||||
@ stub NtUserReportInertia
|
||||
|
@ -1275,7 +1275,7 @@
|
|||
@ stdcall NtUserSystemParametersInfoForDpi(long long ptr long long)
|
||||
@ stub NtUserTestForInteractiveUser
|
||||
@ stdcall -syscall NtUserThunkedMenuInfo(long ptr)
|
||||
@ stub NtUserThunkedMenuItemInfo
|
||||
@ stdcall -syscall NtUserThunkedMenuItemInfo(long long long long ptr ptr)
|
||||
@ stdcall NtUserToUnicodeEx(long long ptr ptr long long long)
|
||||
@ stdcall NtUserTrackMouseEvent(ptr)
|
||||
@ stub NtUserTrackPopupMenuEx
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
SYSCALL_ENTRY( NtUserOpenInputDesktop ) \
|
||||
SYSCALL_ENTRY( NtUserOpenWindowStation ) \
|
||||
SYSCALL_ENTRY( NtUserRemoveClipboardFormatListener ) \
|
||||
SYSCALL_ENTRY( NtUserRemoveMenu ) \
|
||||
SYSCALL_ENTRY( NtUserRemoveProp ) \
|
||||
SYSCALL_ENTRY( NtUserSetKeyboardState ) \
|
||||
SYSCALL_ENTRY( NtUserSetMenuContextHelpId ) \
|
||||
|
@ -157,6 +158,7 @@
|
|||
SYSCALL_ENTRY( NtUserSetWinEventHook ) \
|
||||
SYSCALL_ENTRY( NtUserSetWindowsHookEx ) \
|
||||
SYSCALL_ENTRY( NtUserThunkedMenuInfo ) \
|
||||
SYSCALL_ENTRY( NtUserThunkedMenuItemInfo ) \
|
||||
SYSCALL_ENTRY( NtUserUnhookWinEvent ) \
|
||||
SYSCALL_ENTRY( NtUserUnhookWindowsHookEx ) \
|
||||
SYSCALL_ENTRY( NtUserWindowFromDC )
|
||||
|
|
|
@ -30,6 +30,22 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wow);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT cbSize;
|
||||
UINT fMask;
|
||||
UINT fType;
|
||||
UINT fState;
|
||||
UINT wID;
|
||||
UINT32 hSubMenu;
|
||||
UINT32 hbmpChecked;
|
||||
UINT32 hbmpUnchecked;
|
||||
UINT32 dwItemData;
|
||||
UINT32 dwTypeData;
|
||||
UINT cch;
|
||||
UINT32 hbmpItem;
|
||||
} MENUITEMINFOW32;
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserInitializeClientPfnArrays( UINT *args )
|
||||
{
|
||||
FIXME( "\n" );
|
||||
|
@ -708,3 +724,50 @@ NTSTATUS WINAPI wow64_NtUserThunkedMenuInfo( UINT *args )
|
|||
|
||||
return NtUserThunkedMenuInfo( menu, info32 ? &info : NULL );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserThunkedMenuItemInfo( UINT *args )
|
||||
{
|
||||
HMENU handle = get_handle( &args );
|
||||
UINT pos = get_ulong( &args );
|
||||
UINT flags = get_ulong( &args );
|
||||
UINT method = get_ulong( &args );
|
||||
MENUITEMINFOW32 *info32 = get_ptr( &args );
|
||||
UNICODE_STRING32 *str32 = get_ptr( &args );
|
||||
MENUITEMINFOW info = { sizeof(info) }, *info_ptr;
|
||||
UNICODE_STRING str;
|
||||
|
||||
if (info32)
|
||||
{
|
||||
info.cbSize = sizeof(info);
|
||||
info.fMask = info32->fMask;
|
||||
switch (method)
|
||||
{
|
||||
case NtUserSetMenuItemInfo:
|
||||
case NtUserInsertMenuItem:
|
||||
info.fType = info32->fType;
|
||||
info.fState = info32->fState;
|
||||
info.wID = info32->wID;
|
||||
info.hSubMenu = UlongToHandle( info32->hSubMenu );
|
||||
info.hbmpChecked = UlongToHandle( info32->hbmpUnchecked );
|
||||
info.dwItemData = info32->dwItemData;
|
||||
info.dwTypeData = UlongToPtr( info32->dwTypeData );
|
||||
info.cch = info32->cch;
|
||||
info.hbmpItem = UlongToHandle( info32->hbmpItem );
|
||||
break;
|
||||
}
|
||||
info_ptr = &info;
|
||||
}
|
||||
else info_ptr = NULL;
|
||||
|
||||
return NtUserThunkedMenuItemInfo( handle, pos, flags, method, info_ptr,
|
||||
unicode_str_32to64( &str, str32 ));
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserRemoveMenu( UINT *args )
|
||||
{
|
||||
HMENU handle = get_handle( &args );
|
||||
UINT id = get_ulong( &args );
|
||||
UINT flags = get_ulong( &args );
|
||||
|
||||
return NtUserRemoveMenu( handle, id, flags );
|
||||
}
|
||||
|
|
|
@ -178,6 +178,13 @@ enum
|
|||
NtUserSpyExit = 0x0301,
|
||||
};
|
||||
|
||||
/* NtUserThunkedMenuItemInfo codes */
|
||||
enum
|
||||
{
|
||||
NtUserSetMenuItemInfo,
|
||||
NtUserInsertMenuItem,
|
||||
};
|
||||
|
||||
struct send_message_timeout_params
|
||||
{
|
||||
UINT flags;
|
||||
|
@ -581,6 +588,7 @@ ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *
|
|||
BOOL WINAPI NtUserRegisterHotKey( HWND hwnd, INT id, UINT modifiers, UINT vk );
|
||||
INT WINAPI NtUserReleaseDC( HWND hwnd, HDC hdc );
|
||||
BOOL WINAPI NtUserRemoveClipboardFormatListener( HWND hwnd );
|
||||
BOOL WINAPI NtUserRemoveMenu( HMENU menu, UINT id, UINT flags );
|
||||
HANDLE WINAPI NtUserRemoveProp( HWND hwnd, const WCHAR *str );
|
||||
BOOL WINAPI NtUserScrollDC( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
|
||||
HRGN ret_update_rgn, RECT *update_rect );
|
||||
|
@ -629,6 +637,8 @@ BOOL WINAPI NtUserShowWindowAsync( HWND hwnd, INT cmd );
|
|||
BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT winini );
|
||||
BOOL WINAPI NtUserSystemParametersInfoForDpi( UINT action, UINT val, PVOID ptr, UINT winini, UINT dpi );
|
||||
BOOL WINAPI NtUserThunkedMenuInfo( HMENU menu, const MENUINFO *info );
|
||||
UINT WINAPI NtUserThunkedMenuItemInfo( HMENU menu, UINT pos, UINT flags, UINT method,
|
||||
MENUITEMINFOW *info, UNICODE_STRING *str );
|
||||
INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state,
|
||||
WCHAR *str, int size, UINT flags, HKL layout );
|
||||
BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info );
|
||||
|
|
Loading…
Reference in New Issue