/// <summary>
        /// Displays the CommandContextMenu at the specified location and returns the command that
        /// was selected by the user.
        /// </summary>
        /// <param name="parentWindow">Window that owns the shortcut menu.</param>
        /// <param name="position">Specifies the location of the shortcut menu, in screen coordinates.</param>
        /// <param name="alternateXPosition">An alternate X-position in case the showing of the
        /// menu results in the menu going offscreen to the right</param>
        /// <returns>Command that was selected by the user; or null if a command was not selected.</returns>
        private Command ShowModal(Control parentWindow, Point position, int alternateXPosition)
        {
            //	Recursively raise the BeforeShow event.
            RecursivelyRaiseBeforeShow(MenuItems);

            bool rtl = BidiHelper.IsRightToLeft;

            uint layout = TPM.LEFTALIGN;

            if (rtl)
            {
                layout |= TPM.LAYOUTRTL;

                // When the parent is a RTL form, we don't need to do all
                // this--it gets done implicitly
                if (!(parentWindow is Form))
                {
                    layout |= TPM.RIGHTALIGN;

                    int x = position.X;
                    position.X         = alternateXPosition;
                    alternateXPosition = x;
                }
            }

            //	Calculate the right edge of the menu
            const int ESTIMATED_MENU_WIDTH = 250;
            Point     menuRightEdge        = position;

            menuRightEdge.Offset(ESTIMATED_MENU_WIDTH * (rtl ? -1 : 1), 0);

            //	Check to see whether the menu is likely to go offscreen to the right
            if (!Screen.FromControl(parentWindow).Bounds.Contains(menuRightEdge))
            {
                position.X = alternateXPosition;
            }

            //	Pop it up!  (.NET should have provided this functionality, damn it.)
            int menuID = User32.TrackPopupMenu(Handle,
                                               TPM.NONOTIFY | TPM.RETURNCMD | layout,
                                               position.X,
                                               position.Y,
                                               0,
                                               parentWindow.Handle,
                                               IntPtr.Zero);

            //	If the user didn't make a selection, return null.
            if (menuID == 0)
            {
                return(null);
            }

            //	Return the command that the user selected.
            CommandOwnerDrawMenuItem commandOwnerDrawMenuItem = LocateCommandOwnerDrawMenuItem(MenuItems, menuID);

            Debug.Assert(commandOwnerDrawMenuItem != null, "CommandContextMenu.ShowModal was not able to locate the CommandOwnerDrawMenuItem corresponding to the user's selection.  Call Brian.");
            return(commandOwnerDrawMenuItem.Command);
        }
        /// <summary>
        /// Gets the MenuItem for this MenuDefinitionEntry.
        /// </summary>
        /// <param name="commandManager">The CommandManager to use.</param>
        /// <param name="menuType">The MenuType.</param>
        /// <returns>The menu item for this MenuDefinitionEntry.</returns>
        protected override MenuItem GetMenuItem(CommandManager commandManager, MenuType menuType)
        {
            Command command = commandManager.Get(commandIdentifier);

            if (command == null || !command.On)
            {
                return(null);
            }
            if ((menuType == MenuType.Context || menuType == MenuType.CommandBarContext) && !command.VisibleOnContextMenu)
            {
                return(null);
            }

            //	Instantiate and initialize the CommandOwnerDrawMenuItem.
            CommandOwnerDrawMenuItem commandOwnerDrawMenuItem = new CommandOwnerDrawMenuItem(menuType, command, command.MenuText);

            return(commandOwnerDrawMenuItem);
        }
 /// <summary>
 /// Helper to recursively locate a CommandOwnerDrawMenuItem with the specified menu id.
 /// </summary>
 /// <param name="menuItemCollection">The MenuItemCollection to search.</param>
 /// <param name="menuID">The menu id to search for.</param>
 /// <returns>The CommandOwnerDrawMenuItem, or null if it could not be found.</returns>
 private CommandOwnerDrawMenuItem LocateCommandOwnerDrawMenuItem(MenuItemCollection menuItemCollection, int menuID)
 {
     //	Locate the matching CommandOwnerDrawMenuItem that was selected.
     foreach (MenuItem menuItem in menuItemCollection)
     {
         if (menuItem is CommandOwnerDrawMenuItem)
         {
             CommandOwnerDrawMenuItem commandOwnerDrawMenuItem = (CommandOwnerDrawMenuItem)menuItem;
             if (commandOwnerDrawMenuItem.GetMenuID() == menuID)
             {
                 return(commandOwnerDrawMenuItem);
             }
         }
         else
         {
             CommandOwnerDrawMenuItem commandOwnerDrawMenuItem = LocateCommandOwnerDrawMenuItem(menuItem.MenuItems, menuID);
             if (commandOwnerDrawMenuItem != null)
             {
                 return(commandOwnerDrawMenuItem);
             }
         }
     }
     return(null);
 }
        /// <summary>
        /// Gets the MenuItem for this MenuDefinitionEntry.
        /// </summary>
        /// <param name="commandManager">The CommandManager to use.</param>
        /// <param name="menuType">The MenuType.</param>
        /// <returns>The menu item for this MenuDefinitionEntry.</returns>
        protected override MenuItem GetMenuItem(CommandManager commandManager, MenuType menuType)
        {
            Command command = commandManager.Get(commandIdentifier);
            if (command == null || !command.On)
                return null;
            if ((menuType == MenuType.Context || menuType == MenuType.CommandBarContext) && !command.VisibleOnContextMenu)
                return null;

            //	Instantiate and initialize the CommandOwnerDrawMenuItem.
            CommandOwnerDrawMenuItem commandOwnerDrawMenuItem = new CommandOwnerDrawMenuItem(menuType, command, command.MenuText);
            return commandOwnerDrawMenuItem;
        }
        /// <summary>
        /// Creates and returns a set of menu items from the child merge menu entries in this merge
        /// menu entry.
        /// </summary>
        /// <param name="mainMenu">The level at which the MenuItems will appear.</param>
        /// <returns>Array of menu items.</returns>
        public MenuItem[] CreateMenuItems()
        {
            //	If this merge menu entry has no child merge menu entries, return null.
            if (childMergeMenuEntries.Count == 0)
            {
                return(null);
            }

            //	Construct an array list to hold the menu items being created.
            ArrayList menuItemArrayList = new ArrayList();

            //	Enumerate the child merge menu entries of this merge menu entry.
            foreach (CommandMenuBuilderEntry mergeMenuEntry in childMergeMenuEntries.Values)
            {
                //	Get the text of the merge menu entry.
                string text = mergeMenuEntry.Text;

                //	Create the menu item for this child merge menu entry.
                MenuItem menuItem;
                bool     separatorBefore, separatorAfter;
                if (commandMenuBuilder.MenuType == MenuType.Main && mergeMenuEntry.level == 0)
                {
                    //	Level zero of a main menu.
                    menuItem        = new OwnerDrawMenuItem(commandMenuBuilder.MenuType, text);
                    separatorBefore = separatorAfter = false;
                }
                else
                {
                    //	Determine whether a separator before and a separator after the menu item
                    //	should be inserted.
                    separatorBefore = text.StartsWith(SEPARATOR_CHAR.ToString());
                    separatorAfter  = text.EndsWith(SEPARATOR_CHAR.ToString());
                    if (separatorBefore || separatorAfter)
                    {
                        text = text.Trim(SEPARATOR_CHAR);
                    }

                    //	Instantiate the menu item.
                    if (mergeMenuEntry.Command == null)
                    {
                        menuItem = new OwnerDrawMenuItem(commandMenuBuilder.MenuType, text);
                    }
                    else
                    {
                        menuItem = new CommandOwnerDrawMenuItem(commandMenuBuilder.MenuType, mergeMenuEntry.Command, text);
                    }
                }

                //	Set the menu item text.
                // menuItem.Text = text;

                //	If this child merge menu entry has any child merge menu entries, recursively
                //	create their menu items.
                MenuItem[] childMenuItems = mergeMenuEntry.CreateMenuItems();
                if (childMenuItems != null)
                {
                    menuItem.MenuItems.AddRange(childMenuItems);
                }

                //	Add the separator menu item, as needed.
                if (separatorBefore)
                {
                    menuItemArrayList.Add(MakeSeparatorMenuItem(commandMenuBuilder.MenuType));
                }

                //	Add the menu item to the array of menu items being returned.
                menuItemArrayList.Add(menuItem);

                //	Add the separator menu item, as needed.
                if (separatorAfter)
                {
                    menuItemArrayList.Add(MakeSeparatorMenuItem(commandMenuBuilder.MenuType));
                }
            }

            // remove leading, trailing, and adjacent separators
            for (int i = menuItemArrayList.Count - 1; i >= 0; i--)
            {
                if (((MenuItem)menuItemArrayList[i]).Text == "-")
                {
                    if (i == 0 ||                                         // leading
                        i == menuItemArrayList.Count - 1 ||               // trailing
                        ((MenuItem)menuItemArrayList[i - 1]).Text == "-") // adjacent
                    {
                        menuItemArrayList.RemoveAt(i);
                    }
                }
            }

            //	Done.  Convert the array list into a MenuItem array and return it.
            return((MenuItem[])menuItemArrayList.ToArray(typeof(MenuItem)));
        }
        /// <summary>
        /// Creates and returns a set of menu items from the child merge menu entries in this merge
        /// menu entry.
        /// </summary>
        /// <param name="mainMenu">The level at which the MenuItems will appear.</param>
        /// <returns>Array of menu items.</returns>
        public MenuItem[] CreateMenuItems()
        {
            //	If this merge menu entry has no child merge menu entries, return null.
            if (childMergeMenuEntries.Count == 0)
                return null;

            //	Construct an array list to hold the menu items being created.
            ArrayList menuItemArrayList = new ArrayList();

            //	Enumerate the child merge menu entries of this merge menu entry.
            foreach (CommandMenuBuilderEntry mergeMenuEntry in childMergeMenuEntries.Values)
            {
                //	Get the text of the merge menu entry.
                string text = mergeMenuEntry.Text;

                //	Create the menu item for this child merge menu entry.
                MenuItem menuItem;
                bool separatorBefore, separatorAfter;
                if (commandMenuBuilder.MenuType == MenuType.Main && mergeMenuEntry.level == 0)
                {
                    //	Level zero of a main menu.
                    menuItem = new OwnerDrawMenuItem(commandMenuBuilder.MenuType, text);
                    separatorBefore = separatorAfter = false;
                }
                else
                {
                    //	Determine whether a separator before and a separator after the menu item
                    //	should be inserted.
                    separatorBefore = text.StartsWith(SEPARATOR_CHAR.ToString());
                    separatorAfter = text.EndsWith(SEPARATOR_CHAR.ToString());
                    if (separatorBefore || separatorAfter)
                        text = text.Trim(SEPARATOR_CHAR);

                    //	Instantiate the menu item.
                    if (mergeMenuEntry.Command == null)
                        menuItem = new OwnerDrawMenuItem(commandMenuBuilder.MenuType, text);
                    else
                        menuItem = new CommandOwnerDrawMenuItem(commandMenuBuilder.MenuType, mergeMenuEntry.Command, text);
                }

                //	Set the menu item text.
                // menuItem.Text = text;

                //	If this child merge menu entry has any child merge menu entries, recursively
                //	create their menu items.
                MenuItem[] childMenuItems = mergeMenuEntry.CreateMenuItems();
                if (childMenuItems != null)
                    menuItem.MenuItems.AddRange(childMenuItems);

                //	Add the separator menu item, as needed.
                if (separatorBefore)
                    menuItemArrayList.Add(MakeSeparatorMenuItem(commandMenuBuilder.MenuType));

                //	Add the menu item to the array of menu items being returned.
                menuItemArrayList.Add(menuItem);

                //	Add the separator menu item, as needed.
                if (separatorAfter)
                    menuItemArrayList.Add(MakeSeparatorMenuItem(commandMenuBuilder.MenuType));
            }

            // remove leading, trailing, and adjacent separators
            for (int i = menuItemArrayList.Count - 1; i >= 0; i--)
            {
                if (((MenuItem)menuItemArrayList[i]).Text == "-")
                {
                    if (i == 0 ||  // leading
                        i == menuItemArrayList.Count - 1 ||  // trailing
                        ((MenuItem)menuItemArrayList[i - 1]).Text == "-")  // adjacent
                    {
                        menuItemArrayList.RemoveAt(i);
                    }
                }
            }

            //	Done.  Convert the array list into a MenuItem array and return it.
            return (MenuItem[])menuItemArrayList.ToArray(typeof(MenuItem));
        }