ToolStrip.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / ToolStrip.cs / 2 / ToolStrip.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

 
namespace System.Windows.Forms { 
    using System;
    using System.Configuration; 
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing; 
    using System.Windows.Forms;
    using System.Diagnostics; 
    using System.Runtime.InteropServices; 
    using System.Security.Permissions;
    using System.Threading; 
    using System.Windows.Forms.Layout;
    using System.ComponentModel.Design.Serialization;
    using System.Drawing.Drawing2D;
    using System.Text.RegularExpressions; 
    using System.Text;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization; 
    using System.Windows.Forms.Internal;
    using Microsoft.Win32; 

    /// 
    /// 
    /// Summary of ToolStrip. 
    /// 
 
    [ComVisible(true)] 
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [DesignerSerializer("System.Windows.Forms.Design.ToolStripCodeDomSerializer, " + AssemblyRef.SystemDesign, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + AssemblyRef.SystemDesign)] 
    [Designer("System.Windows.Forms.Design.ToolStripDesigner, " + AssemblyRef.SystemDesign)]
    [DefaultProperty("Items")]
    [SRDescription(SR.DescriptionToolStrip)]
    [DefaultEvent("ItemClicked")] 

 
    public class ToolStrip : System.Windows.Forms.ScrollableControl, 
                             IArrangedElement,
                             ISupportToolStripPanel 
                              {


        private static  Size                    onePixel                = new Size(1,1); 
        internal static Point                   InvalidMouseEnter       = new Point(Int32.MaxValue, Int32.MaxValue);
 
        private ToolStripItemCollection        toolStripItemCollection    = null; 
        private ToolStripOverflowButton        toolStripOverflowButton    = null;
        private ToolStripGrip                  toolStripGrip              = null; 
        private ToolStripItemCollection        displayedItems          = null;
        private ToolStripItemCollection        overflowItems           = null;
        private ToolStripDropTargetManager     dropTargetManager       = null;
        private IntPtr                         hwndThatLostFocus       = IntPtr.Zero; 
        private ToolStripItem                  lastMouseActiveItem     = null;
        private ToolStripItem                  lastMouseDownedItem     = null; 
        private LayoutEngine                   layoutEngine            = null; 
        private ToolStripLayoutStyle           layoutStyle             = ToolStripLayoutStyle.StackWithOverflow;
        private LayoutSettings                 layoutSettings          = null; 
        private Rectangle                      lastInsertionMarkRect   = Rectangle.Empty;
        private ImageList                      imageList               = null;
        private ToolStripGripStyle             toolStripGripStyle      = ToolStripGripStyle.Visible;
        private ISupportOleDropSource          itemReorderDropSource   = null; 
        private IDropTarget                    itemReorderDropTarget   = null;
        private int                            toolStripState          = 0; 
        private bool                           showItemToolTips        = false; 
        private MouseHoverTimer                mouseHoverTimer         = null;
        private ToolStripItem                  currentlyActiveTooltipItem; 
        private NativeWindow                   dropDownOwnerWindow;
        private byte                           mouseDownID             = 0;  // NEVER use this directly from another class, 0 should never be returned to another class.

        private Orientation                    orientation              = Orientation.Horizontal; 

        private ArrayList                      activeDropDowns          = new ArrayList(1); 
        private ToolStripRenderer              renderer                 = null; 
        private Type                           currentRendererType      = typeof(System.Type);
        private Hashtable                      shortcuts                = null; 
        private Stack            mergeHistoryStack        = null;
        private ToolStripDropDownDirection     toolStripDropDownDirection = ToolStripDropDownDirection.Default;
        private Size                           largestDisplayedItemSize  = Size.Empty;
        private CachedItemHdcInfo              cachedItemHdcInfo             = null; 
        private bool                           alreadyHooked  = false;
 
        private Size                           imageScalingSize         = new Size(16,16); 

        private Font                           defaultFont              = null; 
        private RestoreFocusMessageFilter             restoreFocusFilter;

        private bool                           layoutRequired = false;
 

 
        private Point                          mouseEnterWhenShown      = InvalidMouseEnter; 

        internal const int                     INSERTION_BEAM_WIDTH     = 6; 


        private static readonly object EventPaintGrip                = new object();
        private static readonly object EventLayoutCompleted          = new object(); 
        private static readonly object EventItemAdded                = new object();
        private static readonly object EventItemRemoved              = new object(); 
        private static readonly object EventLayoutStyleChanged       = new object(); 
        private static readonly object EventRendererChanged          = new object();
        private static readonly object EventItemClicked              = new object(); 
        private static readonly object EventLocationChanging         = new object();
        private static readonly object EventBeginDrag                = new object();
        private static readonly object EventEndDrag                  = new object();
 
        private static readonly int PropBindingContext                 = PropertyStore.CreateKey();
        private static readonly int PropTextDirection                  = PropertyStore.CreateKey(); 
        private static readonly int PropToolTip                        = PropertyStore.CreateKey(); 
        private static readonly int PropToolStripPanelCell             = PropertyStore.CreateKey();
 
        internal const int STATE_CANOVERFLOW            = 0x00000001;
        internal const int STATE_ALLOWITEMREORDER       = 0x00000002;
        internal const int STATE_DISPOSINGITEMS         = 0x00000004;
        internal const int STATE_MENUAUTOEXPAND         = 0x00000008; 
        internal const int STATE_MENUAUTOEXPANDDEFAULT  = 0x00000010;
        internal const int STATE_SCROLLBUTTONS          = 0x00000020; 
        internal const int STATE_USEDEFAULTRENDERER     = 0x00000040; 
        internal const int STATE_ALLOWMERGE             = 0x00000080;
        internal const int STATE_RAFTING                = 0x00000100; 
        internal const int STATE_STRETCH                = 0x00000200;
        internal const int STATE_LOCATIONCHANGING       = 0x00000400;
        internal const int STATE_DRAGGING               = 0x00000800;
        internal const int STATE_HASVISIBLEITEMS        = 0x00001000; 
        internal const int STATE_SUSPENDCAPTURE         = 0x00002000;
        internal const int STATE_LASTMOUSEDOWNEDITEMCAPTURE = 0x00004000; 
        internal const int STATE_MENUACTIVE             = 0x00008000; 

 
#if DEBUG
        internal static readonly TraceSwitch SelectionDebug = new TraceSwitch("SelectionDebug", "Debug ToolStrip Selection code");
        internal static readonly TraceSwitch DropTargetDebug = new TraceSwitch("DropTargetDebug", "Debug ToolStrip Drop code");
        internal static readonly TraceSwitch LayoutDebugSwitch = new TraceSwitch("Layout debug", "Debug ToolStrip layout code"); 
        internal static readonly TraceSwitch MouseActivateDebug = new TraceSwitch("ToolStripMouseActivate", "Debug ToolStrip WM_MOUSEACTIVATE code");
        internal static readonly TraceSwitch MergeDebug = new TraceSwitch("ToolStripMergeDebug", "Debug toolstrip merging"); 
        internal static readonly TraceSwitch SnapFocusDebug = new TraceSwitch("SnapFocus", "Debug snapping/restoration of focus"); 
        internal static readonly TraceSwitch FlickerDebug = new TraceSwitch("FlickerDebug", "Debug excessive calls to Invalidate()");
        internal static readonly TraceSwitch ItemReorderDebug = new TraceSwitch("ItemReorderDebug", "Debug excessive calls to Invalidate()"); 
        internal static readonly TraceSwitch MDIMergeDebug = new TraceSwitch("MDIMergeDebug", "Debug toolstrip MDI merging");
        internal static readonly TraceSwitch MenuAutoExpandDebug = new TraceSwitch("MenuAutoExpand", "Debug menu auto expand");
        internal static readonly TraceSwitch ControlTabDebug = new TraceSwitch("ControlTab", "Debug ToolStrip Control+Tab selection");
#else 
        internal static readonly TraceSwitch SelectionDebug;
        internal static readonly TraceSwitch DropTargetDebug; 
        internal static readonly TraceSwitch LayoutDebugSwitch; 
        internal static readonly TraceSwitch MouseActivateDebug;
        internal static readonly TraceSwitch MergeDebug; 
        internal static readonly TraceSwitch SnapFocusDebug;
        internal static readonly TraceSwitch FlickerDebug;
        internal static readonly TraceSwitch ItemReorderDebug;
        internal static readonly TraceSwitch MDIMergeDebug; 
        internal static readonly TraceSwitch MenuAutoExpandDebug;
        internal static readonly TraceSwitch ControlTabDebug; 
#endif 

        private delegate void BooleanMethodInvoker(bool arg); 

        /// 
        /// 
        /// Summary of ToolStrip. 
        /// 
        public ToolStrip() { 
 
            SuspendLayout();
            this.CanOverflow = true; 
            this.TabStop = false;
            this.MenuAutoExpand = false;
            SetStyle(ControlStyles.OptimizedDoubleBuffer |
                     ControlStyles.AllPaintingInWmPaint  | 
                     ControlStyles.SupportsTransparentBackColor, true);
 
            SetStyle(ControlStyles.Selectable, false); 
            SetToolStripState(STATE_USEDEFAULTRENDERER | STATE_ALLOWMERGE, true);
 
            SetState2(STATE2_MAINTAINSOWNCAPTUREMODE // VSWhidbey 458967: a toolstrip does not take capture on MouseDown.
                      | STATE2_USEPREFERREDSIZECACHE, // this class overrides GetPreferredSizeCore, let Control automatically cache the result
                       true);
 
            //add a weak ref link in ToolstripManager
            ToolStripManager.ToolStrips.Add(this); 
 
            layoutEngine = new ToolStripSplitStackLayout(this);
            this.Dock = DefaultDock; 
            this.AutoSize = true;
            this.CausesValidation = false;
            Size defaultSize = DefaultSize;
            SetAutoSizeMode(AutoSizeMode.GrowAndShrink); 
            this.ShowItemToolTips = DefaultShowItemToolTips;
            ResumeLayout(true); 
 
        }
 
        public ToolStrip(params ToolStripItem[] items) : this() {
            Items.AddRange(items);
        }
 
        internal ArrayList ActiveDropDowns {
            get { return activeDropDowns; } 
        } 

        // returns true when entered into menu mode through this toolstrip/menustrip 
        // this is only really supported for menustrip active event, but to prevent casting everywhere...
        internal virtual bool KeyboardActive {
            get { return GetToolStripState(STATE_MENUACTIVE); }
            set { SetToolStripState(STATE_MENUACTIVE, value);} 
        }
 
        // This is only for use in determining whether to show scroll bars on 
        // ToolStripDropDownMenus.  No one else should be using it for anything.
        internal virtual bool AllItemsVisible { 
            get {
                return true;
            }
            set { 
                // we do nothing in repsonse to a set, since we calculate the value above.
            } 
        } 

        [DefaultValue(true), Browsable(true), EditorBrowsable(EditorBrowsableState.Always), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)
        ]
        public override bool AutoSize {
            get { 
                return base.AutoSize;
            } 
            set { 
                if (IsInToolStripPanel && base.AutoSize && !value) {
                    // VSWhidbey 351717 - restoring the bounds can change the location of the toolstrip - 
                    // which would join it to a new row.  Set the specified bounds to the new location to
                    // prevent this.
                    Rectangle bounds = CommonProperties.GetSpecifiedBounds(this);
                    bounds.Location = this.Location; 
                    CommonProperties.UpdateSpecifiedBounds(this, bounds.X, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.Location);
 
                } 
                base.AutoSize = value;
            } 
        }

        /// 
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.ControlOnAutoSizeChangedDescr)] 
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        new public event EventHandler AutoSizeChanged 
        { 
            add
            { 
                base.AutoSizeChanged += value;
            }
            remove
            { 
                base.AutoSizeChanged -= value;
            } 
        } 

 
        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public override bool AutoScroll { 
            get { 
                return base.AutoScroll;
            } 
            set {
                throw new NotSupportedException(SR.GetString(SR.ToolStripDoesntSupportAutoScroll));
            }
        } 

        [ 
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public new Size AutoScrollMargin {
            get {
                return base.AutoScrollMargin; 
            }
            set { 
                base.AutoScrollMargin = value; 
            }
        } 

        [
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public new Size AutoScrollMinSize { 
            get {
                return base.AutoScrollMinSize; 
            }
            set {
                base.AutoScrollMinSize = value;
            } 
        }
 
        [ 
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public new Point AutoScrollPosition {
            get { 
                return base.AutoScrollPosition;
            } 
            set { 
                base.AutoScrollPosition = value;
            } 
        }

        /// 
        ///  
        /// Summary of AllowDrop.
        ///  
        public override bool AllowDrop { 
            get {
                return base.AllowDrop; 
            }
            set {
                if (value && AllowItemReorder) {
                    throw new ArgumentException(SR.GetString(SR.ToolStripAllowItemReorderAndAllowDropCannotBeSetToTrue)); 
                }
 
                base.AllowDrop = value; 

                // SECREVIEW:  If we toggle between AllowDrop and AllowItemReorder 
                // make sure that we're demanding the Clipboard permission in
                // ToolStripDropTargetManager.SetAcceptDrops
                if (value)  {
                     this.DropTargetManager.EnsureRegistered(this); 
                }
                else { 
                     this.DropTargetManager.EnsureUnRegistered(this); 
                }
 
            }
        }
        /// 
        ///  
        ///
        ///  
        [ 
        DefaultValue(false),
        SRDescription(SR.ToolStripAllowItemReorderDescr), 
        SRCategory(SR.CatBehavior)
        ]
        public bool AllowItemReorder {
            get { return GetToolStripState(STATE_ALLOWITEMREORDER); } 
            set {
                if (GetToolStripState(STATE_ALLOWITEMREORDER) != value) { 
                    if (AllowDrop && value) { 
                        throw new ArgumentException(SR.GetString(SR.ToolStripAllowItemReorderAndAllowDropCannotBeSetToTrue));
                    } 
                    SetToolStripState(STATE_ALLOWITEMREORDER, value);

                    // SECREVIEW:  If we toggle between AllowDrop and AllowItemReorder
                    // make sure that we're demanding the Clipboard permission in 
                    // ToolStripDropTargetManager.SetAcceptDrops
                    if (value)  { 
                        ToolStripSplitStackDragDropHandler dragDropHandler = new ToolStripSplitStackDragDropHandler(this); 
                        this.ItemReorderDropSource =  dragDropHandler;
                        this.ItemReorderDropTarget =  dragDropHandler; 

                        this.DropTargetManager.EnsureRegistered(this);
                    }
                    else { 
                         this.DropTargetManager.EnsureUnRegistered(this);
                    } 
 
                }
 


            }
        } 

        ///  
        ///  
        ///
        ///  
        [
        DefaultValue(true),
        SRDescription(SR.ToolStripAllowMergeDescr),
        SRCategory(SR.CatBehavior) 
        ]
        public bool AllowMerge { 
            get { return GetToolStripState(STATE_ALLOWMERGE); } 
            set {
                if (GetToolStripState(STATE_ALLOWMERGE) != value) { 
                    SetToolStripState(STATE_ALLOWMERGE, value);
                }
            }
        } 

 
        public override AnchorStyles Anchor { 
            get {
                return base.Anchor; 
            }
            set {
                // the base calls SetDock, which causes an OnDockChanged to be called
                // which forces two layouts of the parent. 
                using (new LayoutTransaction(this, this, PropertyNames.Anchor)) {
                    base.Anchor = value; 
                } 
            }
        } 

        /// 
        /// 
        ///  
        /// Just here so we can implement ShouldSerializeBackColor
        ///  
        [ 
        SRDescription(SR.ToolStripBackColorDescr),
        SRCategory(SR.CatAppearance) 
        ]
        public new Color BackColor {
            get {
                return base.BackColor; 
            }
            set { 
                base.BackColor = value; 
            }
        } 

        [SRCategory(SR.CatBehavior), SRDescription(SR.ToolStripOnBeginDrag)]
        public event EventHandler BeginDrag {
            add { 
                Events.AddHandler(EventBeginDrag, value);
            } 
            remove { 
                Events.RemoveHandler(EventBeginDrag, value);
            } 
        }

        /// 
        public override BindingContext BindingContext { 
            get {
                BindingContext bc = (BindingContext) this.Properties.GetObject(PropBindingContext); 
                if (bc != null) 
                    return bc;
 
                // try the parent
                //
                Control p = ParentInternal;
                if (p != null && p.CanAccessProperties) 
                    return p.BindingContext;
 
                // we don't have a binding context 
                return null;
            } 
            set {
                if (this.Properties.GetObject(PropBindingContext) != value) {
                    this.Properties.SetObject(PropBindingContext, value);
 
                    // re-wire the bindings
                    OnBindingContextChanged(EventArgs.Empty); 
                } 
            }
        } 



 
        /// 
        ///  
        /// Summary of CanOverflow. 
        /// 
        [ 
        DefaultValue(true),
        SRDescription(SR.ToolStripCanOverflowDescr),
        SRCategory(SR.CatLayout)
        ] 
        public bool CanOverflow {
            get { 
                return GetToolStripState(STATE_CANOVERFLOW); 
            }
            set { 
                if (GetToolStripState(STATE_CANOVERFLOW) != value) {
                    SetToolStripState(STATE_CANOVERFLOW, value);
                    InvalidateLayout();
                } 
            }
        } 
 
        /// we can only shift selection when we're not focused (someone mousing over us)
        ///         or we are focused and one of our toolstripcontrolhosts do not have focus. 
        ///         SCENARIO: put focus in combo box, move the mouse over another item... selectioni
        ///         should not shift until the combobox relinquishes its focus.
        ///
        internal bool CanHotTrack { 
            get {
                if (!Focused) { 
                    // if  ContainsFocus in one of the children = false, someone is just mousing by, we can hot track 
                    return (ContainsFocus == false);
                } 
                else {
                    // if the toolstrip itself contains focus we can definately hottrack.
                    return true;
                } 
            }
        } 
 

         [ 
         Browsable(false),
         DefaultValue(false),
         ]
         public new bool CausesValidation { 
             get {
                 // By default: CausesValidation is false for a ToolStrip 
                 // we want people to be able to use menus without validating 
                 // their controls.
                 return base.CausesValidation; 
             }
             set {
                 base.CausesValidation = value;
             } 
         }
 
        [Browsable(false)] 
        public new event EventHandler CausesValidationChanged {
            add { 
                base.CausesValidationChanged += value;
            }
            remove {
                base.CausesValidationChanged -= value; 
            }
        } 
 
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Control.ControlCollection Controls {
            get { return base.Controls; }
        } 

        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlAdded {
            add { 
                base.ControlAdded += value;
            }
            remove {
                base.ControlAdded -= value; 
            }
        } 
 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Cursor Cursor { 
            get { return base.Cursor; }
            set { base.Cursor = value; }
        }
 
        /// 
        ///    Hide browsable property 
        ///  
        [Browsable(false)]
        public new event EventHandler CursorChanged { 
            add {
                base.CursorChanged += value;
            }
            remove { 
                base.CursorChanged -= value;
            } 
        } 

        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event ControlEventHandler ControlRemoved {
             add {
                 base.ControlRemoved += value; 
             }
             remove { 
                 base.ControlRemoved -= value; 
             }
        } 

        [SRCategory(SR.CatBehavior), SRDescription(SR.ToolStripOnEndDrag)]
        public event EventHandler EndDrag {
            add { 
                Events.AddHandler(EventEndDrag, value);
            } 
            remove { 
                Events.RemoveHandler(EventEndDrag, value);
            } 
        }

        /// 
        public override Font Font { 
            get {
                if (this.IsFontSet()) { 
                    return base.Font; 
                }
                if (defaultFont == null) { 
                    // since toolstrip manager default font is thread static, hold onto a copy of the
                    // pointer in an instance variable for perf so we dont have to keep fishing into
                    // thread local storage for it.
                    defaultFont = ToolStripManager.DefaultFont; 
                }
                return defaultFont; 
            } 
            set {
                base.Font = value; 
            }
        }

        ///  
        /// 
        /// Deriving classes can override this to configure a default size for their control. 
        /// This is more efficient than setting the size in the control's constructor. 
        /// 
        protected override Size DefaultSize { 
            get {
                return new Size(100, 25);
            }
        } 

        protected override Padding DefaultPadding { 
            get { 
                // one pixel from the right edge to prevent the right border from painting over the
                // aligned-right toolstrip item. 
                return new Padding(0,0,1,0);
            }
        }
 
        protected override Padding DefaultMargin {
            get { return Padding.Empty; } 
        } 

        protected virtual DockStyle DefaultDock { 
            get {
                return DockStyle.Top;
            }
        } 

        protected virtual Padding DefaultGripMargin { 
            get { 
                if (toolStripGrip != null) {
                    return toolStripGrip.DefaultMargin; 
                }
                else {
                    return new Padding(2);
                } 
            }
        } 
 
        protected virtual bool DefaultShowItemToolTips {
            get { 
                return true;
            }
        }
 
        [Browsable(false)]
        [SRDescription(SR.ToolStripDefaultDropDownDirectionDescr)] 
        [SRCategory(SR.CatBehavior)] 
        public virtual ToolStripDropDownDirection DefaultDropDownDirection {
            get { 
                ToolStripDropDownDirection direction = toolStripDropDownDirection;
                if (direction == ToolStripDropDownDirection.Default) {
                    if (Orientation == Orientation.Vertical) {
                       if (IsInToolStripPanel) { 
                            // parent can be null when we're swapping between ToolStripPanels.
                            DockStyle actualDock = (ParentInternal != null) ? ParentInternal.Dock : DockStyle.Left; 
                            direction = (actualDock == DockStyle.Right) ? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right; 
                            if (DesignMode && actualDock == DockStyle.Left)
                            { 
                                direction = ToolStripDropDownDirection.Right ;
                            }

                       } 
                       else {
                            direction = ((Dock == DockStyle.Right) && (RightToLeft == RightToLeft.No)) ? ToolStripDropDownDirection.Left : ToolStripDropDownDirection.Right; 
                            if (DesignMode && Dock == DockStyle.Left) 
                            {
                                direction = ToolStripDropDownDirection.Right ; 
                            }
                       }
                    }
                    else  { // horizontal 
                       DockStyle dock = this.Dock;
                       if (IsInToolStripPanel && ParentInternal != null) { 
                            dock = ParentInternal.Dock;  // we want the orientation of the ToolStripPanel; 
                       }
 
                       if (dock == DockStyle.Bottom) {
                           direction = (RightToLeft == RightToLeft.Yes) ? ToolStripDropDownDirection.AboveLeft : ToolStripDropDownDirection.AboveRight;
                       }
                       else { 
                           // assume Dock.Top
                           direction = (RightToLeft == RightToLeft.Yes) ? ToolStripDropDownDirection.BelowLeft : ToolStripDropDownDirection.BelowRight; 
                       } 
                    }
                } 
                return direction;
            }
            set {
                // cant use Enum.IsValid as its not sequential 
                switch (value) {
                   case ToolStripDropDownDirection.AboveLeft: 
                   case ToolStripDropDownDirection.AboveRight: 
                   case ToolStripDropDownDirection.BelowLeft:
                   case ToolStripDropDownDirection.BelowRight: 
                   case ToolStripDropDownDirection.Left:
                   case ToolStripDropDownDirection.Right:
                   case ToolStripDropDownDirection.Default:
                      break; 
                   default:
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripDropDownDirection)); 
                } 

                toolStripDropDownDirection = value; 
            }
        }
        /// 
        ///  
        /// 
        /// Just here so we can add the default value attribute 
        ///  
        [DefaultValue(DockStyle.Top)]
        public override DockStyle Dock { 
            get {
                return base.Dock;
            }
            set { 
                if (value != Dock) {
                    using (new LayoutTransaction(this, this, PropertyNames.Dock)) 
                    using (new LayoutTransaction(this.ParentInternal, this, PropertyNames.Dock)) { 
                        // We don't call base.Dock = value, because that would cause us to get 2 LocationChanged events.
                        // The first is when the parent gets a Layout due to the DockChange, and the second comes from when we 
                        // change the orientation.  Instead we've duplicated the logic of Control.Dock.set here, but with a
                        // LayoutTransaction on the Parent as well.
                        // See VSWhidbey:489688 and VSWhidbey:474781 for more details.
                        DefaultLayout.SetDock(this, value); 
                        UpdateLayoutStyle(Dock);
                    } 
                    // This will cause the DockChanged event to fire. 
                    OnDockChanged(EventArgs.Empty);
                } 
            }
        }

        ///  
        ///     Returns an owner window that can be used to
        ///     own a drop down. 
        ///  
        internal virtual NativeWindow DropDownOwnerWindow {
            get { 
                if (dropDownOwnerWindow == null) {
                    dropDownOwnerWindow = new NativeWindow();
                }
 
                if (dropDownOwnerWindow.Handle == IntPtr.Zero) {
                    CreateParams cp = new CreateParams(); 
                    cp.ExStyle = NativeMethods.WS_EX_TOOLWINDOW; 
                    dropDownOwnerWindow.CreateHandle(cp);
                } 

                return dropDownOwnerWindow;
            }
        } 

        ///  
        /// Returns the drop target manager that all the hwndless 
        /// items and this winbar share.  this is necessary as
        /// RegisterDragDrop requires an HWND. 
        /// 
        internal ToolStripDropTargetManager DropTargetManager {
            get {
                if (dropTargetManager == null) { 
                    dropTargetManager = new ToolStripDropTargetManager(this);
                } 
                return dropTargetManager; 

            } 
            set {
                dropTargetManager = value;
            }
 
        }
        ///  
        ///  
        /// 
        /// Just here so we can add the default value attribute 
        /// 
        protected internal virtual ToolStripItemCollection DisplayedItems {
            get {
                if (displayedItems == null) { 
                    displayedItems = new ToolStripItemCollection(this, false);
                } 
                return displayedItems; 
            }
        } 


        /// 
        ///  
        /// 
        ///  
        /// Retreives the current display rectangle. The display rectangle 
        /// is the virtual display area that is used to layout components.
        /// The position and dimensions of the Form's display rectangle 
        /// change during autoScroll.
        /// 
        /// 
        public override Rectangle DisplayRectangle { 
            [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces")]
            get { 
                Rectangle rect = base.DisplayRectangle; 

                if ((LayoutEngine is ToolStripSplitStackLayout)  && (GripStyle == ToolStripGripStyle.Visible)){ 

                    if (Orientation == Orientation.Horizontal) {
                        int gripwidth =  Grip.GripThickness + Grip.Margin.Horizontal;
                        rect.Width -= gripwidth; 
                        // in RTL.No we need to shift the rectangle
                        rect.X += (RightToLeft == RightToLeft.No) ? gripwidth : 0; 
                    } 
                    else { // Vertical Grip placement
                        int gripheight =  Grip.GripThickness + Grip.Margin.Vertical; 
                        rect.Y += gripheight;
                        rect.Height -= gripheight;
                    }
 
                }
                return rect; 
            } 
        }
 
        /// 
        /// 
        /// 
        /// Forecolor really has no meaning for winbars - so lets hide it 
        /// 
        [Browsable(false)] 
        public new Color ForeColor { 
            get {
                return base.ForeColor; 
            }
            set {
                base.ForeColor = value;
            } 
        }
 
        ///  
        /// 
        ///    [ToolStrip ForeColorChanged event, overriden to turn browsing off.] 
        /// 
        [
        Browsable(false)
        ] 
        public new event EventHandler ForeColorChanged
        { 
            add 
            {
                base.ForeColorChanged += value; 
            }
            remove
            {
                base.ForeColorChanged -= value; 
            }
        } 
 
        private bool HasKeyboardInput {
            get { 
                return (ContainsFocus || (ToolStripManager.ModalMenuFilter.InMenuMode && ToolStripManager.ModalMenuFilter.GetActiveToolStrip() == this));
            }
        }
 
        /// 
        /// Summary of ToolStripGrip. 
        ///  
        /// 
        internal ToolStripGrip Grip { 
            get {
                if (toolStripGrip == null) {
                    toolStripGrip = new ToolStripGrip();
                    toolStripGrip.Overflow = ToolStripItemOverflow.Never; 
                    toolStripGrip.Visible = toolStripGripStyle ==ToolStripGripStyle.Visible;
                    toolStripGrip.AutoSize = false; 
                    toolStripGrip.ParentInternal = this; 
                    toolStripGrip.Margin = DefaultGripMargin;
                } 
                return toolStripGrip;
            }
        }
        ///  
        /// 
        /// Summary of GripStyle. 
        ///  
        [
        SRCategory(SR.CatAppearance), 
        SRDescription(SR.ToolStripGripStyleDescr),
        DefaultValue(ToolStripGripStyle.Visible)
        ]
        public ToolStripGripStyle GripStyle { 
            get {
                return toolStripGripStyle; 
            } 
            set {
                //valid values are 0x0 to 0x1 
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolStripGripStyle.Hidden, (int)ToolStripGripStyle.Visible)){
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripGripStyle));
                }
                if (toolStripGripStyle != value) { 
                    toolStripGripStyle = value;
                    Grip.Visible = toolStripGripStyle ==ToolStripGripStyle.Visible; 
                    LayoutTransaction.DoLayout(this, this, PropertyNames.GripStyle); 
                }
            } 

        }

        ///  
        /// 
        /// Summary of GripStyle. 
        ///  
        [
        Browsable(false) 
        ]
        public ToolStripGripDisplayStyle GripDisplayStyle {
            get {
                return (LayoutStyle == ToolStripLayoutStyle.HorizontalStackWithOverflow) ? ToolStripGripDisplayStyle.Vertical 
                                                                     : ToolStripGripDisplayStyle.Horizontal;
            } 
        } 

        ///  
        /// 
        /// The external spacing between the grip and the padding of the winbar and the first item in the collection
        /// 
        [ 
        SRCategory(SR.CatLayout),
        SRDescription(SR.ToolStripGripDisplayStyleDescr) 
        ] 
        public Padding GripMargin {
            get { 
                return Grip.Margin;
            }
            set {
                Grip.Margin = value; 
            }
        } 
 
        /// 
        ///  
        /// The boundaries of the grip on the winbar.  If it is invisible - returns Rectangle.Empty.
        /// 
        [
        Browsable(false) 
        ]
        public Rectangle GripRectangle { 
            get { 
                return (GripStyle == ToolStripGripStyle.Visible) ? Grip.Bounds : Rectangle.Empty;
            } 
        }

        [
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public new bool HasChildren { 
            get {
                return base.HasChildren; 
            }
        }

        internal bool HasVisibleItems { 
            get {
                if (!IsHandleCreated) { 
                    foreach(ToolStripItem item in Items) { 
                        if (((IArrangedElement)item).ParticipatesInLayout) {
                            // set in the state so that when the handle is created, we're accurate. 
                            SetToolStripState(STATE_HASVISIBLEITEMS, true);
                            return true;
                        }
                    } 
                    SetToolStripState(STATE_HASVISIBLEITEMS, false);
                    return false; 
                } 
                // after the handle is created, we start layout... so this state is cached.
                return GetToolStripState(STATE_HASVISIBLEITEMS); 
            }
            set {
                SetToolStripState(STATE_HASVISIBLEITEMS, value);
            } 
        }
 
        ///  
        /// 
        ///    Gets the Horizontal Scroll bar for this ScrollableControl. 
        /// 
        [
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never)
        ] 
        new public HScrollProperties HorizontalScroll
        { 
            get 
            {
                return base.HorizontalScroll; 
            }
        }

        [ 
        DefaultValue(typeof(Size), "16,16"),
        SRCategory(SR.CatAppearance), 
        SRDescription(SR.ToolStripImageScalingSizeDescr), 
        ]
        public Size ImageScalingSize { 
            get {
                return ImageScalingSizeInternal;
            }
            set { 
                ImageScalingSizeInternal = value;
            } 
        } 

        internal virtual Size ImageScalingSizeInternal { 
            get {
                return imageScalingSize;
            }
            set { 
                if (imageScalingSize != value) {
                    imageScalingSize = value; 
 
                    LayoutTransaction.DoLayoutIf((Items.Count > 0), this, this, PropertyNames.ImageScalingSize);
                    foreach (ToolStripItem item in this.Items) { 
                        item.OnImageScalingSizeChanged(EventArgs.Empty);
                    }
                }
            } 
        }
 
        ///  
        /// 
        ///  
        /// Gets or sets the  that contains the  displayed on a label control.
        /// 
        /// 
        [ 
        DefaultValue(null),
        SRCategory(SR.CatAppearance), 
        SRDescription(SR.ToolStripImageListDescr), 
        Browsable(false)
        ] 
        public ImageList ImageList {
            get {
                return imageList;
            } 
            set {
                if (imageList != value) { 
                    EventHandler handler = new EventHandler(ImageListRecreateHandle); 

                    // Remove the previous imagelist handle recreate handler 
                    //
                    if (imageList != null) {
                        imageList.RecreateHandle -= handler;
                    } 

                    imageList = value; 
 
                    // Add the new imagelist handle recreate handler
                    // 
                    if (value != null) {
                        value.RecreateHandle += handler;
                    }
 
                    foreach (ToolStripItem item in Items) {
                        item.InvalidateImageListImage(); 
                    } 
                    Invalidate();
                } 
            }
        }

        ///  
        ///     Specifies whether the control is willing to process mnemonics when hosted in an container ActiveX (Ax Sourcing).
        ///  
        internal override bool IsMnemonicsListenerAxSourced 
        {
            get{ 
                return true;
            }
        }
 
        internal bool IsInToolStripPanel {
            get { 
                return ToolStripPanelRow != null; 

            } 
        }

        ///  indicates whether the user is currently
        ///          moving the toolstrip from one toolstrip container 
        ///          to another
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] 
        public bool IsCurrentlyDragging {
            get { 
                return GetToolStripState(STATE_DRAGGING);
            }
        }
 

        ///  
        ///     indicates if the SetBoundsCore is called thru Locationchanging. 
        /// 
        private bool IsLocationChanging { 
            get {
                return GetToolStripState(STATE_LOCATIONCHANGING);
            }
        } 

 
        ///  
        /// 
        /// The items that belong to this ToolStrip. 
        /// Note - depending on space and layout preferences, not all items
        /// in this collection will be displayed.  They may not even be displayed
        /// on this winbar (say in the case where we're overflowing the item).
        /// The collection of _Displayed_ items is the DisplayedItems collection. 
        /// The displayed items collection also includes things like the OverflowButton
        /// and the Grip. 
        ///  
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        SRCategory(SR.CatData),
        SRDescription(SR.ToolStripItemsDescr),
        MergableProperty(false)
        ] 
        public virtual ToolStripItemCollection Items {
            get { 
                if (toolStripItemCollection == null) { 
                    toolStripItemCollection = new ToolStripItemCollection(this, true);
                } 
                return toolStripItemCollection;
            }
        }
 

        ///  
        [SRCategory(SR.CatAppearance), SRDescription(SR.ToolStripItemAddedDescr)] 
        public event ToolStripItemEventHandler ItemAdded {
          add { 
              Events.AddHandler(EventItemAdded, value);
          }
          remove {
              Events.RemoveHandler(EventItemAdded, value); 
          }
        } 
 

        ///  
        /// 
        /// Occurs when the control is clicked.
        /// 
        [SRCategory(SR.CatAction), SRDescription(SR.ToolStripItemOnClickDescr)] 
        public event ToolStripItemClickedEventHandler ItemClicked {
            add { 
                Events.AddHandler(EventItemClicked, value); 
            }
            remove { 
                Events.RemoveHandler(EventItemClicked, value);
            }
        }
 

        ///  
        ///   we have a backbuffer for painting items... this is cached to be the size of the largest 
        ///   item in the collection - and is cached in OnPaint, and disposed when the toolstrip
        ///   is no longer visible. 
        ///
        ///   [: toolstrip - main hdc       ] <-- visible to user
        ///   [ toolstrip double buffer hdc ] <-- onpaint hands us this buffer, after we're done DBuf is copied to "main hdc"/
        ///   [tsi dc] <-- we copy the background from the DBuf, then paint the item into this DC, then BitBlt back up to DBuf 
        ///
        ///   This is done because GDI wont honor GDI+ TranslateTransform.  We used to use DCMapping to change the viewport 
        ///   origin and clipping rect of the toolstrip double buffer hdc to paint each item, but this proves costly 
        ///   because you need to allocate GDI+ Graphics objects for every single item.  This method allows us to only
        ///   allocate 1 Graphics object and share it between all the items in OnPaint. 
        /// 
        private CachedItemHdcInfo ItemHdcInfo {
            get {
                if  (cachedItemHdcInfo == null) { 
                    cachedItemHdcInfo = new CachedItemHdcInfo();
                } 
                return cachedItemHdcInfo; 
            }
        } 

        /// 
        [SRCategory(SR.CatAppearance), SRDescription(SR.ToolStripItemRemovedDescr)]
        public event ToolStripItemEventHandler ItemRemoved { 
          add {
              Events.AddHandler(EventItemRemoved, value); 
          } 
          remove {
              Events.RemoveHandler(EventItemRemoved, value); 
          }
        }
        /// 
        ///  handy check for painting and sizing  
        [Browsable(false)]
        public bool IsDropDown { 
            get { return (this is ToolStripDropDown); } 
        }
 
        internal bool IsDisposingItems {
            get {
                return GetToolStripState(STATE_DISPOSINGITEMS);
            } 
        }
        ///  
        /// The OnDrag[blah] methods that will be called if AllowItemReorder is true. 
        ///
        /// This allows us to have methods that handle drag/drop of the winbar items 
        /// without calling back on the user's code
        /// 
        internal IDropTarget ItemReorderDropTarget {
            get { 
                return itemReorderDropTarget;
            } 
            set { 
                itemReorderDropTarget = value;
            } 
        }

        /// 
        /// The OnQueryContinueDrag and OnGiveFeedback methods that will be called if 
        /// AllowItemReorder is true.
        /// 
        /// This allows us to have methods that handle drag/drop of the winbar items 
        /// without calling back on the user's code
        ///  
        internal ISupportOleDropSource ItemReorderDropSource {
            get {
                return itemReorderDropSource;
            } 
            set {
                itemReorderDropSource = value; 
            } 
        }
 
        internal bool IsInDesignMode {
            get {
                return DesignMode;
            } 
        }
 
        internal bool IsSelectionSuspended { 
            get { return GetToolStripState(STATE_LASTMOUSEDOWNEDITEMCAPTURE); }
        } 

        internal ToolStripItem LastMouseDownedItem {
            get {
                if (lastMouseDownedItem != null && 
                    (lastMouseDownedItem.IsDisposed || lastMouseDownedItem.ParentInternal != this)){
                    // handle disposal, parent changed since we last mouse downed. 
                    lastMouseDownedItem = null; 
                }
                return lastMouseDownedItem; 

            }
        }
 
        [
        DefaultValue(null), 
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public LayoutSettings LayoutSettings {
            get {
                return layoutSettings;
            } 
            set {
                layoutSettings = value; 
            } 
        }
 

        /// 
        /// 
        /// Specifies whether we're horizontal or vertical 
        /// 
        [ 
        SRDescription(SR.ToolStripLayoutStyle), 
        SRCategory(SR.CatLayout),
        AmbientValue(ToolStripLayoutStyle.StackWithOverflow) 
        ]
        public ToolStripLayoutStyle LayoutStyle {
           get {
                if (layoutStyle == ToolStripLayoutStyle.StackWithOverflow) { 
                    switch (this.Orientation) {
                        case Orientation.Horizontal: 
                            return ToolStripLayoutStyle.HorizontalStackWithOverflow; 
                        case Orientation.Vertical:
                            return ToolStripLayoutStyle.VerticalStackWithOverflow; 
                    }
                }
                return layoutStyle;
            } 
            set {
                //valid values are 0x0 to 0x4 
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolStripLayoutStyle.StackWithOverflow, (int)ToolStripLayoutStyle.Table)){ 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripLayoutStyle));
                } 
                if (layoutStyle != value) {
                    layoutStyle = value;

                    switch (value) { 
                        case ToolStripLayoutStyle.Flow:
                            if (!(layoutEngine is FlowLayout)) { 
                                layoutEngine = FlowLayout.Instance; 
                            }
                            // Orientation really only applies to split stack layout (which swaps based on Dock, ToolStripPanel location) 
                            UpdateOrientation(Orientation.Horizontal);
                            break;
                        case ToolStripLayoutStyle.Table:
 
                            if (!(layoutEngine is TableLayout)) {
                                layoutEngine = TableLayout.Instance; 
                            } 
                            // Orientation really only applies to split stack layout (which swaps based on Dock, ToolStripPanel location)
                            UpdateOrientation(Orientation.Horizontal); 
                            break;
                        case ToolStripLayoutStyle.StackWithOverflow:
                        case ToolStripLayoutStyle.HorizontalStackWithOverflow:
                        case ToolStripLayoutStyle.VerticalStackWithOverflow: 
                        default:
 
                            if (value != ToolStripLayoutStyle.StackWithOverflow) { 
                                UpdateOrientation((value == ToolStripLayoutStyle.VerticalStackWithOverflow) ? Orientation.Vertical : Orientation.Horizontal);
                            } 
                            else {
                                if (IsInToolStripPanel) {
                                    UpdateLayoutStyle(ToolStripPanelRow.Orientation);
                                } 
                                else {
                                    UpdateLayoutStyle(this.Dock); 
                                } 
                            }
                            if (!(layoutEngine is ToolStripSplitStackLayout)) { 
                                layoutEngine = new ToolStripSplitStackLayout(this);
                            }
                            break;
                    } 

                    using (LayoutTransaction.CreateTransactionIf(IsHandleCreated, this, this, PropertyNames.LayoutStyle)) { 
                        LayoutSettings = CreateLayoutSettings(layoutStyle); 
                    }
                    OnLayoutStyleChanged(EventArgs.Empty); 
                }
            }
        }
        ///  
        /// 
        /// [To be supplied.] 
        ///  
        [SRCategory(SR.CatAppearance), SRDescription(SR.ToolStripLayoutCompleteDescr)]
        public event EventHandler LayoutCompleted { 
            add {
                Events.AddHandler(EventLayoutCompleted, value);
            }
            remove { 
                Events.RemoveHandler(EventLayoutCompleted, value);
            } 
        } 

        internal bool LayoutRequired { 
            get {
                return this.layoutRequired;
            }
            set { 
                this.layoutRequired = value;
            } 
        } 

        ///  
        /// 
        /// [To be supplied.]
        /// 
        [SRCategory(SR.CatAppearance), SRDescription(SR.ToolStripLayoutStyleChangedDescr)] 
        public event EventHandler LayoutStyleChanged {
            add { 
                Events.AddHandler(EventLayoutStyleChanged, value); 
            }
            remove { 
                Events.RemoveHandler(EventLayoutStyleChanged, value);
            }
        }
 
        /// 
        public override LayoutEngine LayoutEngine { 
             get { 
                 //
                 return layoutEngine; 
             }
        }

 

        ///  
        ///  
        /// [To be supplied.]
        ///  
        internal event ToolStripLocationCancelEventHandler LocationChanging {
            add {
                Events.AddHandler(EventLocationChanging, value);
            } 
            remove {
                Events.RemoveHandler(EventLocationChanging, value); 
            } 
        }
 
        /// 
        protected internal virtual Size MaxItemSize {
            get {
              return this.DisplayRectangle.Size; 
            }
        } 
 
        internal bool MenuAutoExpand {
            get { 
                if (!DesignMode) {
                    if (GetToolStripState(STATE_MENUAUTOEXPAND)) {
                        if (!IsDropDown && !ToolStripManager.ModalMenuFilter.InMenuMode) {
                            SetToolStripState(STATE_MENUAUTOEXPAND, false); 
                            return false;
                        } 
                        return true; 
                    }
                } 
                return false;

            }
            set { 
                if (!DesignMode) {
                    SetToolStripState(STATE_MENUAUTOEXPAND, value); 
                } 

            } 
        }

        internal Stack MergeHistoryStack {
            get { 
                if(mergeHistoryStack == null) {
                    mergeHistoryStack = new Stack(); 
                } 
                return mergeHistoryStack;
            } 
        }


        private MouseHoverTimer MouseHoverTimer { 
            get {
                if (mouseHoverTimer == null) { 
                    mouseHoverTimer = new MouseHoverTimer(); 
                }
                return mouseHoverTimer; 
            }
        }

 
        /// 
        ///  
        /// Summary of OverflowButton. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)] 
        public ToolStripOverflowButton OverflowButton {
            get {
                if (toolStripOverflowButton == null) {
                    toolStripOverflowButton = new ToolStripOverflowButton(this); 
                    toolStripOverflowButton.Overflow = ToolStripItemOverflow.Never;
                    toolStripOverflowButton.ParentInternal = this; 
                    toolStripOverflowButton.Alignment = ToolStripItemAlignment.Right; 
                    toolStripOverflowButton.Size = toolStripOverflowButton.GetPreferredSize(this.DisplayRectangle.Size - this.Padding.Size);
                } 
                return toolStripOverflowButton;
            }
        }
 
        //
        // SECREVIEW VSWhidbey 436973: adding control host items to this collection in 
        // the internet zone will throw security exceptions 
        //
        internal ToolStripItemCollection OverflowItems { 
            get {
                if (overflowItems == null) {
                    overflowItems = new ToolStripItemCollection(this, false);
                } 
                return overflowItems;
            } 
        } 

        [Browsable(false)] 
        public Orientation Orientation {
            get {
                return orientation;
            } 
        }
 
        ///  
        /// 
        /// [To be supplied.] 
        /// 
        [SRCategory(SR.CatAppearance), SRDescription(SR.ToolStripPaintGripDescr)]
        public event PaintEventHandler PaintGrip {
            add { 
                Events.AddHandler(EventPaintGrip, value);
            } 
            remove { 
                Events.RemoveHandler(EventPaintGrip, value);
            } 
        }

        internal RestoreFocusMessageFilter RestoreFocusFilter {
            get { 
                if (restoreFocusFilter == null) {
                    restoreFocusFilter = new RestoreFocusMessageFilter(this); 
                } 
                return restoreFocusFilter;
            } 
        }

        internal  ToolStripPanelCell ToolStripPanelCell {
            get { return ((ISupportToolStripPanel)this).ToolStripPanelCell; } 
        }
 
 
        internal  ToolStripPanelRow ToolStripPanelRow {
            get { return ((ISupportToolStripPanel)this).ToolStripPanelRow; } 
        }

        // fetches the Cell associated with this toolstrip.
        ToolStripPanelCell ISupportToolStripPanel.ToolStripPanelCell { 
            get {
                ToolStripPanelCell toolStripPanelCell = null; 
                if (!IsDropDown && !IsDisposed) { 
                    if (Properties.ContainsObject(ToolStrip.PropToolStripPanelCell)) {
                        toolStripPanelCell = (ToolStripPanelCell)Properties.GetObject(ToolStrip.PropToolStripPanelCell); 
                    }
                    else {
                        toolStripPanelCell = new ToolStripPanelCell(this);
                        Properties.SetObject(ToolStrip.PropToolStripPanelCell, toolStripPanelCell); 
                    }
                } 
                return toolStripPanelCell; 
            }
        } 


        ToolStripPanelRow ISupportToolStripPanel.ToolStripPanelRow {
            get { 
                ToolStripPanelCell cell = ToolStripPanelCell;
                if (cell == null) { 
                    return null; 
                }
                return ToolStripPanelCell.ToolStripPanelRow; 
            }
            set {
                ToolStripPanelRow oldToolStripPanelRow = ToolStripPanelRow;
 
                if (oldToolStripPanelRow != value) {
                    ToolStripPanelCell cell = ToolStripPanelCell; 
                    if (cell == null) { 
                        return;
                    } 
                    cell.ToolStripPanelRow = value;

                    if (value != null) {
                       if (oldToolStripPanelRow == null || oldToolStripPanelRow.Orientation != value.Orientation) { 
                           if (layoutStyle == ToolStripLayoutStyle.StackWithOverflow)
                           { 
                               UpdateLayoutStyle(value.Orientation); 
                           }
                           else 
                           {
                               UpdateOrientation(value.Orientation);
                           }
 
                       }
                    } 
                    else { 
                        if (oldToolStripPanelRow != null && oldToolStripPanelRow.ControlsInternal.Contains(this)) {
                            oldToolStripPanelRow.ControlsInternal.Remove(this); 
                        }
                        UpdateLayoutStyle(Dock);
                    }
                } 

            } 
 
        }
 

        [DefaultValue(false)]
        [SRCategory(SR.CatLayout)]
        [SRDescription(SR.ToolStripStretchDescr)] 
        public bool Stretch {
            get { 
                return GetToolStripState(STATE_STRETCH); 
            }
            set { 
                if (Stretch != value) {
                    SetToolStripState(STATE_STRETCH,value);
                }
            } 
        }
 
        ///  
        /// 
        /// The renderer is used to paint the hwndless winbar items.  If someone wanted to 
        /// change the "Hot" look of all of their buttons to be a green triangle, they should
        /// create a class that derives from ToolStripRenderer, assign it to this property and call
        /// invalidate.
        ///  
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public ToolStripRenderer Renderer {
            get { 

                if (IsDropDown) {
                    // PERF: since this is called a lot we dont want to make it virtual
                    ToolStripDropDown dropDown = this as ToolStripDropDown; 
                    if (dropDown is ToolStripOverflow || dropDown.IsAutoGenerated) {
                        if (dropDown.OwnerToolStrip != null) { 
                            return dropDown.OwnerToolStrip.Renderer; 
                        }
                    } 
                }
                if (RenderMode == ToolStripRenderMode.ManagerRenderMode) {
                    return ToolStripManager.Renderer;
                } 
                // always return a valid renderer so our paint code
                // doesn't have to be bogged down by checks for null. 
 
                SetToolStripState(STATE_USEDEFAULTRENDERER, false);
                if (renderer == null) { 
                    Renderer = ToolStripManager.CreateRenderer(RenderMode);
                }
                return renderer;
 
            }
            set { 
                // if the value happens to be null, the next get 
                // will autogenerate a new ToolStripRenderer.
                if (renderer != value) { 
                    SetToolStripState(STATE_USEDEFAULTRENDERER, (value == null));
                    renderer = value;
                    currentRendererType = (renderer != null) ? renderer.GetType() : typeof(System.Type);
                    OnRendererChanged(EventArgs.Empty); 
                }
            } 
        } 

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public event EventHandler RendererChanged {
            add {
                Events.AddHandler(EventRendererChanged, value);
            } 
            remove {
                Events.RemoveHandler(EventRendererChanged, value); 
            } 
        }
 
         /// 
         [
         SRDescription(SR.ToolStripRenderModeDescr),
         SRCategory(SR.CatAppearance), 
         ]
         public ToolStripRenderMode RenderMode { 
             get { 
                 if (GetToolStripState(STATE_USEDEFAULTRENDERER)) {
                    return ToolStripRenderMode.ManagerRenderMode; 
                 }
                 if (renderer != null && !renderer.IsAutoGenerated) {
                    return ToolStripRenderMode.Custom;
                 } 
                 // check the type of the currently set renderer.
                 // types are cached as this may be called frequently. 
                 if (currentRendererType == ToolStripManager.ProfessionalRendererType) { 
                     return ToolStripRenderMode.Professional;
                 } 
                 if (currentRendererType == ToolStripManager.SystemRendererType) {
                     return ToolStripRenderMode.System;
                 }
                 return  ToolStripRenderMode.Custom; 

             } 
             set { 
                 //valid values are 0x0 to 0x3
                 if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolStripRenderMode.Custom, (int)ToolStripRenderMode.ManagerRenderMode)){ 
                     throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripRenderMode));
                 }
                 if (value == ToolStripRenderMode.Custom) {
                     throw new NotSupportedException(SR.GetString(SR.ToolStripRenderModeUseRendererPropertyInstead)); 
                 }
 
                 if (value == ToolStripRenderMode.ManagerRenderMode) { 
                     if (!GetToolStripState(STATE_USEDEFAULTRENDERER)) {
                         SetToolStripState(STATE_USEDEFAULTRENDERER, true); 
                         OnRendererChanged(EventArgs.Empty);
                     }
                 }
                 else { 
                    SetToolStripState(STATE_USEDEFAULTRENDERER, false);
                    Renderer = ToolStripManager.CreateRenderer(value); 
                 } 
             }
         } 


        /// 
        /// ToolStripItems need to access this to determine if they should be showing underlines 
        /// for their accelerators.  Since they are not HWNDs, and this method is protected on control
        /// we need a way for them to get at it. 
        ///  
        internal bool ShowKeyboardCuesInternal {
            get { 
                return this.ShowKeyboardCues;

            }
        } 

 
        ///  
        [DefaultValue(true)]
        [SRDescription(SR.ToolStripShowItemToolTipsDescr)] 
        [SRCategory(SR.CatBehavior)]
        public bool ShowItemToolTips {
            get {
                return showItemToolTips; 
            }
            set { 
                if (showItemToolTips != value) { 
                    showItemToolTips = value;
                    if (!showItemToolTips) { 
                        UpdateToolTip(null);
                    }
                }
            } 
        }
 
        ///  internal lookup table for shortcuts... intended to speed search time  
        internal Hashtable Shortcuts {
            get { 
                if (shortcuts == null) {
                    shortcuts = new Hashtable(1);
                }
                return shortcuts; 
            }
        } 
 
        /// 
        ///  
        /// Indicates whether the user can give the focus to this control using the TAB
        /// key. This property is read-only.
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(false), 
        DispId(NativeMethods.ActiveX.DISPID_TABSTOP), 
        SRDescription(SR.ControlTabStopDescr)
        ] 
        public new bool TabStop {
            get {
                return base.TabStop;
            } 
            set {
                base.TabStop = value; 
            } 
        }
 

        ///  this is the ToolTip used for the individual items
        ///          it only works if ShowItemToolTips = true
        ///  
        internal ToolTip ToolTip {
            get { 
                ToolTip toolTip; 
                if (!Properties.ContainsObject(ToolStrip.PropToolTip)) {
                    toolTip = new ToolTip(); 
                    Properties.SetObject(ToolStrip.PropToolTip,toolTip );
                }
                else {
                    toolTip = (ToolTip)Properties.GetObject(ToolStrip.PropToolTip); 
                }
                return toolTip; 
            } 
        }
 
        /// 
        [
        DefaultValue(ToolStripTextDirection.Horizontal),
        SRDescription(SR.ToolStripTextDirectionDescr), 
        SRCategory(SR.CatAppearance)
        ] 
        public virtual ToolStripTextDirection TextDirection { 
            get {
                ToolStripTextDirection textDirection = ToolStripTextDirection.Inherit; 
                if (Properties.ContainsObject(ToolStrip.PropTextDirection)) {
                   textDirection= (ToolStripTextDirection)Properties.GetObject(ToolStrip.PropTextDirection);
                }
 
                if (textDirection == ToolStripTextDirection.Inherit) {
                    textDirection = ToolStripTextDirection.Horizontal; 
                } 

                return textDirection; 
            }
            set {
                //valid values are 0x0 to 0x3
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)ToolStripTextDirection.Inherit, (int)ToolStripTextDirection.Vertical270)){ 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(ToolStripTextDirection));
                } 
                Properties.SetObject(ToolStrip.PropTextDirection, value); 

                using(new LayoutTransaction(this, this, "TextDirection")) { 
                    for (int i = 0; i < Items.Count; i++) {
                        Items[i].OnOwnerTextDirectionChanged();
                    }
                } 

            } 
        } 

        ///  
        /// 
        ///    Gets the Vertical Scroll bar for this ScrollableControl.
        /// 
        [ 
        Browsable(false), EditorBrowsable(EditorBrowsableState.Never)
        ] 
        new public VScrollProperties VerticalScroll 
        {
            get 
            {
                return base.VerticalScroll;
            }
        } 

        void ISupportToolStripPanel.BeginDrag() { 
            OnBeginDrag(EventArgs.Empty); 
        }
 
        // Internal so that it's not a public API.
        internal virtual void ChangeSelection(ToolStripItem nextItem) {

            if (nextItem != null) { 
                ToolStripControlHost controlHost = nextItem as ToolStripControlHost;
                // if we contain focus, we should set focus to ourselves 
                // so we get the focus off the thing that's currently focused 
                // e.g. go from a text box to a toolstrip button
                if (ContainsFocus && !Focused) { 
                    this.FocusInternal();
                    if (controlHost == null) {
                        // if nextItem IS a toolstripcontrolhost, we're going to focus it anyways
                        // we only fire KeyboardActive when "focusing" a non-hwnd backed item 
                        KeyboardActive = true;
                    } 
                } 
                if (controlHost != null) {
                    if (hwndThatLostFocus == IntPtr.Zero) { 
                        SnapFocus(UnsafeNativeMethods.GetFocus());
                    }
                    controlHost.Control.Select();
                    controlHost.Control.FocusInternal(); 
                }
 
 
                nextItem.Select();
 
                ToolStripMenuItem tsNextItem = nextItem as ToolStripMenuItem;
                if (tsNextItem != null && !IsDropDown) {
                  // only toplevel menus auto expand when the selection changes.
                   tsNextItem.HandleAutoExpansion(); 
                }
 
           } 

        } 

        protected virtual LayoutSettings CreateLayoutSettings(ToolStripLayoutStyle layoutStyle) {
            switch (layoutStyle) {
                case ToolStripLayoutStyle.Flow: 
                    return new FlowLayoutSettings(this);
                case ToolStripLayoutStyle.Table: 
                    return new TableLayoutSettings(this); 
                default:
                    return null; 
            }
        }

        protected internal virtual ToolStripItem CreateDefaultItem(string text, Image image, EventHandler onClick) { 
            if (text == "-") {
                return new ToolStripSeparator(); 
            } 
            else {
                return new ToolStripButton(text,image,onClick); 
            }
        }

 
        /// 
        /// Summary of ClearAllSelections. 
        ///  
        private void ClearAllSelections() {
            ClearAllSelectionsExcept(null); 
        }

        /// 
        /// Summary of ClearAllSelectionsExcept. 
        /// 
        ///  
        private void ClearAllSelectionsExcept(ToolStripItem item) { 
            Rectangle regionRect = (item == null) ? Rectangle.Empty : item.Bounds;
            Region region = null; 

            try {

                for (int i = 0; i < DisplayedItems.Count; i++)  { 
                    if (DisplayedItems[i] == item) {
                        continue; 
                    } 
                    else if (item != null && DisplayedItems[i].Pressed) {
                        // 
                         ToolStripDropDownItem dropDownItem = DisplayedItems[i] as ToolStripDropDownItem;

                         if (dropDownItem != null && dropDownItem.HasDropDownItems) {
                            dropDownItem.AutoHide(item); 
                         }
                    } 
                    bool invalidate = false; 
                    if (DisplayedItems[i].Selected) {
                        DisplayedItems[i].Unselect(); 
                        Debug.WriteLineIf(SelectionDebug.TraceVerbose,"[SelectDBG ClearAllSelectionsExcept] Unselecting " + DisplayedItems[i].Text);
                        invalidate = true;
                    }
 

                    if (invalidate) { 
                        // since regions are heavy weight - only use if we need it. 
                        if (region == null) {
                            region = new Region(regionRect); 
                        }
                        region.Union(DisplayedItems[i].Bounds);
                    }
                } 

                // force an WM_PAINT to happen now to instantly reflect the selection change. 
                if (region != null) { 
                     Invalidate(region, true);
                     Update(); 
                }
                else if (regionRect != Rectangle.Empty) {
                    Invalidate(regionRect, true);
                    Update(); 
                }
 
            } 
            finally {
                if (region != null) { 
                    region.Dispose();
                }
            }
            // fire accessibility 
            if (IsHandleCreated && item != null) {
                int focusIndex = DisplayedItems.IndexOf(item); 
                AccessibilityNotifyClients(AccessibleEvents.Focus, focusIndex); 
            }
        } 

        internal void ClearInsertionMark() {
            if (lastInsertionMarkRect != Rectangle.Empty) {
                // stuff away the lastInsertionMarkRect 
                // and clear it out _before_ we call paint OW
                // the call to invalidate wont help as it will get 
                // repainted. 
                Rectangle invalidate = lastInsertionMarkRect;
                lastInsertionMarkRect = Rectangle.Empty; 

                this.Invalidate(invalidate);
            }
 
        }
        private void ClearLastMouseDownedItem() { 
            ToolStripItem lastItem = lastMouseDownedItem; 
            lastMouseDownedItem = null;
            if (IsSelectionSuspended) { 
                SetToolStripState(STATE_LASTMOUSEDOWNEDITEMCAPTURE, false);
                if (lastItem != null) {
                    lastItem.Invalidate();
                } 
            }
        } 
 
        /// 
        ///  
        /// Clean up any resources being used.
        /// 
        protected override void Dispose( bool disposing ) {
            if(disposing) { 
                ToolStripOverflow overflow = GetOverflow();
 
                try { 

                   this.SuspendLayout(); 
                   if (overflow != null) {
                       overflow.SuspendLayout();
                    }
                    // if there's a problem in config, dont be a leaker. 
                    SetToolStripState(STATE_DISPOSINGITEMS, true);
                    lastMouseDownedItem = null; 
 
                    HookStaticEvents(/*hook=*/false);
 
                    ToolStripPanelCell toolStripPanelCell = Properties.GetObject(ToolStrip.PropToolStripPanelCell) as ToolStripPanelCell;
                    if (toolStripPanelCell != null) {
                        toolStripPanelCell.Dispose();
                    } 

                    if (cachedItemHdcInfo != null) { 
                        cachedItemHdcInfo.Dispose(); 
                    }
 
                    if (mouseHoverTimer != null) {
                        mouseHoverTimer.Dispose();
                    }
 
                    ToolTip toolTip = (ToolTip)Properties.GetObject(ToolStrip.PropToolTip);
                    if (toolTip != null) { 
                        toolTip.Dispose (); 
                    }
 
                    if (!Items.IsReadOnly) {
                        // only dispose the items we actually own.
                        for (int i = Items.Count - 1; i >= 0; i--) {
                            Items[i].Dispose(); 
                        }
                        Items.Clear(); 
                    } 
                    // clean up items not in the Items list
                    if (toolStripGrip != null) { 
                        toolStripGrip.Dispose();
                    }
                    if (toolStripOverflowButton != null) {
                        toolStripOverflowButton.Dispose(); 
                    }
 
                    // remove the restore focus filter 
                    if (restoreFocusFilter != null) {
                        // PERF, SECREVIEW: dont call Application.RemoveMessageFilter as this could 
                        // get called a lot and we want to have to assert AWP.
                        Application.ThreadContext.FromCurrent().RemoveMessageFilter(restoreFocusFilter);
                        restoreFocusFilter = null;
                    } 

 
                    // exit menu mode if necessary. 
                    bool exitMenuMode = false;
                    if (ToolStripManager.ModalMenuFilter.GetActiveToolStrip() == this) { 
                        exitMenuMode = true;
                    }
                    ToolStripManager.ModalMenuFilter.RemoveActiveToolStrip(this);
                    // if we were the last toolstrip in the queue, exit menu mode. 
                    if (exitMenuMode && ToolStripManager.ModalMenuFilter.GetActiveToolStrip() == null) {
                        Debug.WriteLineIf(ToolStrip.SnapFocusDebug.TraceVerbose, "Exiting menu mode because we're the last toolstrip in the queue, and we've disposed."); 
                        ToolStripManager.ModalMenuFilter.ExitMenuMode(); 
                    }
 
                    ToolStripManager.ToolStrips.Remove(this);
                }
                finally {
 
                    this.ResumeLayout(false);
                    if (overflow != null) { 
                        overflow.ResumeLayout(false); 
                    }
                    SetToolStripState(STATE_DISPOSINGITEMS, false); 
                }
            }
            base.Dispose( disposing );
 
        }
 
        internal void DoLayoutIfHandleCreated(ToolStripItemEventArgs e) { 
            if (this.IsHandleCreated) {
                LayoutTransaction.DoLayout(this, e.Item, PropertyNames.Items); 
                this.Invalidate();
                // Adding this item may have added it to the overflow
                // However, we can't check if it's in OverflowItems, because
                // it gets added there in Layout, and layout might be suspended. 
                if (this.CanOverflow && this.OverflowButton.HasDropDown) {
                    if (DeferOverflowDropDownLayout()) { 
                        CommonProperties.xClearPreferredSizeCache(this.OverflowButton.DropDown); 
                        this.OverflowButton.DropDown.LayoutRequired = true;
                    } 
                    else {
                        LayoutTransaction.DoLayout(this.OverflowButton.DropDown, e.Item, PropertyNames.Items);
                        this.OverflowButton.DropDown.Invalidate();
                    } 
                }
            } 
            else { 
                // next time we fetch the preferred size, recalc it.
                CommonProperties.xClearPreferredSizeCache(this); 
                this.LayoutRequired = true;
                if (this.CanOverflow && this.OverflowButton.HasDropDown) {
                    this.OverflowButton.DropDown.LayoutRequired = true;
                } 
            }
        } 
 
        private bool DeferOverflowDropDownLayout() {
            return this.IsLayoutSuspended 
                ||!this.OverflowButton.DropDown.Visible
                || !this.OverflowButton.DropDown.IsHandleCreated;
        }
 
        void ISupportToolStripPanel.EndDrag() {
            ToolStripPanel.ClearDragFeedback(); 
            OnEndDrag(EventArgs.Empty); 
        }
 
        internal ToolStripOverflow GetOverflow() {
           return (toolStripOverflowButton == null || !toolStripOverflowButton.HasDropDown) ? null : toolStripOverflowButton.DropDown as ToolStripOverflow;
        }
        internal byte GetMouseId() { 
            // never return 0 as the mousedown ID, this is the "reset" value.
            if (mouseDownID == 0) { 
                mouseDownID++; 
            }
            return mouseDownID; 
        }
        internal virtual ToolStripItem GetNextItem(ToolStripItem start, ArrowDirection direction, bool rtlAware) {

            if (rtlAware && RightToLeft == RightToLeft.Yes) { 
                if (direction == ArrowDirection.Right) {
                    direction = ArrowDirection.Left; 
                } 
                else if (direction == ArrowDirection.Left) {
                    direction = ArrowDirection.Right; 
                }
            }
            return GetNextItem(start, direction);
        } 

        ///  
        ///  
        /// Gets the next item from the given start item in the direction specified.
        ///   - This function wraps if at the end 
        ///   - This function will only surf the items in the current container
        ///   - Overriding this function will change the tab ordering and accessible child ordering.
        /// 
        public virtual ToolStripItem GetNextItem(ToolStripItem start, ArrowDirection direction) 
        {
            if (!WindowsFormsUtils.EnumValidator.IsValidArrowDirection(direction)) { 
                throw new InvalidEnumArgumentException("direction", (int)direction, typeof(ArrowDirection)); 
            }
 
            switch (direction) {
                case ArrowDirection.Right:
                    return GetNextItemHorizontal(start, /*forward = */true);
                case ArrowDirection.Left: 
                    return GetNextItemHorizontal(start, /*forward = */false);
                case ArrowDirection.Down: 
                    return GetNextItemVertical(start, /*forward = */true); 
                case ArrowDirection.Up:
                    return GetNextItemVertical(start, /*forward = */false); 
            }

            return null;
       } 

 
        //  
        //  Helper function for GetNextItem - do not directly call this.
        //  
        private ToolStripItem GetNextItemHorizontal(ToolStripItem start, bool forward) {

            if (DisplayedItems.Count <= 0)
                return null; 

            if (start == null)  { 
                start = (forward) ? DisplayedItems[DisplayedItems.Count -1] : DisplayedItems[0]; 
            }
 
            int current = DisplayedItems.IndexOf(start);
            if (current == -1) {
                Debug.WriteLineIf(SelectionDebug.TraceVerbose, "Started from a visible = false item");
                return null; 
            }
 
            Debug.WriteLineIf(SelectionDebug.TraceVerbose && (current != -1), "[SelectDBG GetNextToolStripItem] Last selected item was " + ((current != -1) ?  DisplayedItems[current].Text : "")); 
            Debug.WriteLineIf(SelectionDebug.TraceVerbose && (current == -1), "[SelectDBG GetNextToolStripItem] Last selected item was null");
 
            int count = DisplayedItems.Count;

            do {
 
                if (forward) {
                    current = ++current % count; 
                } 
                else {  // provide negative wrap if necessary
                    current = (--current < 0) ? count + current : current; 
                }
                ToolStripDropDown dropDown = this as ToolStripDropDown;
                if (dropDown!= null)
                { 
                    if (dropDown.OwnerItem != null && dropDown.OwnerItem.IsInDesignMode) {
                    	return DisplayedItems[current]; 
                    } 
                }
                if (DisplayedItems[current].CanKeyboardSelect) { 
                    Debug.WriteLineIf(SelectionDebug.TraceVerbose, "[SelectDBG GetNextToolStripItem] selecting " + DisplayedItems[current].Text);
                    //ClearAllSelectionsExcept(Items[current]);
                    return DisplayedItems[current];
                } 

            } while (DisplayedItems[current] != start); 
            return null; 
        }
 



       //  
       //  Helper function for GetNextItem - do not directly call this.
       //  
       [SuppressMessage("Microsoft.Portability", "CA1902:AvoidTestingForFloatingPointEquality")] 
       private ToolStripItem GetNextItemVertical(ToolStripItem selectedItem, bool down) {
 
                 ToolStripItem tanWinner = null;
                 ToolStripItem hypotenuseWinner = null;

                 double minHypotenuse = Double.MaxValue; 
                 double minTan = Double.MaxValue;
                 double hypotenuseOfTanWinner = Double.MaxValue; 
                 double tanOfHypotenuseWinner = Double.MaxValue; 

                  if (selectedItem == null) { 
                     ToolStripItem item = GetNextItemHorizontal(selectedItem, down);
                     return item;
                 }
     		 
                 ToolStripDropDown dropDown = this as ToolStripDropDown;
                 if (dropDown != null) 
                 { 
                     if (dropDown.OwnerItem != null && (dropDown.OwnerItem.IsInDesignMode || (dropDown.OwnerItem.Owner != null && dropDown.OwnerItem.Owner.IsInDesignMode))) {
                         ToolStripItem item = GetNextItemHorizontal(selectedItem, down); 
                         return item;
                     }
                 }
 

                 Point midPointOfCurrent = new Point(selectedItem.Bounds.X + selectedItem.Width / 2, 
                                                         selectedItem.Bounds.Y + selectedItem.Height / 2); 

 

                 for(int i = 0; i < DisplayedItems.Count; i++) {
                     ToolStripItem otherItem = DisplayedItems[i];
                     if (otherItem == selectedItem || !otherItem.CanKeyboardSelect) { 
                         continue;
                     } 
                     if (!down && otherItem.Bounds.Bottom > selectedItem.Bounds.Top) { 
                         // if we are going up the other control has to be above
                         continue; 
                     }
                     else if (down && otherItem.Bounds.Top < selectedItem.Bounds.Bottom) {
                         // if we are going down the other control has to be below
                         continue; 
                     }
 
                     //[ otherControl ] 
                     //       *
                     Point otherItemMidLocation = new Point(otherItem.Bounds.X + otherItem.Width/2, (down)? otherItem.Bounds.Top : otherItem.Bounds.Bottom); 
 #if DEBUG_UPDOWN
                         Graphics g = Graphics.FromHwnd(this.Handle);

                         using (Pen p = new Pen(Color.FromKnownColor((KnownColor)i))) { 
                             g.DrawLine(p,otherItemMidLocation, midPointOfCurrent);
                         } 
                         System.Threading.Thread.Sleep(100); 
                         g.Dispose();
 #endif 
                     int oppositeSide = otherItemMidLocation.X - midPointOfCurrent.X;
                     int adjacentSide = otherItemMidLocation.Y - midPointOfCurrent.Y;

                     // use pythagrian theorem to calculate the length of the distance 
                     // between the middle of the current control in question and it's adjacent
                     // objects. 
                     double hypotenuse = Math.Sqrt(adjacentSide*adjacentSide + oppositeSide*oppositeSide); 

                     if (adjacentSide != 0) { // avoid divide by zero - we dont do layered controls 
                         //    _[o]
                         //    |/
                         //   [s]
                         //   get the angle between s and o by taking the arctan. 
                         //   PERF consider using approximation instead
                         double tan = Math.Abs(Math.Atan(oppositeSide/adjacentSide)); 
 
                         // we want the thing with the smallest angle and smallest distance between midpoints
                         minTan = Math.Min(minTan, tan); 
                         minHypotenuse = Math.Min(minHypotenuse, hypotenuse);

                         if (minTan == tan && minTan != Double.NaN) {
                             tanWinner = otherItem; 
                             hypotenuseOfTanWinner = hypotenuse;
                         } 
 
                         if (minHypotenuse == hypotenuse) {
                             hypotenuseWinner = otherItem; 
                             tanOfHypotenuseWinner = tan;
                         }
                     }
                 } 

 
     #if DEBUG_UPDOWN 
                 string tanWinnerString = (tanWinner == null) ? "null" : tanWinner.ToString();
                 string hypWinnerString = (hypotenuseWinner == null) ? "null": hypotenuseWinner.ToString(); 
                 Debug.WriteLine(String.Format("Tangent winner is {0} Hyp winner is {1}",  tanWinnerString, hypWinnerString));

     #endif
                 if ((tanWinner == null) || (hypotenuseWinner == null)) { 
                      return (GetNextItemHorizontal(null,down));
                 } 
                 else { 
                     // often times the guy with the best angle will be the guy with the closest hypotenuse.
                     // however in layouts where things are more randomly spaced, this is not necessarily the case. 
                     if (tanOfHypotenuseWinner == minTan) {
                         // if the angles match up, such as in the case of items of the same width in vertical flow
                         // then pick the closest one.
                         return hypotenuseWinner; 
                     }
                       else if ((!down && tanWinner.Bounds.Bottom <= hypotenuseWinner.Bounds.Top) 
                         ||(down && tanWinner.Bounds.Top > hypotenuseWinner.Bounds.Bottom)) { 
                             // we prefer the case where the angle is smaller than
                             // the case where the hypotenuse is smaller.  The only 
                             // scenarios where that is not the case is when the hypoteneuse
                             // winner is clearly closer than the angle winner.

                             //   [a.winner]                       |       [s] 
                             //                                    |         [h.winner]
                             //       [h.winner]                   | 
                             //     [s]                            |    [a.winner] 
                         return hypotenuseWinner;
                     } 
                     else {
                        return tanWinner;
                   }
                 } 
             }
 
 
        internal override Size GetPreferredSizeCore(Size proposedSize) {
             // We act like a container control 

             // Translating 0,0 from ClientSize to actual Size tells us how much space
             // is required for the borders.
              if (proposedSize.Width == 1) { 
                 proposedSize.Width = Int32.MaxValue;
             } 
             if (proposedSize.Height == 1) { 
                 proposedSize.Height = Int32.MaxValue;
             } 

             Padding padding = Padding;
             Size prefSize = LayoutEngine.GetPreferredSize(this, proposedSize - padding.Size);
             Padding newPadding = Padding; 

             // VSWhidbey 471860: 
             // as a side effect of some of the layouts, we can change the padding. 
             // if this happens, we need to clear the cache.
             if (padding != newPadding) { 
                CommonProperties.xClearPreferredSizeCache(this);
             }
             return prefSize + newPadding.Size;
 
         }
 
#region GetPreferredSizeHelpers 

        // 
        // These are here so they can be shared between splitstack layout and StatusStrip
        //
        internal static Size GetPreferredSizeHorizontal(IArrangedElement container, Size proposedConstraints) {
           Size maxSize = Size.Empty; 
           ToolStrip toolStrip = container as ToolStrip;
 
           // ensure preferred size respects default size as a minimum. 
           Size defaultSize = toolStrip.DefaultSize - toolStrip.Padding.Size;
           maxSize.Height = Math.Max(0, defaultSize.Height); 

           bool requiresOverflow = false;
           bool foundItemParticipatingInLayout = false;
 
           for (int j = 0; j < toolStrip.Items.Count; j++) {
               ToolStripItem item = toolStrip.Items[j]; 
 
               if (((IArrangedElement)item).ParticipatesInLayout) {
                   foundItemParticipatingInLayout =true; 
                   if (item.Overflow != ToolStripItemOverflow.Always) {
                       Padding itemMargin = item.Margin;
                       Size prefItemSize = GetPreferredItemSize(item);
                       maxSize.Width += itemMargin.Horizontal + prefItemSize.Width; 
                       maxSize.Height = Math.Max(maxSize.Height, itemMargin.Vertical + prefItemSize.Height);
                   } 
                   else { 
                       requiresOverflow = true;
                   } 
               }
           }

           if (toolStrip.Items.Count == 0 || (!foundItemParticipatingInLayout)) { 
               // if there are no items there, create something anyways.
               maxSize = defaultSize; 
           } 

 
           if (requiresOverflow) {
               // add in the width of the overflow button
               ToolStripOverflowButton overflowItem = toolStrip.OverflowButton;
               Padding overflowItemMargin = overflowItem.Margin; 

               maxSize.Width += overflowItemMargin.Horizontal + overflowItem.Bounds.Width; 
           } 
           else {
               maxSize.Width += 2;  //add Padding of 2 Pixels to the right if not Overflow. 
           }

           if (toolStrip.GripStyle == ToolStripGripStyle.Visible) {
               // add in the grip width 
               Padding gripMargin = toolStrip.GripMargin;
               maxSize.Width += gripMargin.Horizontal + toolStrip.Grip.GripThickness; 
           } 

           maxSize = LayoutUtils.IntersectSizes(maxSize, proposedConstraints); 
           return maxSize;
       }

 
 	[SuppressMessage("Microsoft.Portability", "CA1902:AvoidTestingForFloatingPointEquality")]
 
        internal static Size GetPreferredSizeVertical(IArrangedElement container, Size proposedConstraints) { 
           Size maxSize = Size.Empty;
           bool requiresOverflow = false; 
           ToolStrip toolStrip = container as ToolStrip;

           bool foundItemParticipatingInLayout = false;
 

           for (int j = 0; j < toolStrip.Items.Count; j++) { 
               ToolStripItem item = toolStrip.Items[j]; 

               if (((IArrangedElement)item).ParticipatesInLayout) { 
                   foundItemParticipatingInLayout = true;
                   if (item.Overflow != ToolStripItemOverflow.Always) {
                       Size preferredSize = GetPreferredItemSize(item);
                       Padding itemMargin = item.Margin; 
                       maxSize.Height += itemMargin.Vertical + preferredSize.Height;
                       maxSize.Width = Math.Max(maxSize.Width, itemMargin.Horizontal + preferredSize.Width); 
                   } 
                   else {
                       requiresOverflow = true; 
                   }
               }
           }
 

           if (toolStrip.Items.Count == 0 || !foundItemParticipatingInLayout) { 
               // if there are no items there, create something anyways. 
               maxSize = LayoutUtils.FlipSize( toolStrip.DefaultSize);
           } 

           if (requiresOverflow) {
               // add in the width of the overflow button
               ToolStripOverflowButton overflowItem = toolStrip.OverflowButton; 
               Padding overflowItemMargin = overflowItem.Margin;
               maxSize.Height += overflowItemMargin.Vertical + overflowItem.Bounds.Height; 
           } 
           else {
               maxSize.Height +=  2;  //add Padding to the bottom if not Overflow. 
           }

           if (toolStrip.GripStyle == ToolStripGripStyle.Visible) {
               // add in the grip width 
               Padding gripMargin = toolStrip.GripMargin;
			   maxSize.Height += gripMargin.Vertical + toolStrip.Grip.GripThickness; 
           } 

           // note here the difference in vertical - we want the strings to fit perfectly so we're not going to constrain by the specified size. 
           if (toolStrip.Size != maxSize)
           {
               CommonProperties.xClearPreferredSizeCache(toolStrip);
           } 
           return maxSize;
        } 
 
        private static Size GetPreferredItemSize(ToolStripItem item) {
            return item.AutoSize ? item.GetPreferredSize(Size.Empty) : item.Size; 
        }
#endregion
#region MeasurementGraphics
        // 
        internal static Graphics GetMeasurementGraphics() {
            return WindowsFormsUtils.CreateMeasurementGraphics(); 
        } 
#endregion
        ///  
        /// Summary of GetSelectedItem.
        /// 
        internal ToolStripItem GetSelectedItem() {
            ToolStripItem selectedItem = null; 

            for (int i = 0; i < DisplayedItems.Count; i++) { 
                if (DisplayedItems[i].Selected) { 
                    selectedItem = DisplayedItems[i];
                } 
            }

            return selectedItem;
        } 
        /// 
        ///     Retrieves the current value of the specified bit in the control's state. 
        ///  
        internal bool GetToolStripState(int flag) {
            return (toolStripState & flag) != 0; 
        }

        internal virtual ToolStrip GetToplevelOwnerToolStrip() {
            return this; 
        }
 
        /// In the case of a 
        ///    toolstrip -> toolstrip
        ///    contextmenustrip -> the control that is showing it 
        ///    toolstripdropdown -> top most toolstrip
        internal virtual Control GetOwnerControl() {
            return this;
        } 

 
        private void HandleMouseLeave() { 
            // If we had a particular item that was "entered"
            // notify it that we have left. 
            if (lastMouseActiveItem != null) {
                if (!DesignMode) {
                    MouseHoverTimer.Cancel(lastMouseActiveItem);
                } 
                try {
                    Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, "firing mouse leave on " + lastMouseActiveItem.ToString()); 
                    lastMouseActiveItem.FireEvent(EventArgs.Empty,ToolStripItemEventType.MouseLeave); 
                }
                finally { 
                    Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, "setting last active item to null");
                    lastMouseActiveItem = null;
                }
            } 
            ToolStripMenuItem.MenuTimer.HandleToolStripMouseLeave(this);
        } 
 
        /// 
        /// Summary of HandleItemClick. 
        /// 
        internal void HandleItemClick(ToolStripItem dismissingItem) {
            ToolStripItemClickedEventArgs e= new ToolStripItemClickedEventArgs(dismissingItem);
            OnItemClicked(e); 
            // VSWhidbey 395136 - ensure both the overflow and the main toolstrip fire ItemClick event
            // otherwise the overflow wont dismiss. 
            if (!IsDropDown && dismissingItem.IsOnOverflow) { 
                OverflowButton.DropDown.HandleItemClick(dismissingItem);
            } 
        }

        internal virtual void HandleItemClicked(ToolStripItem dismissingItem) {
            // post processing after the click has happened. 
            /*if (ContainsFocus && !Focused) {
                RestoreFocusInternal(); 
            }*/ 
            ToolStripDropDownItem item = dismissingItem as ToolStripDropDownItem;
            if (item != null && !item.HasDropDownItems) 
            {
                KeyboardActive = false;
            }
 
        }
 
        private void HookStaticEvents(bool hook) { 
            if (hook) {
                if (!alreadyHooked) { 
                    try {
                        ToolStripManager.RendererChanged += new EventHandler(OnDefaultRendererChanged);
                        SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnUserPreferenceChanged);
                    } 
                    finally{
                        alreadyHooked = true; 
                    } 
                }
            } 
            else if (alreadyHooked) {
                try {
                    ToolStripManager.RendererChanged -= new EventHandler(OnDefaultRendererChanged);
                    SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(OnUserPreferenceChanged); 
                }
                finally { 
                    alreadyHooked = false; 
                }
 
            }
        }

        //initialize winbar 
        private void InitializeRenderer(ToolStripRenderer renderer) {
            // wrap this in a LayoutTransaction so that if they change sizes 
            // in this method we've suspended layout. 
            using(LayoutTransaction.CreateTransactionIf(AutoSize, this, this, PropertyNames.Renderer)) {
                renderer.Initialize(this); 
                for (int i = 0; i < this.Items.Count; i++) {
                    renderer.InitializeItem(this.Items[i]);
                }
            } 
            Invalidate( this.Controls.Count > 0);
        } 
 

        // sometimes you only want to force a layout if the winbar is visible. 
        private void InvalidateLayout() {
            if (IsHandleCreated) {
                LayoutTransaction.DoLayout(this, this, null);
            } 
        }
        internal void InvalidateTextItems() { 
            using (new LayoutTransaction(this, this, "ShowKeyboardFocusCues", /*PerformLayout=*/Visible)) { 
              for (int j = 0; j < DisplayedItems.Count; j++) {
                  if (((DisplayedItems[j].DisplayStyle & ToolStripItemDisplayStyle.Text) == ToolStripItemDisplayStyle.Text)){ 
                       DisplayedItems[j].InvalidateItemLayout("ShowKeyboardFocusCues");
                  }
              }
            } 
        }
        ///  
        ///  
        /// Summary of IsInputKey.
        ///  
        /// 
        protected override bool IsInputKey(Keys keyData) {
            ToolStripItem item = this.GetSelectedItem();
            if ((item != null) && item.IsInputKey(keyData)) { 
                return true;
            } 
            return base.IsInputKey(keyData); 
        }
        ///  
        /// 
        /// Summary of IsInputChar.
        /// 
        ///  
        protected override bool IsInputChar(char charCode) {
            ToolStripItem item = this.GetSelectedItem(); 
            if ((item != null) && item.IsInputChar(charCode)) { 
                return true;
            } 
            return base.IsInputChar(charCode);
        }

        private static bool IsPseudoMnemonic(char charCode, string text) { 
            if (!String.IsNullOrEmpty(text)) {
                if (!WindowsFormsUtils.ContainsMnemonic(text)) { 
                     char charToCompare = Char.ToUpper(charCode, CultureInfo.CurrentCulture); 
                     char firstLetter = Char.ToUpper(text[0], CultureInfo.CurrentCulture);
                     if (firstLetter == charToCompare ||(Char.ToLower(charCode, CultureInfo.CurrentCulture) == Char.ToLower(text[0], CultureInfo.CurrentCulture)) ) { 
                         return true;
                     }
                }
             } 
            return false;
        } 
 
        ///  Force an item to be painted immediately, rather than waiting for WM_PAINT to occur. 
        internal void InvokePaintItem(ToolStripItem item) { 
            // Force a WM_PAINT to happen NOW.
            Invalidate(item.Bounds);
            Update();
        } 
        /// 
        ///       Gets or sets the  that contains the  displayed on a label control 
        ///  
        private void ImageListRecreateHandle(object sender, EventArgs e) {
            Invalidate(); 
        }

        /// 
        ///       This override fires the LocationChanging event if 
        ///       1) We are not currently Rafting .. since this cause this infinite times...
        ///       2) If we havent been called once .. Since the "LocationChanging" is listened to by the RaftingCell and calls "JOIN" which may call us back. 
        ///  
        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
 
            Point location = this.Location;

            if (!IsCurrentlyDragging && !IsLocationChanging && IsInToolStripPanel)
            { 
                ToolStripLocationCancelEventArgs cae = new ToolStripLocationCancelEventArgs(new Point(x, y), false);
                try { 
                    if (location.X != x || location.Y != y) { 
                        SetToolStripState(STATE_LOCATIONCHANGING, true);
                        OnLocationChanging(cae); 
                    }

                    if (!cae.Cancel) {
                        base.SetBoundsCore(x, y, width, height, specified); 
                    }
                } 
                finally { 
                    SetToolStripState(STATE_LOCATIONCHANGING, false);
                } 
            }
            else {
                if (IsCurrentlyDragging) {
                    Region transparentRegion = Renderer.GetTransparentRegion(this); 
                    if (transparentRegion != null && (location.X != x || location.Y != y)) {
                        try { 
                            Invalidate(transparentRegion); 
                            Update();
                        } 
                        finally {
                            transparentRegion.Dispose();
                        }
                    } 
                }
                SetToolStripState(STATE_LOCATIONCHANGING, false); 
                base.SetBoundsCore(x, y, width, height, specified); 
            }
 
        }

        internal void PaintParentRegion(Graphics g, Region region) {
 
        }
 
        internal bool ProcessCmdKeyInternal(ref Message m, Keys keyData) { 
            return ProcessCmdKey(ref  m, keyData);
        } 

        // This function will print to the PrinterDC. ToolStrip have there own buffered painting and doesnt play very well
        // with the DC translations done by base Control class. Hence we do our own Painting and the BitBLT the DC into the printerDc.
        // Refer to VsWhidbey : 400683. 
        internal override void PrintToMetaFileRecursive(HandleRef hDC, IntPtr lParam, Rectangle bounds) {
            Bitmap image = new Bitmap(bounds.Width, bounds.Height); 
 
            using (Graphics g = Graphics.FromImage(image)) {
                IntPtr imageHdc = g.GetHdc(); 
                //send the actual wm_print message
                UnsafeNativeMethods.SendMessage(new HandleRef(this, this.Handle), NativeMethods.WM_PRINT, (IntPtr)imageHdc,
                    (IntPtr)(NativeMethods.PRF_CHILDREN | NativeMethods.PRF_CLIENT | NativeMethods.PRF_ERASEBKGND | NativeMethods.PRF_NONCLIENT));
 
                //now BLT the result to the destination bitmap.
                IntPtr desthDC = hDC.Handle; 
                SafeNativeMethods.BitBlt(new HandleRef(this, desthDC), bounds.X, bounds.Y, bounds.Width, bounds.Height, 
                                             new HandleRef(g, imageHdc), 0, 0, NativeMethods.SRCCOPY);
                g.ReleaseHdcInternal(imageHdc); 
            }
        }

        ///  
        /// 
        /// Summary of ProcessCmdKey. 
        ///  
        /// 
        ///  
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override bool ProcessCmdKey(ref Message m, Keys keyData) {

            if (ToolStripManager.IsMenuKey(keyData)) { 
               if (!IsDropDown &&  ToolStripManager.ModalMenuFilter.InMenuMode) {
                    ClearAllSelections(); 
                    ToolStripManager.ModalMenuFilter.MenuKeyToggle = true; 
                    Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip.ProcessCmdKey] Detected a second ALT keypress while in Menu Mode.");
                    ToolStripManager.ModalMenuFilter.ExitMenuMode(); 
               }

            }
 
			// Give the ToolStripItem very first chance at
			// processing keys (except for ALT handling) 
            ToolStripItem selectedItem = this.GetSelectedItem(); 
            if (selectedItem != null){
                if (selectedItem.ProcessCmdKey(ref m, keyData)) { 
                    return true;
                }
            }
 
            foreach (ToolStripItem item in this.Items) {
                if (item == selectedItem) { 
                    continue; 
                }
                if (item.ProcessCmdKey(ref m, keyData)) { 
                    return true;
                }
            }
 

            if (!IsDropDown) { 
                bool isControlTab = ((keyData & (Keys.Tab | Keys.Control)) == (Keys.Tab | Keys.Control)); 

                if (isControlTab  && !TabStop && HasKeyboardInput) { 
                    bool handled = false;
                    if ((keyData & Keys.Shift) == Keys.None) {
                        handled = ToolStripManager.SelectNextToolStrip(this, /*forward*/true);
                    } 
                    else {
                        handled = ToolStripManager.SelectNextToolStrip(this, /*forward*/false); 
                    } 
                    if (handled) {
                        return true; 
                    }
                }
            }
            return base.ProcessCmdKey(ref m, keyData); 
        }
 
        ///  
        /// 
        /// Processes a dialog key. Overrides Control.processDialogKey(). This 
        /// method implements handling of the TAB, LEFT, RIGHT, UP, and DOWN
        /// keys in dialogs.
        /// The method performs no processing on keys that include the ALT or
        /// CONTROL modifiers. For the TAB key, the method selects the next control 
        /// on the form. For the arrow keys,
        /// !!! 
        ///  
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
        protected override bool ProcessDialogKey(Keys keyData) { 
            bool retVal = false;

            // Give the ToolStripItem first dibs
            ToolStripItem item = this.GetSelectedItem(); 
            if (item != null){
                if(item.ProcessDialogKey(keyData)) { 
                    return true; 
                }
            } 

            // if the ToolStrip receives an escape, then we
            // should send the focus back to the last item that
            // had focus. 
            bool hasModifiers = ((keyData & (Keys.Alt | Keys.Control)) != Keys.None);
 
            Keys keyCode = (Keys)keyData & Keys.KeyCode; 
            switch (keyCode) {
                case Keys.Back: 
                    // if it's focused itself, process.  if it's not focused, make sure a child control
                    // doesnt have focus before processing
                    if (!ContainsFocus) {
                        // shift backspace/backspace work as backspace, which is the same as shift+tab 
                        retVal = ProcessTabKey(false);
                    } 
                    break; 
                case Keys.Tab:
                    // ctrl+tab does nothing 
                    if (!hasModifiers){
                        retVal = ProcessTabKey((keyData & Keys.Shift) == Keys.None);
                    }
                    break; 
                case Keys.Left:
                case Keys.Right: 
                case Keys.Up: 
                case Keys.Down:
                    retVal = ProcessArrowKey(keyCode); 
                    break;
                case Keys.Home:
                    SelectNextToolStripItem(null, /*forward =*/ true );
                    retVal = true; 
                    break;
                case Keys.End: 
                    SelectNextToolStripItem(null, /*forward =*/ false ); 
                    retVal = true;
                    break; 
                case Keys.Escape: // escape and menu key should restore focus
                    // ctrl+esc does nothing
                    if (!hasModifiers && !TabStop){
                        RestoreFocusInternal(); 
                        retVal = true;
                    } 
                    break; 

            } 


            if (retVal) {
                return retVal; 
            }
            Debug.WriteLineIf(SelectionDebug.TraceVerbose, "[SelectDBG ProcessDialogKey] calling base"); 
           return base.ProcessDialogKey(keyData); 
        }
 
        internal virtual void ProcessDuplicateMnemonic(ToolStripItem item, char charCode) {
            if (!CanProcessMnemonic()) {  // Checking again for security...
                return;
            } 
            // SECREVIEW see toolstrip dropdown ProcessDuplicateMnemonic for special security implications
            if (item != null) { 
                // SECREVIEW: SetFocusUnsafe as ProcessMnemonic has link demand for AWP. 
                SetFocusUnsafe();
                item.Select(); 
            }
        }
        /// 
        ///  
        ///
        ///    Rules for parsing mnemonics 
        ///    PASS 1: Real mnemonics 
        ///    Check items for the character after the &.  If it matches, perform the click event or open the dropdown (in the case that it has dropdown items)
        ///    PASS 2: Fake mnemonics 
        ///        Begin with the current selection and parse through the first character in the items in the menu.
        ///    If there is only one item that matches
        ///     perform the click event or open the dropdown (in the case that it has dropdown items)
        ///    Else 
        ///    change the selection from the current selected item to the first item that matched.
        ///  
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] 
        protected internal override bool ProcessMnemonic(char charCode) {
            // menus and toolbars only take focus on ALT 
            if (!CanProcessMnemonic()) {
                return false;
            }
            if (Focused || ContainsFocus) { 
                return ProcessMnemonicInternal(charCode);
            } 
            bool inMenuMode = ToolStripManager.ModalMenuFilter.InMenuMode; 
            if (!inMenuMode && Control.ModifierKeys == Keys.Alt) {
                // This is the case where someone hasnt released the ALT key yet, but has pushed another letter. 
                // In some cases we can activate the menu that is not the MainMenuStrip...
                // See VSWhidbey 501382 for more details.
                return ProcessMnemonicInternal(charCode);
            } 
            else if (inMenuMode && ToolStripManager.ModalMenuFilter.GetActiveToolStrip() == this) {
                return ProcessMnemonicInternal(charCode); 
            } 

            // do not call base, as we dont want to walk through the controls collection and reprocess everything 
            // we should have processed in the displayed items collection.
            return false;

        } 
        private bool ProcessMnemonicInternal(char charCode) {
            if (!CanProcessMnemonic()) {  // Checking again for security... 
                return false; 
            }
            // at this point we assume we can process mnemonics as process mnemonic has filtered for use. 
            ToolStripItem startingItem = GetSelectedItem();
            int startIndex = 0;
            if (startingItem != null) {
                startIndex = DisplayedItems.IndexOf(startingItem); 
            }
            startIndex = Math.Max(0, startIndex); 
 
            ToolStripItem firstMatch = null;
            bool foundMenuItem = false; 
            int index = startIndex;

            // PASS1, iterate through the real mnemonics
            for (int i = 0;  i < DisplayedItems.Count; i++) { 
                ToolStripItem currentItem = DisplayedItems[index];
 
                index = (index +1)%DisplayedItems.Count; 
                if (string.IsNullOrEmpty(currentItem.Text) || !currentItem.Enabled) {
                    continue; 
                }
                // VSWhidbey 429513 - only items which display text should be processed
                if ((currentItem.DisplayStyle & ToolStripItemDisplayStyle.Text) != ToolStripItemDisplayStyle.Text) {
                    continue; 
                }
                // keep track whether we've found a menu item - we'll have to do a 
                // second pass for fake mnemonics in that case. 
                foundMenuItem =  (foundMenuItem || (currentItem is ToolStripMenuItem));
 
                if (Control.IsMnemonic(charCode,currentItem.Text)) {
                    if (firstMatch == null) {
                        firstMatch = currentItem;
                    } 
                    else {
                        // we've found a second match - we should only change selection. 
                        if (firstMatch == startingItem) { 
                            // change the selection to be the second match as the first is already selected
                            ProcessDuplicateMnemonic(currentItem, charCode); 
                        }
                        else {
                            ProcessDuplicateMnemonic(firstMatch, charCode);
                        } 
                        // we've found two mnemonics, just return.
                        return true; 
                    } 
                }
            } 
            // We've found a singular match.
            if (firstMatch != null) {
                return firstMatch.ProcessMnemonic(charCode);
            } 

            if (!foundMenuItem) { 
                return false; 
            }
 
            index = startIndex;

            // 242501 MenuStrip parity: key presses should change selection if mnemonic not present
            // if we havent found a mnemonic, cycle through the menu items and 
            // checbbbMk if we match.
 
            // PASS2, iterate through the pseudo mnemonics 
            for (int i = 0;  i < DisplayedItems.Count; i++) {
                ToolStripItem currentItem = DisplayedItems[index]; 
                index = (index +1)%DisplayedItems.Count;

                // Menu items only
                if (!(currentItem is ToolStripMenuItem)  || string.IsNullOrEmpty(currentItem.Text) || !currentItem.Enabled) { 
                    continue;
                } 
                // VSWhidbey 429513 - only items which display text should be processed 
                if ((currentItem.DisplayStyle & ToolStripItemDisplayStyle.Text) != ToolStripItemDisplayStyle.Text) {
                    continue; 
                }


                if (ToolStrip.IsPseudoMnemonic(charCode,currentItem.Text)) { 
                    if (firstMatch == null) {
                        firstMatch = currentItem; 
                    } 
                    else {
                        // we've found a second match - we should only change selection. 
                        if (firstMatch == startingItem) {
                            // change the selection to be the second match as the first is already selected
                            ProcessDuplicateMnemonic(currentItem, charCode);
                        } 
                        else {
                            ProcessDuplicateMnemonic(firstMatch, charCode); 
                        } 
                        // we've found two mnemonics, just return.
                        return true; 
                    }
                }
            }
 
            if (firstMatch != null) {
                return firstMatch.ProcessMnemonic(charCode); 
            } 

            // do not call base, as we dont want to walk through the controls collection and reprocess everything 
            // we should have processed in the displayed items collection.
            return false;
        }
 
        /// 
        ///  
        /// Summary of ProcessTabKey. 
        /// 
        ///  
        private bool ProcessTabKey(bool forward) {
            if (TabStop) {
               // ToolBar in tab-order parity
               //  this means we want the toolstrip in the normal tab order - which means it shouldnt wrap. 
               //  First tab gets you into the toolstrip, second tab moves you on your way outside the container.
               //  arrow keys would continue to wrap. 
               return false; 
            }
            else { 
                // TabStop = false
                // this means we dont want the toolstrip in the normal tab order (default).
                // We got focus to the toolstrip by putting focus into a control contained on the toolstrip or
                // via a mnemonic e.g. Bold.  In this case we want to wrap. 
                // arrow keys would continue to wrap
                if (RightToLeft == RightToLeft.Yes) { 
                    forward = !forward; 
                }
                SelectNextToolStripItem(GetSelectedItem(), forward); 
                return true;
            }
        }
 
        /// 
        ///  
        /// Summary of ProcessArrowKey: this is more useful than overriding ProcessDialogKey because usually 
        /// the difference between ToolStrip/ToolStripDropDown is arrow key handling.  ProcessDialogKey first gives
        /// the selected ToolStripItem the chance to process the message... so really a proper inheritor would 
        /// call down to the base first. Unfortunately doing this would cause the the arrow keys would be eaten
        /// in the base class.  Instead we're providing a separate place to override all arrow key handling.
        /// 
        internal virtual bool ProcessArrowKey(Keys keyCode) { 

            bool retVal = false; 
            Debug.WriteLineIf(MenuAutoExpandDebug.TraceVerbose, "[ToolStrip.ProcessArrowKey] MenuTimer.Cancel called"); 
            ToolStripMenuItem.MenuTimer.Cancel();
 
            switch (keyCode) {
                    case Keys.Left:
                    case Keys.Right:
                        retVal = ProcessLeftRightArrowKey(keyCode == Keys.Right); 
                        break;
                    case Keys.Up: 
                    case Keys.Down: 
                        if (IsDropDown || Orientation != Orientation.Horizontal) {
                            ToolStripItem currentSel = GetSelectedItem(); 
                            if (keyCode == Keys.Down) {
                                ToolStripItem nextItem = GetNextItem(currentSel, ArrowDirection.Down);
                                if (nextItem != null) {
                                    ChangeSelection(nextItem); 
                                    retVal = true;
                                } 
                            } 
                            else {
                                ToolStripItem nextItem = GetNextItem(currentSel, ArrowDirection.Up); 
                                if (nextItem != null){
                                    ChangeSelection(nextItem);
                                    retVal = true;
                                } 
                            }
                        } 
                        break; 
            }
            return retVal; 
        }

        /// 
        ///     Process an arrowKey press by selecting the next control in the group 
        ///     that the activeControl belongs to.
        ///  
        ///  
        private bool ProcessLeftRightArrowKey(bool right) {
            ToolStripItem selectedItem = GetSelectedItem(); 
            ToolStripItem nextItem = SelectNextToolStripItem(GetSelectedItem(), right);
            return true;
        }
 
        /// 
        /// Summary of NotifySelectionChange. 
        ///  
        /// 
        internal void NotifySelectionChange(ToolStripItem item) { 
            if (item == null) {
                Debug.WriteLineIf(SelectionDebug.TraceVerbose, "[SelectDBG NotifySelectionChange] none should be selected");
                ClearAllSelections();
            } 
            else if (item.Selected) {
                Debug.WriteLineIf(SelectionDebug.TraceVerbose, "[SelectDBG NotifySelectionChange] Notify selection change: " + item.ToString() + ": " + item.Selected.ToString()); 
                ClearAllSelectionsExcept(item); 
            }
        } 

        private void OnDefaultRendererChanged(object sender, EventArgs e) {
            // callback from static event
            if (GetToolStripState(STATE_USEDEFAULTRENDERER)) { 
                OnRendererChanged(e);
            } 
        } 

        protected virtual void OnBeginDrag(EventArgs e) { 
            SetToolStripState(STATE_DRAGGING, true);
            Debug.Assert(ToolStripPanelRow != null, "Why is toolstrippanel row null?");
            Debug.Assert(this.ParentInternal as ToolStripPanel != null, "Why is our parent not a toolstrip panel?");
 
            ClearAllSelections();
            UpdateToolTip(null); // supress the tooltip. 
            EventHandler handler = (EventHandler)Events[EventBeginDrag]; 
            if (handler != null)  handler(this,e);
        } 

        protected virtual void OnEndDrag(EventArgs e) {
            SetToolStripState(STATE_DRAGGING, false);
            Debug.Assert(ToolStripPanelRow != null, "Why is toolstrippanel row null?"); 
            Debug.Assert(this.ParentInternal as ToolStripPanel != null, "Why is our parent not a toolstrip panel?");
            Debug.Assert(ToolStripPanelRow == null || ToolStripPanelRow.ToolStripPanel.RowsInternal.Contains(ToolStripPanelRow), "Why are we in an orphaned row?"); 
 
            EventHandler handler = (EventHandler)Events[EventEndDrag];
            if (handler != null)  handler(this,e); 

        }

 

        protected override void OnDockChanged(EventArgs e){ 
            base.OnDockChanged(e); 
        }
 
        /// 
        protected virtual void OnRendererChanged(EventArgs e) {
           InitializeRenderer(Renderer);
 
           EventHandler handler = (EventHandler)Events[EventRendererChanged];
           if (handler != null)  handler(this,e); 
 
        }
        ///  
        /// 
        /// Summary of OnEnabledChanged.
        /// 
        protected override void OnEnabledChanged(EventArgs e) { 
            base.OnEnabledChanged(e);
 
            // notify items that the parent has changed 
            for (int i = 0; i < this.Items.Count; i++) {
                if (Items[i] != null && Items[i].ParentInternal == this) { 
                    Items[i].OnParentEnabledChanged(e);
                }
            }
 
        }
 
 
        internal void OnDefaultFontChanged() {
            defaultFont = null; 
            if (!IsFontSet()) {
                OnFontChanged(EventArgs.Empty);
            }
        } 

        protected override void OnFontChanged(EventArgs e) { 
            base.OnFontChanged(e); 
            for (int i = 0; i < this.Items.Count; i++) {
                 Items[i].OnOwnerFontChanged(e); 
            }
        }

        protected override void OnInvalidated(InvalidateEventArgs e) { 
            base.OnInvalidated(e);
#if false 
// DEBUG code which is helpful for FlickerFest debugging. 
            if (FlickerDebug.TraceVerbose) {
                string name = this.Name; 
                if (string.IsNullOrEmpty(name)) {
                    if (IsDropDown) {
                        ToolStripItem item = ((ToolStripDropDown)this).OwnerItem;
                        if (item != null && item.Name != null) { 
                            name = item.Name = ".DropDown";
                        } 
                    } 
                    if (string.IsNullOrEmpty(name)) {
                        name = this.GetType().Name; 
                    }
                }
                // for debugging VS we want to filter out the propgrid toolstrip
                Debug.WriteLineIf(!(this.ParentInternal is PropertyGrid), "Invalidate called on: " + name + new StackTrace().ToString()); 
            }
#endif 
        } 
        /// 
        ///  
        /// Summary of OnHandleCreated.
        /// 
        protected override void OnHandleCreated(EventArgs e) {
            if ((this.AllowDrop || this.AllowItemReorder) && (DropTargetManager != null)) { 
                this.DropTargetManager.EnsureRegistered(this);
            } 
 
            // calling control's (in base) version AFTER we register our DropTarget, so it will
            // listen to us instead of control's implementation 
            base.OnHandleCreated(e);
        }

        ///  
        /// 
        /// Summary of OnHandleDestroyed. 
        ///  
        protected override void OnHandleDestroyed(EventArgs e) {
            if (DropTargetManager != null) { 
                // Make sure we unregister ourselves as a drop target
                this.DropTargetManager.EnsureUnRegistered(this);
            }
            base.OnHandleDestroyed(e); 
        }
 
        ///  
        protected internal virtual void OnItemAdded(ToolStripItemEventArgs e) {
            DoLayoutIfHandleCreated(e); 

            if (!HasVisibleItems && e.Item != null && ((IArrangedElement)e.Item).ParticipatesInLayout) {
                // VSWhidbey 441403
                // in certain cases, we may not have laid out yet (e.g. a dropdown may not layout until 
                // it becomes visible.)   We will recalculate this in SetDisplayedItems, but for the moment
                // if we find an item that ParticipatesInLayout, mark us as having visible items. 
                HasVisibleItems = true; 
            }
 
            ToolStripItemEventHandler handler = (ToolStripItemEventHandler)Events[EventItemAdded];
            if (handler != null) handler(this, e);
        }
 
        /// 
        ///  
        /// Called when an item has been clicked on the winbar. 
        /// 
        protected virtual void OnItemClicked(ToolStripItemClickedEventArgs e) { 
            ToolStripItemClickedEventHandler handler = (ToolStripItemClickedEventHandler)Events[EventItemClicked];
            if (handler != null) handler(this, e);

        } 

        ///  
        protected internal virtual void OnItemRemoved(ToolStripItemEventArgs e) { 

            // clear cached item states. 
            OnItemVisibleChanged(e, /*performlayout*/true);

            ToolStripItemEventHandler handler = (ToolStripItemEventHandler)Events[EventItemRemoved];
            if (handler != null) handler(this, e); 
        }
 
 
        internal void OnItemVisibleChanged(ToolStripItemEventArgs e, bool performLayout) {
 
            // clear cached item states.
            if (e.Item == lastMouseActiveItem) {
                lastMouseActiveItem = null;
            } 
            if (e.Item == LastMouseDownedItem) {
                lastMouseDownedItem = null; 
            } 
            if (e.Item == currentlyActiveTooltipItem) {
                UpdateToolTip(null); 
            }
            if (performLayout) {
                DoLayoutIfHandleCreated(e);
            } 
        }
        ///  
        protected override void OnLayout(LayoutEventArgs e) { 
            this.LayoutRequired = false;
 
            // we need to do this to prevent autosizing to happen while we're reparenting.
            ToolStripOverflow overflow = GetOverflow();
            if (overflow != null) {
                 overflow.SuspendLayout(); 
                 toolStripOverflowButton.Size = toolStripOverflowButton.GetPreferredSize(this.DisplayRectangle.Size - this.Padding.Size);
            } 
 
            for (int j = 0; j < Items.Count; j++) {
               Items[j].OnLayout(e); 
            }

            base.OnLayout(e);
            SetDisplayedItems(); 
            OnLayoutCompleted(EventArgs.Empty);
            Invalidate(); 
 
            if (overflow != null) {
                overflow.ResumeLayout(); 
            }
        }

        ///  
        protected virtual void OnLayoutCompleted(EventArgs e) {
            EventHandler handler = (EventHandler)Events[EventLayoutCompleted]; 
            if (handler != null) handler(this, e); 
        }
 
        /// 
        protected virtual void OnLayoutStyleChanged(EventArgs e) {
             EventHandler handler = (EventHandler)Events[EventLayoutStyleChanged];
             if (handler != null) handler(this, e); 
        }
 
        ///  
        protected override void OnLostFocus(EventArgs e) {
            base.OnLostFocus(e); 
            ClearAllSelections();
        }

        protected override void OnLeave(EventArgs e) { 
            base.OnLeave(e);
            if (!IsDropDown) { 
                Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "uninstalling RestoreFocusFilter"); 

                // PERF, SECREVIEW: dont call Application.RemoveMessageFilter as this could 
                // get called a lot and we want to have to assert AWP.
                Application.ThreadContext.FromCurrent().RemoveMessageFilter(RestoreFocusFilter);
            }
        } 
        /// 
        internal virtual void OnLocationChanging(ToolStripLocationCancelEventArgs e) { 
            ToolStripLocationCancelEventHandler handler = (ToolStripLocationCancelEventHandler)Events[EventLocationChanging]; 
            if (handler != null) handler(this, e);
        } 

        /// 
        /// 
        /// Delegate mouse down to the winbar and its affected items 
        /// 
        protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs mea) { 
 
            // NEVER use this directly from another class.  Always use GetMouseID so that
            // 0 is not returned to another class. 
            mouseDownID++;

            ToolStripItem item = GetItemAt(mea.X, mea.Y);
            if (item != null) { 
                if (!IsDropDown && (!(item is ToolStripDropDownItem))){
                    // set capture only when we know we're not on a dropdown (already effectively have capture due to modal menufilter) 
                    // and the item in question requires the mouse to be in the same item to be clicked. 
                    SetToolStripState(STATE_LASTMOUSEDOWNEDITEMCAPTURE, true);
                    this.CaptureInternal = true; 
                }
                MenuAutoExpand = true;

                if (mea != null) { 
                    // Transpose this to "client coordinates" of the ToolStripItem.
                    Point itemRelativePoint = item.TranslatePoint(new Point(mea.X, mea.Y), ToolStripPointType.ToolStripCoords, ToolStripPointType.ToolStripItemCoords); 
                    mea = new MouseEventArgs(mea.Button, mea.Clicks,itemRelativePoint.X, itemRelativePoint.Y, mea.Delta); 
                }
                lastMouseDownedItem = item; 
                item.FireEvent(mea, ToolStripItemEventType.MouseDown);
            }
            else {
                base.OnMouseDown(mea); 
            }
 
        } 

 
        /// 
        /// 
        /// Delegate mouse moves to the winbar and its affected items
        ///  
        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs mea) {
            Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose,"OnMouseMove called"); 
 
            ToolStripItem item = GetItemAt(mea.X, mea.Y);
 
            if (!Grip.MovingToolStrip) {

                // If we had a particular item that was "entered"
                // notify it that we have entered.  It's fair to put 
                // this in the MouseMove event, as MouseEnter is fired during
                // control's WM_MOUSEMOVE. Waiting until this event gives us 
                // the actual coordinates. 

 
                Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, String.Format(CultureInfo.CurrentCulture, "Item to get mouse move: {0}",  (item == null) ? "null" : item.ToString()));
                if (item != lastMouseActiveItem) {
                    Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, String.Format(CultureInfo.CurrentCulture, "This is a new item - last item to get was {0}",  (lastMouseActiveItem == null) ? "null" : lastMouseActiveItem.ToString()));
 
                    // notify the item that we've moved on
                    HandleMouseLeave(); 
 
                    // track only items that dont get mouse events themselves.
                    lastMouseActiveItem = (item is ToolStripControlHost) ? null : item; 

                    if (lastMouseActiveItem != null) {
                        Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, String.Format(CultureInfo.CurrentCulture, "Firing MouseEnter on: {0}",  (lastMouseActiveItem == null) ? "null" : lastMouseActiveItem.ToString()));
                        item.FireEvent(new System.EventArgs(), ToolStripItemEventType.MouseEnter); 
                    }
                    // 
 
                    if (!DesignMode) {
                        MouseHoverTimer.Start(lastMouseActiveItem); 
                    }


 
                }
            } 
            else { 
                item = this.Grip;
            } 
            if (item != null) {
                Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, String.Format(CultureInfo.CurrentCulture, "Firing MouseMove on: {0}",  (item == null) ? "null" : item.ToString()));

                // Fire mouse move on the item 
                // Transpose this to "client coordinates" of the ToolStripItem.
                Point itemRelativePoint = item.TranslatePoint(new Point(mea.X, mea.Y), ToolStripPointType.ToolStripCoords, ToolStripPointType.ToolStripItemCoords); 
                mea = new MouseEventArgs(mea.Button, mea.Clicks,itemRelativePoint.X, itemRelativePoint.Y, mea.Delta); 
                item.FireEvent(mea, ToolStripItemEventType.MouseMove);
            } 
            else {
                Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, String.Format(CultureInfo.CurrentCulture, "Firing MouseMove on: {0}",  (this == null) ? "null" : this.ToString()));

                base.OnMouseMove(mea); 
            }
        } 
 

 
        /// 
        /// 
        /// Delegate mouse leave to the winbar and its affected items
        ///  
        protected override void OnMouseLeave(System.EventArgs e) {
            HandleMouseLeave(); 
            base.OnMouseLeave(e); 
        }
 

        /// 
        protected override void OnMouseCaptureChanged(System.EventArgs e) {
            if (!GetToolStripState(STATE_SUSPENDCAPTURE)) { 
                // while we're showing a feedback rect, dont cancel moving the toolstrip.
                Grip.MovingToolStrip = false; 
            } 
            ClearLastMouseDownedItem();
 


            base.OnMouseCaptureChanged(e);
        } 

        ///  
        ///  
        /// Delegate mouse up to the winbar and its affected items
        ///  
        protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs mea) {

            ToolStripItem item = (Grip.MovingToolStrip) ? Grip : GetItemAt(mea.X, mea.Y);
 
            if (item != null) {
                if (mea != null) { 
                    // Transpose this to "client coordinates" of the ToolStripItem. 
                    Point itemRelativePoint = item.TranslatePoint(new Point(mea.X, mea.Y), ToolStripPointType.ToolStripCoords, ToolStripPointType.ToolStripItemCoords);
                    mea = new MouseEventArgs(mea.Button, mea.Clicks,itemRelativePoint.X, itemRelativePoint.Y, mea.Delta); 
                }
                item.FireEvent(mea, ToolStripItemEventType.MouseUp);
            }
            else { 
                base.OnMouseUp(mea);
            } 
            ClearLastMouseDownedItem(); 

        } 



 
        protected override void OnPaint(PaintEventArgs e) {
              base.OnPaint(e); 
 
              Graphics toolstripGraphics = e.Graphics;
              Size bitmapSize  = this.largestDisplayedItemSize; 
              bool excludedTransparentRegion = false;

              Rectangle viewableArea = this.DisplayRectangle;
              Region transparentRegion = Renderer.GetTransparentRegion(this); 

              try { 
 
                  // Paint the items
                  // The idea here is to let items pretend they are controls. 
                  // they should get paint events at 0,0 and have proper clipping regions
                  // set up for them.  We cannot use g.TranslateTransform as that does
                  // not translate the GDI world, and things like XP Visual Styles and the
                  // TextRenderer only know how to speak GDI. 
                  //
                  // The previous appropach was to set up the GDI clipping region and allocate a graphics 
                  // from that, but that meant we were allocating graphics objects left and right, which 
                  // turned out to be slow.
                  // 
                  // So now we allocate an offscreen bitmap of size == MaxItemSize, copy the background
                  // of the toolstrip into that bitmap, then paint the item on top of the bitmap, then copy
                  // the contents of the bitmap back onto the toolstrip.  This gives us our paint event starting
                  // at 0,0.  Combine this with double buffering of the toolstrip and the entire toolstrip is updated 
                  // after returning from this function.
                  if (!LayoutUtils.IsZeroWidthOrHeight(bitmapSize)) { 
                    // cant create a 0x0 bmp. 

                     // Supporting RoundedEdges... 
                     // we've got a concept of a region that we shouldnt paint (the TransparentRegion as specified in the Renderer).
                     // in order to support this we're going to intersect that region with the clipping region.
                     // this new region will be excluded during the guts of OnPaint, and restored at the end of OnPaint.
                     if (transparentRegion != null) { 
                           // only use the intersection so we can easily add back in the bits we took out at the end.
                           transparentRegion.Intersect(toolstripGraphics.Clip); 
                           toolstripGraphics.ExcludeClip(transparentRegion); 
                           excludedTransparentRegion = true;
                     } 

                     // Preparing for painting the individual items...
                     // using WindowsGraphics here because we want to preserve the clipping information.
 
                     // calling GetHdc by itself does not set up the clipping info.
                      using(WindowsGraphics toolStripWindowsGraphics = WindowsGraphics.FromGraphics(toolstripGraphics, ApplyGraphicsProperties.Clipping)){ 
                          // get the cached item HDC. 
                          HandleRef toolStripHDC = new HandleRef(this, toolStripWindowsGraphics.GetHdc());
                          HandleRef itemHDC = ItemHdcInfo.GetCachedItemDC(toolStripHDC, bitmapSize); 

                          Graphics itemGraphics = Graphics.FromHdcInternal(itemHDC.Handle);
                          try {
                                // Painting the individual items... 
                                // iterate through all the items, painting them
                                // one by one into the compatible offscreen DC, and then copying 
                                // them back onto the main toolstrip. 
                                for (int i = 0; i < DisplayedItems.Count; i++) {
                                   ToolStripItem item = DisplayedItems[i]; 
                                   if (item != null)  { //
                                       Rectangle clippingRect = e.ClipRectangle;
                                       Rectangle bounds = item.Bounds;
 
                                       if (!IsDropDown && item.Owner == this) {
                                           // owned items should not paint outside the client 
                                           // area. (this is mainly to prevent obscuring the grip 
                                           // and overflowbutton - ToolStripDropDownMenu places items
                                           // outside of the display rectangle - so we need to allow for this 
                                           // in dropdoowns).
                                           clippingRect.Intersect(viewableArea);
                                       }
 
                                       // get the intersection of these two.
                                       clippingRect.Intersect(bounds); 
 
                                       if (LayoutUtils.IsZeroWidthOrHeight(clippingRect)) {
                                           continue;  // no point newing up a graphics object if there's nothing to paint. 
                                       }

                                       Size itemSize = item.Size;
 
                                       // check if our item buffer is large enough to handle.
                                       if (!LayoutUtils.AreWidthAndHeightLarger(bitmapSize, itemSize)) { 
                                            // the cached HDC isnt big enough for this item.  make it bigger. 
                                            this.largestDisplayedItemSize = itemSize;
                                            bitmapSize = itemSize; 
                                            // dispose the old graphics - create a new, bigger one.
                                            itemGraphics.Dispose();

                                            // calling this should take the existing DC and select in a bigger bitmap. 
                                            itemHDC = ItemHdcInfo.GetCachedItemDC(toolStripHDC, bitmapSize);
 
                                            // allocate a new graphics. 
                                            itemGraphics = Graphics.FromHdcInternal(itemHDC.Handle);
 
                                       }
                                       // since the item graphics object will have 0,0 at the
                                       // corner we need to actually shift the origin of the rect over
                                       // so it will be 0,0 too. 
                                       clippingRect.Offset(-bounds.X, -bounds.Y);
 
                                       // PERF - consider - we only actually need to copy the clipping rect. 
                                       // copy the background from the toolstrip onto the offscreen bitmap
                                       SafeNativeMethods.BitBlt(itemHDC, 0, 0, item.Size.Width, item.Size.Height, toolStripHDC, item.Bounds.X, item.Bounds.Y, NativeMethods.SRCCOPY); 

                                       // paint the item into the offscreen bitmap
                                       using (PaintEventArgs itemPaintEventArgs = new PaintEventArgs(itemGraphics, clippingRect)) {
                                           item.FireEvent(itemPaintEventArgs, ToolStripItemEventType.Paint); 
                                       }
 
                                       // copy the item back onto the toolstrip 
                                       SafeNativeMethods.BitBlt(toolStripHDC, item.Bounds.X, item.Bounds.Y, item.Size.Width, item.Size.Height, itemHDC, 0, 0, NativeMethods.SRCCOPY);
 
                                    }
                                }
                          }
                          finally { 
                                if (itemGraphics != null) {
                                    itemGraphics.Dispose(); 
                                } 
                          }
                      } 

                  }

                  // Painting the edge effects... 
                  // These would include things like (shadow line on the bottom, some overflow effects)
                  Renderer.DrawToolStripBorder(new ToolStripRenderEventArgs(toolstripGraphics, this)); 
 
                  // Restoring the clip region to its original state...
                  // the transparent region should be added back in as the insertion mark should paint over it. 
                  if (excludedTransparentRegion) {
                     toolstripGraphics.SetClip(transparentRegion,CombineMode.Union);
                  }
 
                  // Paint the item re-order insertion mark...
                  // This should ignore the transparent region and paint 
                  // over the entire area. 
                  PaintInsertionMark(toolstripGraphics);
              } 
              finally {
                 if (transparentRegion != null) {
                     transparentRegion.Dispose();
                 } 
              }
        } 
 

 
        /// 
        /// 
        /// [To be supplied.]
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected override void OnRightToLeftChanged(EventArgs e) { 
            base.OnRightToLeftChanged(e); 

            // normally controls just need to do handle recreation, but ToolStrip does it based on layout of items. 
            using(new LayoutTransaction(this, this, PropertyNames.RightToLeft)) {
                for (int i = 0; i < Items.Count; i++) {
                    Items[i].OnParentRightToLeftChanged(e);
                } 
                if (toolStripOverflowButton != null) {
                    toolStripOverflowButton.OnParentRightToLeftChanged(e); 
                } 
                if (toolStripGrip != null) {
                    toolStripGrip.OnParentRightToLeftChanged(e); 
                }
            }

 
        }
 
        ///  
        /// 
        /// Inheriting classes should override this method to handle the erase 
        /// background request from windows. It is not necessary to call
        /// base.onPaintBackground, however if you do not want the default
        /// Windows behavior you must set event.handled to true.
        ///  
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected override void OnPaintBackground(PaintEventArgs e) { 
            base.OnPaintBackground(e); 

            Graphics g = e.Graphics; 
            GraphicsState graphicsState = g.Save();
            try {
                using (Region transparentRegion = Renderer.GetTransparentRegion(this)) {
                    if (transparentRegion != null) { 
                        EraseCorners(e, transparentRegion);
                        g.ExcludeClip(transparentRegion); 
                    } 
                }
                Renderer.DrawToolStripBackground(new ToolStripRenderEventArgs(g, this)); 

            }
            finally {
                if (graphicsState != null) { 
                    g.Restore(graphicsState);
                } 
            } 
        }
 
        protected override void OnVisibleChanged(EventArgs e) {
            base.OnVisibleChanged(e);
            if (!Disposing && !IsDisposed) {
                HookStaticEvents(Visible); 
            }
        } 
 

 
        private void EraseCorners(PaintEventArgs e, Region transparentRegion) {
            if (transparentRegion != null) {
               PaintTransparentBackground(e, ClientRectangle, transparentRegion);
            } 
        }
 
        ///  
        /// 
        /// Summary of OnPaint. 
        /// 
        internal protected virtual void OnPaintGrip(System.Windows.Forms.PaintEventArgs e) {

            Renderer.DrawGrip(new ToolStripGripRenderEventArgs(e.Graphics, this)); 

            PaintEventHandler handler = (PaintEventHandler)Events[EventPaintGrip]; 
            if (handler != null)  handler(this,e); 

 
        }

        /// 
        protected override void OnScroll(ScrollEventArgs se) { 

            if (se.Type != ScrollEventType.ThumbTrack && se.NewValue != se.OldValue) { 
               ScrollInternal(se.OldValue - se.NewValue); 
            }
            base.OnScroll(se); 

        }

        private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { 
            switch (e.Category) {
                case UserPreferenceCategory.Window: 
                    OnDefaultFontChanged(); 
                    break;
                case UserPreferenceCategory.General: 
                    InvalidateTextItems();
                    break;
            }
 
        }
 
        protected override void OnTabStopChanged(EventArgs e) { 
            // VSWhidbey 442518 - SelectNextControl can select non-tabstop things.
            // we need to prevent this by changing the value of "CanSelect" 
            SetStyle(ControlStyles.Selectable, TabStop);
            base.OnTabStopChanged(e);
        }
        ///  
        /// Paints the I beam when items are being reordered
        ///  
        internal void PaintInsertionMark(Graphics g) { 
            if (lastInsertionMarkRect != Rectangle.Empty)  {
                int widthOfBeam = INSERTION_BEAM_WIDTH; 
                if (Orientation == Orientation.Horizontal) {
                   int start = lastInsertionMarkRect.X;
                   int verticalBeamStart = start + 2;
 
                   // draw two vertical lines
                   g.DrawLines(SystemPens.ControlText, 
                       new Point[] { new Point(verticalBeamStart, lastInsertionMarkRect.Y), new Point(verticalBeamStart, lastInsertionMarkRect.Bottom-1), // first vertical line 
   								  new Point(verticalBeamStart+1, lastInsertionMarkRect.Y), new Point(verticalBeamStart+1, lastInsertionMarkRect.Bottom-1), //second  vertical line
   								  }); 
                   // then two top horizontal
                   g.DrawLines(SystemPens.ControlText,
                       new Point[] { new Point(start, lastInsertionMarkRect.Bottom-1), new Point(start + widthOfBeam-1, lastInsertionMarkRect.Bottom-1), //bottom line
   								  new Point(start+1, lastInsertionMarkRect.Bottom -2), new Point(start + widthOfBeam-2, lastInsertionMarkRect.Bottom-2),//bottom second line 
   								  });
                   // then two bottom horizontal 
                   g.DrawLines(SystemPens.ControlText, 
                        new Point[] {  new Point(start, lastInsertionMarkRect.Y), new Point(start + widthOfBeam-1, lastInsertionMarkRect.Y), //top line
   									new Point(start+1, lastInsertionMarkRect.Y+1), new Point(start + widthOfBeam-2, lastInsertionMarkRect.Y+1)//top second line 
   									});
                }
                else {
 
                    widthOfBeam = INSERTION_BEAM_WIDTH;
                    int start = lastInsertionMarkRect.Y; 
                    int horizontalBeamStart = start + 2; 

                    // draw two horizontal lines 
                    g.DrawLines(SystemPens.ControlText,
                        new Point[] { new Point(lastInsertionMarkRect.X, horizontalBeamStart), new Point(lastInsertionMarkRect.Right-1, horizontalBeamStart), // first vertical line
    								  new Point(lastInsertionMarkRect.X, horizontalBeamStart+1), new Point(lastInsertionMarkRect.Right-1, horizontalBeamStart+1), //second  vertical line
    								  }); 
                    // then two left vertical
                    g.DrawLines(SystemPens.ControlText, 
                        new Point[] { new Point(lastInsertionMarkRect.X, start), new Point(lastInsertionMarkRect.X, start + widthOfBeam-1), //left line 
    								  new Point(lastInsertionMarkRect.X+1, start+1), new Point(lastInsertionMarkRect.X+1, start + widthOfBeam-2), //second left line
    								   }); 
                    // then two right vertical
                    g.DrawLines(SystemPens.ControlText,
                         new Point[] { new Point(lastInsertionMarkRect.Right-1, start), new Point(lastInsertionMarkRect.Right-1, start + widthOfBeam-1), //right line
    								  new Point(lastInsertionMarkRect.Right-2, start+1), new Point(lastInsertionMarkRect.Right-2, start + widthOfBeam-2), //second right line 
                                      });
                } 
 
            }
        } 

        /// 
        /// Paints the I beam when items are being reordered
        ///  
        internal void PaintInsertionMark(Rectangle insertionRect) {
            if (lastInsertionMarkRect != insertionRect)  { 
                ClearInsertionMark(); 
                lastInsertionMarkRect = insertionRect;
                this.Invalidate(insertionRect); 
            }
        }

        [EditorBrowsable(EditorBrowsableState.Never)] 
        public new Control GetChildAtPoint(Point point) {
            return base.GetChildAtPoint(point); 
        } 

        [EditorBrowsable(EditorBrowsableState.Never)] 
        public new Control GetChildAtPoint(Point pt, GetChildAtPointSkip skipValue) {
            return base.GetChildAtPoint(pt, skipValue);
        }
 
        // GetNextControl for ToolStrip should always return null
        // we do our own tabbing/etc - this allows us to pretend 
        // we dont have child controls. 
        internal override Control GetFirstChildControlInTabOrder(bool forward) {
           return null; 
        }
        /// 
        /// 
        /// Finds the ToolStripItem contained within a specified client coordinate point 
        /// If item not found - returns null
        ///  
        public ToolStripItem GetItemAt(int x, int y) { 
            return GetItemAt(new Point(x,y));
        } 


        /// 
        ///  
        /// Finds the ToolStripItem contained within a specified client coordinate point
        /// If item not found - returns null 
        ///  
        public ToolStripItem GetItemAt(Point point) {
 
            Rectangle comparisonRect = new Rectangle(point, onePixel);
            Rectangle bounds;

            // Check the last item we had the mouse over 
            if (lastMouseActiveItem != null) {
                bounds = lastMouseActiveItem.Bounds; 
 
                if (bounds.IntersectsWith(comparisonRect) && lastMouseActiveItem.ParentInternal == this) {
                    return this.lastMouseActiveItem; 
                }
            }

 
            // Walk the ToolStripItem collection
            for (int i = 0; i < this.DisplayedItems.Count; i++) { 
                if (DisplayedItems[i] == null || DisplayedItems[i].ParentInternal != this) { 
                    continue;
                } 

                bounds = DisplayedItems[i].Bounds;

                // inflate the grip so it is easier to access 
                if (toolStripGrip != null && DisplayedItems[i] == toolStripGrip) {
                    bounds = LayoutUtils.InflateRect(bounds, GripMargin); 
                } 
                if (bounds.IntersectsWith(comparisonRect)) {
                    return this.DisplayedItems[i]; 
                }
            }

            return null; 

        } 
 
        private void RestoreFocusInternal(bool wasInMenuMode) {
            // VSWhidbey 503500 
            // This is called from the RestoreFocusFilter.  If the state of MenuMode has changed
            // since we posted this message, we do not know enough information about whether
            // we should exit menu mode.
            if (wasInMenuMode == ToolStripManager.ModalMenuFilter.InMenuMode) { 
                RestoreFocusInternal();
            } 
        } 

        ///  RestoreFocus - returns focus to the control who activated us 
        ///          See comment on SnapFocus
        /// 
        internal void RestoreFocusInternal() {
            ToolStripManager.ModalMenuFilter.MenuKeyToggle = false; 
            ClearAllSelections();
            lastMouseDownedItem = null; 
 
            Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip.RestoreFocus] Someone has called RestoreFocus, exiting MenuMode.");
            ToolStripManager.ModalMenuFilter.ExitMenuMode(); 

            if (!IsDropDown) {
                // reset menu auto expansion.
                Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip.RestoreFocus] Setting menu auto expand to false"); 
                Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip.RestoreFocus] uninstalling RestoreFocusFilter");
 
                // PERF, SECREVIEW: dont call Application.RemoveMessageFilter as this could 
                // get called a lot and we want to have to assert AWP.
                Application.ThreadContext.FromCurrent().RemoveMessageFilter(RestoreFocusFilter); 

                MenuAutoExpand = false;

                if (!DesignMode && !TabStop && (Focused || ContainsFocus)) { 
                   RestoreFocus();
                } 
 
            }
 
            // this matches the case where you click on a toolstrip control host
            // then tab off of it, then hit ESC.  ESC would "restore focus" and
            // we should cancel keyboard activation if this method has cancelled focus.
            if (KeyboardActive && !Focused && !ContainsFocus) { 
                KeyboardActive = false;
            } 
 
        }
 
        // override if you want to control (when TabStop = false) where the focus returns to
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void RestoreFocus() {
 
           bool focusSuccess = false;
 
           if ((hwndThatLostFocus != IntPtr.Zero) && (hwndThatLostFocus != this.Handle)) { 
                Control c = Control.FromHandleInternal(hwndThatLostFocus);
 
                Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip RestoreFocus]: Will Restore Focus to: " + WindowsFormsUtils.GetControlInformation(hwndThatLostFocus));
                hwndThatLostFocus = IntPtr.Zero;

                if ((c != null) && c.Visible) { 
                    focusSuccess = c.FocusInternal();
                } 
            } 
            hwndThatLostFocus = IntPtr.Zero;
 
            if (!focusSuccess) {
                // clear out the focus, we have focus, we're not supposed to anymore.
                UnsafeNativeMethods.SetFocus(NativeMethods.NullHandleRef);
            } 
        }
 
        internal virtual void ResetRenderMode() { 
            RenderMode = ToolStripRenderMode.ManagerRenderMode;
        } 

        /// 
        [EditorBrowsable(EditorBrowsableState.Never)]
        public void ResetMinimumSize() { 
            CommonProperties.SetMinimumSize(this, new Size(-1,-1));
        } 
 
        private void ResetGripMargin() {
            GripMargin = Grip.DefaultMargin; 
        }

        internal void ResumeCaputureMode() {
            SetToolStripState(STATE_SUSPENDCAPTURE, false); 
        }
 
        internal void SuspendCaputureMode() { 
            SetToolStripState(STATE_SUSPENDCAPTURE, true);
        } 

        internal virtual void ScrollInternal(int delta) {
            SuspendLayout();
            foreach (ToolStripItem item in this.Items) { 
                Point newLocation = item.Bounds.Location;
 
                newLocation.Y -= delta; 

                SetItemLocation(item, newLocation); 
            }

            ResumeLayout(false);
            Invalidate(); 
        }
 
        ///  
        /// 
        /// Summary of SetItemLocation 
        /// 
        /// 
        protected internal void SetItemLocation(ToolStripItem item, Point location) {
            if (item == null) { 
                throw new ArgumentNullException("item");
            } 
            if (item.Owner != this) { 
                throw new NotSupportedException(SR.GetString(SR.ToolStripCanOnlyPositionItsOwnItems));
            } 

            item.SetBounds(new Rectangle(location, item.Size));
        }
        ///  
        /// 
        /// This is needed so that people doing custom layout engines can change the "Parent" property of the item. 
        ///  
        protected static void SetItemParent(ToolStripItem item, ToolStrip parent) {
             item.Parent = parent; 
        }

        protected override void SetVisibleCore(bool visible) {
            if (visible) { 
                SnapMouseLocation();
            } 
            else { 
                // make sure we reset selection - this is critical for close/reopen dropdowns.
                if (!Disposing && !IsDisposed) { 
                    ClearAllSelections();
                }

                // when we're not visible, clear off old item HDC. 
                CachedItemHdcInfo lastInfo = cachedItemHdcInfo;
                cachedItemHdcInfo = null; 
 
                lastMouseDownedItem = null;
 
                if (lastInfo != null) {
                    lastInfo.Dispose();
                }
            } 
            base.SetVisibleCore(visible);
        } 
 
        internal bool ShouldSelectItem() {
            // we only want to select the item if the cursor position has 
            // actually moved from when the window became visible.

            // We ALWAYS get a WM_MOUSEMOVE when the window is shown,
            // which could accidentally change selection. 
            if (mouseEnterWhenShown == InvalidMouseEnter) {
                Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, "[TS: ShouldSelectItem] MouseEnter already reset."); 
                return true; 
            }
 
            Point mousePosition = WindowsFormsUtils.LastCursorPoint;
            if (mouseEnterWhenShown != mousePosition) {
                Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, "[TS: ShouldSelectItem] Mouse position has changed - call Select().");
                mouseEnterWhenShown = InvalidMouseEnter; 
                return true;
            } 
            Debug.WriteLineIf(ToolStripItem.MouseDebugging.TraceVerbose, "[TS: ShouldSelectItem] Mouse hasnt actually moved yet."); 

            return false; 
        }
        /// 
        /// 
        /// Summary of Select. 
        /// 
        ///  
        ///  
        protected override void Select(bool directed, bool forward) {
            bool correctParentActiveControl = true; 
            if (ParentInternal != null) {
                IContainerControl c = ParentInternal.GetContainerControlInternal();

                if (c != null) { 
                    c.ActiveControl = this;
                    correctParentActiveControl = (c.ActiveControl == this); 
                } 
            }
            if (directed && correctParentActiveControl) { 
                SelectNextToolStripItem(null, forward);
            }
        }
 

        ///  
        /// Summary of SelectNextToolStripItem. 
        ///
 


        internal ToolStripItem SelectNextToolStripItem(ToolStripItem start, bool forward) {
 
            ToolStripItem nextItem = GetNextItem(start, (forward) ? ArrowDirection.Right : ArrowDirection.Left, /*RTLAware=*/true);
            ChangeSelection(nextItem); 
            return nextItem; 
        }
 
        //
        // SECREVIEW: only call from places protected by a link demand for AllWindowsPermission.
        //
        internal void SetFocusUnsafe() { 
            if (TabStop) {
                Debug.WriteLineIf(SnapFocusDebug.TraceVerbose,"[ToolStrip.SetFocus] Focusing toolstrip."); 
                FocusInternal(); 
            }
            else { 
                Debug.WriteLineIf(SnapFocusDebug.TraceVerbose,"[ToolStrip.SetFocus] Entering menu mode.");
                ToolStripManager.ModalMenuFilter.SetActiveToolStrip(this, /*menuKeyPressed=*/false);
            }
        } 

        private void SetupGrip() { 
           Rectangle gripRectangle = Rectangle.Empty; 
           Rectangle displayRect = DisplayRectangle;
 

           if (Orientation == Orientation.Horizontal) {
               // the display rectangle already knows about the padding and the grip rectangle width
               // so place it relative to that. 
               gripRectangle.X = Math.Max(0, displayRect.X - Grip.GripThickness);
               gripRectangle.Y = Math.Max(0,displayRect.Top - Grip.Margin.Top); 
               gripRectangle.Width = Grip.GripThickness; 
               gripRectangle.Height = displayRect.Height;
               if (RightToLeft == RightToLeft.Yes) { 
                   gripRectangle.X = ClientRectangle.Right - gripRectangle.Width - Grip.Margin.Horizontal;
                   gripRectangle.X  += Grip.Margin.Left;
               }
               else { 
                   gripRectangle.X  -= Grip.Margin.Right;
               } 
           } 
           else {
               // vertical split stack mode 
               gripRectangle.X = displayRect.Left;
               gripRectangle.Y = displayRect.Top - (Grip.GripThickness + Grip.Margin.Bottom);
               gripRectangle.Width = displayRect.Width;
               gripRectangle.Height = Grip.GripThickness; 
           }
 
           if (Grip.Bounds !=gripRectangle) { 
               Grip.SetBounds(gripRectangle);
           } 

        }

        ///  
        /// 
        ///     
        ///       Sets the size of the auto-scroll margins. 
        ///    
        ///  
        [EditorBrowsable(EditorBrowsableState.Never)]
        new public void SetAutoScrollMargin(int x, int y) {
            base.SetAutoScrollMargin(x, y);
        } 

        internal void SetLargestItemSize(Size size) { 
 
            if (toolStripOverflowButton != null && toolStripOverflowButton.Visible) {
                size = LayoutUtils.UnionSizes(size, toolStripOverflowButton.Bounds.Size); 
            }
            if (toolStripGrip != null && toolStripGrip.Visible) {
                size = LayoutUtils.UnionSizes(size, toolStripGrip.Bounds.Size);
 
            }
            largestDisplayedItemSize = size; 
 
        }
 
        /// 
        /// 
        /// Afer we've performed a layout we need to reset the DisplayedItems and the OverflowItems collection.
        /// OverflowItems are not supported in layouts other than ToolStripSplitStack 
        /// 
        protected virtual void SetDisplayedItems() { 
            this.DisplayedItems.Clear(); 
            this.OverflowItems.Clear();
            HasVisibleItems = false; 

            Size biggestItemSize  = Size.Empty; // used in determining OnPaint caching.

 
            if (this.LayoutEngine is ToolStripSplitStackLayout) {
                if (ToolStripGripStyle.Visible == GripStyle) { 
                    this.DisplayedItems.Add(Grip); 
                    SetupGrip();
                } 

                // VSWhidbey 468104
                // for splitstack layout we re-arrange the items in the displayed items
                // collection so that we can easily tab through them in natural order 
                Rectangle displayRect = this.DisplayRectangle;
                int lastRightAlignedItem = -1; 
 
                for (int pass=0; pass < 2; pass++) {
                    int j = 0; 

                    if (pass == 1 /*add right aligned items*/) {
                        j = lastRightAlignedItem;
                    } 

                    // add items to the DisplayedItem collection. 
                    // in pass 0, we go forward adding the head (left) aligned items 
                    // in pass 1, we go backward starting from the last (right) aligned item we found
 
                    for (; j >= 0 && j < Items.Count; j = (pass == 0) ? j+1 : j-1){

                        ToolStripItem item = Items[j];
                        ToolStripItemPlacement placement = item.Placement; 
                        if (((IArrangedElement)item).ParticipatesInLayout) {
                            if (placement == ToolStripItemPlacement.Main) { 
                               bool addItem = false; 
                               if (pass == 0) { // Align.Left items
                                    addItem = (item.Alignment ==  ToolStripItemAlignment.Left); 
                                    if (!addItem) {
                                        // stash away this index so we dont have to iterate through the whole list again.
                                        lastRightAlignedItem = j;
                                    } 
                               }
                               else if (pass == 1) { // Align.Right items 
                                   addItem =  (item.Alignment ==  ToolStripItemAlignment.Right); 
                               }
                               if (addItem) { 
                                   HasVisibleItems = true;
                                   biggestItemSize = LayoutUtils.UnionSizes(biggestItemSize, item.Bounds.Size);
                                   this.DisplayedItems.Add(item);
                               } 
                            }
                            else if (placement == ToolStripItemPlacement.Overflow && !(item is ToolStripSeparator)) { 
                                if (item is ToolStripControlHost && this.OverflowButton.DropDown.IsRestrictedWindow) { 
                                   // VSWhidbey 436973: control hosts cannot be added to the overflow in the Internet
                                   // just set the placement to None. 
                                   item.SetPlacement(ToolStripItemPlacement.None);
                                }
                                else {
                                    this.OverflowItems.Add(item); 
                                }
                            } 
                        } 
                        else {
                            item.SetPlacement(ToolStripItemPlacement.None); 
                        }
                    }

                } 
                ToolStripOverflow overflow = GetOverflow();
                if (overflow != null) { 
                    overflow.LayoutRequired = true; 
                }
                if (OverflowItems.Count ==0) { 
                    this.OverflowButton.Visible = false;
                }
                else if (CanOverflow){
                    this.DisplayedItems.Add(OverflowButton); 
                }
 
            } 
            else {
                // NOT a SplitStack layout.  We dont change the order of the displayed items collection 
                // for custom keyboard handling override GetNextItem.
                Debug.WriteLineIf(LayoutDebugSwitch.TraceVerbose, "Setting Displayed Items: Current bounds: " + this.Bounds.ToString());
                Rectangle clientBounds = this.ClientRectangle;
 
                // for all other layout managers, we ignore overflow placement
                bool allContained = true; 
                for (int j = 0; j < Items.Count; j++) { 
                    ToolStripItem item = Items[j];
                    if (((IArrangedElement)item).ParticipatesInLayout) 
 					{
                        item.ParentInternal = this;

                        bool boundsCheck = !IsDropDown; 
                        bool intersects = item.Bounds.IntersectsWith(clientBounds);
 
                        bool verticallyContained = clientBounds.Contains(clientBounds.X, item.Bounds.Top) && 
                        						clientBounds.Contains(clientBounds.X, item.Bounds.Bottom);
                        if (!verticallyContained) { 
                        	allContained = false;
                        }

                        if (!boundsCheck || intersects) { 
                        	HasVisibleItems = true;
                        	biggestItemSize = LayoutUtils.UnionSizes(biggestItemSize, item.Bounds.Size); 
                        	this.DisplayedItems.Add(item); 
                        	item.SetPlacement(ToolStripItemPlacement.Main);
                        } 
                    }
                    else {
                         item.SetPlacement(ToolStripItemPlacement.None);
                    } 

                    Debug.WriteLineIf(LayoutDebugSwitch.TraceVerbose, item.ToString() + Items[j].Bounds); 
                } 

                // For performance we calculate this here, since we're already iterating over the items. 
                // the only one who cares about it is ToolStripDropDownMenu (to see if it needs scroll buttons).
                this.AllItemsVisible = allContained;
            }
 
            SetLargestItemSize(biggestItemSize);
        } 
 

        ///  
        ///     Sets the current value of the specified bit in the control's state.
        /// 
        internal void SetToolStripState(int flag, bool value) {
            toolStripState = value? toolStripState | flag: toolStripState & ~flag; 
        }
 
        // remembers the current mouse location so we can determine 
        // later if we need to shift selection.
        internal void SnapMouseLocation() { 
            mouseEnterWhenShown = WindowsFormsUtils.LastCursorPoint;
        }

 
        ///  SnapFocus
        ///    When get focus to the toolstrip (and we're not participating in the tab order) 
        ///    it's probably cause someone hit the ALT key. We need to remember who that was 
        ///    so when we're done here we can RestoreFocus back to it.
        /// 
        ///    We're called from WM_SETFOCUS, and otherHwnd is the HWND losing focus.
        ///
        ///    Required checks
        ///        - make sure it's not a dropdown 
        ///        - make sure it's not a child control of this control.
        ///        - make sure the control is on this window 
        ///  
        private void SnapFocus(IntPtr otherHwnd) {
#if DEBUG 
            if (SnapFocusDebug.TraceVerbose) {
                string stackTrace = new StackTrace().ToString();
                Regex regex = new Regex("FocusInternal");
                Debug.WriteLine(!regex.IsMatch(stackTrace), "who is setting focus to us?"); 
            }
#endif 
            // we need to know who sent us focus so we know who to send it back to later. 

            if (!TabStop && !IsDropDown) { 
               bool snapFocus = false;
               if (Focused && (otherHwnd != this.Handle)) {
                    // the case here is a label before a combo box calling FocusInternal in ProcessMnemonic.
                    // we'll filter out children later. 
                    snapFocus = true;
               } 
               else if (!ContainsFocus && !Focused) { 
                    snapFocus =true;
               } 

               if (snapFocus) {
                   // remember the current mouse position so that we can check later if it actually moved
                   // otherwise we'd unexpectedly change selection to whatever the cursor was over at this moment. 
                   SnapMouseLocation();
 
                   // start auto expanding for keyboard and mouse. 
                  // MenuAutoExpand = true;
 
                   HandleRef thisHandle = new HandleRef(this, this.Handle);
                   HandleRef otherHandle = new HandleRef(null, otherHwnd);

                   // make sure the otherHandle is not a child of thisHandle 
                   if ((thisHandle.Handle != otherHandle.Handle) &&
                       !UnsafeNativeMethods.IsChild(thisHandle, otherHandle)) { 
 
                      // make sure the root window of the otherHwnd is the same as
                      // the root window of thisHwnd. 
                      HandleRef thisHwndRoot = WindowsFormsUtils.GetRootHWnd(this);
                      HandleRef otherHwndRoot = WindowsFormsUtils.GetRootHWnd(otherHandle);

                      if (thisHwndRoot.Handle == otherHwndRoot.Handle && (thisHwndRoot.Handle != IntPtr.Zero)) { 
                           Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip SnapFocus]: Caching for return focus:" + WindowsFormsUtils.GetControlInformation(otherHandle.Handle));
                           // we know we're in the same window heirarchy. 
                           hwndThatLostFocus = otherHandle.Handle; 
                      }
                   } 
               }
           }

        } 

        // when we're control tabbing around we need to remember the original 
        // thing that lost focus. 
        internal void SnapFocusChange(ToolStrip otherToolStrip) {
            otherToolStrip.hwndThatLostFocus = this.hwndThatLostFocus; 
        }

        private bool ShouldSerializeDefaultDropDownDirection() {
            return (toolStripDropDownDirection != ToolStripDropDownDirection.Default); 
        }
 
        internal virtual bool ShouldSerializeLayoutStyle() { 
            return layoutStyle != ToolStripLayoutStyle.StackWithOverflow;
        } 

        internal override bool ShouldSerializeMinimumSize() {
            Size invalidDefaultSize = new Size(-1,-1);
            return (CommonProperties.GetMinimumSize(this, invalidDefaultSize) != invalidDefaultSize); 
        }
 
        private bool ShouldSerializeGripMargin() { 
            return GripMargin != DefaultGripMargin;
        } 

        internal virtual bool ShouldSerializeRenderMode() {
            // We should NEVER serialize custom.
            return (RenderMode != ToolStripRenderMode.ManagerRenderMode && RenderMode != ToolStripRenderMode.Custom); 
        }
 
        public override string ToString() { 
            StringBuilder sb = new StringBuilder(base.ToString());
            sb.Append(", Name: "); 
            sb.Append(this.Name);
            sb.Append(", Items: ").Append(this.Items.Count);
            return sb.ToString();
        } 

        internal void UpdateToolTip(ToolStripItem item) { 
            if (ShowItemToolTips) { 

                if (item != currentlyActiveTooltipItem && ToolTip != null) { 

                    // SECREVIEW: VSWhidbey 531915 - ToolTip should show in internet zone
                    IntSecurity.AllWindows.Assert();
                    try { 
                        ToolTip.Hide(this);
                    } 
                    finally { 
                         System.Security.CodeAccessPermission.RevertAssert();
                    } 
                    ToolTip.Active = false;

                    currentlyActiveTooltipItem = item;
 

                    if (currentlyActiveTooltipItem != null && !GetToolStripState(STATE_DRAGGING)) { 
                        Cursor currentCursor = Cursor.CurrentInternal; 

                        if (currentCursor != null) { 
                            ToolTip.Active = true;

                            Point cursorLocation = Cursor.Position;
                            cursorLocation.Y += Cursor.Size.Height - currentCursor.HotSpot.Y; 

                            cursorLocation = WindowsFormsUtils.ConstrainToScreenBounds(new Rectangle(cursorLocation, onePixel)).Location; 
 
                            // SECREVIEW: VSWhidbey 531915 - ToolTip should show in internet zone
                            IntSecurity.AllWindows.Assert(); 
                            try {
                                ToolTip.Show(currentlyActiveTooltipItem.ToolTipText,
                                         this,
                                         PointToClient(cursorLocation), 
                                         ToolTip.AutoPopDelay);
                            } 
                            finally { 
                                System.Security.CodeAccessPermission.RevertAssert();
                            } 
                        }
                    }
                }
            } 

        } 
 
        private void UpdateLayoutStyle(DockStyle newDock) {
            if (!IsInToolStripPanel && layoutStyle  != ToolStripLayoutStyle.HorizontalStackWithOverflow  && layoutStyle  != ToolStripLayoutStyle.VerticalStackWithOverflow) { 
                using (new LayoutTransaction(this, this, PropertyNames.Orientation)) {
                    //
                    //  We want the ToolStrip to size appropriately when the dock has switched.
                    // 
                    if (newDock == DockStyle.Left || newDock == DockStyle.Right) {
                        UpdateOrientation(Orientation.Vertical); 
                    } 
                    else {
                        UpdateOrientation(Orientation.Horizontal); 
                    }
                }

                OnLayoutStyleChanged(EventArgs.Empty); 

                if (this.ParentInternal != null) { 
                    LayoutTransaction.DoLayout(this.ParentInternal, this, PropertyNames.Orientation); 
                }
            } 
        }

        private void UpdateLayoutStyle(Orientation newRaftingRowOrientation) {
           if (layoutStyle  != ToolStripLayoutStyle.HorizontalStackWithOverflow  && layoutStyle  != ToolStripLayoutStyle.VerticalStackWithOverflow) { 
               using (new LayoutTransaction(this, this, PropertyNames.Orientation)) {
 
                     // 
                     //  We want the ToolStrip to size appropriately when the rafting container orientation has switched.
                     // 
                  /*   if (newRaftingRowOrientation != orientation) {
                         int oldHeight = this.Height;
                         this.Height = this.Width;
                         this.Width = oldHeight; 
                     }*/
 
                     UpdateOrientation(newRaftingRowOrientation); 
                     if (LayoutEngine is ToolStripSplitStackLayout && layoutStyle == ToolStripLayoutStyle.StackWithOverflow) {
                         OnLayoutStyleChanged(EventArgs.Empty); 
                     }

                 }
			} 
            else {
                // update the orientation but dont force a layout. 
               UpdateOrientation(newRaftingRowOrientation); 
            }
 
        }


        private void UpdateOrientation(Orientation newOrientation) { 
            if (newOrientation != orientation) {
                // snap our last dimensions before switching over. 
                // use specifed bounds so that if something is docked or anchored we dont take the extra stretching 
                // effects into account.
                Size size = CommonProperties.GetSpecifiedBounds(this).Size; 
                orientation = newOrientation;
                // since the Grip affects the DisplayRectangle, we need to re-adjust the size
                SetupGrip();
            } 
        }
 
        ///  
        /// 
        /// Summary of WndProc. 
        /// 
        /// 
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m) { 

            if (m.Msg == NativeMethods.WM_SETFOCUS) { 
                SnapFocus(m.WParam); 
            }
            if (m.Msg == NativeMethods.WM_MOUSEACTIVATE) { 
                    // we want to prevent taking focus if someone clicks on the toolstrip dropdown
                    // itself.  the mouse message will still go through, but focus wont be taken.
                    // if someone clicks on a child control (combobox, textbox, etc) focus will
                    // be taken - but we'll handle that in WM_NCACTIVATE handler. 
                    Point pt = PointToClient(WindowsFormsUtils.LastCursorPoint);
                    IntPtr hwndClicked = UnsafeNativeMethods.ChildWindowFromPointEx(new HandleRef(null, Handle), pt.X, pt.Y,(int)(GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Disabled | GetChildAtPointSkip.Transparent)); 
                    // if we click on the toolstrip itself, eat the activation. 
                    // if we click on a child control, allow the toolstrip to activate.
                    if (hwndClicked == this.Handle) { 
                        lastMouseDownedItem = null;
                        m.Result = (IntPtr)NativeMethods.MA_NOACTIVATE;

                        if (!IsDropDown) { 

                            // VSWhidbey 473357: if our root HWND is not the active hwnd, 
                            // eat the mouse message and bring the form to the front. 
                            HandleRef rootHwnd = WindowsFormsUtils.GetRootHWnd(this);
                            if (rootHwnd.Handle != IntPtr.Zero) { 

                                // snap the active window and compare to our root window.
                                IntPtr hwndActive = UnsafeNativeMethods.GetActiveWindow();
                                if (hwndActive != rootHwnd.Handle) { 
                                    // Activate the window, and discard the mouse message.
                                    // this appears to be the same behavior as office. 
                                    m.Result = (IntPtr)NativeMethods.MA_ACTIVATEANDEAT; 
                                }
                            } 
                        }
                        return;
                    }
                    else { 
                        // we're setting focus to a child control - remember who gave it to us
                        // so we can restore it on ESC. 
                        SnapFocus(UnsafeNativeMethods.GetFocus()); 
                        if (!IsDropDown && !TabStop) {
                            Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "Installing restoreFocusFilter"); 
                            // PERF, SECREVIEW: dont call Application.AddMessageFilter as this could
                            // get called a lot and we want to have to assert AWP.
                            Application.ThreadContext.FromCurrent().AddMessageFilter(RestoreFocusFilter);
                        } 
                    }
            } 
 

            base.WndProc(ref m); 

            if (m.Msg == NativeMethods.WM_NCDESTROY) {
                // Destroy the owner window, if we created one.  We
                // cannot do this in OnHandleDestroyed, because at 
                // that point our handle is not actually destroyed so
                // destroying our parent actually causes a recursive 
                // WM_DESTROY. 
                if (dropDownOwnerWindow != null) {
                    dropDownOwnerWindow.DestroyHandle(); 
                }
            }
        }
 
        // Overriden to return Items instead of Controls.
        ///  
        ///  
        ArrangedElementCollection IArrangedElement.Children {
            get { return Items; } 
        }

        /// 
        ///  
        void IArrangedElement.SetBounds(Rectangle bounds, BoundsSpecified specified) {
            SetBoundsCore(bounds.X, bounds.Y, bounds.Width, bounds.Height, specified); 
        } 

        ///  
        /// 
        bool IArrangedElement.ParticipatesInLayout {
            get { return GetState(STATE_VISIBLE);}
        } 

        ///  
        protected override AccessibleObject CreateAccessibilityInstance() { 
            return new ToolStripAccessibleObject(this);
        } 

        /// 
        protected override Control.ControlCollection CreateControlsInstance() {
            return new WindowsFormsUtils.ReadOnlyControlCollection(this, /* isReadOnly = */ !DesignMode); 
        }
 
      ///  
        [System.Runtime.InteropServices.ComVisible(true)]
        public class ToolStripAccessibleObject : ControlAccessibleObject { 

            private ToolStrip owner;

            ///  
            public ToolStripAccessibleObject(ToolStrip owner) : base(owner) {
                this.owner = owner; 
            } 

            ///  
            /// 
            /// Return the child object at the given screen coordinates.
            /// 
            public override AccessibleObject HitTest(int x, int y) { 

                Point clientHit = owner.PointToClient(new Point(x,y)); 
                ToolStripItem item = owner.GetItemAt(clientHit); 
                return ((item != null) && (item.AccessibilityObject != null)) ?
                    item.AccessibilityObject : 
                    base.HitTest(x,y);
            }

 
            /// 
            ///  
            /// When overridden in a derived class, gets the accessible child corresponding to the specified 
            /// index.
            ///  
            //
            public override AccessibleObject GetChild(int index) {
                if ((owner == null) || (owner.Items == null))
                    return null; 

                if (index == 0 && owner.Grip.Visible) { 
                    return owner.Grip.AccessibilityObject; 
                }
                else if (owner.Grip.Visible && index > 0) { 
                    index--;
                }

                if (index < owner.Items.Count) { 
                    ToolStripItem item = null;
                    int myIndex = 0; 
 
                    // First we walk through the head aligned items.
                    for (int i = 0; i < owner.Items.Count; ++i) 
                    {
                        if (owner.Items[i].Available  && owner.Items[i].Alignment == ToolStripItemAlignment.Left) {
                            if (myIndex == index) {
                                item = owner.Items[i]; 
                                break;
                            } 
                            myIndex++; 
                        }
                    } 

                    // If we didn't find it, then we walk through the tail aligned items.
                    if (item == null) {
                        for (int i = 0; i < owner.Items.Count; ++i) { 
                            if (owner.Items[i].Available && owner.Items[i].Alignment == ToolStripItemAlignment.Right) {
                                if (myIndex == index) { 
                                    item = owner.Items[i]; 
                                    break;
                                } 
                                myIndex++;
                            }
                        }
                    } 

                    if (item == null) { 
                        Debug.Fail("No item matched the index??"); 
                        return null;
                    } 

                    if (item.Placement == ToolStripItemPlacement.Overflow) {
                        return new ToolStripAccessibleObjectWrapperForItemsOnOverflow(item);
                    } 
                    return item.AccessibilityObject;
                } 
 
                if (owner.CanOverflow && owner.OverflowButton.Visible && index == owner.Items.Count) {
                    return owner.OverflowButton.AccessibilityObject; 
                }
                return null;
            }
 
            /// 
            ///  
            ///  When overridden in a derived class, gets the number of children 
            /// belonging to an accessible object.
            ///  
            public override int GetChildCount() {
                if ((owner == null) || (owner.Items == null))
                    return -1;
 
                int count = 0;
                for (int i = 0; i < owner.Items.Count; i++) { 
                    if (owner.Items[i].Available) { 
                        count++;
                    } 
                }
                if (owner.Grip.Visible){
                    count++;
                } 
                if (owner.CanOverflow && owner.OverflowButton.Visible) {
                    count++; 
                } 
                return count;
 

            }

            ///  
            public override AccessibleRole Role {
                get { 
                    AccessibleRole role = Owner.AccessibleRole; 
                    if (role != AccessibleRole.Default) {
                        return role; 
                    }
                    return AccessibleRole.ToolBar;
                }
            } 

        } 
 
        private class ToolStripAccessibleObjectWrapperForItemsOnOverflow : ToolStripItem.ToolStripItemAccessibleObject {
            public ToolStripAccessibleObjectWrapperForItemsOnOverflow(ToolStripItem item) 
                : base(item) {
            }
            public override AccessibleStates State {
                get { 
                    AccessibleStates state = base.State;
                    state |= AccessibleStates.Offscreen; 
                    state |= AccessibleStates.Invisible; 
                    return state;
                } 
            }
        }

        // When we click somewhere outside of the toolstrip it should be as if we hit esc. 

        internal class RestoreFocusMessageFilter : IMessageFilter { 
              private ToolStrip ownerToolStrip; 

              public RestoreFocusMessageFilter(ToolStrip ownerToolStrip) { 
                  this.ownerToolStrip = ownerToolStrip;
              }

              public bool PreFilterMessage(ref Message m) { 

                  if (ownerToolStrip.Disposing || ownerToolStrip.IsDisposed || ownerToolStrip.IsDropDown) { 
                        return false; 
                  }
                  // if the app has changed activation, restore focus 

                  switch (m.Msg) {

                       case NativeMethods.WM_LBUTTONDOWN: 
                       case NativeMethods.WM_RBUTTONDOWN:
                       case NativeMethods.WM_MBUTTONDOWN: 
                       case NativeMethods.WM_NCLBUTTONDOWN: 
                       case NativeMethods.WM_NCRBUTTONDOWN:
                       case NativeMethods.WM_NCMBUTTONDOWN: 
                            if (ownerToolStrip.ContainsFocus) {
                                // if we've clicked on something that's not a child of the toolstrip and we
                                // currently have focus, restore it.
                                if (!UnsafeNativeMethods.IsChild(new HandleRef(this, ownerToolStrip.Handle), new HandleRef(this,m.HWnd))) { 
                                    HandleRef rootHwnd =  WindowsFormsUtils.GetRootHWnd(ownerToolStrip);
                                    if (rootHwnd.Handle == m.HWnd || UnsafeNativeMethods.IsChild(rootHwnd, new HandleRef(this,m.HWnd))) { 
                                        // Only RestoreFocus if the hwnd is a child of the root window and isnt on the toolstrip. 
                                        RestoreFocusInternal();
                                    } 
                                }
                            }
                           return false;
 
                      default:
                          return false; 
                  } 
              }
              private void RestoreFocusInternal() { 
                  Debug.WriteLineIf(SnapFocusDebug.TraceVerbose, "[ToolStrip.RestoreFocusFilter] Detected a click, restoring focus.");


                  ownerToolStrip.BeginInvoke(new BooleanMethodInvoker(ownerToolStrip.RestoreFocusInternal), new object[]{ ToolStripManager.ModalMenuFilter.InMenuMode } ); 

                  // PERF, SECREVIEW: dont call Application.RemoveMessageFilter as this could 
                  // get called a lot and we want to have to assert AWP. 
                  Application.ThreadContext.FromCurrent().RemoveMessageFilter(this);
              } 
        }

    }
 

 
 

    internal class CachedItemHdcInfo : IDisposable { 

        internal CachedItemHdcInfo() {
        }
 
        ~CachedItemHdcInfo() {
            Dispose(); 
        } 

        private HandleRef cachedItemHDC = NativeMethods.NullHandleRef; 
        private Size cachedHDCSize = Size.Empty;
        private HandleRef cachedItemBitmap = NativeMethods.NullHandleRef;
        // this DC is cached and should only be deleted on Dispose or when the size changes.
        public HandleRef GetCachedItemDC(HandleRef toolStripHDC, Size bitmapSize) { 

               if ((cachedHDCSize.Width < bitmapSize.Width) 
                    || (cachedHDCSize.Height < bitmapSize.Height)) { 

                    if (cachedItemHDC.Handle == IntPtr.Zero) { 
                        // create a new DC - we dont have one yet.
                        IntPtr compatibleHDC = UnsafeNativeMethods.CreateCompatibleDC(toolStripHDC);
                        cachedItemHDC = new HandleRef(this, compatibleHDC);
                    } 

                    // create compatible bitmap with the correct size. 
                    cachedItemBitmap = new HandleRef(this, SafeNativeMethods.CreateCompatibleBitmap(toolStripHDC, bitmapSize.Width, bitmapSize.Height)); 
                    IntPtr oldBitmap = SafeNativeMethods.SelectObject(cachedItemHDC,cachedItemBitmap);
 
                    // delete the old bitmap
                    if (oldBitmap != IntPtr.Zero) {
                      // ExternalDelete to prevent Handle underflow
                      SafeNativeMethods.ExternalDeleteObject(new HandleRef(null, oldBitmap)); 
                      oldBitmap = IntPtr.Zero;
                    } 
 

                    // remember what size we created. 
                    cachedHDCSize = bitmapSize;

               }
               return cachedItemHDC; 
        }
 
 
        private void DeleteCachedItemHDC() {
 
            if (cachedItemHDC.Handle != IntPtr.Zero) {
               // delete the bitmap
               if (cachedItemBitmap.Handle != IntPtr.Zero) {
                  SafeNativeMethods.DeleteObject(cachedItemBitmap); 
                  cachedItemBitmap = NativeMethods.NullHandleRef;
               } 
               // delete the DC itself. 
               UnsafeNativeMethods.DeleteCompatibleDC(cachedItemHDC);
            } 

            cachedItemHDC = NativeMethods.NullHandleRef;
            cachedItemBitmap = NativeMethods.NullHandleRef;
            cachedHDCSize = Size.Empty; 
        }
 
        public void Dispose() { 
           DeleteCachedItemHDC();
           GC.SuppressFinalize(this); 
        }

    }
 

 
    internal class MouseHoverTimer : IDisposable { 

           private System.Windows.Forms.Timer mouseHoverTimer = new System.Windows.Forms.Timer(); 
           private const int SPI_GETMOUSEHOVERTIME_WIN9X = 400;  // in Win9x this is not supported so lets use the default from a more modern OS.

           // consider - weak reference?
           private ToolStripItem currentItem = null; 

           public MouseHoverTimer() { 
               int interval = SystemInformation.MouseHoverTime; 
               if (interval == 0) {
                   interval = SPI_GETMOUSEHOVERTIME_WIN9X; 
               }

               mouseHoverTimer.Interval = interval;
               mouseHoverTimer.Tick    += new EventHandler(OnTick); 
           }
 
           public void Start(ToolStripItem item) { 
               if (item != currentItem) {
                   Cancel(currentItem); 
               }
               currentItem = item;
               if (currentItem != null) {
                   mouseHoverTimer.Enabled = true; 
               }
           } 
 

           public void Cancel() { 
                mouseHoverTimer.Enabled = false;
                currentItem = null;
           }
           /// cancels if and only if this item was the one that 
           ///         requested the timer
           /// 
           public void Cancel(ToolStripItem item) { 
               if (item == currentItem) {
                   Cancel(); 
              }
           }

           public void Dispose() { 
              if (mouseHoverTimer != null) {
                  Cancel(); 
                  mouseHoverTimer.Dispose(); 
                  mouseHoverTimer = null;
              } 
           }


           private void OnTick(object sender, EventArgs e) { 
               mouseHoverTimer.Enabled = false;
               if (currentItem != null && !currentItem.IsDisposed) { 
                   currentItem.FireEvent(EventArgs.Empty,ToolStripItemEventType.MouseHover); 
               }
           } 


       }
 
        ///  
        ///   This class supports the AllowItemReorder feature. 
        ///   When reordering items ToolStrip and ToolStripItem drag/drop events 
        ///   are routed here.
        ///  
        internal sealed class ToolStripSplitStackDragDropHandler : IDropTarget, ISupportOleDropSource {

            private ToolStrip owner;
 
            public ToolStripSplitStackDragDropHandler(ToolStrip owner) {
 
                if (owner == null) { 
                    //
                    throw new ArgumentNullException("owner"); 
                }
                this.owner = owner;
            }
 
            public void OnDragEnter(DragEventArgs e){
                Debug.WriteLineIf(ToolStrip.ItemReorderDebug.TraceVerbose, "OnDragEnter: " + e.ToString()); 
                if (e.Data.GetDataPresent(typeof(ToolStripItem))) { 
                    e.Effect = DragDropEffects.Move;
                    this.ShowItemDropPoint(owner.PointToClient(new Point(e.X, e.Y))); 

                }
            }
 
            public void OnDragLeave(System.EventArgs e){
                Debug.WriteLineIf(ToolStrip.ItemReorderDebug.TraceVerbose, "OnDragLeave: " + e.ToString()); 
                owner.ClearInsertionMark(); 
            }
 
            public void OnDragDrop(DragEventArgs e){
                Debug.WriteLineIf(ToolStrip.ItemReorderDebug.TraceVerbose, "OnDragDrop: " + e.ToString());

 
                if (e.Data.GetDataPresent(typeof(ToolStripItem))) {
                    ToolStripItem item = (ToolStripItem)e.Data.GetData(typeof(ToolStripItem)); 
                    OnDropItem(item, owner.PointToClient(new Point(e.X, e.Y))); 
                }
 
            }
            public void OnDragOver(DragEventArgs e){
                Debug.WriteLineIf(ToolStrip.ItemReorderDebug.TraceVerbose, "OnDragOver: " + e.ToString());
 
                if (e.Data.GetDataPresent(typeof(ToolStripItem))) {
                    if (this.ShowItemDropPoint(owner.PointToClient(new Point(e.X, e.Y)))) { 
                        e.Effect = DragDropEffects.Move; 
                    }
                    else { 
                        if (owner != null) {
                            owner.ClearInsertionMark();
                        }
                        e.Effect = DragDropEffects.None; 
                    }
                } 
 

            } 

            public void OnGiveFeedback(GiveFeedbackEventArgs e) {
            }
 
            public void OnQueryContinueDrag(QueryContinueDragEventArgs e) {
            } 
 
            private void OnDropItem(ToolStripItem droppedItem, Point ownerClientAreaRelativeDropPoint) {
                Point start = Point.Empty; 

                int toolStripItemIndex = GetItemInsertionIndex(ownerClientAreaRelativeDropPoint);
                if (toolStripItemIndex >= 0) {
                    ToolStripItem item = owner.Items[toolStripItemIndex]; 
                    if (item == droppedItem) {
                        owner.ClearInsertionMark(); 
                        return;  // optimization 
                    }
 
                    RelativeLocation relativeLocation = ComparePositions(item.Bounds, ownerClientAreaRelativeDropPoint);
                    droppedItem.Alignment = item.Alignment;

                    // Protect against negative indicies 
                    int insertIndex = Math.Max(0, toolStripItemIndex);
 
                    if (relativeLocation == RelativeLocation.Above) { 
                        insertIndex = (item.Alignment == ToolStripItemAlignment.Left) ? insertIndex : insertIndex + 1;
                    } 
                    else if (relativeLocation == RelativeLocation.Below) {
                        insertIndex = (item.Alignment == ToolStripItemAlignment.Left) ? insertIndex : insertIndex-1;
                    }
                    else if (((item.Alignment == ToolStripItemAlignment.Left) && (relativeLocation == RelativeLocation.Left)) || 
                        ((item.Alignment == ToolStripItemAlignment.Right) && (relativeLocation == RelativeLocation.Right))) {
 
                        // the item alignment is Tail & dropped to right of the center of the item 
                        // or the item alignment is Head & dropped to the left of the center of the item
 
                        // Normally, insert the new item after the item, however in RTL insert before the item
                        insertIndex = Math.Max(0, (owner.RightToLeft == RightToLeft.Yes) ? insertIndex + 1 : insertIndex);
                    }
                    else { 
                        // the item alignment is Tail & dropped to left of the center of the item
                        // or the item alignment is Head & dropped to the right of the center of the item 
 

                        // Normally, insert the new item before the item, however in RTL insert after the item 
                        insertIndex = Math.Max(0, (owner.RightToLeft == RightToLeft.No) ? insertIndex + 1 : insertIndex);
                    }

                    // VSWhidbey 517774 
                    // If the control is moving from a lower to higher index, you actually want to set it one less than its position.
                    // This is because it is being removed from its original position, which lowers the index of every control before 
                    // its new drop point by 1. 
                    if (owner.Items.IndexOf(droppedItem) < insertIndex) {
                        insertIndex--; 
                    }

                    owner.Items.MoveItem(Math.Max(0,insertIndex), droppedItem);
                    owner.ClearInsertionMark(); 

                } 
                else if (toolStripItemIndex == -1 && owner.Items.Count == 0) { 
                    owner.Items.Add(droppedItem);
                    owner.ClearInsertionMark(); 
                }
            }

 

            private bool ShowItemDropPoint(Point ownerClientAreaRelativeDropPoint) { 
 
                int i = GetItemInsertionIndex(ownerClientAreaRelativeDropPoint);
                if (i >= 0) { 
                    ToolStripItem item = owner.Items[i];
                    RelativeLocation relativeLocation = ComparePositions(item.Bounds, ownerClientAreaRelativeDropPoint);

                    Debug.WriteLineIf(ToolStrip.ItemReorderDebug.TraceVerbose, "Drop relative loc " + relativeLocation); 
                    Debug.WriteLineIf(ToolStrip.ItemReorderDebug.TraceVerbose, "Index " + i);
 
                    Rectangle insertionRect = Rectangle.Empty; 
                    switch (relativeLocation) {
                        case RelativeLocation.Above: 
                            insertionRect = new Rectangle(owner.Margin.Left, item.Bounds.Top, owner.Width - (owner.Margin.Horizontal) -1, ToolStrip.INSERTION_BEAM_WIDTH);
                            break;
                        case RelativeLocation.Below:
                            insertionRect = new Rectangle(owner.Margin.Left, item.Bounds.Bottom, owner.Width - (owner.Margin.Horizontal) -1, ToolStrip.INSERTION_BEAM_WIDTH); 
                            break;
                        case RelativeLocation.Right: 
                            insertionRect = new Rectangle(item.Bounds.Right, owner.Margin.Top, ToolStrip.INSERTION_BEAM_WIDTH, owner.Height- (owner.Margin.Vertical)-1); 
                            break;
                        case RelativeLocation.Left: 
                            insertionRect = new Rectangle(item.Bounds.Left, owner.Margin.Top, ToolStrip.INSERTION_BEAM_WIDTH, owner.Height - (owner.Margin.Vertical) -1);
                            break;
                    }
 
                    owner.PaintInsertionMark(insertionRect);
                    return true; 
                } 
                else if (owner.Items.Count == 0) {
                    Rectangle insertionRect = owner.DisplayRectangle; 
                    insertionRect.Width = ToolStrip.INSERTION_BEAM_WIDTH;
                    owner.PaintInsertionMark(insertionRect);
                    return true;
                } 
                return false;
            } 
 

            private int GetItemInsertionIndex(Point ownerClientAreaRelativeDropPoint) { 
                for(int i = 0; i< owner.DisplayedItems.Count; i++) {
                    Rectangle bounds = owner.DisplayedItems[i].Bounds;
                    bounds.Inflate(owner.DisplayedItems[i].Margin.Size);
                    if (bounds.Contains(ownerClientAreaRelativeDropPoint)) { 
                        Debug.WriteLineIf(ToolStrip.DropTargetDebug.TraceVerbose, "MATCH " + owner.DisplayedItems[i].Text + " Bounds: " + owner.DisplayedItems[i].Bounds.ToString());
 
                        // consider what to do about items not in the display 
                        return owner.Items.IndexOf(owner.DisplayedItems[i]);
                    } 
                }

                if (owner.DisplayedItems.Count > 0) {
                    for (int i = 0; i < owner.DisplayedItems.Count; i++) { 
                        if (owner.DisplayedItems[i].Alignment == ToolStripItemAlignment.Right) {
                            if (i > 0) { 
                                return owner.Items.IndexOf(owner.DisplayedItems[i - 1]); 
                            }
                            return owner.Items.IndexOf(owner.DisplayedItems[i]); 
                        }
                    }
                    return owner.Items.IndexOf(owner.DisplayedItems[owner.DisplayedItems.Count - 1]);
                } 
                return -1;
            } 
 
            private enum RelativeLocation {
                Above, 
                Below,
                Right,
                Left
            } 

            private RelativeLocation ComparePositions(Rectangle [....], Point check) { 
 
                if (owner.Orientation == Orientation.Horizontal) {
                    int widthUnit = [....].Width / 2; 
                    RelativeLocation relativeLocation = RelativeLocation.Left;

                    // we can return here if we are checking abovebelowleftright, because
                    // the left right calculation is more picky than the above/below calculation 
                    // and the above below calculation will just override this one.
                    if (([....].Left + widthUnit) >= check.X) { 
                        relativeLocation = RelativeLocation.Left; 
                        return relativeLocation;
                    } 
                    else if (([....].Right - widthUnit) <= check.X) {
                        relativeLocation = RelativeLocation.Right;
                        return relativeLocation;
                    } 
                }
 
                if (owner.Orientation == Orientation.Vertical) { 
                    int heightUnit = [....].Height/ 2;
                    RelativeLocation relativeLocation = (check.Y <= ([....].Top + heightUnit)) ? 
                        RelativeLocation.Above
                        : RelativeLocation.Below;

                    return relativeLocation; 
                }
 
                Debug.Fail("Could not calculate the relative position for AllowItemReorder"); 
                return RelativeLocation.Left;
            } 
        }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK