[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