protected bool GenerateShortcut(Shortcut sc, MenuCommandCollection mcc) { foreach(MenuCommand mc in mcc) { // Does the command match? if (mc.Enabled && (mc.Shortcut == sc)) { // Generate event for command mc.OnClick(EventArgs.Empty); return true; } else { // Any child items to test? if (mc.MenuCommands.Count > 0) { // Recursive descent of all collections if (GenerateShortcut(sc, mc.MenuCommands)) return true; } } } return false; }
public MenuControl() { // Set default values this.Dock = DockStyle.Top; _trackItem = -1; _selected = false; _multiLine = false; _popupMenu = null; _mouseOver = false; _manualFocus = false; _drawUpwards = false; _plainAsBlock = false; _oldFocus = IntPtr.Zero; _ignoreEscapeUp = false; _ignoreMouseMove = false; _dismissTransfer = false; _style = VisualStyle.IDE; _chevronStartCommand = null; _direction = Direction.Horizontal; _menuCommands = new MenuCommandCollection(); // Prevent flicker with double buffering and all painting inside WM_PAINT SetStyle(ControlStyles.DoubleBuffer, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); // Should not be allowed to select this control SetStyle(ControlStyles.Selectable, false); // Hookup to collection events _menuCommands.Cleared += new CollectionWithEvents.CollectionClear(OnCollectionCleared); _menuCommands.Inserted += new CollectionWithEvents.CollectionChange(OnCollectionInserted); _menuCommands.Removed += new CollectionWithEvents.CollectionChange(OnCollectionRemoved); // Set the default menu color as background this.BackColor = SystemColors.Control; // Do not allow tab key to select this control this.TabStop = false; // Default the Font we use this.Font = SystemInformation.MenuFont; // Calculate the initial height/width of the control _rowWidth = _rowHeight = this.Font.Height + _breadthGap * 2 + 1; // Default to one line of items this.Height = _rowHeight; // Add ourself to the application filtering list Application.AddMessageFilter(this); }
internal void OperateSubMenu(DrawCommand dc, bool selectFirst, bool trackRemove) { Rectangle drawRect = dc.DrawRect; // Find screen positions for popup menu Point screenPos; if (_style == VisualStyle.IDE) { if (_direction == Direction.Horizontal) screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom - _lengthGap - 1)); else screenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Top + _boxExpandSides - 1)); } else { if (_direction == Direction.Horizontal) screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom)); else screenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Top)); } Point aboveScreenPos; if (_style == VisualStyle.IDE) { if (_direction == Direction.Horizontal) aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top + _lengthGap + 1)); else aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Bottom + _lengthGap)); } else { if (_direction == Direction.Horizontal) aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top)); else aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Bottom)); } int borderGap; // Calculate the missing gap in the PopupMenu border if (_direction == Direction.Horizontal) borderGap = dc.DrawRect.Width - _subMenuBorderAdjust; else borderGap = dc.DrawRect.Height - _subMenuBorderAdjust; _popupMenu = new PopupMenu(); // Define the correct visual style based on ours _popupMenu.Style = this.Style; // Key direction when keys cause dismissal int returnDir = 0; if (dc.Chevron) { MenuCommandCollection mcc = new MenuCommandCollection(); bool addCommands = false; // Generate a collection of menu commands for those not visible foreach(MenuCommand command in _menuCommands) { if (!addCommands && (command == _chevronStartCommand)) addCommands = true; if (addCommands) mcc.Add(command); } // Track the popup using provided menu item collection _popupMenu.TrackPopup(screenPos, aboveScreenPos, _direction, mcc, borderGap, selectFirst, this, ref returnDir); } else { // Generate event so that caller has chance to modify MenuCommand contents OnPopupStart(dc.MenuCommand); // Track the popup using provided menu item collection _popupMenu.TrackPopup(screenPos, aboveScreenPos, _direction, dc.MenuCommand.MenuCommands, borderGap, selectFirst, this, ref returnDir); // Generate event so that caller has chance to modify MenuCommand contents OnPopupEnd(dc.MenuCommand); } // Remove unwanted object _popupMenu = null; // Was arrow key used to dismiss the submenu? if (returnDir != 0) { // Using keyboard movements means we should have the focus if (!_manualFocus) { _manualFocus = true; GrabTheFocus(); } if (returnDir < 0) { // Shift selection left one ProcessMoveLeft(true); } else { // Shift selection right one ProcessMoveRight(true); } // A WM_MOUSEMOVE is generated when we open up the new submenu for // display, ignore this as it causes the selection to move _ignoreMouseMove = true; } else { // Only if the submenu was dismissed at the request of the submenu // should the selection mode be cancelled, otherwise keep selection mode if (!_dismissTransfer) { // This item is no longer selected _selected = false; _drawUpwards = false; // Should we stop tracking this item if (trackRemove) { ReturnTheFocus(); // Unselect the current item _trackItem = SwitchTrackingItem(_trackItem, -1); } else { // Repaint the item DrawCommand(_trackItem, true); } } else { // Do not change _selected status _dismissTransfer = false; } } }
protected MenuCommand InternalTrackPopup(Point screenPosTR, Point screenPosTL, MenuCommandCollection menuCollection, PopupMenu parentMenu, bool selectFirst, MenuControl parentControl, bool popupRight, bool popupDown, ref int returnDir) { // Default the drawing direction _direction = Direction.Horizontal; // Remember the MenuControl that initiated us _parentControl = parentControl; // We have a parent popup menu that should be consulted about operation _parentMenu = parentMenu; // Remember any currect menu item collection MenuCommandCollection oldCollection = _menuCommands; // Use the passed in collection of menu commands _menuCommands = menuCollection; // Remember screen positions _screenPos = screenPosTR; _aboveScreenPos = screenPosTR; _leftScreenPos = screenPosTL; // Remember display directions _popupRight = popupRight; _popupDown = popupDown; MenuCommand ret = InternalTrackPopup(selectFirst); // Restore to original collection _menuCommands = oldCollection; // Remove references no longer required _parentControl = null; _parentMenu = null; // Return the direction key that caused dismissal returnDir = _returnDir; return ret; }
internal MenuCommand TrackPopup(Point screenPos, Point aboveScreenPos, Direction direction, MenuCommandCollection menuCollection, int borderGap, bool selectFirst, MenuControl parentControl, ref int returnDir) { // Remember which direction the MenuControl is drawing in _direction = direction; // Remember the MenuControl that initiated us _parentControl = parentControl; // Remember the gap in drawing the top border _borderGap = borderGap; // Remember any currect menu item collection MenuCommandCollection oldCollection = _menuCommands; // Use the passed in collection of menu commands _menuCommands = menuCollection; // Remember screen positions _screenPos = screenPos; _aboveScreenPos = aboveScreenPos; _leftScreenPos = screenPos; MenuCommand ret = InternalTrackPopup(selectFirst); // Restore to original collection _menuCommands = oldCollection; // Remove reference no longer required _parentControl = null; // Return the direction key that caused dismissal returnDir = _returnDir; return ret; }
public PopupMenu() { // Create collection objects _drawCommands = new ArrayList(); _menuCommands = new MenuCommandCollection(); // Default the properties _returnDir = 0; _extraSize = 0; _popupItem = -1; _trackItem = -1; _childMenu = null; _exitLoop = false; _popupDown = true; _mouseOver = false; _grabFocus = false; _excludeTop = true; _popupRight = true; _parentMenu = null; _excludeOffset = 0; _focusCatcher = null; _parentControl = null; _returnCommand = null; _oldFocus = IntPtr.Zero; _showInfrequent = false; _style = VisualStyle.IDE; _lastMousePos = new Point(-1,-1); _direction = Direction.Horizontal; _textFont = SystemInformation.MenuFont; // Create and initialise the timer object (but do not start it running!) _timer = new Timer(); _timer.Interval = _selectionDelay; _timer.Tick += new EventHandler(OnTimerExpire); }
protected void InternalConstruct(string text, ImageList imageList, int imageIndex, Shortcut shortcut, EventHandler clickHandler, Bitmap bitmap, object realOwner) { // Save parameters this.text = text; this.imageList = imageList; this.imageIndex = imageIndex; this.shortcut = shortcut; image = bitmap; this.realOwner = realOwner; this.comboBox = null; if (clickHandler != null) Click += clickHandler; // Define defaults for others enabled = true; _checked = false; radioCheck = false; _break = false; userData = null; visible = true; infrequent = false; // Create the collection of embedded menu commands menuItems = new MenuCommandCollection(); }