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 -> EZShellExtensionsMFC
View previous topic :: View next topic  
Author Message
Support



Joined: 18 Jul 2005
Posts: 731

Posted: Tue Oct 07, 2008 7:43 am    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 OnGetMenuItems function using e.maxMenuItemsAvailable (CGetMenuitemsEventArgs.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 :

Code:
int startID; // start ID available for our use
CShellMenuItem* lastpopupMenuItem ; // last sub menu which popped

void CContextMenuExtension1::OnGetMenuItems(CGetMenuitemsEventArgs& e)
{
   // Add main menus
   CShellMenuItem* mi1 =  e.menu->AddItem(_T("MenuItem1"));
   mi1->SetTag((void*)1); // level 1
   CShellMenuItem* mi2 =  e.menu->AddItem(_T("MenuItem2"));
   mi2->SetTag((void*)1); // level 1
   CShellMenuItem* mi3 =  e.menu->AddItem(_T("MenuItem3"));
   mi3->SetTag((void*)1); // level 1

   mi1->SetHasSubMenu(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->GetSubMenu()->AddItem(_T("dummy"))->GetID(); // Add a dummy item to submenu **necessary

   mi2->SetHasSubMenu(TRUE); // Indicate menu has submenu
   mi2->GetSubMenu()->AddItem(_T("dummy"),startID); // Add a dummy item to submenu **necessary

   mi3->SetHasSubMenu(TRUE); // Indicate menu has submenu
   mi3->GetSubMenu()->AddItem(_T("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;   
}

void CContextMenuExtension1::OnPopupSubMenu(CShellMenuItem* menuItem)
{
   // New menu items are at current level + 1
   int level = (int)(menuItem->GetTag()) + 1;

   lastpopupMenuItem = menuItem; // store the last menu which popped up
   menuItem->GetSubMenu()->RemoveAll(); // remove 'dummy' item

   // Add the 50 menu items
   for (int i = 0; i < 50;i++)
   {
      // Explicitly specify id for the menu item.
      CString str;
      str.Format(menuItem->GetCaption()+ _T("_subMenuItem %d") ,i);
      CShellMenuItem* item =  menuItem->GetSubMenu()->AddItem(str, startID + i);

      // We will limit sub-menus to 2 levels
      if (level<=2)
      {
         item->SetHasSubMenu(true);
         item->GetSubMenu()->AddItem(_T("dummy"), startID);
         item->SetTag((void*)(level + 1));
      }
   }

}
BOOL CContextMenuExtension1::OnExecuteMenuItem(CExecuteItemEventArgs& 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'
   CShellMenuItem* real = lastpopupMenuItem->GetSubMenu()->GetItemFromID(e.menuItem->GetID());
   AfxMessageBox(real->GetCaption());
   
   return TRUE;
}
Back to top
Display posts from previous:   
Forum Index -> EZShellExtensionsMFC All times are GMT
Page 1 of 1

 
Jump to:  


Powered by phpBB © 2001, 2005 phpBB Group