win32u: Move get_menu_item_info implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This commit is contained in:
Jacek Caban 2022-04-14 19:39:06 +02:00 committed by Alexandre Julliard
parent 4a53c479e8
commit 7099c8d7e8
3 changed files with 131 additions and 206 deletions

View file

@ -96,91 +96,6 @@ const struct builtin_class_descr MENU_builtin_class =
};
/***********************************************************************
* debug_print_menuitem
*
* Print a menuitem in readable form.
*/
#define debug_print_menuitem(pre, mp, post) \
do { if (TRACE_ON(menu)) do_debug_print_menuitem(pre, mp, post); } while (0)
#define MENUOUT(text) \
TRACE("%s%s", (count++ ? "," : ""), (text))
#define MENUFLAG(bit,text) \
do { \
if (flags & (bit)) { flags &= ~(bit); MENUOUT ((text)); } \
} while (0)
static void do_debug_print_menuitem(const char *prefix, const MENUITEM *mp,
const char *postfix)
{
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"};
TRACE("%s ", prefix);
if (mp) {
UINT flags = mp->fType;
TRACE( "{ ID=0x%Ix", mp->wID);
if ( mp->hSubMenu)
TRACE( ", Sub=%p", mp->hSubMenu);
if (flags) {
int count = 0;
TRACE( ", 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)
TRACE( "+0x%x", flags);
}
flags = mp->fState;
if (flags) {
int count = 0;
TRACE( ", 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)
TRACE( "+0x%x", flags);
}
if (mp->hCheckBit)
TRACE( ", Chk=%p", mp->hCheckBit);
if (mp->hUnCheckBit)
TRACE( ", Unc=%p", mp->hUnCheckBit);
if (mp->text)
TRACE( ", Text=%s", debugstr_w(mp->text));
if (mp->dwItemData)
TRACE( ", ItemData=0x%08Ix", mp->dwItemData);
if (mp->hbmpItem)
{
if( IS_MAGIC_BITMAP(mp->hbmpItem))
TRACE( ", hbitmap=%s", hbmmenus[ (INT_PTR)mp->hbmpItem + 1]);
else
TRACE( ", hbitmap=%p", mp->hbmpItem);
}
TRACE( " }");
} else
TRACE( "NULL");
TRACE(" %s\n", postfix);
}
#undef MENUOUT
#undef MENUFLAG
/***********************************************************************
* MENU_GetMenu
*
@ -1012,122 +927,6 @@ BOOL WINAPI IsMenu( HMENU menu )
return FALSE;
}
/**********************************************************************
* GetMenuItemInfo_common
*/
static BOOL GetMenuItemInfo_common ( HMENU hmenu, UINT id, BOOL bypos,
LPMENUITEMINFOW lpmii, BOOL unicode)
{
POPUPMENU *menu;
MENUITEM *item;
UINT pos;
menu = find_menu_item(hmenu, id, bypos ? MF_BYPOSITION : 0, &pos);
item = menu ? &menu->items[pos] : NULL;
debug_print_menuitem("GetMenuItemInfo_common: ", item, "");
if (!menu)
{
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return FALSE;
}
if( lpmii->fMask & MIIM_TYPE) {
if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) {
release_menu_ptr(menu);
WARN("invalid combination of fMask bits used\n");
/* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER);
return FALSE;
}
lpmii->fType = item->fType & MENUITEMINFO_TYPE_MASK;
if (item->hbmpItem && !IS_MAGIC_BITMAP(item->hbmpItem))
lpmii->fType |= MFT_BITMAP;
lpmii->hbmpItem = item->hbmpItem; /* not on Win9x/ME */
if( lpmii->fType & MFT_BITMAP) {
lpmii->dwTypeData = (LPWSTR) item->hbmpItem;
lpmii->cch = 0;
} else if( lpmii->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) {
/* this does not happen on Win9x/ME */
lpmii->dwTypeData = 0;
lpmii->cch = 0;
}
}
/* copy the text string */
if ((lpmii->fMask & (MIIM_TYPE|MIIM_STRING))) {
if (!item->text) {
if(lpmii->dwTypeData && lpmii->cch) {
if( unicode)
*((WCHAR *)lpmii->dwTypeData) = 0;
else
*((CHAR *)lpmii->dwTypeData) = 0;
}
lpmii->cch = 0;
} else {
int len;
if (unicode)
{
len = lstrlenW(item->text);
if(lpmii->dwTypeData && lpmii->cch)
lstrcpynW(lpmii->dwTypeData, item->text, lpmii->cch);
}
else
{
len = WideCharToMultiByte( CP_ACP, 0, item->text, -1, NULL,
0, NULL, NULL ) - 1;
if(lpmii->dwTypeData && lpmii->cch)
if (!WideCharToMultiByte( CP_ACP, 0, item->text, -1,
(LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL ))
((LPSTR)lpmii->dwTypeData)[lpmii->cch - 1] = 0;
}
/* if we've copied a substring we return its length */
if(lpmii->dwTypeData && lpmii->cch)
if (lpmii->cch <= len + 1)
lpmii->cch--;
else
lpmii->cch = len;
else {
/* return length of string */
/* not on Win9x/ME if fType & MFT_BITMAP */
lpmii->cch = len;
}
}
}
if (lpmii->fMask & MIIM_FTYPE)
lpmii->fType = item->fType & MENUITEMINFO_TYPE_MASK;
if (lpmii->fMask & MIIM_BITMAP)
lpmii->hbmpItem = item->hbmpItem;
if (lpmii->fMask & MIIM_STATE)
lpmii->fState = item->fState & MENUITEMINFO_STATE_MASK;
if (lpmii->fMask & MIIM_ID)
lpmii->wID = item->wID;
if (lpmii->fMask & MIIM_SUBMENU)
lpmii->hSubMenu = item->hSubMenu;
else {
/* hSubMenu is always cleared
* (not on Win9x/ME ) */
lpmii->hSubMenu = 0;
}
if (lpmii->fMask & MIIM_CHECKMARKS) {
lpmii->hbmpChecked = item->hCheckBit;
lpmii->hbmpUnchecked = item->hUnCheckBit;
}
if (lpmii->fMask & MIIM_DATA)
lpmii->dwItemData = item->dwItemData;
release_menu_ptr(menu);
return TRUE;
}
/**********************************************************************
* GetMenuItemInfoA (USER32.@)
@ -1144,10 +943,10 @@ BOOL WINAPI GetMenuItemInfoA( HMENU hmenu, UINT item, BOOL bypos,
}
memcpy( &mii, lpmii, lpmii->cbSize);
mii.cbSize = sizeof( mii);
ret = GetMenuItemInfo_common (hmenu, item, bypos,
(LPMENUITEMINFOW)&mii, FALSE);
ret = NtUserThunkedMenuItemInfo( hmenu, item, bypos ? MF_BYPOSITION : 0,
NtUserGetMenuItemInfoA, (MENUITEMINFOW *)&mii, NULL );
mii.cbSize = lpmii->cbSize;
memcpy( lpmii, &mii, mii.cbSize);
memcpy( lpmii, &mii, mii.cbSize );
return ret;
}
@ -1166,9 +965,10 @@ BOOL WINAPI GetMenuItemInfoW( HMENU hmenu, UINT item, BOOL bypos,
}
memcpy( &mii, lpmii, lpmii->cbSize);
mii.cbSize = sizeof( mii);
ret = GetMenuItemInfo_common (hmenu, item, bypos, &mii, TRUE);
ret = NtUserThunkedMenuItemInfo( hmenu, item, bypos ? MF_BYPOSITION : 0,
NtUserGetMenuItemInfoW, &mii, NULL );
mii.cbSize = lpmii->cbSize;
memcpy( lpmii, &mii, mii.cbSize);
memcpy( lpmii, &mii, mii.cbSize );
return ret;
}

View file

@ -992,6 +992,123 @@ UINT get_menu_state( HMENU handle, UINT item_id, UINT flags )
return state;
}
static BOOL get_menu_item_info( HMENU handle, UINT id, UINT flags, MENUITEMINFOW *info, BOOL ansi )
{
POPUPMENU *menu;
MENUITEM *item;
UINT pos;
if (!info || info->cbSize != sizeof(*info))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
menu = find_menu_item( handle, id, flags, &pos );
item = menu ? &menu->items[pos] : NULL;
TRACE( "%s\n", debugstr_menuitem( item ));
if (!menu)
{
SetLastError( ERROR_MENU_ITEM_NOT_FOUND);
return FALSE;
}
if (info->fMask & MIIM_TYPE)
{
if (info->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP))
{
release_menu_ptr( menu );
WARN( "invalid combination of fMask bits used\n" );
/* this does not happen on Win9x/ME */
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
info->fType = item->fType & MENUITEMINFO_TYPE_MASK;
if (item->hbmpItem && !IS_MAGIC_BITMAP(item->hbmpItem))
info->fType |= MFT_BITMAP;
info->hbmpItem = item->hbmpItem; /* not on Win9x/ME */
if (info->fType & MFT_BITMAP)
{
info->dwTypeData = (WCHAR *)item->hbmpItem;
info->cch = 0;
}
else if (info->fType & (MFT_OWNERDRAW | MFT_SEPARATOR))
{
/* this does not happen on Win9x/ME */
info->dwTypeData = 0;
info->cch = 0;
}
}
/* copy the text string */
if ((info->fMask & (MIIM_TYPE|MIIM_STRING)))
{
if (!item->text)
{
if (info->dwTypeData && info->cch)
{
if (ansi)
*((char *)info->dwTypeData) = 0;
else
*((WCHAR *)info->dwTypeData) = 0;
}
info->cch = 0;
}
else
{
DWORD len, text_len;
if (ansi)
{
text_len = wcslen( item->text );
len = win32u_wctomb_size( &ansi_cp, item->text, text_len );
if (info->dwTypeData && info->cch)
if (!win32u_wctomb( &ansi_cp, (char *)info->dwTypeData, info->cch,
item->text, text_len + 1 ))
((char *)info->dwTypeData)[info->cch - 1] = 0;
}
else
{
len = lstrlenW( item->text );
if (info->dwTypeData && info->cch)
lstrcpynW( info->dwTypeData, item->text, info->cch );
}
if (info->dwTypeData && info->cch)
{
/* if we've copied a substring we return its length */
if (info->cch <= len + 1)
info->cch--;
else
info->cch = len;
}
else
{
/* return length of string, not on Win9x/ME if fType & MFT_BITMAP */
info->cch = len;
}
}
}
if (info->fMask & MIIM_FTYPE) info->fType = item->fType & MENUITEMINFO_TYPE_MASK;
if (info->fMask & MIIM_BITMAP) info->hbmpItem = item->hbmpItem;
if (info->fMask & MIIM_STATE) info->fState = item->fState & MENUITEMINFO_STATE_MASK;
if (info->fMask & MIIM_ID) info->wID = item->wID;
if (info->fMask & MIIM_DATA) info->dwItemData = item->dwItemData;
if (info->fMask & MIIM_SUBMENU) info->hSubMenu = item->hSubMenu;
else info->hSubMenu = 0; /* hSubMenu is always cleared (not on Win9x/ME ) */
if (info->fMask & MIIM_CHECKMARKS)
{
info->hbmpChecked = item->hCheckBit;
info->hbmpUnchecked = item->hUnCheckBit;
}
release_menu_ptr( menu );
return TRUE;
}
/**********************************************************************
* NtUserThunkedMenuItemInfo (win32u.@)
*/
@ -1004,6 +1121,12 @@ UINT WINAPI NtUserThunkedMenuItemInfo( HMENU handle, UINT pos, UINT flags, UINT
switch (method)
{
case NtUserGetMenuItemInfoA:
return get_menu_item_info( handle, pos, flags, info, TRUE );
case NtUserGetMenuItemInfoW:
return get_menu_item_info( handle, pos, flags, info, FALSE );
case NtUserInsertMenuItem:
if (!info || info->cbSize != sizeof(*info))
{

View file

@ -224,6 +224,8 @@ enum
NtUserSetMenuItemInfo,
NtUserInsertMenuItem,
/* Wine extensions */
NtUserGetMenuItemInfoA,
NtUserGetMenuItemInfoW,
NtUserGetMenuState,
};