From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/user32/menu.c | 212 ++------------------------------------------- dlls/win32u/menu.c | 123 ++++++++++++++++++++++++++ include/ntuser.h | 2 + 3 files changed, 131 insertions(+), 206 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 74a43eaab1a..df260b063d9 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -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; }
diff --git a/dlls/win32u/menu.c b/dlls/win32u/menu.c index 6a464047427..ca2c018f7e1 100644 --- a/dlls/win32u/menu.c +++ b/dlls/win32u/menu.c @@ -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)) { diff --git a/include/ntuser.h b/include/ntuser.h index 6e6819038ac..d92332f13b9 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -224,6 +224,8 @@ enum NtUserSetMenuItemInfo, NtUserInsertMenuItem, /* Wine extensions */ + NtUserGetMenuItemInfoA, + NtUserGetMenuItemInfoW, NtUserGetMenuState, };