WinFormsSpinner.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / UIAutomation / Win32Providers / MS / Internal / AutomationProxies / WinFormsSpinner.cs / 1305600 / WinFormsSpinner.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: Spinner Proxy 
//
// History: 
//              a-jeanp                 Entirely revised
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Text; 
using System.ComponentModel;
using System.Globalization; 
using System.Windows.Automation;
using System.Windows.Automation.Provider;
using System.Windows;
using MS.Win32; 

namespace MS.Internal.AutomationProxies 
{ 
    // [....] NumericUpDown proxy
    class WinformsSpinner : ProxyHwnd, IRawElementProviderHwndOverride, IRangeValueProvider, IValueProvider 
    {
        // -----------------------------------------------------
        //
        // Constructors 
        //
        // ----------------------------------------------------- 
 
        #region Constructors
 
        // Contructor for WinformsSpinner class. Calls the base class constructor.
        internal WinformsSpinner(IntPtr hwnd, IntPtr hwndEdit, IntPtr hwndUpDown, ProxyFragment parent, int item)
            : base(hwnd, parent, item)
        { 
            _elEdit = new WindowsEditBox(hwndEdit, this, (int)0);
            _elUpDown = new WindowsUpDown(hwndUpDown, this, (int)0); 
 
            string text;
            try 
            {
                text = Misc.ProxyGetText(hwndEdit);
            }
            catch (TimeoutException) 
            {
                text = null; 
            } 
            catch (Win32Exception)
            { 
                text = null;
            }

            if (!string.IsNullOrEmpty(text)) 
            {
                try 
                { 
                    double.Parse(text, NumberStyles.Any, CultureInfo.InvariantCulture);
 
                    // the text parsed just fine so must be a number.
                    _type = SpinnerType.Numeric;
                }
                catch (FormatException) 
                {
                    // the text is not a based 10 number.  Check if the text is a hex number. 
                    try 
                    {
                        int.Parse(text, NumberStyles.HexNumber, CultureInfo.InvariantCulture); 

                        // the text parsed just fine so must be a number.
                        _type = SpinnerType.Numeric;
                    } 
                    catch (FormatException)
                    { 
                        // the text does not consist solely of an optional negative sign followed by a sequence of 
                        // digits ranging from 0 to 9, so this spinner must be a domain spinner
                        _type = SpinnerType.Domain; 
                    }
                    catch (OverflowException)
                    {
                        // the text represents a number less than MinValue or greater than MaxValue, but it is still 
                        // a number, therefore must be a numeric spinner
                        _type = SpinnerType.Numeric; 
                    } 
                }
                catch (OverflowException) 
                {
                    // the text represents a number less than MinValue or greater than MaxValue, but it is still
                    // a number, therefore must be a numeric spinner
                    _type = SpinnerType.Numeric; 
                }
            } 
            else 
            {
                // numeric spinners always have a value.  The defualt state of a domain spinner 
                // may be blank.  The text value is blank so this must be a domain spinner.
                _type = SpinnerType.Domain;
            }
 
            // Set the strings to return properly the properties.
            _cControlType = ControlType.Spinner; 
 
            // support for events
            _createOnEvent = new WinEventTracker.ProxyRaiseEvents(WindowsUpDown.RaiseEvents); 
        }

        #endregion
 
        #region Proxy Create
 
        // Static Create method called by UIAutomation to create this proxy. 
        // returns null if unsuccessful
        internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild, int idObject) 
        {
            return Create(hwnd, idChild);
        }
 
        internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild)
        { 
            // If idChild is not zero this can't be a [....] spinner.  The way this 
            // code is called, the passed in hwnd could be some other control and in
            // that case the calling code should continue looking for a valid proxy. 
            if (idChild != 0)
            {
                return null;
            } 

            try 
            { 
                //
                // A winform spinner control can only have 2 children - An Edit and an UpDown. 
                //

                // First child
                IntPtr hwndFirstChild = Misc.GetWindow(hwnd, NativeMethods.GW_CHILD); 
                if (hwndFirstChild == IntPtr.Zero)
                { 
                    return null; 
                }
 
                // Last child
                IntPtr hwndLastChild = Misc.GetWindow(hwndFirstChild, NativeMethods.GW_HWNDLAST);
                if (hwndLastChild == IntPtr.Zero)
                { 
                    return null;
                } 
 
                // No children in the middle
                if (Misc.GetWindow(hwndFirstChild, NativeMethods.GW_HWNDNEXT) != hwndLastChild) 
                {
                    return null;
                }
 

                // We need to positively identify the two children as Edit and UpDown controls 
                IntPtr hwndEdit; 
                IntPtr hwndSpin;
 
                // Find the Edit control.  Typically the UpDown is first so we'll start with the other window.
                if (Misc.ProxyGetClassName(hwndLastChild).IndexOf("Edit", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    hwndEdit = hwndLastChild; 
                    hwndSpin = hwndFirstChild;
                } 
                else 
                {
                    // Haven't seen this but suppose it's possible.  Subsequent test will confirm. 
                    if (Misc.ProxyGetClassName(hwndFirstChild).IndexOf("Edit", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        hwndEdit = hwndFirstChild;
                        hwndSpin = hwndLastChild; 
                    }
                    else 
                    { 
                        // Must contain an Edit/UpDown control pair
                        return null; 
                    }
                }

                // 
                // A winform UpDown control can only have 2 children, both spin buttons.
                // 
 
                // Use IAccessible implementation to confirm the spinner & children
                Accessible acc = null; 
                if (Accessible.AccessibleObjectFromWindow(hwndSpin, NativeMethods.OBJID_CLIENT, ref acc) != NativeMethods.S_OK || acc == null)
                {
                    return null;
                } 

                if ((acc.Role != AccessibleRole.SpinButton) || (acc.ChildCount != 2)) 
                { 
                    return null;
                } 

                // Confirmed spinner
                return new WinformsSpinner(hwnd, hwndEdit, hwndSpin, null, 0);
            } 
            catch (ElementNotAvailableException)
            { 
                // Ignore ElementNotAvailableExceptions and return null 
                return null;
            } 
        }

        #endregion Proxy Create
 
        //------------------------------------------------------
        // 
        //  Patterns Implementation 
        //
        //----------------------------------------------------- 

        // ------------------------------------------------------
        //
        // ProxySimple interface implementation 
        //
        // ------------------------------------------------------ 
 
        #region ProxySimple Interface
 
        // Returns a pattern interface if supported.
        internal override object GetPatternProvider (AutomationPattern iid)
        {
            if (iid == RangeValuePattern.Pattern && _type == SpinnerType.Numeric) 
            {
                return this; 
            } 
            else if (_type == SpinnerType.Domain)
            { 
                if (iid == ValuePattern.Pattern)
                {
                    return this;
                } 
                else if (iid == SelectionPattern.Pattern)
                { 
                    // Special case for a [....] domain spinner. It is supposed to support 
                    // SelectionPattern, but because it is based on an edit control, this is
                    // not possible unless each of the items in the spinner have been reviewed 
                    // at least once. Call out this unusual case by throwing the following
                    // NotImplementedException.
                    throw new NotImplementedException();
                } 
            }
            return null; 
        } 

        #endregion 

        // -----------------------------------------------------
        //
        // ProxyFragment interface implementation 
        //
        // ------------------------------------------------------ 
 
        #region ProxyFragment Interface
 
        // Returns a Proxy element corresponding to the specified screen coordinates.
        internal override ProxySimple ElementProviderFromPoint(int x, int y)
        {
            Rect rcUpDown = _elUpDown.BoundingRectangle; 

            if (rcUpDown.Contains(new Point(x, y))) 
            { 
                return _elUpDown.ElementProviderFromPoint (x, y);
            } 

            return this;
        }
 
        #endregion
 
        // ----------------------------------------------------- 
        //
        // ProxyHwnd interface implementation 
        //
        // -----------------------------------------------------

        #region ProxyHwnd Interface 

        internal override void AdviseEventAdded(AutomationEvent eventId, AutomationProperty[] aidProps) 
        { 
            base.AdviseEventAdded(eventId, aidProps);
 
            // Need to also advise the edit portions of the spinner so that it can raise events.
            if (_elEdit != null)
            {
                _elEdit.AdviseEventAdded(eventId, aidProps); 
            }
        } 
 
        internal override void AdviseEventRemoved(AutomationEvent eventId, AutomationProperty[] aidProps)
        { 
            base.AdviseEventRemoved(eventId, aidProps);

            // Need to also remove the advise from the edit portions of the spinner.
            if (_elEdit != null) 
            {
                _elEdit.AdviseEventRemoved(eventId, aidProps); 
            } 
        }
 
        #endregion

        // -----------------------------------------------------
        // 
        // IRawElementProviderHwndOverride interface implementation
        // 
        // ------------------------------------------------------ 

        #region IRawElementProviderHwndOverride 

        IRawElementProviderSimple IRawElementProviderHwndOverride.GetOverrideProviderForHwnd(IntPtr hwnd)
        {
            // The Edit hwnd in the spinner is not a Logical Element 
            // returns the full spinner on the request to get a provider for the edit
            if (IsEdit(hwnd)) 
            { 
                return new WinformsSpinnerEdit(_hwnd, _elEdit._hwnd, _elUpDown._hwnd, _parent, _item);
            } 

            return null;
        }
 
        #endregion IRawElementProviderHwndOverride
 
        // ----------------------------------------------------- 
        //
        // IRangeValueProvider interface implementation 
        //
        // ------------------------------------------------------

        #region RangeValue Pattern 

        // Sets a new position for the edit part of the spinner. 
        void IRangeValueProvider.SetValue (double obj) 
        {
            ((IRangeValueProvider)_elUpDown).SetValue(obj); 
        }

        // Request to get the value that this UI element is representing in a native format
        double IRangeValueProvider.Value 
        {
            get 
            { 
                return ((IRangeValueProvider)_elUpDown).Value;
            } 
        }

        bool IRangeValueProvider.IsReadOnly
        { 
            get
            { 
                return (bool)((IRangeValueProvider)_elUpDown).IsReadOnly && 
                       (bool)((IValueProvider)_elEdit).IsReadOnly;
            } 
        }

        double IRangeValueProvider.Maximum
        { 
            get
            { 
                return ((IRangeValueProvider)_elUpDown).Maximum; 
            }
        } 

        double IRangeValueProvider.Minimum
        {
            get 
            {
                return ((IRangeValueProvider)_elUpDown).Minimum; 
            } 
        }
 
        double IRangeValueProvider.SmallChange
        {
            get
            { 
                return ((IRangeValueProvider)_elUpDown).SmallChange;
            } 
        } 

        double IRangeValueProvider.LargeChange 
        {
            get
            {
                return ((IRangeValueProvider)_elUpDown).LargeChange; 
            }
        } 
        #endregion RangeValuePattern 

        #region Value Pattern 

        // ------------------------------------------------------
        //
        // IValueProvider interface implementation 
        //
        // ----------------------------------------------------- 
 
        // Sets a value into the edit box
        void IValueProvider.SetValue(string val) 
        {
            ((IValueProvider)_elEdit).SetValue(val);
        }
 
        // Returns the value of the edit.
        string IValueProvider.Value 
        { 
            get
            { 
                return ((IValueProvider)_elEdit).Value;
            }
        }
 
        // Returns if the edit control is read-only.
        bool IValueProvider.IsReadOnly 
        { 
            get
            { 
                return true;
            }
        }
 
        #endregion
 
        // ------------------------------------------------------ 
        //
        // Private methods 
        //
        // -----------------------------------------------------

        #region Private Methods 

        // Check if the hwnd is the Edit Window in the spinner box 
        private bool IsEdit(IntPtr hwnd) 
        {
            return _elEdit._hwnd == hwnd; 
        }

        #endregion
 
        // -----------------------------------------------------
        // 
        // Private Fields 
        //
        // ----------------------------------------------------- 

        #region Private Fields

        private WindowsEditBox _elEdit; 
        private WindowsUpDown _elUpDown;
 
        private SpinnerType _type; 

        #endregion 

        // ------------------------------------------------------
        //
        // Private Types 
        //
        // ----------------------------------------------------- 
 
        #region Private Types
 
        // Button control types based on groupings of style constants
        private enum SpinnerType
        {
            Numeric, 
            Domain
        }; 
 
        #endregion
 
        //------------------------------------------------------
        //
        //  WinformsSpinnerEdit Private Class
        // 
        //------------------------------------------------------
 
        #region WinformsSpinnerEdit 

        // Proxy for ComboBox Edit portion 
        // The Edit proxy does not exist, it the the whole spinner. This class is needed
        // though to override ProviderOptions
        class WinformsSpinnerEdit : WinformsSpinner
        { 
            //-----------------------------------------------------
            // 
            //  Constructors 
            //
            //------------------------------------------------------ 

            #region Constructor

            internal WinformsSpinnerEdit(IntPtr hwnd, IntPtr hwndEdit, IntPtr hwndUpDown, ProxyFragment parent, int item) 
            : base(hwnd, hwndEdit, hwndUpDown, parent, item)
            { 
            } 

            #endregion Constructor 

            //-----------------------------------------------------
            //
            //  Provider Implementation 
            //
            //----------------------------------------------------- 
 
            internal override ProviderOptions ProviderOptions
            { 
                get
                {
                    return base.ProviderOptions | ProviderOptions.OverrideProvider;
                } 
            }
        } 
 
        #endregion
 
    }
}

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


                        

Link Menu

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