Search code examples
c#contextmenusubmenuexplorer

Adding submenu's to explorer context menu


I have a bit of code based of this, which allows me to add extra functionality for to the windows explorer context menu. I have been able to successfully get this working.

However I now want to add multiple items into the context menu, and add it inside a submenu. However I can't seem to work out, firstly how to add the submenu into it, then how to link the extra items to be inside that menu.

        // Use either InsertMenu or InsertMenuItem to add menu items.
        MENUITEMINFO mii = new MENUITEMINFO();
        mii.cbSize = (uint)Marshal.SizeOf(mii);
        mii.fMask = MIIM.MIIM_BITMAP | MIIM.MIIM_STRING | MIIM.MIIM_FTYPE | 
            MIIM.MIIM_ID | MIIM.MIIM_STATE;
        mii.wID = idCmdFirst + IDM_DISPLAY;
        mii.fType = MFT.MFT_STRING;
        mii.dwTypeData = this.menuText;
        mii.fState = MFS.MFS_ENABLED;
        mii.hbmpItem = this.menuBmp;
        if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii))
        {
            return Marshal.GetHRForLastWin32Error();
        }

That is the code I have to add the item currently. Unsure how i need to modify this for a submenu, as well as how to link the click action of the multiple items.

There is a shellExtLib which is what has most of that stuff defined, and looks like it is just importing stuff from the user32.dll. There is also a InvokeCommand() defined, which is where my actual "action-taking" code is.


Solution

  • This is the solution I ended up with:

        private MENUITEMINFO CreateSubMenu(string menuText, IntPtr menuIcon, IntPtr hSubMenu, bool isEnabled = true)
        {
            MENUITEMINFO subMenu = new MENUITEMINFO();
            subMenu.cbSize = (uint)Marshal.SizeOf(subMenu);
            subMenu.fMask = MIIM.MIIM_BITMAP | MIIM.MIIM_SUBMENU | MIIM.MIIM_STRING | MIIM.MIIM_FTYPE | MIIM.MIIM_STATE;
            subMenu.hSubMenu = hSubMenu;
            //subMenu.wID = itemID;
            subMenu.fType = MFT.MFT_STRING;
            subMenu.dwTypeData = menuText;
            subMenu.fState = isEnabled ? MFS.MFS_ENABLED : MFS.MFS_DISABLED;
            subMenu.hbmpItem = menuIcon;
            //itemID++;
            return subMenu;
        }
    

    Combined with:

        IntPtr hSubMenu = NativeMethods.CreatePopupMenu();
    
        [DllImport("user32.dll")]
        public static extern IntPtr CreatePopupMenu();