Sky Software Homepage LogicNP Software Knowledge Base And FAQ

 
Contact Product Support    SearchSearch      Subscribe to the RSS feed for this forum

HOWTO: Add large number of menu items (beyond the number of menu item slots provided by Windows)

 
Subscribe to the RSS feed for this forum  Forum Index -> EZShellExtensions.Net
View previous topic :: View next topic  
Author Message
Support



Joined: 18 Jul 2005
Posts: 731

Posted: Mon Oct 06, 2008 2:48 pm    Post subject: HOWTO: Add large number of menu items (beyond the number of menu item slots provided by Windows)

Windows reserves a specific number of menu item IDs for each context menu extension. This limit is generally at least 100. The exact number can be determined in the GetMenuItems method using e.MaxMenuItemsAvailable (GetMenuitemsEventArgs.MaxMenuItemsAvailable ). This limit is sufficient for most purposes, but if you need to add a large number of menu items (including all items in sub-menus and sub-sub-menus), you must reuse the same IDs for menu items in different sub-menus (reasonably assuming that your large number of items are spread across more than one sub-menu). The following code demonstrates how to achieve that :

[C#]

Code:
int startID; // start ID available for our use
ShellMenuItem lastpopupMenuItem = null; // last sub menu which popped

protected override void OnGetMenuItems(LogicNP.EZShellExtensions.GetMenuitemsEventArgs e)
{
        // Add main menus
        ShellMenuItem mi1 =  e.Menu.AddItem("MenuItem1");
        mi1.Tag = 1; // level 1
        ShellMenuItem mi2 = e.Menu.AddItem("MenuItem2");
        mi2.Tag = 1;  // level 1
        ShellMenuItem mi3 = e.Menu.AddItem("MenuItem3");
        mi3.Tag = 1;  // level 1

        mi1.HasSubMenu = true; // Indicate menu has submenu
        // Store the ID of the 'dummy menu item.
        // All dummy menu items will have this ID
        // All actual menu items will have IDs starting from startID to startID+49 (total 50 items)
        startID = mi1.SubMenu.AddItem("dummy").ID; // Add a dummy item to submenu **necessary

        mi2.HasSubMenu = true; // Indicate menu has submenu
        mi2.SubMenu.AddItem("dummy",startID); // Add a dummy item to submenu **necessary

        mi3.HasSubMenu = true; // Indicate menu has submenu
        mi3.SubMenu.AddItem("dummy",startID); // Add a dummy item to submenu **necessary

        // Each submenu of mi1,mi2 and mi3 can have maximum of 50 submenu items, so reserve space for
        // 49 more (1 ID for the 'dummy' item already added which will be removed as each submenu pops up)
        e.ReservedMenuItemCount=49;
}

protected override void OnPopupSubMenu(ShellMenuItem menuItem)
{
        // New menu items are at current level + 1
        int level = (int)menuItem.Tag + 1;

        lastpopupMenuItem = menuItem; // store the last menu which popped up

        menuItem.SubMenu.RemoveAll(); // remove 'dummy' item

        // Add the 50 menu items
        for (int i = 0; i < 50;i++)
        {
            // Explicitly specify id for the menu item.
            ShellMenuItem item =  menuItem.SubMenu.AddItem(menuItem.Caption + "_subMenuItem" + i.ToString(), startID + i);

            // We will limit sub-menus to 2 levels
            if (level<=2)
            {
                item.HasSubMenu = true;
                item.SubMenu.AddItem("dummy", startID);
                item.Tag = level + 1;
            }
        }

}

protected override bool OnExecuteMenuItem(LogicNP.EZShellExtensions.ExecuteItemEventArgs e)
{
        // e,MenuItem is not the correct menu item because we have used duplicate ids which confuses Windows.
        // The real menu item which has been clicked is the one with the same ID as e.MenuItem.ID but which is
        // a sub menu item of 'lastpopupMenuItem'
        ShellMenuItem real = lastpopupMenuItem.SubMenu.GetItemFromID(e.MenuItem.ID);
        MessageBox.Show(real.Caption);
        return true;
}



[VB.Net]

Code:
Dim startID As Integer ' start ID available for our use
Dim lastpopupMenuItem As ShellMenuItem = Nothing ' last sub menu which popped

' Override this method to add your menu items to the context menu
Protected Overrides Sub OnGetMenuItems(ByVal e As LogicNP.EZShellExtensions.GetMenuitemsEventArgs)

    ' Add main menus
    Dim mi1 As ShellMenuItem = e.Menu.AddItem("MenuItem1")
    mi1.Tag = 1  ' level 1
    Dim mi2 As ShellMenuItem = e.Menu.AddItem("MenuItem2")
    mi2.Tag = 1  ' level 1
    Dim mi3 As ShellMenuItem = e.Menu.AddItem("MenuItem3")
    mi3.Tag = 1  ' level 1

    mi1.HasSubMenu = True ' Indicate menu has submenu
    ' Store the ID of the dummy menu item.
    ' All dummy menu items will have this ID
    ' All actual menu items will have IDs starting from startID to startID+49 (total 50 items)
    startID = mi1.SubMenu.AddItem("dummy").ID  ' Add a dummy item to submenu **necessary

    mi2.HasSubMenu = True  ' Indicate menu has submenu
    mi2.SubMenu.AddItem("dummy", startID)  ' Add a dummy item to submenu **necessary

    mi3.HasSubMenu = True ' Indicate menu has submenu
    mi3.SubMenu.AddItem("dummy", startID)  ' Add a dummy item to submenu **necessary

    ' Each submenu of mi1,mi2 and mi3 can have maximum of 50 submenu items, so reserve space for
    ' 49 more (1 ID for the 'dummy' item already added which will be removed as each submenu pops up)
    e.ReservedMenuItemCount = 49

End Sub

Protected Overrides Sub OnPopupSubMenu(ByVal menuItem As ShellMenuItem)

    ' New menu items are at current level + 1
    Dim level As Integer = CType(menuItem.Tag + 1, Integer)

    lastpopupMenuItem = menuItem ' store the last menu which popped up

    menuItem.SubMenu.RemoveAll() ' remove 'dummy' item

    Dim i As Integer
    ' Add the 50 menu items
    For i = 0 To 49
        ' Explicitly specify id for the menu item.
        Dim item As ShellMenuItem = menuItem.SubMenu.AddItem(menuItem.Caption + "_subMenuItem" + i.ToString(), startID + i)

        ' We will limit sub-menus to 2 levels
        If (level <= 2) Then
            item.HasSubMenu = True
            item.SubMenu.AddItem("dummy", startID)
            item.Tag = level + 1
        End If
    Next i

End Sub


' Override this method to perform your own tasks when any of the
' menu items provided by your contextmenu extension is selected by the user.
Protected Overrides Function OnExecuteMenuItem(ByVal e As LogicNP.EZShellExtensions.ExecuteItemEventArgs) As Boolean

    ' e,MenuItem is not the correct menu item because we have used duplicate ids which confuses Windows.
    ' The real menu item which has been clicked is the one with the same ID as e.MenuItem.ID but which is
    ' a sub menu item of 'lastpopupMenuItem'
    Dim real As ShellMenuItem = lastpopupMenuItem.SubMenu.GetItemFromID(e.MenuItem.ID)
    MessageBox.Show(real.Caption)

    Return True

End Function
Back to top
Display posts from previous:   
Forum Index -> EZShellExtensions.Net All times are GMT
Page 1 of 1

 
Jump to:  


Powered by phpBB © 2001, 2005 phpBB Group