ToolStrip.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / ToolStrip.cs / 1305376 / 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; 
    using System.Runtime.Versioning;

    /// 
    ///  
    /// 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 { 
            [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] 
            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) { 
            using (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.Control) == Keys.Control && (keyData & Keys.KeyCode) == Keys.Tab; 

                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 && !IsInDesignMode) { 
 
                            // 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.
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)] 
        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.
                        

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