public MenuCommand Add(MenuCommand value) { // Use base class to process actual collection operation base.List.Add(value as object); return value; }
public DrawCommand(Rectangle drawRect, bool expansion) { _row = -1; _col = -1; _mnemonic = '0'; _enabled = true; _subMenu = false; _expansion = expansion; _separator = !expansion; _vertSeparator = !expansion; _topBorder = false; _bottomBorder = false; _infrequent = false; _chevron = false; _drawRect = drawRect; _selectRect = drawRect; _command = null; }
protected MenuCommand InternalTrackPopup(bool selectFirst) { // MenuCommand to return as method result _returnCommand = null; // No item is being tracked _trackItem = -1; // Flag to indicate when to exit the message loop _exitLoop = false; // Assume the mouse does not start over our window _mouseOver = false; // Direction of key press if this caused dismissal _returnDir = 0; // Flag to indicate if the message should be dispatched bool leaveMsg = false; // First time a submenu is shown we pass in our value _animateFirst = true; // Create and show the popup window (without taking the focus) CreateAndShowWindow(); // Create an object for storing windows message information Win32.MSG msg = new Win32.MSG(); // Pretend user pressed key down to get the first valid item selected if (selectFirst) ProcessKeyDown(); // Always use the arrow cursor User32.SetCursor(User32.LoadCursor(IntPtr.Zero, (uint)Win32.Cursors.IDC_ARROW)); // Must hide caret so user thinks focus has changed bool hideCaret = User32.HideCaret(IntPtr.Zero); // Process messages until exit condition recognised while(!_exitLoop) { // Suspend thread until a windows message has arrived if (User32.WaitMessage()) { // Take a peek at the message details without removing from queue while(!_exitLoop && User32.PeekMessage(ref msg, 0, 0, 0, (int)Win32.PeekMessageFlags.PM_NOREMOVE)) { // Console.WriteLine("Track {0} {1}", this.Handle, ((Win32.Msgs)msg.message).ToString()); bool eatMessage = false; int localWidth = _currentSize.Width - _position[(int)_style, (int)PI.ShadowWidth]; int localHeight = _currentSize.Height - _position[(int)_style, (int)PI.ShadowHeight]; // Mouse was pressed in a window of this application if ((msg.message == (int)Win32.Msgs.WM_LBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_MBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_RBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_XBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_NCLBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_NCMBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_NCRBUTTONUP) || (msg.message == (int)Win32.Msgs.WM_NCXBUTTONUP)) { Win32.POINT screenPos = MousePositionToScreen(msg); // Is the POINT inside the Popup window rectangle if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) && (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight))) { OnWM_YBUTTONUP(screenPos.x, screenPos.y); // Eat the message to prevent the intended destination getting it eatMessage = true; } else { PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg); // Let the parent chain of PopupMenu's decide if they want it if (target != null) { target.OnWM_YBUTTONUP(screenPos.x, screenPos.y); // Eat the message to prevent the intended destination getting it eatMessage = true; } } } // Mouse was pressed in a window of this application if ((msg.message == (int)Win32.Msgs.WM_LBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_MBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_RBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_XBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_NCLBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_NCMBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_NCRBUTTONDOWN) || (msg.message == (int)Win32.Msgs.WM_NCXBUTTONDOWN)) { Win32.POINT screenPos = MousePositionToScreen(msg); // Is the POINT inside the Popup window rectangle if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) && (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight))) { // Eat the message to prevent the intended destination getting it eatMessage = true; } else { // Let the parent chain of PopupMenu's decide if they want it if (ParentPopupMenuWantsMouseMessage(screenPos, ref msg) == null) { if (ParentControlWantsMouseMessage(screenPos, ref msg)) { // Let the MenuControl do its business _parentControl.OnWM_MOUSEDOWN(screenPos); // Eat the message to prevent the intended destination getting it eatMessage = true; } else { // No, then we need to exit the popup menu tracking _exitLoop = true; // DO NOT process the message, leave it on the queue // and let the real destination window handle it. leaveMsg = true; // Is a parent control specified? if (_parentControl != null) { // Is the mouse event destination the parent control? if (msg.hwnd == _parentControl.Handle) { // Then we want to consume the message so it does not get processed // by the parent control. Otherwise, pressing down will cause this // popup to disappear but the message will then get processed by // the parent and cause a popup to reappear again. When we actually // want the popup to disappear and nothing more. leaveMsg = false; } } } } else { // Eat the message to prevent the intended destination getting it eatMessage = true; } } } // Mouse move occured if (msg.message == (int)Win32.Msgs.WM_MOUSEMOVE) { Win32.POINT screenPos = MousePositionToScreen(msg); // Is the POINT inside the Popup window rectangle if ((screenPos.x >= _currentPoint.X) && (screenPos.x <= (_currentPoint.X + localWidth)) && (screenPos.y >= _currentPoint.Y) && (screenPos.y <= (_currentPoint.Y + localHeight))) { OnWM_MOUSEMOVE(screenPos.x, screenPos.y); } else { // Do we still think the mouse is over our window? if (_mouseOver) { // Process mouse leaving situation OnWM_MOUSELEAVE(); } // Let the parent chain of PopupMenu's decide if they want it PopupMenu target = ParentPopupMenuWantsMouseMessage(screenPos, ref msg); if (target != null) { // Let parent target process the message target.OnWM_MOUSEMOVE(screenPos.x, screenPos.y); } else { if (ParentControlWantsMouseMessage(screenPos, ref msg)) { // Let the MenuControl do its business _parentControl.OnWM_MOUSEMOVE(screenPos); } } } // Eat the message to prevent the intended destination getting it eatMessage = true; } if (msg.message == (int)Win32.Msgs.WM_SETCURSOR) { OnWM_SETCURSOR(); // Eat the message to prevent the intended destination getting it eatMessage = true; } // Was the alt key pressed? if (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN) { // Alt key pressed on its own if((int)msg.wParam == (int)Win32.VirtualKeys.VK_MENU) // ALT key { // Then we should dimiss ourself _exitLoop = true; } else { // Pretend it is a normal keypress for processing msg.message = (int)Win32.Msgs.WM_KEYDOWN; } } // Was a non-alt key pressed? if (msg.message == (int)Win32.Msgs.WM_KEYDOWN) { switch((int)msg.wParam) { case (int)Win32.VirtualKeys.VK_UP: ProcessKeyUp(); break; case (int)Win32.VirtualKeys.VK_DOWN: ProcessKeyDown(); break; case (int)Win32.VirtualKeys.VK_LEFT: ProcessKeyLeft(); break; case (int)Win32.VirtualKeys.VK_RIGHT: if(ProcessKeyRight()) { // Do not attempt to pull a message off the queue as the // ProcessKeyRight has eaten the message for us leaveMsg = true; } break; case (int)Win32.VirtualKeys.VK_RETURN: // Is an item currently selected if (_trackItem != -1) { DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; // Does this item have a submenu? if (dc.SubMenu) { // Handle the submenu OperateSubMenu(_trackItem, false); // Do not attempt to pull a message off the queue as it has already // been eaten by us in the above code leaveMsg = true; } else { // Is this item the expansion command? if (dc.Expansion) { RegenerateExpansion(); } else { // Define the selection to return to caller _returnCommand = dc.MenuCommand; // Finish processing messages _exitLoop = true; } } } break; case (int)Win32.VirtualKeys.VK_ESCAPE: // User wants to exit the menu, so set the flag to exit the message loop but // let the message get processed. This way the key press is thrown away. _exitLoop = true; break; default: // Any other key is treated as a possible mnemonic int selectItem = ProcessMnemonicKey((char)msg.wParam); if (selectItem != -1) { DrawCommand dc = _drawCommands[selectItem] as DrawCommand; // Define the selection to return to caller _returnCommand = dc.MenuCommand; // Finish processing messages _exitLoop = true; // Do not attempt to pull a message off the queue as it has already // been eaten by us in the above code leaveMsg = true; } break; } } // We consume all keyboard input if ((msg.message == (int)Win32.Msgs.WM_KEYDOWN) || (msg.message == (int)Win32.Msgs.WM_KEYUP) || (msg.message == (int)Win32.Msgs.WM_SYSKEYDOWN) || (msg.message == (int)Win32.Msgs.WM_SYSKEYUP)) { // Eat the message to prevent the intended destination getting it eatMessage = true; } // Should the message be eaten to prevent intended destination getting it? if (eatMessage) { Win32.MSG eat = new Win32.MSG(); User32.GetMessage(ref eat, 0, 0, 0); } else { // Should the message we pulled from the queue? if (!leaveMsg) { if (User32.GetMessage(ref msg, 0, 0, 0)) { User32.TranslateMessage(ref msg); User32.DispatchMessage(ref msg); } } else leaveMsg = false; } } } } // If caret was hidden then show it again now if (hideCaret) User32.ShowCaret(IntPtr.Zero); // Remove tracking of any item, this ensure 'Deselected' event is generated if required SwitchSelection(_trackItem, -1, false, false); // Hide the window from view before killing it, as sometimes there is a // short delay between killing it and it disappearing because of the time // it takes for the destroy messages to get processed HideMenuWindow(); // Commit suicide DestroyHandle(); // Was a command actually selected in a top level PopupMenu AND we // are not here at the request of a MenuControl if ((_parentMenu == null) && (_returnCommand != null) && (_parentControl == null)) { // Pulse the selected event for the command _returnCommand.OnClick(EventArgs.Empty); } return _returnCommand; }
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; _excludeTop = true; _popupRight = true; _parentMenu = null; _excludeOffset = 0; _parentControl = null; _returnCommand = null; _controlLBrush = null; _controlEBrush = null; _controlLLBrush = null; _highlightInfrequent = false; _showInfrequent = false; _style = VisualStyle.IDE; _rememberExpansion = true; _lastMousePos = new Point(-1,-1); _direction = Direction.Horizontal; _textFont = SystemInformation.MenuFont; // Animation details _animateTime = 100; _animate = Animate.System; _animateStyle = Animation.System; _animateFirst = true; _animateIn = true; // Create and initialise the timer object (but do not start it running!) _timer = new Timer(); _timer.Interval = _selectionDelay; _timer.Tick += new EventHandler(OnTimerExpire); // Define default colors _textColor = SystemColors.MenuText; _highlightTextColor = SystemColors.HighlightText; DefineHighlightColors(SystemColors.Highlight); DefineColors(SystemColors.Control); }
public virtual void OnSelected(MenuCommand mc) { // Any attached event handlers? if (Selected != null) Selected(mc); }
protected void Recalculate() { int length; if (_direction == Direction.Horizontal) length = this.Width; else length = this.Height; // Is there space for any commands? if (length > 0) { // Count the number of rows needed int rows = 0; // Number of items on this row int columns = 0; // Create a collection of drawing objects _drawCommands = new ArrayList(); // Minimum length is a gap on either side of the text int cellMinLength = _lengthGap * 2; // Each cell is as broad as the whole control int cellBreadth = this.Height; // Accumulate starting position of each cell int lengthStart = 0; // Allow enough space to draw a chevron length -= (cellMinLength + _chevronLength); bool showPendant = ((rows == 0) && (_activeChild != null)); // If we are showing on a single line but the active child is not // currently maximized then we can show a menu item in pendant space if (showPendant && !_multiLine && (_activeChild.WindowState != FormWindowState.Maximized)) showPendant = false; // Pendant positioning information int xPos = 0; int yPos = 0; int xInc = 0; int yInc = 0; // First line needs extra space for pendant if (showPendant) { length -= (_pendantLength + _pendantOffset + _shadowGap); bool popupStyle = (_style == VisualStyle.IDE); int borderWidth = (_style == VisualStyle.IDE) ? 1 : 2; // Define the correct visual style _minButton.PopupStyle = popupStyle; _restoreButton.PopupStyle = popupStyle; _closeButton.PopupStyle = popupStyle; // Define correct border width _minButton.BorderWidth = borderWidth; _restoreButton.BorderWidth = borderWidth; _closeButton.BorderWidth = borderWidth; if (_direction == Direction.Horizontal) { xPos = this.Width - _pendantOffset - _buttonLength; yPos = _pendantOffset; xInc = -_buttonLength; } else { xPos = _pendantOffset; yPos = this.Height - _pendantOffset - _buttonLength; yInc = -_buttonLength; } } // Assume chevron is not needed by default _chevronStartCommand = null; using(Graphics g = this.CreateGraphics()) { // Count the item we are processing int index = 0; foreach(MenuCommand command in _menuCommands) { // Give the command a chance to update its state command.OnUpdate(EventArgs.Empty); // Ignore items that are marked as hidden if (!command.Visible) continue; int cellLength = 0; // Is this a separator? if (command.Text == "-") cellLength = _separatorWidth; else { // Calculate the text width of the cell SizeF dimension = g.MeasureString(command.Text, this.Font); // Always add 1 to ensure that rounding is up and not down cellLength = cellMinLength + (int)dimension.Width + 1; } Rectangle cellRect; // Create a new position rectangle if (_direction == Direction.Horizontal) cellRect = new Rectangle(lengthStart, _rowHeight * rows, cellLength, _rowHeight); else cellRect = new Rectangle(_rowWidth * rows, lengthStart, _rowWidth, cellLength); lengthStart += cellLength; columns++; // If this item is overlapping the control edge and it is not the first // item on the line then we should wrap around to the next row. if ((lengthStart > length) && (columns > 1)) { if (_multiLine) { // Move to next row rows++; // Reset number of items on this column columns = 1; // Reset starting position of next item lengthStart = cellLength; // Reset position of this item if (_direction == Direction.Horizontal) { cellRect.X = 0; cellRect.Y += _rowHeight; } else { cellRect.X += _rowWidth; cellRect.Y = 0; } // Only the first line needs extra space for pendant if (showPendant && (rows == 1)) length += (_pendantLength + _pendantOffset); } else { // Is a tracked item being make invisible if (index <= _trackItem) { // Need to remove tracking of this item RemoveItemTracking(); } // Remember which item is first for the chevron submenu _chevronStartCommand = command; if (_direction == Direction.Horizontal) { cellRect.Y = 0; cellRect.Width = cellMinLength + _chevronLength; cellRect.X = this.Width - cellRect.Width; cellRect.Height = _rowHeight; xPos -= cellRect.Width; } else { cellRect.X = 0; cellRect.Height = cellMinLength + _chevronLength; cellRect.Y = this.Height - (cellMinLength + _chevronLength); cellRect.Width = _rowWidth; yPos -= cellRect.Height; } // Create a draw command for this chevron _drawCommands.Add(new DrawCommand(cellRect)); // Exit, do not add the current item or any afterwards break; } } Rectangle selectRect = cellRect; // Selection rectangle differs from drawing rectangle with IDE, because pressing the // mouse down causes the menu to appear and because the popup menu appears drawn slightly // over the drawing area the mouse up might select the first item in the popup. if (_style == VisualStyle.IDE) { // Modify depending on orientation if (_direction == Direction.Horizontal) selectRect.Height -= (_lengthGap + 2); else selectRect.Width -= _breadthGap; } // Create a drawing object _drawCommands.Add(new DrawCommand(command, cellRect, selectRect)); index++; } } // Position the pendant buttons if (showPendant) { if (_activeChild.WindowState == FormWindowState.Maximized) { // Window maximzied, must show the buttons if (!_minButton.Visible) { _minButton.Show(); _restoreButton.Show(); _closeButton.Show(); } // Only enabled minimize box if child is allowed to be minimized _minButton.Enabled = _activeChild.MinimizeBox; _closeButton.Location = new Point(xPos, yPos); xPos += xInc; yPos += yInc; _restoreButton.Location = new Point(xPos, yPos); xPos += xInc; yPos += yInc; _minButton.Location = new Point(xPos, yPos); } else { // No window is maximized, so hide the buttons if (_minButton.Visible) { _minButton.Hide(); _restoreButton.Hide(); _closeButton.Hide(); } } } else { // No window is maximized, so hide the buttons if ((_minButton != null) && _minButton.Visible) { _minButton.Hide(); _restoreButton.Hide(); _closeButton.Hide(); } } if (_direction == Direction.Horizontal) { int controlHeight = (rows + 1) * _rowHeight; // Ensure the control is the correct height if (this.Height != controlHeight) this.Height = controlHeight; } else { int controlWidth = (rows + 1) * _rowWidth; // Ensure the control is the correct width if (this.Width != controlWidth) this.Width = controlWidth; } } }
protected bool ProcessKeyRight() { // Are we the first submenu of a parent control? bool autoRight = (_parentControl != null); bool checkKeys = false; bool ret = false; // Is an item currently selected? if (_trackItem != -1) { DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; // Does this item have a submenu? if (dc.SubMenu) { // Handle the submenu OperateSubMenu(_trackItem, true); ret = true; } else { // Grab the current column/row values int col = dc.Col; int row = dc.Row; // If not in the first column then move left one int newItem = -1; int newRow = -1; int findCol = col + 1; DrawCommand newDc = null; for(int i=0; i<_drawCommands.Count; i++) { DrawCommand listDc = _drawCommands[i] as DrawCommand; // Interesting in cells in the required column if (listDc.Col == findCol) { // Is this Row nearer to the one required than those found so far? if ((listDc.Row <= row) && (listDc.Row > newRow) && !listDc.Separator && listDc.Enabled) { // Remember this item newRow = listDc.Row; newDc = listDc; newItem = i; } } } if (newDc != null) { // Track the new item // Modify the display of the two items SwitchSelection(_trackItem, newItem, false, false); } else checkKeys = true; } } else { if (_parentMenu != null) { if (!ProcessKeyDown()) checkKeys = true; } else checkKeys = true; } // If we have a parent control and nothing to move right into if (autoRight && checkKeys) { _returnCommand = null; // Finish processing messages _timer.Stop(); _exitLoop = true; _returnDir = 1; } return ret; }
protected void OnWM_YBUTTONUP(int xPos, int yPos) { // Convert from screen to client coordinates xPos -= _currentPoint.X; yPos -= _currentPoint.Y; Point pos = new Point(xPos, yPos); for(int i=0; i<_drawCommands.Count; i++) { DrawCommand dc = _drawCommands[i] as DrawCommand; if (dc.DrawRect.Contains(pos)) { // Is there a change in selected item? if (_trackItem != i) { // Modify the display of the two items SwitchSelection(_trackItem, i, false, false); } } } // Is an item selected? if (_trackItem != -1) { DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; // Does this item have a submenu? if (dc.SubMenu) { // If we are not already showing this submenu... if (_popupItem != _trackItem) { // Is a submenu for a different item showing? if (_childMenu != null) { // Inform the child menu it is no longer needed User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); } // Handle the submenu OperateSubMenu(_trackItem, false); } } else { if (dc.Expansion) RegenerateExpansion(); else { // Kill any child menus open if (_childMenu != null) { // Inform the child menu it is no longer needed User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); } // Define the selection to return to caller _returnCommand = dc.MenuCommand; // Finish processing messages _timer.Stop(); _exitLoop = true; } } } }
public void Insert(int index, MenuCommand value) { // Use base class to process actual collection operation base.List.Insert(index, value as object); }
public int IndexOf(MenuCommand value) { // Find the 0 based index of the requested entry return base.List.IndexOf(value); }
public bool Contains(MenuCommand value) { // Use base class to process actual collection operation return base.List.Contains(value as object); }
public void AddRange(MenuCommand[] values) { // Use existing method to add each array entry foreach(MenuCommand page in values) Add(page); }
public DrawCommand(MenuCommand command, Rectangle drawRect, int row, int col) { InternalConstruct(command, drawRect, drawRect, row, col); }
public DrawCommand(MenuCommand command, Rectangle drawRect, Rectangle selectRect) { InternalConstruct(command, drawRect, selectRect, -1, -1); }
protected void OnWM_DISMISS() { // Pass on to any child menu of ours if (_childMenu != null) { // Inform the child menu it is no longer needed User32.PostMessage(_childMenu.Handle, WM_DISMISS, 0, 0); } // Define the selection to return to caller _returnCommand = null; // Finish processing messages _timer.Stop(); _exitLoop = true; // Hide ourself HideMenuWindow(); // Kill ourself DestroyHandle(); }
public void Remove(MenuCommand value) { // Use base class to process actual collection operation base.List.Remove(value as object); }
protected void OnWM_OPERATE_SUBMENU(ref Message m) { int popupItem = (int)m.WParam; bool selectFirst = (m.LParam != IntPtr.Zero); _popupItem = popupItem; _childMenu = new PopupMenu(); DrawCommand dc = _drawCommands[popupItem] as DrawCommand; // Find screen coordinate of Top right of item cell Win32.POINT screenPosTR; screenPosTR.x = dc.DrawRect.Right; screenPosTR.y = dc.DrawRect.Top; User32.ClientToScreen(this.Handle, ref screenPosTR); // Find screen coordinate of top left of item cell Win32.POINT screenPosTL; screenPosTL.x = dc.DrawRect.Left; screenPosTL.y = dc.DrawRect.Top; User32.ClientToScreen(this.Handle, ref screenPosTL); // Ensure the child has the same properties as ourself _childMenu.Style = this.Style; _childMenu.Font = this.Font; _childMenu.BackColor = this.BackColor; _childMenu.TextColor = this.TextColor; _childMenu.HighlightTextColor = this.HighlightTextColor; _childMenu.HighlightColor = this.HighlightColor; _childMenu.Animate = this.Animate; _childMenu.AnimateStyle = this.AnimateStyle; _childMenu.AnimateTime = this.AnimateTime; // Record keyboard direction int returnDir = 0; // Propogate the remembering of expansion state _childMenu.RememberExpansion = _rememberExpansion; // Honour the collections request for showing infrequent items _childMenu._showInfrequent = dc.MenuCommand.MenuCommands.ShowInfrequent; // Propogate the highlight property _childMenu.HighlightInfrequent = _highlightInfrequent; // Generate event so that caller has chance to modify MenuCommand contents dc.MenuCommand.OnPopupStart(); _returnCommand = _childMenu.InternalTrackPopup(new Point(screenPosTR.x, screenPosTR.y), new Point(screenPosTL.x, screenPosTL.y), dc.MenuCommand.MenuCommands, this, selectFirst, _parentControl, _popupRight, _popupDown, _animateFirst, ref returnDir); // Generate event so that caller has chance to modify MenuCommand contents dc.MenuCommand.OnPopupEnd(); _popupItem = -1;; _childMenu = null; // Subsequent times a submenu is shown we do not want it to animate _animateFirst = false; if ((_returnCommand != null) || (returnDir != 0)) { // Finish processing messages _timer.Stop(); _exitLoop = true; _returnDir = returnDir; } }
public MenuControl() { // Set default values _trackItem = -1; _oldFocus = IntPtr.Zero; _minButton = null; _popupMenu = null; _activeChild = null; _closeButton = null; _controlLPen = null; _mdiContainer = null; _restoreButton = null; _controlLBrush = null; _chevronStartCommand = null; _animateFirst = true; _exitLoop = false; _selected = false; _multiLine = false; _mouseOver = false; _defaultFont = true; _manualFocus = false; _drawUpwards = false; _plainAsBlock = false; _clientSubclass = null; _ignoreMouseMove = false; _deselectReset = true; _expandAllTogether = true; _rememberExpansion = true; _highlightInfrequent = true; _dismissTransfer = false; _style = VisualStyle.IDE; _direction = Direction.Horizontal; _menuCommands = new MenuCommandCollection(); this.Dock = DockStyle.Top; this.Cursor = System.Windows.Forms.Cursors.Arrow; // Animation details _animateTime = 100; _animate = Animate.System; _animateStyle = Animation.System; // 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 CollectionClear(OnCollectionCleared); _menuCommands.Inserted += new CollectionChange(OnCollectionInserted); _menuCommands.Removed += new CollectionChange(OnCollectionRemoved); // Need notification when the MenuFont is changed Microsoft.Win32.SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnPreferenceChanged); DefineColors(); // Set the starting Font DefineFont(SystemInformation.MenuFont); // Do not allow tab key to select this control this.TabStop = false; // Default to one line of items this.Height = _rowHeight; // Add ourself to the application filtering list Application.AddMessageFilter(this); }
protected void ProcessKeyLeft() { // Are we the first submenu of a parent control? bool autoLeft = (_parentMenu != null) || (_parentControl != null); bool checkKeys = false; if (_trackItem != -1) { // Get the col this item is in DrawCommand dc = _drawCommands[_trackItem] as DrawCommand; // Grab the current column/row values int col = dc.Col; int row = dc.Row; // If not in the first column then move left one if (col > 0) { int newItem = -1; int newRow = -1; int findCol = col - 1; DrawCommand newDc = null; for(int i=0; i<_drawCommands.Count; i++) { DrawCommand listDc = _drawCommands[i] as DrawCommand; // Interested in cells in the required column if (listDc.Col == findCol) { // Is this Row nearer to the one required than those found so far? if ((listDc.Row <= row) && (listDc.Row > newRow) && !listDc.Separator && listDc.Enabled) { // Remember this item newRow = listDc.Row; newDc = listDc; newItem = i; } } } if (newDc != null) { // Track the new item // Modify the display of the two items SwitchSelection(_trackItem, newItem, false, false); } else checkKeys = true; } else checkKeys = true; } else { if (_parentMenu != null) { if (!ProcessKeyUp()) checkKeys = true; } else checkKeys = true; } // If we have a parent control and nothing to move right into if (autoLeft && checkKeys) { _returnCommand = null; // Finish processing messages _timer.Stop(); _exitLoop = true; // Only a top level PopupMenu should cause the MenuControl to select the // next left menu command. A submenu should just become dismissed. if (_parentMenu == null) _returnDir = -1; } }
protected void OnCommandChanged(MenuCommand item, MenuCommand.Property prop) { Recalculate(); Invalidate(); }
public virtual void OnSelected(MenuCommand mc) { // If initiated by a MenuControl item then let the control handle this if (_parentControl != null) _parentControl.OnSelected(mc); else { // If we have an event defined then fire it if (Selected != null) Selected(mc); else { // Maybe our parent has an event defined instead if (_parentMenu != null) _parentMenu.OnSelected(mc); } } }
public void InternalConstruct(MenuCommand command, Rectangle drawRect, Rectangle selectRect, int row, int col) { _row = row; _col = col; _enabled = command.Enabled; _expansion = false; _vertSeparator = false; _drawRect = drawRect; _selectRect = selectRect; _command = command; _topBorder = false; _bottomBorder = false; _infrequent = command.Infrequent; _chevron = false; // Is this MenuCommand a separator? _separator = (_command.Text == "-"); // Does this MenuCommand contain a submenu? _subMenu = (_command.MenuCommands.Count > 0); // Find position of first mnemonic character int position = -1; if (command.Text != null) position = command.Text.IndexOf('&'); // Did we find a mnemonic indicator? if (position != -1) { // Must be a character after the indicator if (position < (command.Text.Length - 1)) { // Remember the character _mnemonic = char.ToUpper(command.Text[position + 1]); } } }