Esempio n. 1
0
        private static void EnumMenuItems(
            Shell32.IContextMenu cMenu,
            HMENU hMenu,
            List <Win32ContextMenuItem> menuItemsResult,
            Func <string, bool> itemFilter = null)
        {
            var itemCount = User32.GetMenuItemCount(hMenu);
            var mii       = new User32.MENUITEMINFO();

            mii.cbSize = (uint)Marshal.SizeOf(mii);
            mii.fMask  = User32.MenuItemInfoMask.MIIM_BITMAP
                         | User32.MenuItemInfoMask.MIIM_FTYPE
                         | User32.MenuItemInfoMask.MIIM_STRING
                         | User32.MenuItemInfoMask.MIIM_ID
                         | User32.MenuItemInfoMask.MIIM_SUBMENU;
            for (uint ii = 0; ii < itemCount; ii++)
            {
                var menuItem  = new ContextMenuItem();
                var container = new SafeCoTaskMemString(512);
                mii.dwTypeData = (IntPtr)container;
                mii.cch        = (uint)container.Capacity - 1; // https://devblogs.microsoft.com/oldnewthing/20040928-00/?p=37723
                var retval = User32.GetMenuItemInfo(hMenu, ii, true, ref mii);
                if (!retval)
                {
                    container.Dispose();
                    continue;
                }
                menuItem.Type = (MenuItemType)mii.fType;
                menuItem.ID   = (int)(mii.wID - 1); // wID - idCmdFirst
                if (menuItem.Type == MenuItemType.MFT_STRING)
                {
                    Debug.WriteLine("Item {0} ({1}): {2}", ii, mii.wID, mii.dwTypeData);
                    menuItem.Label         = mii.dwTypeData;
                    menuItem.CommandString = GetCommandString(cMenu, mii.wID - 1);
                    if (itemFilter != null && (itemFilter(menuItem.CommandString) || itemFilter(menuItem.Label)))
                    {
                        // Skip items implemented in UWP
                        container.Dispose();
                        continue;
                    }
                    if (mii.hbmpItem != HBITMAP.NULL && !Enum.IsDefined(typeof(HBITMAP_HMENU), ((IntPtr)mii.hbmpItem).ToInt64()))
                    {
                        using var bitmap = Win32API.GetBitmapFromHBitmap(mii.hbmpItem);
                        if (bitmap != null)
                        {
                            byte[] bitmapData = (byte[])new ImageConverter().ConvertTo(bitmap, typeof(byte[]));
                            menuItem.IconBase64 = Convert.ToBase64String(bitmapData, 0, bitmapData.Length);
                        }
                    }
                    if (mii.hSubMenu != HMENU.NULL)
                    {
                        Debug.WriteLine("Item {0}: has submenu", ii);
                        var subItems = new List <Win32ContextMenuItem>();
                        try
                        {
                            (cMenu as Shell32.IContextMenu2)?.HandleMenuMsg((uint)User32.WindowMessage.WM_INITMENUPOPUP, (IntPtr)mii.hSubMenu, new IntPtr(ii));
                        }
                        catch (NotImplementedException)
                        {
                            // Only for dynamic/owner drawn? (open with, etc)
                        }
                        EnumMenuItems(cMenu, mii.hSubMenu, subItems, itemFilter);
                        menuItem.SubItems = subItems;
                        Debug.WriteLine("Item {0}: done submenu", ii);
                    }
                }
                else
                {
                    Debug.WriteLine("Item {0}: {1}", ii, mii.fType.ToString());
                }
                container.Dispose();
                menuItemsResult.Add(menuItem);
            }
        }