UpDownBase.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / UpDownBase.cs / 1305376 / UpDownBase.cs

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

namespace System.Windows.Forms { 
    using System.Runtime.Serialization.Formatters; 
    using System.Threading;
    using System.Runtime.Remoting; 
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.Diagnostics;
    using System; 
    using System.Security.Permissions;
    using System.Windows.Forms.VisualStyles; 
    using System.Drawing; 
    using Microsoft.Win32;
 
    /// 
    /// 
    ///    Implements the basic
    ///       functionality required by an up-down control. 
    /// 
    [ 
    ComVisible(true), 
    ClassInterface(ClassInterfaceType.AutoDispatch),
    Designer("System.Windows.Forms.Design.UpDownBaseDesigner, " + AssemblyRef.SystemDesign), 
    System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors") // Shipped in Everett
    ]
    public abstract class UpDownBase : ContainerControl {
 
        private const int                       DefaultWheelScrollLinesPerPage = 1;
        private const int                       DefaultButtonsWidth = 16; 
        private const int                       DefaultControlWidth = 120; 
        private const int                       ThemedBorderWidth = 1; // width of custom border we draw when themed
        private const BorderStyle               DefaultBorderStyle = BorderStyle.Fixed3D; 
        private static readonly bool            DefaultInterceptArrowKeys = true;
        private const LeftRightAlignment        DefaultUpDownAlign = LeftRightAlignment.Right;
        private const int                       DefaultTimerInterval = 500;
 
        ////////////////////////////////////////////////////////////////////////
        // Member variables 
        // 
        ////////////////////////////////////////////////////////////////////////
 
        // Child controls
        internal UpDownEdit upDownEdit; // See nested class at end of this file
        internal UpDownButtons upDownButtons; // See nested class at end of this file
 
        // Intercept arrow keys?
        private bool interceptArrowKeys = DefaultInterceptArrowKeys; 
 
        // If true, the updown buttons will be drawn on the left-hand side of the control.
        private LeftRightAlignment upDownAlign = DefaultUpDownAlign; 

        // userEdit is true when the text of the control has been changed,
        // and the internal value of the control has not yet been updated.
        // We do not always want to keep the internal value up-to-date, 
        // hence this variable.
        private bool userEdit = false; 
 
        /// 
        ///  
        ///     The current border for this edit control.
        /// 
        private BorderStyle borderStyle = DefaultBorderStyle;
 
        // Mouse wheel movement
        private int wheelDelta = 0; 
 
        // Indicates if the edit text is being changed
        private bool changingText = false; 

        // Indicates whether we have doubleClicked
        private bool doubleClickFired = false;
 
        /// 
        ///  
        ///     
        ///       Initializes a new instance of the 
        ///       class. 
        ///    
        /// 
        public UpDownBase() {
 
            upDownButtons = new UpDownButtons(this);
            upDownEdit = new UpDownEdit(this); 
            upDownEdit.BorderStyle = BorderStyle.None; 
            upDownEdit.AutoSize = false;
            upDownEdit.KeyDown += new KeyEventHandler(this.OnTextBoxKeyDown); 
            upDownEdit.KeyPress += new KeyPressEventHandler(this.OnTextBoxKeyPress);
            upDownEdit.TextChanged += new EventHandler(this.OnTextBoxTextChanged);
            upDownEdit.LostFocus += new EventHandler(this.OnTextBoxLostFocus);
            upDownEdit.Resize += new EventHandler(this.OnTextBoxResize); 
            upDownButtons.TabStop = false;
            upDownButtons.Size = new Size(DefaultButtonsWidth, PreferredHeight); 
            upDownButtons.UpDown += new UpDownEventHandler(this.OnUpDown); 

            Controls.AddRange(new Control[] { upDownButtons, upDownEdit} ); 

            SetStyle(ControlStyles.Opaque | ControlStyles.FixedHeight | ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.StandardClick, false);
            SetStyle(ControlStyles.UseTextForAccessibility, false); 
        }
 
        //////////////////////////////////////////////////////////////////////// 
        // Properties
        // 
        ////////////////////////////////////////////////////////////////////////

        // AutoScroll is not relevant to an UpDownBase
        ///  
        /// 
        ///  
        ///  
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public override bool AutoScroll {
            get {
                return false;
            } 
            set {
                // Don't allow AutoScroll to be set to anything 
            } 
        }
 
        // AutoScrollMargin is not relevant to an UpDownBase
        /// 
        /// 
        ///  
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        new public Size AutoScrollMargin {
            get { 
                return base.AutoScrollMargin;
            }
            set {
                base.AutoScrollMargin = value; 
            }
        } 
 
        // AutoScrollMinSize is not relevant to an UpDownBase
        ///  
        /// 
        /// 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        new public Size AutoScrollMinSize { 
            get { 
                return base.AutoScrollMinSize;
            } 
            set {
                base.AutoScrollMinSize = value;
            }
        } 

        ///  
        ///  
        ///     Override to re-expose AutoSize.
        ///  
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public override bool AutoSize
        { 
            get
            { 
                return base.AutoSize; 
            }
            set 
            {
                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;
            } 
        }

        /// 
        ///  
        /// 
        ///     
        ///       Gets or sets the background color for the 
        ///       text box portion of the up-down control.
        ///     
        /// 
        public override Color BackColor {
            get {
                return upDownEdit.BackColor; 
            }
            set { 
                base.BackColor = value; // Don't remove this or you will break serialization. See VSWhidbey #517574 
                upDownEdit.BackColor = value;
                Invalidate(); // VSWhidbey #335074 
            }
        }

        ///  
        /// 
        ///  
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage { 
            get {
                return base.BackgroundImage;
            }
            set { 
                base.BackgroundImage = value;
            } 
        } 

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

        /// 
        ///  
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public override ImageLayout BackgroundImageLayout {
            get { 
                return base.BackgroundImageLayout;
            }
            set {
                base.BackgroundImageLayout = value; 
            }
        } 
 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackgroundImageLayoutChanged {
            add {
                base.BackgroundImageLayoutChanged += value; 
            }
            remove { 
                base.BackgroundImageLayoutChanged -= value; 
            }
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets the border style for
        ///       the up-down control. 
        ///     
        /// 
        [ 
        SRCategory(SR.CatAppearance),
        DefaultValue(BorderStyle.Fixed3D),
        DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE),
        SRDescription(SR.UpDownBaseBorderStyleDescr) 
        ]
        public BorderStyle BorderStyle { 
            get { 
                return borderStyle;
            } 

            set {
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)) 
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); 
                } 

                if (borderStyle != value) { 
                    borderStyle = value;
                    RecreateHandle();
                }
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether the text
        ///       property is being changed internally by its parent class.
        ///    
        ///  
        protected bool ChangingText {
            get { 
                return changingText; 
            }
 
            set {
                changingText = value;
            }
        } 

        ///  
        ///  
        /// 
        ///  
        public override ContextMenu ContextMenu {
            get {
                return base.ContextMenu;
            } 
            set {
                base.ContextMenu = value; 
                this.upDownEdit.ContextMenu = value; 
            }
        } 

        public override ContextMenuStrip ContextMenuStrip {
            get {
                return base.ContextMenuStrip; 
            }
            set { 
                base.ContextMenuStrip = value; 
                this.upDownEdit.ContextMenuStrip = value;
            } 
        }


        ///  
        /// 
        ///  
        ///     
        ///       Returns the parameters needed to create the handle. Inheriting classes
        ///       can override this to provide extra functionality. They should not, 
        ///       however, forget to call base.getCreateParams() first to get the struct
        ///       filled up with the basic info.
        ///    
        ///  
        protected override CreateParams CreateParams {
            [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] 
            get { 
                CreateParams cp = base.CreateParams;
 
                cp.Style &= (~NativeMethods.WS_BORDER);
                if (!Application.RenderWithVisualStyles) {
                    switch (borderStyle) {
                        case BorderStyle.Fixed3D: 
                            cp.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE;
                            break; 
                        case BorderStyle.FixedSingle: 
                            cp.Style |= NativeMethods.WS_BORDER;
                            break; 
                    }
                }
                return cp;
            } 
        }
 
        ///  
        /// 
        ///     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(DefaultControlWidth, PreferredHeight);
            } 
        } 

        // DockPadding is not relevant to UpDownBase 
        /// 
        /// 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        new public DockPaddingEdges DockPadding { 
            get { 
                return base.DockPadding;
            } 
        }

        /// 
        ///  
        ///     Returns true if this control has focus.
        ///  
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.ControlFocusedDescr)
        ]
        public override bool Focused {
            get { 
                return upDownEdit.Focused;
            } 
        } 

        ///  
        /// 
        /// 
        ///    
        ///       Indicates the foreground color for the control. 
        ///    
        ///  
        public override Color ForeColor { 
            get {
                return upDownEdit.ForeColor; 
            }
            set {
                base.ForeColor = value;
                upDownEdit.ForeColor = value; 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets a value indicating whether
        ///       the user can use the UP
        ///       ARROW and DOWN ARROW keys to select values. 
        ///    
        ///  
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(true), 
        SRDescription(SR.UpDownBaseInterceptArrowKeysDescr)
        ]
        public bool InterceptArrowKeys {
 
            get {
                return interceptArrowKeys; 
            } 

            set { 
                interceptArrowKeys = value;
            }
        }
 
        /// 
        public override Size MaximumSize { 
            get { return base.MaximumSize; } 
            set {
                base.MaximumSize = new Size(value.Width, 0); 
            }
        }

        ///  
        public override Size MinimumSize {
            get { return base.MinimumSize; } 
            set { 
                base.MinimumSize = new Size(value.Width, 0);
            } 
        }

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

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

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

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

        ///  
        ///  
        ///    
        ///       Gets the height of 
        ///       the up-down control.
        ///    
        /// 
        [ 
        SRCategory(SR.CatLayout),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.UpDownBasePreferredHeightDescr)
        ] 
        public int PreferredHeight {
            get {

                int height = FontHeight; 

                // Adjust for the border style 
                if (borderStyle != BorderStyle.None) { 
                    height += SystemInformation.BorderSize.Height * 4 + 3;
                } 
                else {
                    height += 3;
                }
 
                return height;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets
        ///       a 
        ///       value
        ///       indicating whether the text may only be changed by the 
        ///       use 
        ///       of the up or down buttons.
        ///     
        /// 
        [
        SRCategory(SR.CatBehavior),
        DefaultValue(false), 
        SRDescription(SR.UpDownBaseReadOnlyDescr)
        ] 
        public bool ReadOnly { 

            get { 
                return upDownEdit.ReadOnly;
            }

            set { 
                upDownEdit.ReadOnly = value;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets the text
        ///       displayed in the up-down control. 
        ///    
        ///  
        [ 
        Localizable(true)
        ] 
        public override string Text {
            get {
                return upDownEdit.Text;
            } 

            set { 
                upDownEdit.Text = value; 
                // The text changed event will at this point be triggered.
                // After returning, the value of UserEdit will reflect 
                // whether or not the current upDownEditbox text is in [....]
                // with any internally stored values. If UserEdit is true,
                // we must validate the text the user typed or set.
 
                ChangingText = false;
                // Details: Usually, the code in the Text changed event handler 
                // sets ChangingText back to false. 
                // If the text hasn't actually changed though, the event handler
                // never fires. ChangingText should always be false on exit from 
                // this property.

                if (UserEdit) {
                    ValidateEditText(); 
                }
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or
        ///       sets the alignment of the text in the up-down 
        ///       control.
        ///     
        ///  
        [
        Localizable(true), 
        SRCategory(SR.CatAppearance),
        DefaultValue(HorizontalAlignment.Left),
        SRDescription(SR.UpDownBaseTextAlignDescr)
        ] 
        public HorizontalAlignment TextAlign {
            get { 
                return upDownEdit.TextAlign; 
            }
            set { 
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)HorizontalAlignment.Left, (int)HorizontalAlignment.Center))
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(HorizontalAlignment)); 
                }
                upDownEdit.TextAlign = value; 
            } 
        }
 
        internal TextBox TextBox {
            get {
                return upDownEdit;
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets
        ///       or sets the
        ///       alignment
        ///       of the up and down buttons on the up-down control. 
        ///    
        ///  
        [ 
        Localizable(true),
        SRCategory(SR.CatAppearance), 
        DefaultValue(LeftRightAlignment.Right),
        SRDescription(SR.UpDownBaseAlignmentDescr)
        ]
        public LeftRightAlignment UpDownAlign { 

            get { 
                return upDownAlign; 
            }
 
            set {
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)LeftRightAlignment.Left, (int)LeftRightAlignment.Right))
                { 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(LeftRightAlignment));
                } 
 
                if (upDownAlign != value) {
 
                    upDownAlign = value;
                    PositionControls();
                    Invalidate();
                } 
            }
        } 
 
        internal UpDownButtons UpDownButtonsInternal {
            get { 
                return upDownButtons;
            }
        }
 
        /// 
        ///  
        ///     
        ///       Gets
        ///       or sets a value indicating whether a value has been entered by the 
        ///       user.
        ///    
        /// 
        protected bool UserEdit { 
            get {
                return userEdit; 
            } 

            set { 
                userEdit = value;
            }
        }
 

        //////////////////////////////////////////////////////////////////////// 
        // Methods 
        //
        //////////////////////////////////////////////////////////////////////// 


        /// 
        ///  
        ///    
        ///       When overridden in a derived class, handles the pressing of the down button 
        ///       on the up-down control. 
        ///    
        ///  
        public abstract void DownButton();

        // GetPreferredSize and SetBoundsCore call this method to allow controls to self impose
        // constraints on their size. 
        internal override Rectangle ApplyBoundsConstraints(int suggestedX, int suggestedY, int proposedWidth, int proposedHeight) {
            return base.ApplyBoundsConstraints(suggestedX,suggestedY, proposedWidth, PreferredHeight); 
        } 

        ///  
        /// 
        /// 
        /// When overridden in a derived class, raises the Changed event.
        /// event. 
        /// 
        protected virtual void OnChanged(object source, EventArgs e) { 
        } 

        ///  
        /// 
        /// 
        ///    
        ///       Initialize the updown. Adds the upDownEdit and updown buttons. 
        ///    
        ///  
        protected override void OnHandleCreated(EventArgs e) 
        {
            base.OnHandleCreated(e); 
            PositionControls();
            SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(this.UserPreferenceChanged);
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Tear down the updown. 
        ///    
        /// 
        protected override void OnHandleDestroyed(EventArgs e)
        { 
            SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.UserPreferenceChanged);
            base.OnHandleDestroyed(e); 
        } 

        ///  
        /// 
        ///     Handles painting the buttons on the control.
        ///
        ///  
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e); 
 
            Rectangle editBounds = upDownEdit.Bounds;
            if (Application.RenderWithVisualStyles) { 
                if (borderStyle != BorderStyle.None) {
                    Rectangle bounds = ClientRectangle;
                    Rectangle clipBounds = e.ClipRectangle;
 
                    //Draw a themed textbox-like border, which is what the spin control does
                    VisualStyleRenderer vsr = new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Normal); 
                    int border = ThemedBorderWidth; 
                    Rectangle clipLeft = new Rectangle(bounds.Left, bounds.Top, border, bounds.Height);
                    Rectangle clipTop = new Rectangle(bounds.Left, bounds.Top, bounds.Width, border); 
                    Rectangle clipRight = new Rectangle(bounds.Right - border, bounds.Top, border, bounds.Height);
                    Rectangle clipBottom = new Rectangle(bounds.Left, bounds.Bottom - border, bounds.Width, border);
                    clipLeft.Intersect(clipBounds);
                    clipTop.Intersect(clipBounds); 
                    clipRight.Intersect(clipBounds);
                    clipBottom.Intersect(clipBounds); 
                    vsr.DrawBackground(e.Graphics, bounds, clipLeft); 
                    vsr.DrawBackground(e.Graphics, bounds, clipTop);
                    vsr.DrawBackground(e.Graphics, bounds, clipRight); 
                    vsr.DrawBackground(e.Graphics, bounds, clipBottom);
                    // Draw rectangle around edit control with background color
                    using (Pen pen = new Pen(BackColor)) {
                        Rectangle backRect = editBounds; 
                        backRect.X--;
                        backRect.Y--; 
                        backRect.Width++; 
                        backRect.Height++;
                        e.Graphics.DrawRectangle(pen, backRect); 
                    }
                }
            }
            else { 
                // Draw rectangle around edit control with background color
                using (Pen pen = new Pen(BackColor, Enabled ? 2 : 1)) 
                { 
                    Rectangle backRect = editBounds;
                    backRect.Inflate(1, 1); 
                    if (!Enabled)
                    {
                        backRect.X--;
                        backRect.Y--; 
                        backRect.Width++;
                        backRect.Height++; 
                    } 
                    e.Graphics.DrawRectangle(pen, backRect);
                } 
            }
            if (!Enabled && BorderStyle != BorderStyle.None && !upDownEdit.ShouldSerializeBackColor()) {
                //draws a grayed rectangled around the upDownEdit, since otherwise we will have a white
                //border around the upDownEdit, which is inconsistent with Windows' behavior 
                //we only want to do this when BackColor is not serialized, since otherwise
                //we should display the backcolor instead of the usual grayed textbox. 
                editBounds.Inflate(1, 1); 
                ControlPaint.DrawBorder(e.Graphics, editBounds, SystemColors.Control, ButtonBorderStyle.Solid);
            } 
        }

        /// 
        ///  
        /// Raises the 
        /// event. 
        ///  
        protected virtual void OnTextBoxKeyDown(object source, KeyEventArgs e) {
            this.OnKeyDown(e); 
            if (interceptArrowKeys) {

                // Intercept up arrow
                if (e.KeyData == Keys.Up) { 
                    UpButton();
                    e.Handled = true; 
                } 

                // Intercept down arrow 
                else if (e.KeyData == Keys.Down) {
                    DownButton();
                    e.Handled = true;
                } 
            }
 
            // Perform text validation if ENTER is pressed 
            //
            if (e.KeyCode == Keys.Return && UserEdit) { 
                ValidateEditText();
            }
        }
 
        /// 
        ///  
        /// Raises the  
        /// event.
        ///  
        protected virtual void OnTextBoxKeyPress(object source, KeyPressEventArgs e) {
            this.OnKeyPress(e);

        } 

        ///  
        ///  
        /// Raises the  event.
        ///  
        protected virtual void OnTextBoxLostFocus(object source, EventArgs e) {
            if (UserEdit) {
                ValidateEditText();
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        protected virtual void OnTextBoxResize(object source, EventArgs e) {
            this.Height = PreferredHeight;
            PositionControls(); 
        }
 
        ///  
        /// 
        /// Raises the TextBoxTextChanged event. 
        /// event.
        /// 
        protected virtual void OnTextBoxTextChanged(object source, EventArgs e) {
            if (changingText) { 
                Debug.Assert(UserEdit == false, "OnTextBoxTextChanged() - UserEdit == true");
                ChangingText = false; 
            } 
            else {
                UserEdit = true; 
            }

            this.OnTextChanged(e);
            OnChanged(source, new EventArgs()); 
        }
 
        ///  
        ///     Called from the UpDownButtons member. Provided for derived controls to have a finer way to handle the event.
        ///  
        internal virtual void OnStartTimer() {
        }

        internal virtual void OnStopTimer() { 
        }
 
        ///  
        ///       Raises the  event.
        ///  
        protected override void OnMouseDown(MouseEventArgs e) {
            if (e.Clicks == 2 && e.Button == MouseButtons.Left) {
                doubleClickFired = true;
            } 

            base.OnMouseDown(e); 
        } 

        ///  
        /// 
        ///    
        ///       Raises the  event.
        /// 
        ///    
        ///  
        protected override void OnMouseUp(MouseEventArgs mevent) { 
            if (mevent.Button == MouseButtons.Left) {
                Point pt = PointToScreen(new Point(mevent.X, mevent.Y)); 
                if (UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle && !ValidationCancelled) {
                    if (!doubleClickFired) {
                        OnClick(mevent);
                        OnMouseClick(mevent); 
                    }
                    else { 
                        doubleClickFired = false; 
                        OnDoubleClick(mevent);
                        OnMouseDoubleClick(mevent); 
                    }
                }
                doubleClickFired = false;
            } 
            base.OnMouseUp(mevent);
        } 
 
        /// 
        ///  
        /// Raises the  event.
        /// 
        protected override void OnMouseWheel(MouseEventArgs e) {
            base.OnMouseWheel(e); 
            HandledMouseEventArgs hme = e as HandledMouseEventArgs;
            if (hme != null) { 
               if (hme.Handled) { 
                   return;
               } 
               hme.Handled = true;
            }

            if ((ModifierKeys & (Keys.Shift | Keys.Alt)) != 0 || MouseButtons != MouseButtons.None) { 
                return; // Do not scroll when Shift or Alt key is down, or when a mouse button is down.
            } 
 
            int wheelScrollLines = SystemInformation.MouseWheelScrollLines;
            if (wheelScrollLines == 0) { 
                return; // Do not scroll when the user system setting is 0 lines per notch
            }

            Debug.Assert(this.wheelDelta > -NativeMethods.WHEEL_DELTA, "wheelDelta is too smal"); 
            Debug.Assert(this.wheelDelta < NativeMethods.WHEEL_DELTA, "wheelDelta is too big");
            this.wheelDelta += e.Delta; 
 
            float partialNotches;
            partialNotches = (float)this.wheelDelta / (float)NativeMethods.WHEEL_DELTA; 

            if (wheelScrollLines == -1) {
               wheelScrollLines = DefaultWheelScrollLinesPerPage;
            } 

            // Evaluate number of bands to scroll 
            int scrollBands = (int)((float)wheelScrollLines * partialNotches); 
            if (scrollBands != 0) {
               int absScrollBands; 
               if (scrollBands > 0) {
                  absScrollBands = scrollBands;
                  while (absScrollBands > 0) {
                     UpButton(); 
                     absScrollBands--;
                  } 
                  this.wheelDelta -= (int)((float)scrollBands * ((float)NativeMethods.WHEEL_DELTA / (float)wheelScrollLines)); 
               }
               else { 
                  absScrollBands = -scrollBands;
                  while (absScrollBands > 0) {
                     DownButton();
                     absScrollBands--; 
                  }
                  this.wheelDelta -= (int)((float)scrollBands * ((float)NativeMethods.WHEEL_DELTA / (float)wheelScrollLines)); 
               } 
            }
        } 


        /// 
        ///  
        /// 
        ///    Handle the layout event. The size of the upDownEdit control, and the 
        ///    position of the UpDown control must be modified. 
        /// 
        protected override void OnLayout(LayoutEventArgs e) { 

            PositionControls();
            base.OnLayout(e);
        } 

        ///  
        ///  
        /// 
        ///     
        ///       Raises the FontChanged event.
        ///    
        /// 
        protected override void OnFontChanged(EventArgs e) { 
            // Clear the font height cache
            FontHeight = -1; 
 
            Height = PreferredHeight;
            PositionControls(); 

            base.OnFontChanged(e);
        }
 
        /// 
        ///  
        /// 
        ///     Handles UpDown events, which are generated by clicking on
        ///     the updown buttons in the child updown control. 
        ///
        /// 
        private void OnUpDown(object source, UpDownEventArgs e) {
            // Modify the value 
            if (e.ButtonID == (int)ButtonID.Up)
                UpButton(); 
            else if (e.ButtonID == (int)ButtonID.Down) 
                DownButton();
        } 

        /// 
        /// 
        ///     Calculates the size and position of the upDownEdit control and 
        ///     the updown buttons.
        ///  
        private void PositionControls() { 
            Rectangle upDownEditBounds    = Rectangle.Empty,
                      upDownButtonsBounds = Rectangle.Empty; 

            Rectangle clientArea     = new Rectangle(Point.Empty, ClientSize);
            int totalClientWidth     = clientArea.Width;
            bool themed              = Application.RenderWithVisualStyles; 
            BorderStyle borderStyle  = BorderStyle;
 
 
            // determine how much to squish in - Fixed3d and FixedSingle have 2PX border
            int borderWidth = (borderStyle == BorderStyle.None) ? 0 : 2; 
            clientArea.Inflate(-borderWidth, -borderWidth);

            // Reposition and resize the upDownEdit control
            // 
            if (upDownEdit != null) {
                upDownEditBounds = clientArea; 
                upDownEditBounds.Size = new Size(clientArea.Width - DefaultButtonsWidth, clientArea.Height); 
            }
 
            // Reposition and resize the updown buttons
            //
            if (upDownButtons != null) {
                int borderFixup = (themed) ? 1: 2; 
                if (borderStyle == BorderStyle.None) {
                    borderFixup = 0; 
                } 
                upDownButtonsBounds = new Rectangle(/*x*/clientArea.Right - DefaultButtonsWidth+borderFixup,
                                                    /*y*/clientArea.Top-borderFixup, 
                                                    /*w*/DefaultButtonsWidth,
                                                    /*h*/clientArea.Height+(borderFixup*2));
            }
 
            // Right to left translation
            LeftRightAlignment updownAlign = UpDownAlign; 
            updownAlign = RtlTranslateLeftRight(updownAlign); 

            // left/right updown align translation 
            if (updownAlign == LeftRightAlignment.Left) {
                // if the buttons are aligned to the left, swap position of text box/buttons
                upDownButtonsBounds.X = totalClientWidth - upDownButtonsBounds.Right;
                upDownEditBounds.X = totalClientWidth - upDownEditBounds.Right; 
            }
 
            // apply locations 
            if (upDownEdit != null) {
                 upDownEdit.Bounds = upDownEditBounds; 
            }
            if (upDownButtons != null) {
                upDownButtons.Bounds = upDownButtonsBounds;
                upDownButtons.Invalidate(); 
            }
 
       } 

        ///  
        /// 
        ///    
        ///       Selects a range of
        ///       text in the up-down control. 
        ///    
        ///  
        public void Select(int start, int length) { 
            upDownEdit.Select(start, length);
        } 


        /// 
        ///   Child controls run their 
        /// 
        private MouseEventArgs TranslateMouseEvent(Control child, MouseEventArgs e) { 
            if (child != null && IsHandleCreated) { 
                // same control as PointToClient or PointToScreen, just
                // with two specific controls in mind. 
                NativeMethods.POINT point = new NativeMethods.POINT(e.X, e.Y);
                UnsafeNativeMethods.MapWindowPoints(new HandleRef(child, child.Handle), new HandleRef(this, Handle), point, 1);
                return new MouseEventArgs(e.Button, e.Clicks, point.x, point.y , e.Delta);
            } 
            return e;
        } 
 
        /// 
        ///  
        ///    
        ///       When overridden in a derived class, handles the pressing of the up button on the up-down control.
        ///    
        ///  
        public abstract void UpButton();
 
        ///  
        /// 
        ///     
        ///       When overridden
        ///       in a derived class, updates the text displayed in the up-down control.
        ///    
        ///  
        protected abstract void UpdateEditText();
 
        private void UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs pref) { 
            if (pref.Category == UserPreferenceCategory.Locale) {
                UpdateEditText(); 
            }
        }

        ///  
        /// 
        ///     
        ///       When overridden in a 
        ///       derived class, validates the text displayed in the up-down control.
        ///     
        /// 
        protected virtual void ValidateEditText() {
        }
 
        /// 
        ///  
        ///  
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg) 
            {
                case NativeMethods.WM_SETFOCUS: 
                    if (!HostedInWin32DialogManager) { 
                        if (ActiveControl == null) {
                            SetActiveControlInternal(TextBox); 
                        }
                        else {
                            FocusActiveControlInternal();
                        } 
                    }
                    else { 
                        if (TextBox.CanFocus){ 
                            UnsafeNativeMethods.SetFocus(new HandleRef(TextBox, TextBox.Handle));
                        } 
                        base.WndProc(ref m);
                    }
                    break;
                case NativeMethods.WM_KILLFOCUS: 
                    DefWndProc(ref m);
                    break; 
                default: 
                    base.WndProc(ref m);
                    break; 
            }
        }

        ///  
        /// 
        ///  
        ///    This Function sets the ToolTip for this composite control. 
        /// 
        internal void SetToolTip(ToolTip toolTip, string caption) { 
            toolTip.SetToolTip(this.upDownEdit , caption);
            toolTip.SetToolTip(this.upDownButtons , caption);
        }
 
        internal class UpDownEdit : TextBox{
            ///////////////////////////////////////////////////////////////////// 
            // Member variables 
            //
            ///////////////////////////////////////////////////////////////////// 

            // Parent control
            private UpDownBase parent;
            private bool doubleClickFired = false; 
            /////////////////////////////////////////////////////////////////////
            // Constructors 
            // 
            /////////////////////////////////////////////////////////////////////
 
            internal UpDownEdit(UpDownBase parent)
            : base() {

                SetStyle(ControlStyles.FixedHeight | 
                         ControlStyles.FixedWidth, true);
 
                SetStyle(ControlStyles.Selectable, false); 

                this.parent = parent; 
            }

            protected override AccessibleObject CreateAccessibilityInstance() {
                return new UpDownEditAccessibleObject(this, parent); 
            }
 
            protected override void OnMouseDown(MouseEventArgs e) { 
                if (e.Clicks == 2 && e.Button == MouseButtons.Left) {
                    doubleClickFired = true; 
                }
                parent.OnMouseDown(parent.TranslateMouseEvent(this, e));
            }
 
            /// 
            ///  
            /// 
            ///     Handles detecting when the mouse button is released.
            /// 
            /// 
            protected override void OnMouseUp(MouseEventArgs e) {

                Point pt = new Point(e.X,e.Y); 
                pt = PointToScreen(pt);
 
                MouseEventArgs me = parent.TranslateMouseEvent(this, e); 
                if (e.Button == MouseButtons.Left) {
                    if (!parent.ValidationCancelled && UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle) { 
                        if (!doubleClickFired) {
                            parent.OnClick(me);
                            parent.OnMouseClick(me);
                        } 
                        else {
                            doubleClickFired = false; 
                            parent.OnDoubleClick(me); 
                            parent.OnMouseDoubleClick(me);
                        } 
                    }
                    doubleClickFired = false;
                }
 
                parent.OnMouseUp(me);
            } 
 
            internal override void WmContextMenu(ref Message m) {
                // VSWhidbey 521337: want to make the SourceControl to be the UpDownBase, not the Edit. 
                if (ContextMenu == null && ContextMenuStrip != null) {
                    WmContextMenu(ref m, parent);
                }
                else { 
                    WmContextMenu(ref m, this);
                } 
            } 

 
            /// 
            /// 
            /// Raises the 
            /// event. 
            /// 
            protected override void OnKeyUp(KeyEventArgs e) { 
                parent.OnKeyUp(e); 
            }
 
            protected override void OnGotFocus(EventArgs e) {
                parent.SetActiveControlInternal(this);
                parent.OnGotFocus(e);
            } 

            protected override void OnLostFocus(EventArgs e) { 
                parent.OnLostFocus(e); 
            }
 
            // [....]: Focus fixes. The XXXUpDown control will
            //         also fire a Leave event. We don't want
            //         to fire two of them.
            // protected override void OnLeave(EventArgs e) { 
            //     parent.OnLeave(e);
            // } 
 
            // Create our own accessibility object to map the accessible name
            // back to our parent.  They should track. 
            internal class UpDownEditAccessibleObject : ControlAccessibleObject {
                UpDownBase parent;

                public UpDownEditAccessibleObject(UpDownEdit owner, UpDownBase parent) : base(owner) { 
                    this.parent = parent;
                } 
 
                public override string Name {
                    get { 
                        return parent.AccessibilityObject.Name;
                    }
                    set {
                        parent.AccessibilityObject.Name = value; 
                    }
                } 
 
                public override string KeyboardShortcut {
                    get { 
                        return parent.AccessibilityObject.KeyboardShortcut;
                    }
                }
            } 
        }
 
        ///  
        /// 
        /// 
        ///     Nested class UpDownButtons
        ///
        ///     A control representing the pair of buttons on the end of the upDownEdit control.
        ///     This class handles drawing the updown buttons, and detecting mouse actions 
        ///     on these buttons. Acceleration on the buttons is handled. The control
        ///     sends UpDownEventArgss to the parent UpDownBase class when a button is pressed, 
        ///     or when the acceleration determines that another event should be generated. 
        /// 
        internal class UpDownButtons : Control { 
            //

            /////////////////////////////////////////////////////////////////////
            // Member variables 
            //
            ///////////////////////////////////////////////////////////////////// 
 
            // Parent control
            private UpDownBase parent; 

            // Button state
            private ButtonID pushed = ButtonID.None;
            private ButtonID captured = ButtonID.None; 
            private ButtonID mouseOver = ButtonID.None;
 
            // UpDown event handler 
            private UpDownEventHandler upDownEventHandler;
 
            // Timer
            private Timer timer;                    // generates UpDown events
            private int timerInterval;              // milliseconds between events
 
            private bool doubleClickFired = false;
 
            ///////////////////////////////////////////////////////////////////// 
            // Constructors
            // 
            /////////////////////////////////////////////////////////////////////

            internal UpDownButtons(UpDownBase parent)
 
            : base() {
 
                SetStyle(ControlStyles.Opaque | ControlStyles.FixedHeight | 
                         ControlStyles.FixedWidth, true);
 
                SetStyle(ControlStyles.Selectable, false);

                this.parent = parent;
            } 

 
            ///////////////////////////////////////////////////////////////////// 
            // Methods
            // 
            /////////////////////////////////////////////////////////////////////

            /// 
            ///  
            ///
            ///     Adds a handler for the updown button event. 
            ///  
            public event UpDownEventHandler UpDown {
                add { 
                    upDownEventHandler += value;
                }
                remove {
                    upDownEventHandler -= value; 
                }
            } 
 
            // Called when the mouse button is pressed - we need to start
            // spinning the value of the updown. 
            //
            private void BeginButtonPress(MouseEventArgs e) {

                int half_height = Size.Height / 2; 

                if (e.Y < half_height) { 
 
                    // Up button
                    // 
                    pushed = captured = ButtonID.Up;
                    Invalidate();

                } 
                else {
 
                    // Down button 
                    //
                    pushed = captured = ButtonID.Down; 
                    Invalidate();
                }

                // Capture the mouse 
                //
                CaptureInternal = true; 
 
                // Generate UpDown event
                // 
                OnUpDown(new UpDownEventArgs((int)pushed));

                // Start the timer for new updown events
                // 
                StartTimer();
            } 
 
            protected override AccessibleObject CreateAccessibilityInstance() {
                return new UpDownButtonsAccessibleObject(this); 
            }

            // Called when the mouse button is released - we need to stop
            // spinning the value of the updown. 
            //
            private void EndButtonPress() { 
 
                pushed = ButtonID.None;
                captured = ButtonID.None; 

                // Stop the timer
                StopTimer();
 
                // Release the mouse
                CaptureInternal = false; 
 
                // Redraw the buttons
                Invalidate(); 
            }

            /// 
            ///  
            ///
            ///     Handles detecting mouse hits on the buttons. This method 
            ///     detects which button was hit (up or down), fires a 
            ///     updown event, captures the mouse, and starts a timer
            ///     for repeated updown events. 
            ///
            /// 
            protected override void OnMouseDown(MouseEventArgs e) {
                // Begin spinning the value 
                //
 
                // Focus the parent 
                //
                this.parent.FocusInternal(); 

                if (!parent.ValidationCancelled && e.Button == MouseButtons.Left) {
                    BeginButtonPress(e);
                } 
                if (e.Clicks == 2 && e.Button == MouseButtons.Left) {
                    doubleClickFired = true; 
                } 
                // At no stage should a button be pushed, and the mouse
                // not captured. 
                //
                Debug.Assert(!(pushed != ButtonID.None && captured == ButtonID.None),
                             "Invalid button pushed/captured combination");
 
                parent.OnMouseDown(parent.TranslateMouseEvent(this, e));
            } 
 
            /// 
            ///  
            ///
            ///     Handles detecting mouse movement.
            ///
            ///  
            protected override void OnMouseMove(MouseEventArgs e) {
 
                // If the mouse is captured by the buttons (i.e. an updown button 
                // was pushed, and the mouse button has not yet been released),
                // determine the new state of the buttons depending on where 
                // the mouse pointer has moved.

                if (Capture) {
 
                    // Determine button area
 
                    Rectangle rect = ClientRectangle; 
                    rect.Height /= 2;
 
                    if (captured == ButtonID.Down) {
                        rect.Y += rect.Height;
                    }
 
                    // Test if the mouse has moved outside the button area
 
                    if (rect.Contains(e.X, e.Y)) { 

                        // Inside button 
                        // Repush the button if necessary

                        if (pushed != captured) {
 
                            // Restart the timer
                            StartTimer(); 
 
                            pushed = captured;
                            Invalidate(); 
                        }

                    }
                    else { 

                        // Outside button 
                        // Retain the capture, but pop the button up whilst 
                        // the mouse remains outside the button and the
                        // mouse button remains pressed. 

                        if (pushed != ButtonID.None) {

                            // Stop the timer for updown events 
                            StopTimer();
 
                            pushed = ButtonID.None; 
                            Invalidate();
                        } 
                    }
                }

                //Logic for seeing which button is Hot if any 
                Rectangle rectUp = ClientRectangle, rectDown = ClientRectangle;
                rectUp.Height /= 2; 
                rectDown.Y += rectDown.Height / 2; 

                //Check if the mouse is on the upper or lower button. Note that it could be in neither. 
                if (rectUp.Contains(e.X, e.Y)) {
                    mouseOver = ButtonID.Up;
                    Invalidate();
                } 
                else if (rectDown.Contains(e.X, e.Y)) {
                    mouseOver = ButtonID.Down; 
                    Invalidate(); 
                }
 
                // At no stage should a button be pushed, and the mouse
                // not captured.
                Debug.Assert(!(pushed != ButtonID.None && captured == ButtonID.None),
                             "Invalid button pushed/captured combination"); 

                parent.OnMouseMove(parent.TranslateMouseEvent(this, e)); 
            } 

            ///  
            /// 
            ///
            ///     Handles detecting when the mouse button is released.
            /// 
            /// 
            protected override void OnMouseUp(MouseEventArgs e) { 
 
                if (!parent.ValidationCancelled && e.Button == MouseButtons.Left) {
                    EndButtonPress(); 
                }

                // At no stage should a button be pushed, and the mouse
                // not captured. 
                Debug.Assert(!(pushed != ButtonID.None && captured == ButtonID.None),
                             "Invalid button pushed/captured combination"); 
 
                Point pt = new Point(e.X,e.Y);
                pt = PointToScreen(pt); 

                MouseEventArgs me = parent.TranslateMouseEvent(this, e);
                if (e.Button == MouseButtons.Left) {
                    if (!parent.ValidationCancelled && UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle) { 
                        if (!doubleClickFired) {
                            this.parent.OnClick(me); 
                        } 
                        else {
                            doubleClickFired = false; 
                            this.parent.OnDoubleClick(me);
                            this.parent.OnMouseDoubleClick(me);
                        }
                    } 
                    doubleClickFired = false;
                } 
 
                parent.OnMouseUp(me);
            } 

            /// 
            /// 
            /// 
            ///     Handles detecting when the mouse leaves.
            /// 
            ///  
            protected override void OnMouseLeave(EventArgs e) {
                mouseOver = ButtonID.None; 
                Invalidate();

                parent.OnMouseLeave(e);
            } 

            ///  
            ///  
            ///     Handles painting the buttons on the control.
            /// 
            /// 
            protected override void OnPaint(PaintEventArgs e) {
                int half_height = ClientSize.Height / 2;
 
                /* Draw the up and down buttons */
 
                if (Application.RenderWithVisualStyles) { 
                    VisualStyleRenderer vsr = new VisualStyleRenderer(mouseOver == ButtonID.Up ? VisualStyleElement.Spin.Up.Hot : VisualStyleElement.Spin.Up.Normal);
 
                    if (!Enabled) {
                        vsr.SetParameters(VisualStyleElement.Spin.Up.Disabled);
                    }
                    else if (pushed == ButtonID.Up) { 
                        vsr.SetParameters(VisualStyleElement.Spin.Up.Pressed);
                    } 
 
                    vsr.DrawBackground(e.Graphics, new Rectangle(0, 0, DefaultButtonsWidth, half_height));
 
                    if (!Enabled) {
                        vsr.SetParameters(VisualStyleElement.Spin.Down.Disabled);
                    }
                    else if (pushed == ButtonID.Down) { 
                        vsr.SetParameters(VisualStyleElement.Spin.Down.Pressed);
                    } 
                    else { 
                        vsr.SetParameters(mouseOver == ButtonID.Down ? VisualStyleElement.Spin.Down.Hot : VisualStyleElement.Spin.Down.Normal);
                    } 

                    vsr.DrawBackground(e.Graphics, new Rectangle(0, half_height, DefaultButtonsWidth, half_height));
                }
                else { 
                    ControlPaint.DrawScrollButton(e.Graphics,
                                                  new Rectangle(0, 0, DefaultButtonsWidth, half_height), 
                                                  ScrollButton.Up, 
                                                  pushed == ButtonID.Up ? ButtonState.Pushed : (Enabled ? ButtonState.Normal : ButtonState.Inactive));
 
                    ControlPaint.DrawScrollButton(e.Graphics,
                                                  new Rectangle(0, half_height, DefaultButtonsWidth, half_height),
                                                  ScrollButton.Down,
                                                  pushed == ButtonID.Down ? ButtonState.Pushed : (Enabled ? ButtonState.Normal : ButtonState.Inactive)); 
                }
 
                if (half_height != (ClientSize.Height + 1) / 2) { 
                    // When control has odd height, a line needs to be drawn below the buttons with the backcolor.
                    using (Pen pen = new Pen(this.parent.BackColor)) { 
                        Rectangle clientRect = ClientRectangle;
                        e.Graphics.DrawLine(pen, clientRect.Left, clientRect.Bottom - 1, clientRect.Right - 1, clientRect.Bottom - 1);
                    }
                } 

                base.OnPaint(e); // raise paint event, just in case this inner class goes public some day 
            } 

            ///  
            /// 
            ///     Occurs when the UpDown buttons are pressed and when the acceleration timer tick event is raised.
            /// 
            protected virtual void OnUpDown(UpDownEventArgs upevent) { 
                if (upDownEventHandler != null)
                    upDownEventHandler(this, upevent); 
            } 

            ///  
            /// 
            ///     Starts the timer for generating updown events
            /// 
            protected void StartTimer() { 
                parent.OnStartTimer();
                if (timer == null) { 
                    timer = new Timer();      // generates UpDown events 
                    // Add the timer handler
                    timer.Tick += new EventHandler(TimerHandler); 
                }

                this.timerInterval = DefaultTimerInterval;
 
                timer.Interval = this.timerInterval;
                timer.Start(); 
            } 

            ///  
            /// 
            ///     Stops the timer for generating updown events
            /// 
            protected void StopTimer() { 
                if (timer != null) {
                    timer.Stop(); 
                    timer.Dispose(); 
                    timer = null;
                } 
                parent.OnStopTimer();
            }

            ///  
            /// 
            ///     Generates updown events when the timer calls this function. 
            ///  
            private void TimerHandler(object source, EventArgs args) {
 
                // Make sure we've got mouse capture
                if (!Capture) {
                    EndButtonPress();
                    return; 
                }
 
                OnUpDown(new UpDownEventArgs((int)pushed)); 

                // Accelerate timer. 
                this.timerInterval *= 7;
                this.timerInterval /= 10;

                if (this.timerInterval < 1) 
                {
                    this.timerInterval = 1; 
                } 

                timer.Interval = this.timerInterval; 
            }

            internal class UpDownButtonsAccessibleObject : ControlAccessibleObject {
 
                private DirectionButtonAccessibleObject upButton;
                private DirectionButtonAccessibleObject downButton; 
 
                public UpDownButtonsAccessibleObject(UpDownButtons owner) : base(owner) {
                } 

                public override string Name {
                    get {
                        string baseName = base.Name; 
                        if (baseName == null || baseName.Length == 0) {
                            return "Spinner"; 
                        } 
                        return baseName;
                    } 
                    set {
                        base.Name = value;
                    }
                } 

                ///  
                ///  
                ///    [To be supplied.]
                ///  
                public override AccessibleRole Role {
                    get {
                        AccessibleRole role = Owner.AccessibleRole;
                        if (role != AccessibleRole.Default) { 
                            return role;
                        } 
                        return AccessibleRole.SpinButton; 
                    }
                } 

                private DirectionButtonAccessibleObject UpButton {
                    get {
                        if (upButton == null) { 
                            upButton = new DirectionButtonAccessibleObject(this, true);
                        } 
                        return upButton; 
                    }
                } 

                private DirectionButtonAccessibleObject DownButton {
                    get {
                        if (downButton == null) { 
                            downButton = new DirectionButtonAccessibleObject(this, false);
                        } 
                        return downButton; 
                    }
                } 



                ///  
                /// 
                ///  
                public override AccessibleObject GetChild(int index) { 

                    // Up button 
                    //
                    if (index == 0) {
                        return UpButton;
                    } 

                    // Down button 
                    // 
                    if (index == 1) {
                        return DownButton; 
                    }

                    return null;
                } 

                ///  
                ///  
                /// 
                public override int GetChildCount() { 
                    return 2;
                }

                internal class DirectionButtonAccessibleObject : AccessibleObject { 
                    private bool up;
                    private UpDownButtonsAccessibleObject parent; 
 
                    public DirectionButtonAccessibleObject(UpDownButtonsAccessibleObject parent, bool up) {
                        this.parent = parent; 
                        this.up = up;
                    }

                    public override Rectangle Bounds { 
                        get {
                            // Get button bounds 
                            // 
                            Rectangle bounds = ((UpDownButtons)parent.Owner).Bounds;
                            bounds.Height /= 2; 
                            if (!up) {
                                bounds.Y += bounds.Height;
                            }
 
                            // Convert to screen co-ords
                            // 
                            return (((UpDownButtons)parent.Owner).ParentInternal).RectangleToScreen(bounds); 
                        }
                    } 

                    public override string Name {
                        get {
                            if (up) { 
                                return SR.GetString(SR.UpDownBaseUpButtonAccName);
                            } 
                            return SR.GetString(SR.UpDownBaseDownButtonAccName); 
                        }
                        set { 
                        }
                    }

                    public override AccessibleObject Parent { 
                        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
                        get { 
                            return parent; 
                        }
                    } 

                    public override AccessibleRole Role {
                        get {
                            return AccessibleRole.PushButton; 
                        }
                    } 
                } 
            }
 
        } // end class UpDownButtons

        // Button identifiers
 
        internal enum ButtonID {
            None = 0, 
            Up = 1, 
            Down = 2,
        } 
    } // end class UpDownBase
}


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

namespace System.Windows.Forms { 
    using System.Runtime.Serialization.Formatters; 
    using System.Threading;
    using System.Runtime.Remoting; 
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.Diagnostics;
    using System; 
    using System.Security.Permissions;
    using System.Windows.Forms.VisualStyles; 
    using System.Drawing; 
    using Microsoft.Win32;
 
    /// 
    /// 
    ///    Implements the basic
    ///       functionality required by an up-down control. 
    /// 
    [ 
    ComVisible(true), 
    ClassInterface(ClassInterfaceType.AutoDispatch),
    Designer("System.Windows.Forms.Design.UpDownBaseDesigner, " + AssemblyRef.SystemDesign), 
    System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors") // Shipped in Everett
    ]
    public abstract class UpDownBase : ContainerControl {
 
        private const int                       DefaultWheelScrollLinesPerPage = 1;
        private const int                       DefaultButtonsWidth = 16; 
        private const int                       DefaultControlWidth = 120; 
        private const int                       ThemedBorderWidth = 1; // width of custom border we draw when themed
        private const BorderStyle               DefaultBorderStyle = BorderStyle.Fixed3D; 
        private static readonly bool            DefaultInterceptArrowKeys = true;
        private const LeftRightAlignment        DefaultUpDownAlign = LeftRightAlignment.Right;
        private const int                       DefaultTimerInterval = 500;
 
        ////////////////////////////////////////////////////////////////////////
        // Member variables 
        // 
        ////////////////////////////////////////////////////////////////////////
 
        // Child controls
        internal UpDownEdit upDownEdit; // See nested class at end of this file
        internal UpDownButtons upDownButtons; // See nested class at end of this file
 
        // Intercept arrow keys?
        private bool interceptArrowKeys = DefaultInterceptArrowKeys; 
 
        // If true, the updown buttons will be drawn on the left-hand side of the control.
        private LeftRightAlignment upDownAlign = DefaultUpDownAlign; 

        // userEdit is true when the text of the control has been changed,
        // and the internal value of the control has not yet been updated.
        // We do not always want to keep the internal value up-to-date, 
        // hence this variable.
        private bool userEdit = false; 
 
        /// 
        ///  
        ///     The current border for this edit control.
        /// 
        private BorderStyle borderStyle = DefaultBorderStyle;
 
        // Mouse wheel movement
        private int wheelDelta = 0; 
 
        // Indicates if the edit text is being changed
        private bool changingText = false; 

        // Indicates whether we have doubleClicked
        private bool doubleClickFired = false;
 
        /// 
        ///  
        ///     
        ///       Initializes a new instance of the 
        ///       class. 
        ///    
        /// 
        public UpDownBase() {
 
            upDownButtons = new UpDownButtons(this);
            upDownEdit = new UpDownEdit(this); 
            upDownEdit.BorderStyle = BorderStyle.None; 
            upDownEdit.AutoSize = false;
            upDownEdit.KeyDown += new KeyEventHandler(this.OnTextBoxKeyDown); 
            upDownEdit.KeyPress += new KeyPressEventHandler(this.OnTextBoxKeyPress);
            upDownEdit.TextChanged += new EventHandler(this.OnTextBoxTextChanged);
            upDownEdit.LostFocus += new EventHandler(this.OnTextBoxLostFocus);
            upDownEdit.Resize += new EventHandler(this.OnTextBoxResize); 
            upDownButtons.TabStop = false;
            upDownButtons.Size = new Size(DefaultButtonsWidth, PreferredHeight); 
            upDownButtons.UpDown += new UpDownEventHandler(this.OnUpDown); 

            Controls.AddRange(new Control[] { upDownButtons, upDownEdit} ); 

            SetStyle(ControlStyles.Opaque | ControlStyles.FixedHeight | ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.StandardClick, false);
            SetStyle(ControlStyles.UseTextForAccessibility, false); 
        }
 
        //////////////////////////////////////////////////////////////////////// 
        // Properties
        // 
        ////////////////////////////////////////////////////////////////////////

        // AutoScroll is not relevant to an UpDownBase
        ///  
        /// 
        ///  
        ///  
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public override bool AutoScroll {
            get {
                return false;
            } 
            set {
                // Don't allow AutoScroll to be set to anything 
            } 
        }
 
        // AutoScrollMargin is not relevant to an UpDownBase
        /// 
        /// 
        ///  
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        new public Size AutoScrollMargin {
            get { 
                return base.AutoScrollMargin;
            }
            set {
                base.AutoScrollMargin = value; 
            }
        } 
 
        // AutoScrollMinSize is not relevant to an UpDownBase
        ///  
        /// 
        /// 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        new public Size AutoScrollMinSize { 
            get { 
                return base.AutoScrollMinSize;
            } 
            set {
                base.AutoScrollMinSize = value;
            }
        } 

        ///  
        ///  
        ///     Override to re-expose AutoSize.
        ///  
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public override bool AutoSize
        { 
            get
            { 
                return base.AutoSize; 
            }
            set 
            {
                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;
            } 
        }

        /// 
        ///  
        /// 
        ///     
        ///       Gets or sets the background color for the 
        ///       text box portion of the up-down control.
        ///     
        /// 
        public override Color BackColor {
            get {
                return upDownEdit.BackColor; 
            }
            set { 
                base.BackColor = value; // Don't remove this or you will break serialization. See VSWhidbey #517574 
                upDownEdit.BackColor = value;
                Invalidate(); // VSWhidbey #335074 
            }
        }

        ///  
        /// 
        ///  
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage { 
            get {
                return base.BackgroundImage;
            }
            set { 
                base.BackgroundImage = value;
            } 
        } 

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

        /// 
        ///  
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public override ImageLayout BackgroundImageLayout {
            get { 
                return base.BackgroundImageLayout;
            }
            set {
                base.BackgroundImageLayout = value; 
            }
        } 
 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        new public event EventHandler BackgroundImageLayoutChanged {
            add {
                base.BackgroundImageLayoutChanged += value; 
            }
            remove { 
                base.BackgroundImageLayoutChanged -= value; 
            }
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets the border style for
        ///       the up-down control. 
        ///     
        /// 
        [ 
        SRCategory(SR.CatAppearance),
        DefaultValue(BorderStyle.Fixed3D),
        DispId(NativeMethods.ActiveX.DISPID_BORDERSTYLE),
        SRDescription(SR.UpDownBaseBorderStyleDescr) 
        ]
        public BorderStyle BorderStyle { 
            get { 
                return borderStyle;
            } 

            set {
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)BorderStyle.None, (int)BorderStyle.Fixed3D)) 
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle)); 
                } 

                if (borderStyle != value) { 
                    borderStyle = value;
                    RecreateHandle();
                }
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether the text
        ///       property is being changed internally by its parent class.
        ///    
        ///  
        protected bool ChangingText {
            get { 
                return changingText; 
            }
 
            set {
                changingText = value;
            }
        } 

        ///  
        ///  
        /// 
        ///  
        public override ContextMenu ContextMenu {
            get {
                return base.ContextMenu;
            } 
            set {
                base.ContextMenu = value; 
                this.upDownEdit.ContextMenu = value; 
            }
        } 

        public override ContextMenuStrip ContextMenuStrip {
            get {
                return base.ContextMenuStrip; 
            }
            set { 
                base.ContextMenuStrip = value; 
                this.upDownEdit.ContextMenuStrip = value;
            } 
        }


        ///  
        /// 
        ///  
        ///     
        ///       Returns the parameters needed to create the handle. Inheriting classes
        ///       can override this to provide extra functionality. They should not, 
        ///       however, forget to call base.getCreateParams() first to get the struct
        ///       filled up with the basic info.
        ///    
        ///  
        protected override CreateParams CreateParams {
            [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] 
            get { 
                CreateParams cp = base.CreateParams;
 
                cp.Style &= (~NativeMethods.WS_BORDER);
                if (!Application.RenderWithVisualStyles) {
                    switch (borderStyle) {
                        case BorderStyle.Fixed3D: 
                            cp.ExStyle |= NativeMethods.WS_EX_CLIENTEDGE;
                            break; 
                        case BorderStyle.FixedSingle: 
                            cp.Style |= NativeMethods.WS_BORDER;
                            break; 
                    }
                }
                return cp;
            } 
        }
 
        ///  
        /// 
        ///     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(DefaultControlWidth, PreferredHeight);
            } 
        } 

        // DockPadding is not relevant to UpDownBase 
        /// 
        /// 
        /// 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        new public DockPaddingEdges DockPadding { 
            get { 
                return base.DockPadding;
            } 
        }

        /// 
        ///  
        ///     Returns true if this control has focus.
        ///  
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.ControlFocusedDescr)
        ]
        public override bool Focused {
            get { 
                return upDownEdit.Focused;
            } 
        } 

        ///  
        /// 
        /// 
        ///    
        ///       Indicates the foreground color for the control. 
        ///    
        ///  
        public override Color ForeColor { 
            get {
                return upDownEdit.ForeColor; 
            }
            set {
                base.ForeColor = value;
                upDownEdit.ForeColor = value; 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets a value indicating whether
        ///       the user can use the UP
        ///       ARROW and DOWN ARROW keys to select values. 
        ///    
        ///  
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(true), 
        SRDescription(SR.UpDownBaseInterceptArrowKeysDescr)
        ]
        public bool InterceptArrowKeys {
 
            get {
                return interceptArrowKeys; 
            } 

            set { 
                interceptArrowKeys = value;
            }
        }
 
        /// 
        public override Size MaximumSize { 
            get { return base.MaximumSize; } 
            set {
                base.MaximumSize = new Size(value.Width, 0); 
            }
        }

        ///  
        public override Size MinimumSize {
            get { return base.MinimumSize; } 
            set { 
                base.MinimumSize = new Size(value.Width, 0);
            } 
        }

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

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

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

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

        ///  
        ///  
        ///    
        ///       Gets the height of 
        ///       the up-down control.
        ///    
        /// 
        [ 
        SRCategory(SR.CatLayout),
        Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.UpDownBasePreferredHeightDescr)
        ] 
        public int PreferredHeight {
            get {

                int height = FontHeight; 

                // Adjust for the border style 
                if (borderStyle != BorderStyle.None) { 
                    height += SystemInformation.BorderSize.Height * 4 + 3;
                } 
                else {
                    height += 3;
                }
 
                return height;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets
        ///       a 
        ///       value
        ///       indicating whether the text may only be changed by the 
        ///       use 
        ///       of the up or down buttons.
        ///     
        /// 
        [
        SRCategory(SR.CatBehavior),
        DefaultValue(false), 
        SRDescription(SR.UpDownBaseReadOnlyDescr)
        ] 
        public bool ReadOnly { 

            get { 
                return upDownEdit.ReadOnly;
            }

            set { 
                upDownEdit.ReadOnly = value;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets the text
        ///       displayed in the up-down control. 
        ///    
        ///  
        [ 
        Localizable(true)
        ] 
        public override string Text {
            get {
                return upDownEdit.Text;
            } 

            set { 
                upDownEdit.Text = value; 
                // The text changed event will at this point be triggered.
                // After returning, the value of UserEdit will reflect 
                // whether or not the current upDownEditbox text is in [....]
                // with any internally stored values. If UserEdit is true,
                // we must validate the text the user typed or set.
 
                ChangingText = false;
                // Details: Usually, the code in the Text changed event handler 
                // sets ChangingText back to false. 
                // If the text hasn't actually changed though, the event handler
                // never fires. ChangingText should always be false on exit from 
                // this property.

                if (UserEdit) {
                    ValidateEditText(); 
                }
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or
        ///       sets the alignment of the text in the up-down 
        ///       control.
        ///     
        ///  
        [
        Localizable(true), 
        SRCategory(SR.CatAppearance),
        DefaultValue(HorizontalAlignment.Left),
        SRDescription(SR.UpDownBaseTextAlignDescr)
        ] 
        public HorizontalAlignment TextAlign {
            get { 
                return upDownEdit.TextAlign; 
            }
            set { 
                //valid values are 0x0 to 0x2
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)HorizontalAlignment.Left, (int)HorizontalAlignment.Center))
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(HorizontalAlignment)); 
                }
                upDownEdit.TextAlign = value; 
            } 
        }
 
        internal TextBox TextBox {
            get {
                return upDownEdit;
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets
        ///       or sets the
        ///       alignment
        ///       of the up and down buttons on the up-down control. 
        ///    
        ///  
        [ 
        Localizable(true),
        SRCategory(SR.CatAppearance), 
        DefaultValue(LeftRightAlignment.Right),
        SRDescription(SR.UpDownBaseAlignmentDescr)
        ]
        public LeftRightAlignment UpDownAlign { 

            get { 
                return upDownAlign; 
            }
 
            set {
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)LeftRightAlignment.Left, (int)LeftRightAlignment.Right))
                { 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(LeftRightAlignment));
                } 
 
                if (upDownAlign != value) {
 
                    upDownAlign = value;
                    PositionControls();
                    Invalidate();
                } 
            }
        } 
 
        internal UpDownButtons UpDownButtonsInternal {
            get { 
                return upDownButtons;
            }
        }
 
        /// 
        ///  
        ///     
        ///       Gets
        ///       or sets a value indicating whether a value has been entered by the 
        ///       user.
        ///    
        /// 
        protected bool UserEdit { 
            get {
                return userEdit; 
            } 

            set { 
                userEdit = value;
            }
        }
 

        //////////////////////////////////////////////////////////////////////// 
        // Methods 
        //
        //////////////////////////////////////////////////////////////////////// 


        /// 
        ///  
        ///    
        ///       When overridden in a derived class, handles the pressing of the down button 
        ///       on the up-down control. 
        ///    
        ///  
        public abstract void DownButton();

        // GetPreferredSize and SetBoundsCore call this method to allow controls to self impose
        // constraints on their size. 
        internal override Rectangle ApplyBoundsConstraints(int suggestedX, int suggestedY, int proposedWidth, int proposedHeight) {
            return base.ApplyBoundsConstraints(suggestedX,suggestedY, proposedWidth, PreferredHeight); 
        } 

        ///  
        /// 
        /// 
        /// When overridden in a derived class, raises the Changed event.
        /// event. 
        /// 
        protected virtual void OnChanged(object source, EventArgs e) { 
        } 

        ///  
        /// 
        /// 
        ///    
        ///       Initialize the updown. Adds the upDownEdit and updown buttons. 
        ///    
        ///  
        protected override void OnHandleCreated(EventArgs e) 
        {
            base.OnHandleCreated(e); 
            PositionControls();
            SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(this.UserPreferenceChanged);
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Tear down the updown. 
        ///    
        /// 
        protected override void OnHandleDestroyed(EventArgs e)
        { 
            SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.UserPreferenceChanged);
            base.OnHandleDestroyed(e); 
        } 

        ///  
        /// 
        ///     Handles painting the buttons on the control.
        ///
        ///  
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e); 
 
            Rectangle editBounds = upDownEdit.Bounds;
            if (Application.RenderWithVisualStyles) { 
                if (borderStyle != BorderStyle.None) {
                    Rectangle bounds = ClientRectangle;
                    Rectangle clipBounds = e.ClipRectangle;
 
                    //Draw a themed textbox-like border, which is what the spin control does
                    VisualStyleRenderer vsr = new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Normal); 
                    int border = ThemedBorderWidth; 
                    Rectangle clipLeft = new Rectangle(bounds.Left, bounds.Top, border, bounds.Height);
                    Rectangle clipTop = new Rectangle(bounds.Left, bounds.Top, bounds.Width, border); 
                    Rectangle clipRight = new Rectangle(bounds.Right - border, bounds.Top, border, bounds.Height);
                    Rectangle clipBottom = new Rectangle(bounds.Left, bounds.Bottom - border, bounds.Width, border);
                    clipLeft.Intersect(clipBounds);
                    clipTop.Intersect(clipBounds); 
                    clipRight.Intersect(clipBounds);
                    clipBottom.Intersect(clipBounds); 
                    vsr.DrawBackground(e.Graphics, bounds, clipLeft); 
                    vsr.DrawBackground(e.Graphics, bounds, clipTop);
                    vsr.DrawBackground(e.Graphics, bounds, clipRight); 
                    vsr.DrawBackground(e.Graphics, bounds, clipBottom);
                    // Draw rectangle around edit control with background color
                    using (Pen pen = new Pen(BackColor)) {
                        Rectangle backRect = editBounds; 
                        backRect.X--;
                        backRect.Y--; 
                        backRect.Width++; 
                        backRect.Height++;
                        e.Graphics.DrawRectangle(pen, backRect); 
                    }
                }
            }
            else { 
                // Draw rectangle around edit control with background color
                using (Pen pen = new Pen(BackColor, Enabled ? 2 : 1)) 
                { 
                    Rectangle backRect = editBounds;
                    backRect.Inflate(1, 1); 
                    if (!Enabled)
                    {
                        backRect.X--;
                        backRect.Y--; 
                        backRect.Width++;
                        backRect.Height++; 
                    } 
                    e.Graphics.DrawRectangle(pen, backRect);
                } 
            }
            if (!Enabled && BorderStyle != BorderStyle.None && !upDownEdit.ShouldSerializeBackColor()) {
                //draws a grayed rectangled around the upDownEdit, since otherwise we will have a white
                //border around the upDownEdit, which is inconsistent with Windows' behavior 
                //we only want to do this when BackColor is not serialized, since otherwise
                //we should display the backcolor instead of the usual grayed textbox. 
                editBounds.Inflate(1, 1); 
                ControlPaint.DrawBorder(e.Graphics, editBounds, SystemColors.Control, ButtonBorderStyle.Solid);
            } 
        }

        /// 
        ///  
        /// Raises the 
        /// event. 
        ///  
        protected virtual void OnTextBoxKeyDown(object source, KeyEventArgs e) {
            this.OnKeyDown(e); 
            if (interceptArrowKeys) {

                // Intercept up arrow
                if (e.KeyData == Keys.Up) { 
                    UpButton();
                    e.Handled = true; 
                } 

                // Intercept down arrow 
                else if (e.KeyData == Keys.Down) {
                    DownButton();
                    e.Handled = true;
                } 
            }
 
            // Perform text validation if ENTER is pressed 
            //
            if (e.KeyCode == Keys.Return && UserEdit) { 
                ValidateEditText();
            }
        }
 
        /// 
        ///  
        /// Raises the  
        /// event.
        ///  
        protected virtual void OnTextBoxKeyPress(object source, KeyPressEventArgs e) {
            this.OnKeyPress(e);

        } 

        ///  
        ///  
        /// Raises the  event.
        ///  
        protected virtual void OnTextBoxLostFocus(object source, EventArgs e) {
            if (UserEdit) {
                ValidateEditText();
            } 
        }
 
        ///  
        /// 
        /// Raises the  event. 
        /// 
        protected virtual void OnTextBoxResize(object source, EventArgs e) {
            this.Height = PreferredHeight;
            PositionControls(); 
        }
 
        ///  
        /// 
        /// Raises the TextBoxTextChanged event. 
        /// event.
        /// 
        protected virtual void OnTextBoxTextChanged(object source, EventArgs e) {
            if (changingText) { 
                Debug.Assert(UserEdit == false, "OnTextBoxTextChanged() - UserEdit == true");
                ChangingText = false; 
            } 
            else {
                UserEdit = true; 
            }

            this.OnTextChanged(e);
            OnChanged(source, new EventArgs()); 
        }
 
        ///  
        ///     Called from the UpDownButtons member. Provided for derived controls to have a finer way to handle the event.
        ///  
        internal virtual void OnStartTimer() {
        }

        internal virtual void OnStopTimer() { 
        }
 
        ///  
        ///       Raises the  event.
        ///  
        protected override void OnMouseDown(MouseEventArgs e) {
            if (e.Clicks == 2 && e.Button == MouseButtons.Left) {
                doubleClickFired = true;
            } 

            base.OnMouseDown(e); 
        } 

        ///  
        /// 
        ///    
        ///       Raises the  event.
        /// 
        ///    
        ///  
        protected override void OnMouseUp(MouseEventArgs mevent) { 
            if (mevent.Button == MouseButtons.Left) {
                Point pt = PointToScreen(new Point(mevent.X, mevent.Y)); 
                if (UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle && !ValidationCancelled) {
                    if (!doubleClickFired) {
                        OnClick(mevent);
                        OnMouseClick(mevent); 
                    }
                    else { 
                        doubleClickFired = false; 
                        OnDoubleClick(mevent);
                        OnMouseDoubleClick(mevent); 
                    }
                }
                doubleClickFired = false;
            } 
            base.OnMouseUp(mevent);
        } 
 
        /// 
        ///  
        /// Raises the  event.
        /// 
        protected override void OnMouseWheel(MouseEventArgs e) {
            base.OnMouseWheel(e); 
            HandledMouseEventArgs hme = e as HandledMouseEventArgs;
            if (hme != null) { 
               if (hme.Handled) { 
                   return;
               } 
               hme.Handled = true;
            }

            if ((ModifierKeys & (Keys.Shift | Keys.Alt)) != 0 || MouseButtons != MouseButtons.None) { 
                return; // Do not scroll when Shift or Alt key is down, or when a mouse button is down.
            } 
 
            int wheelScrollLines = SystemInformation.MouseWheelScrollLines;
            if (wheelScrollLines == 0) { 
                return; // Do not scroll when the user system setting is 0 lines per notch
            }

            Debug.Assert(this.wheelDelta > -NativeMethods.WHEEL_DELTA, "wheelDelta is too smal"); 
            Debug.Assert(this.wheelDelta < NativeMethods.WHEEL_DELTA, "wheelDelta is too big");
            this.wheelDelta += e.Delta; 
 
            float partialNotches;
            partialNotches = (float)this.wheelDelta / (float)NativeMethods.WHEEL_DELTA; 

            if (wheelScrollLines == -1) {
               wheelScrollLines = DefaultWheelScrollLinesPerPage;
            } 

            // Evaluate number of bands to scroll 
            int scrollBands = (int)((float)wheelScrollLines * partialNotches); 
            if (scrollBands != 0) {
               int absScrollBands; 
               if (scrollBands > 0) {
                  absScrollBands = scrollBands;
                  while (absScrollBands > 0) {
                     UpButton(); 
                     absScrollBands--;
                  } 
                  this.wheelDelta -= (int)((float)scrollBands * ((float)NativeMethods.WHEEL_DELTA / (float)wheelScrollLines)); 
               }
               else { 
                  absScrollBands = -scrollBands;
                  while (absScrollBands > 0) {
                     DownButton();
                     absScrollBands--; 
                  }
                  this.wheelDelta -= (int)((float)scrollBands * ((float)NativeMethods.WHEEL_DELTA / (float)wheelScrollLines)); 
               } 
            }
        } 


        /// 
        ///  
        /// 
        ///    Handle the layout event. The size of the upDownEdit control, and the 
        ///    position of the UpDown control must be modified. 
        /// 
        protected override void OnLayout(LayoutEventArgs e) { 

            PositionControls();
            base.OnLayout(e);
        } 

        ///  
        ///  
        /// 
        ///     
        ///       Raises the FontChanged event.
        ///    
        /// 
        protected override void OnFontChanged(EventArgs e) { 
            // Clear the font height cache
            FontHeight = -1; 
 
            Height = PreferredHeight;
            PositionControls(); 

            base.OnFontChanged(e);
        }
 
        /// 
        ///  
        /// 
        ///     Handles UpDown events, which are generated by clicking on
        ///     the updown buttons in the child updown control. 
        ///
        /// 
        private void OnUpDown(object source, UpDownEventArgs e) {
            // Modify the value 
            if (e.ButtonID == (int)ButtonID.Up)
                UpButton(); 
            else if (e.ButtonID == (int)ButtonID.Down) 
                DownButton();
        } 

        /// 
        /// 
        ///     Calculates the size and position of the upDownEdit control and 
        ///     the updown buttons.
        ///  
        private void PositionControls() { 
            Rectangle upDownEditBounds    = Rectangle.Empty,
                      upDownButtonsBounds = Rectangle.Empty; 

            Rectangle clientArea     = new Rectangle(Point.Empty, ClientSize);
            int totalClientWidth     = clientArea.Width;
            bool themed              = Application.RenderWithVisualStyles; 
            BorderStyle borderStyle  = BorderStyle;
 
 
            // determine how much to squish in - Fixed3d and FixedSingle have 2PX border
            int borderWidth = (borderStyle == BorderStyle.None) ? 0 : 2; 
            clientArea.Inflate(-borderWidth, -borderWidth);

            // Reposition and resize the upDownEdit control
            // 
            if (upDownEdit != null) {
                upDownEditBounds = clientArea; 
                upDownEditBounds.Size = new Size(clientArea.Width - DefaultButtonsWidth, clientArea.Height); 
            }
 
            // Reposition and resize the updown buttons
            //
            if (upDownButtons != null) {
                int borderFixup = (themed) ? 1: 2; 
                if (borderStyle == BorderStyle.None) {
                    borderFixup = 0; 
                } 
                upDownButtonsBounds = new Rectangle(/*x*/clientArea.Right - DefaultButtonsWidth+borderFixup,
                                                    /*y*/clientArea.Top-borderFixup, 
                                                    /*w*/DefaultButtonsWidth,
                                                    /*h*/clientArea.Height+(borderFixup*2));
            }
 
            // Right to left translation
            LeftRightAlignment updownAlign = UpDownAlign; 
            updownAlign = RtlTranslateLeftRight(updownAlign); 

            // left/right updown align translation 
            if (updownAlign == LeftRightAlignment.Left) {
                // if the buttons are aligned to the left, swap position of text box/buttons
                upDownButtonsBounds.X = totalClientWidth - upDownButtonsBounds.Right;
                upDownEditBounds.X = totalClientWidth - upDownEditBounds.Right; 
            }
 
            // apply locations 
            if (upDownEdit != null) {
                 upDownEdit.Bounds = upDownEditBounds; 
            }
            if (upDownButtons != null) {
                upDownButtons.Bounds = upDownButtonsBounds;
                upDownButtons.Invalidate(); 
            }
 
       } 

        ///  
        /// 
        ///    
        ///       Selects a range of
        ///       text in the up-down control. 
        ///    
        ///  
        public void Select(int start, int length) { 
            upDownEdit.Select(start, length);
        } 


        /// 
        ///   Child controls run their 
        /// 
        private MouseEventArgs TranslateMouseEvent(Control child, MouseEventArgs e) { 
            if (child != null && IsHandleCreated) { 
                // same control as PointToClient or PointToScreen, just
                // with two specific controls in mind. 
                NativeMethods.POINT point = new NativeMethods.POINT(e.X, e.Y);
                UnsafeNativeMethods.MapWindowPoints(new HandleRef(child, child.Handle), new HandleRef(this, Handle), point, 1);
                return new MouseEventArgs(e.Button, e.Clicks, point.x, point.y , e.Delta);
            } 
            return e;
        } 
 
        /// 
        ///  
        ///    
        ///       When overridden in a derived class, handles the pressing of the up button on the up-down control.
        ///    
        ///  
        public abstract void UpButton();
 
        ///  
        /// 
        ///     
        ///       When overridden
        ///       in a derived class, updates the text displayed in the up-down control.
        ///    
        ///  
        protected abstract void UpdateEditText();
 
        private void UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs pref) { 
            if (pref.Category == UserPreferenceCategory.Locale) {
                UpdateEditText(); 
            }
        }

        ///  
        /// 
        ///     
        ///       When overridden in a 
        ///       derived class, validates the text displayed in the up-down control.
        ///     
        /// 
        protected virtual void ValidateEditText() {
        }
 
        /// 
        ///  
        ///  
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)] 
        [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg) 
            {
                case NativeMethods.WM_SETFOCUS: 
                    if (!HostedInWin32DialogManager) { 
                        if (ActiveControl == null) {
                            SetActiveControlInternal(TextBox); 
                        }
                        else {
                            FocusActiveControlInternal();
                        } 
                    }
                    else { 
                        if (TextBox.CanFocus){ 
                            UnsafeNativeMethods.SetFocus(new HandleRef(TextBox, TextBox.Handle));
                        } 
                        base.WndProc(ref m);
                    }
                    break;
                case NativeMethods.WM_KILLFOCUS: 
                    DefWndProc(ref m);
                    break; 
                default: 
                    base.WndProc(ref m);
                    break; 
            }
        }

        ///  
        /// 
        ///  
        ///    This Function sets the ToolTip for this composite control. 
        /// 
        internal void SetToolTip(ToolTip toolTip, string caption) { 
            toolTip.SetToolTip(this.upDownEdit , caption);
            toolTip.SetToolTip(this.upDownButtons , caption);
        }
 
        internal class UpDownEdit : TextBox{
            ///////////////////////////////////////////////////////////////////// 
            // Member variables 
            //
            ///////////////////////////////////////////////////////////////////// 

            // Parent control
            private UpDownBase parent;
            private bool doubleClickFired = false; 
            /////////////////////////////////////////////////////////////////////
            // Constructors 
            // 
            /////////////////////////////////////////////////////////////////////
 
            internal UpDownEdit(UpDownBase parent)
            : base() {

                SetStyle(ControlStyles.FixedHeight | 
                         ControlStyles.FixedWidth, true);
 
                SetStyle(ControlStyles.Selectable, false); 

                this.parent = parent; 
            }

            protected override AccessibleObject CreateAccessibilityInstance() {
                return new UpDownEditAccessibleObject(this, parent); 
            }
 
            protected override void OnMouseDown(MouseEventArgs e) { 
                if (e.Clicks == 2 && e.Button == MouseButtons.Left) {
                    doubleClickFired = true; 
                }
                parent.OnMouseDown(parent.TranslateMouseEvent(this, e));
            }
 
            /// 
            ///  
            /// 
            ///     Handles detecting when the mouse button is released.
            /// 
            /// 
            protected override void OnMouseUp(MouseEventArgs e) {

                Point pt = new Point(e.X,e.Y); 
                pt = PointToScreen(pt);
 
                MouseEventArgs me = parent.TranslateMouseEvent(this, e); 
                if (e.Button == MouseButtons.Left) {
                    if (!parent.ValidationCancelled && UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle) { 
                        if (!doubleClickFired) {
                            parent.OnClick(me);
                            parent.OnMouseClick(me);
                        } 
                        else {
                            doubleClickFired = false; 
                            parent.OnDoubleClick(me); 
                            parent.OnMouseDoubleClick(me);
                        } 
                    }
                    doubleClickFired = false;
                }
 
                parent.OnMouseUp(me);
            } 
 
            internal override void WmContextMenu(ref Message m) {
                // VSWhidbey 521337: want to make the SourceControl to be the UpDownBase, not the Edit. 
                if (ContextMenu == null && ContextMenuStrip != null) {
                    WmContextMenu(ref m, parent);
                }
                else { 
                    WmContextMenu(ref m, this);
                } 
            } 

 
            /// 
            /// 
            /// Raises the 
            /// event. 
            /// 
            protected override void OnKeyUp(KeyEventArgs e) { 
                parent.OnKeyUp(e); 
            }
 
            protected override void OnGotFocus(EventArgs e) {
                parent.SetActiveControlInternal(this);
                parent.OnGotFocus(e);
            } 

            protected override void OnLostFocus(EventArgs e) { 
                parent.OnLostFocus(e); 
            }
 
            // [....]: Focus fixes. The XXXUpDown control will
            //         also fire a Leave event. We don't want
            //         to fire two of them.
            // protected override void OnLeave(EventArgs e) { 
            //     parent.OnLeave(e);
            // } 
 
            // Create our own accessibility object to map the accessible name
            // back to our parent.  They should track. 
            internal class UpDownEditAccessibleObject : ControlAccessibleObject {
                UpDownBase parent;

                public UpDownEditAccessibleObject(UpDownEdit owner, UpDownBase parent) : base(owner) { 
                    this.parent = parent;
                } 
 
                public override string Name {
                    get { 
                        return parent.AccessibilityObject.Name;
                    }
                    set {
                        parent.AccessibilityObject.Name = value; 
                    }
                } 
 
                public override string KeyboardShortcut {
                    get { 
                        return parent.AccessibilityObject.KeyboardShortcut;
                    }
                }
            } 
        }
 
        ///  
        /// 
        /// 
        ///     Nested class UpDownButtons
        ///
        ///     A control representing the pair of buttons on the end of the upDownEdit control.
        ///     This class handles drawing the updown buttons, and detecting mouse actions 
        ///     on these buttons. Acceleration on the buttons is handled. The control
        ///     sends UpDownEventArgss to the parent UpDownBase class when a button is pressed, 
        ///     or when the acceleration determines that another event should be generated. 
        /// 
        internal class UpDownButtons : Control { 
            //

            /////////////////////////////////////////////////////////////////////
            // Member variables 
            //
            ///////////////////////////////////////////////////////////////////// 
 
            // Parent control
            private UpDownBase parent; 

            // Button state
            private ButtonID pushed = ButtonID.None;
            private ButtonID captured = ButtonID.None; 
            private ButtonID mouseOver = ButtonID.None;
 
            // UpDown event handler 
            private UpDownEventHandler upDownEventHandler;
 
            // Timer
            private Timer timer;                    // generates UpDown events
            private int timerInterval;              // milliseconds between events
 
            private bool doubleClickFired = false;
 
            ///////////////////////////////////////////////////////////////////// 
            // Constructors
            // 
            /////////////////////////////////////////////////////////////////////

            internal UpDownButtons(UpDownBase parent)
 
            : base() {
 
                SetStyle(ControlStyles.Opaque | ControlStyles.FixedHeight | 
                         ControlStyles.FixedWidth, true);
 
                SetStyle(ControlStyles.Selectable, false);

                this.parent = parent;
            } 

 
            ///////////////////////////////////////////////////////////////////// 
            // Methods
            // 
            /////////////////////////////////////////////////////////////////////

            /// 
            ///  
            ///
            ///     Adds a handler for the updown button event. 
            ///  
            public event UpDownEventHandler UpDown {
                add { 
                    upDownEventHandler += value;
                }
                remove {
                    upDownEventHandler -= value; 
                }
            } 
 
            // Called when the mouse button is pressed - we need to start
            // spinning the value of the updown. 
            //
            private void BeginButtonPress(MouseEventArgs e) {

                int half_height = Size.Height / 2; 

                if (e.Y < half_height) { 
 
                    // Up button
                    // 
                    pushed = captured = ButtonID.Up;
                    Invalidate();

                } 
                else {
 
                    // Down button 
                    //
                    pushed = captured = ButtonID.Down; 
                    Invalidate();
                }

                // Capture the mouse 
                //
                CaptureInternal = true; 
 
                // Generate UpDown event
                // 
                OnUpDown(new UpDownEventArgs((int)pushed));

                // Start the timer for new updown events
                // 
                StartTimer();
            } 
 
            protected override AccessibleObject CreateAccessibilityInstance() {
                return new UpDownButtonsAccessibleObject(this); 
            }

            // Called when the mouse button is released - we need to stop
            // spinning the value of the updown. 
            //
            private void EndButtonPress() { 
 
                pushed = ButtonID.None;
                captured = ButtonID.None; 

                // Stop the timer
                StopTimer();
 
                // Release the mouse
                CaptureInternal = false; 
 
                // Redraw the buttons
                Invalidate(); 
            }

            /// 
            ///  
            ///
            ///     Handles detecting mouse hits on the buttons. This method 
            ///     detects which button was hit (up or down), fires a 
            ///     updown event, captures the mouse, and starts a timer
            ///     for repeated updown events. 
            ///
            /// 
            protected override void OnMouseDown(MouseEventArgs e) {
                // Begin spinning the value 
                //
 
                // Focus the parent 
                //
                this.parent.FocusInternal(); 

                if (!parent.ValidationCancelled && e.Button == MouseButtons.Left) {
                    BeginButtonPress(e);
                } 
                if (e.Clicks == 2 && e.Button == MouseButtons.Left) {
                    doubleClickFired = true; 
                } 
                // At no stage should a button be pushed, and the mouse
                // not captured. 
                //
                Debug.Assert(!(pushed != ButtonID.None && captured == ButtonID.None),
                             "Invalid button pushed/captured combination");
 
                parent.OnMouseDown(parent.TranslateMouseEvent(this, e));
            } 
 
            /// 
            ///  
            ///
            ///     Handles detecting mouse movement.
            ///
            ///  
            protected override void OnMouseMove(MouseEventArgs e) {
 
                // If the mouse is captured by the buttons (i.e. an updown button 
                // was pushed, and the mouse button has not yet been released),
                // determine the new state of the buttons depending on where 
                // the mouse pointer has moved.

                if (Capture) {
 
                    // Determine button area
 
                    Rectangle rect = ClientRectangle; 
                    rect.Height /= 2;
 
                    if (captured == ButtonID.Down) {
                        rect.Y += rect.Height;
                    }
 
                    // Test if the mouse has moved outside the button area
 
                    if (rect.Contains(e.X, e.Y)) { 

                        // Inside button 
                        // Repush the button if necessary

                        if (pushed != captured) {
 
                            // Restart the timer
                            StartTimer(); 
 
                            pushed = captured;
                            Invalidate(); 
                        }

                    }
                    else { 

                        // Outside button 
                        // Retain the capture, but pop the button up whilst 
                        // the mouse remains outside the button and the
                        // mouse button remains pressed. 

                        if (pushed != ButtonID.None) {

                            // Stop the timer for updown events 
                            StopTimer();
 
                            pushed = ButtonID.None; 
                            Invalidate();
                        } 
                    }
                }

                //Logic for seeing which button is Hot if any 
                Rectangle rectUp = ClientRectangle, rectDown = ClientRectangle;
                rectUp.Height /= 2; 
                rectDown.Y += rectDown.Height / 2; 

                //Check if the mouse is on the upper or lower button. Note that it could be in neither. 
                if (rectUp.Contains(e.X, e.Y)) {
                    mouseOver = ButtonID.Up;
                    Invalidate();
                } 
                else if (rectDown.Contains(e.X, e.Y)) {
                    mouseOver = ButtonID.Down; 
                    Invalidate(); 
                }
 
                // At no stage should a button be pushed, and the mouse
                // not captured.
                Debug.Assert(!(pushed != ButtonID.None && captured == ButtonID.None),
                             "Invalid button pushed/captured combination"); 

                parent.OnMouseMove(parent.TranslateMouseEvent(this, e)); 
            } 

            ///  
            /// 
            ///
            ///     Handles detecting when the mouse button is released.
            /// 
            /// 
            protected override void OnMouseUp(MouseEventArgs e) { 
 
                if (!parent.ValidationCancelled && e.Button == MouseButtons.Left) {
                    EndButtonPress(); 
                }

                // At no stage should a button be pushed, and the mouse
                // not captured. 
                Debug.Assert(!(pushed != ButtonID.None && captured == ButtonID.None),
                             "Invalid button pushed/captured combination"); 
 
                Point pt = new Point(e.X,e.Y);
                pt = PointToScreen(pt); 

                MouseEventArgs me = parent.TranslateMouseEvent(this, e);
                if (e.Button == MouseButtons.Left) {
                    if (!parent.ValidationCancelled && UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle) { 
                        if (!doubleClickFired) {
                            this.parent.OnClick(me); 
                        } 
                        else {
                            doubleClickFired = false; 
                            this.parent.OnDoubleClick(me);
                            this.parent.OnMouseDoubleClick(me);
                        }
                    } 
                    doubleClickFired = false;
                } 
 
                parent.OnMouseUp(me);
            } 

            /// 
            /// 
            /// 
            ///     Handles detecting when the mouse leaves.
            /// 
            ///  
            protected override void OnMouseLeave(EventArgs e) {
                mouseOver = ButtonID.None; 
                Invalidate();

                parent.OnMouseLeave(e);
            } 

            ///  
            ///  
            ///     Handles painting the buttons on the control.
            /// 
            /// 
            protected override void OnPaint(PaintEventArgs e) {
                int half_height = ClientSize.Height / 2;
 
                /* Draw the up and down buttons */
 
                if (Application.RenderWithVisualStyles) { 
                    VisualStyleRenderer vsr = new VisualStyleRenderer(mouseOver == ButtonID.Up ? VisualStyleElement.Spin.Up.Hot : VisualStyleElement.Spin.Up.Normal);
 
                    if (!Enabled) {
                        vsr.SetParameters(VisualStyleElement.Spin.Up.Disabled);
                    }
                    else if (pushed == ButtonID.Up) { 
                        vsr.SetParameters(VisualStyleElement.Spin.Up.Pressed);
                    } 
 
                    vsr.DrawBackground(e.Graphics, new Rectangle(0, 0, DefaultButtonsWidth, half_height));
 
                    if (!Enabled) {
                        vsr.SetParameters(VisualStyleElement.Spin.Down.Disabled);
                    }
                    else if (pushed == ButtonID.Down) { 
                        vsr.SetParameters(VisualStyleElement.Spin.Down.Pressed);
                    } 
                    else { 
                        vsr.SetParameters(mouseOver == ButtonID.Down ? VisualStyleElement.Spin.Down.Hot : VisualStyleElement.Spin.Down.Normal);
                    } 

                    vsr.DrawBackground(e.Graphics, new Rectangle(0, half_height, DefaultButtonsWidth, half_height));
                }
                else { 
                    ControlPaint.DrawScrollButton(e.Graphics,
                                                  new Rectangle(0, 0, DefaultButtonsWidth, half_height), 
                                                  ScrollButton.Up, 
                                                  pushed == ButtonID.Up ? ButtonState.Pushed : (Enabled ? ButtonState.Normal : ButtonState.Inactive));
 
                    ControlPaint.DrawScrollButton(e.Graphics,
                                                  new Rectangle(0, half_height, DefaultButtonsWidth, half_height),
                                                  ScrollButton.Down,
                                                  pushed == ButtonID.Down ? ButtonState.Pushed : (Enabled ? ButtonState.Normal : ButtonState.Inactive)); 
                }
 
                if (half_height != (ClientSize.Height + 1) / 2) { 
                    // When control has odd height, a line needs to be drawn below the buttons with the backcolor.
                    using (Pen pen = new Pen(this.parent.BackColor)) { 
                        Rectangle clientRect = ClientRectangle;
                        e.Graphics.DrawLine(pen, clientRect.Left, clientRect.Bottom - 1, clientRect.Right - 1, clientRect.Bottom - 1);
                    }
                } 

                base.OnPaint(e); // raise paint event, just in case this inner class goes public some day 
            } 

            ///  
            /// 
            ///     Occurs when the UpDown buttons are pressed and when the acceleration timer tick event is raised.
            /// 
            protected virtual void OnUpDown(UpDownEventArgs upevent) { 
                if (upDownEventHandler != null)
                    upDownEventHandler(this, upevent); 
            } 

            ///  
            /// 
            ///     Starts the timer for generating updown events
            /// 
            protected void StartTimer() { 
                parent.OnStartTimer();
                if (timer == null) { 
                    timer = new Timer();      // generates UpDown events 
                    // Add the timer handler
                    timer.Tick += new EventHandler(TimerHandler); 
                }

                this.timerInterval = DefaultTimerInterval;
 
                timer.Interval = this.timerInterval;
                timer.Start(); 
            } 

            ///  
            /// 
            ///     Stops the timer for generating updown events
            /// 
            protected void StopTimer() { 
                if (timer != null) {
                    timer.Stop(); 
                    timer.Dispose(); 
                    timer = null;
                } 
                parent.OnStopTimer();
            }

            ///  
            /// 
            ///     Generates updown events when the timer calls this function. 
            ///  
            private void TimerHandler(object source, EventArgs args) {
 
                // Make sure we've got mouse capture
                if (!Capture) {
                    EndButtonPress();
                    return; 
                }
 
                OnUpDown(new UpDownEventArgs((int)pushed)); 

                // Accelerate timer. 
                this.timerInterval *= 7;
                this.timerInterval /= 10;

                if (this.timerInterval < 1) 
                {
                    this.timerInterval = 1; 
                } 

                timer.Interval = this.timerInterval; 
            }

            internal class UpDownButtonsAccessibleObject : ControlAccessibleObject {
 
                private DirectionButtonAccessibleObject upButton;
                private DirectionButtonAccessibleObject downButton; 
 
                public UpDownButtonsAccessibleObject(UpDownButtons owner) : base(owner) {
                } 

                public override string Name {
                    get {
                        string baseName = base.Name; 
                        if (baseName == null || baseName.Length == 0) {
                            return "Spinner"; 
                        } 
                        return baseName;
                    } 
                    set {
                        base.Name = value;
                    }
                } 

                ///  
                ///  
                ///    [To be supplied.]
                ///  
                public override AccessibleRole Role {
                    get {
                        AccessibleRole role = Owner.AccessibleRole;
                        if (role != AccessibleRole.Default) { 
                            return role;
                        } 
                        return AccessibleRole.SpinButton; 
                    }
                } 

                private DirectionButtonAccessibleObject UpButton {
                    get {
                        if (upButton == null) { 
                            upButton = new DirectionButtonAccessibleObject(this, true);
                        } 
                        return upButton; 
                    }
                } 

                private DirectionButtonAccessibleObject DownButton {
                    get {
                        if (downButton == null) { 
                            downButton = new DirectionButtonAccessibleObject(this, false);
                        } 
                        return downButton; 
                    }
                } 



                ///  
                /// 
                ///  
                public override AccessibleObject GetChild(int index) { 

                    // Up button 
                    //
                    if (index == 0) {
                        return UpButton;
                    } 

                    // Down button 
                    // 
                    if (index == 1) {
                        return DownButton; 
                    }

                    return null;
                } 

                ///  
                ///  
                /// 
                public override int GetChildCount() { 
                    return 2;
                }

                internal class DirectionButtonAccessibleObject : AccessibleObject { 
                    private bool up;
                    private UpDownButtonsAccessibleObject parent; 
 
                    public DirectionButtonAccessibleObject(UpDownButtonsAccessibleObject parent, bool up) {
                        this.parent = parent; 
                        this.up = up;
                    }

                    public override Rectangle Bounds { 
                        get {
                            // Get button bounds 
                            // 
                            Rectangle bounds = ((UpDownButtons)parent.Owner).Bounds;
                            bounds.Height /= 2; 
                            if (!up) {
                                bounds.Y += bounds.Height;
                            }
 
                            // Convert to screen co-ords
                            // 
                            return (((UpDownButtons)parent.Owner).ParentInternal).RectangleToScreen(bounds); 
                        }
                    } 

                    public override string Name {
                        get {
                            if (up) { 
                                return SR.GetString(SR.UpDownBaseUpButtonAccName);
                            } 
                            return SR.GetString(SR.UpDownBaseDownButtonAccName); 
                        }
                        set { 
                        }
                    }

                    public override AccessibleObject Parent { 
                        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
                        get { 
                            return parent; 
                        }
                    } 

                    public override AccessibleRole Role {
                        get {
                            return AccessibleRole.PushButton; 
                        }
                    } 
                } 
            }
 
        } // end class UpDownButtons

        // Button identifiers
 
        internal enum ButtonID {
            None = 0, 
            Up = 1, 
            Down = 2,
        } 
    } // end class UpDownBase
}


// 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