[PATCH v2 3/6] win32u: Move get_menu_item_info implementation from user32.
Jacek Caban
wine at gitlab.winehq.org
Tue Jun 21 08:10:00 CDT 2022
From: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at 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..bee04f36dbf 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,
};
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/294
More information about the wine-devel
mailing list