EventManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / UIAutomation / Win32Providers / MS / Internal / AutomationProxies / EventManager.cs / 1 / EventManager.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: Class to manage UIAutomation events and how they relate to winevents 
//
// 
// History:
//  08/25/2004 : preid Created
//---------------------------------------------------------------------------
using System; 
using System.Text;
using System.Windows.Automation; 
using System.Windows.Automation.Provider; 
using System.Runtime.InteropServices;
using System.ComponentModel; 
using System.Collections;
using Accessibility;
using System.Windows;
using System.Windows.Input; 
using System.Globalization;
using MS.Win32; 
 
namespace MS.Internal.AutomationProxies
{ 
    // Class to manage UIAutomation events and how they relate to winevents
    static class EventManager
    {
        // ----------------------------------------------------- 
        //
        // Constructors 
        // 
        // -----------------------------------------------------
 
        #region Constructors


        #endregion 

        //------------------------------------------------------ 
        // 
        //  Internal Methods
        // 
        //-----------------------------------------------------

        #region Internal Methods
 
        internal static void DispatchEvent(ProxySimple el, IntPtr hwnd, int eventId, object idProp, int idObject)
        { 
            // This logic uses a hastables in order to get to a delegate that will raise the correct Automation event 
            // that may be a property change event a Automation event or a structure changed event.
            // There are three hashtables one for each idObject we support.  Depending on the idObject that gets 
            // passed in we access one of these hashtables with a key of an automation identifier and then retrieve
            // the data which ia a delegate of type RasieEvent.  This delegate is called to raise the correct type of event.
            RaiseEvent raiseEvent = null;
 
            switch (idObject)
            { 
                case NativeMethods.OBJID_WINDOW: 
                    lock (_classLock)
                    { 
                        if (_objectIdWindow == null)
                            InitObjectIdWindow();
                    }
 
                    raiseEvent = (RaiseEvent)_objectIdWindow[idProp];
                    break; 
 
                case NativeMethods.OBJID_CLIENT:
                    lock (_classLock) 
                    {
                        if (_objectIdClient == null)
                            InitObjectIdClient();
                    } 

                    raiseEvent = (RaiseEvent)_objectIdClient[idProp]; 
                    break; 

                case NativeMethods.OBJID_VSCROLL: 
                case NativeMethods.OBJID_HSCROLL:
                    lock (_classLock)
                    {
                        if (_objectIdScroll == null) 
                            InitObjectIdScroll();
                    } 
 
                    raiseEvent = (RaiseEvent)_objectIdScroll[idProp];
                    break; 

                case NativeMethods.OBJID_CARET:
                    lock (_classLock)
                    { 
                        if (_objectIdCaret == null)
                            InitObjectIdCaret(); 
                    } 

                    raiseEvent = (RaiseEvent)_objectIdCaret[idProp]; 
                    break;

                case NativeMethods.OBJID_SYSMENU:
                case NativeMethods.OBJID_MENU: 
                    lock (_classLock)
                    { 
                        if (_objectIdMenu == null) 
                            InitObjectIdMenu();
                    } 

                    raiseEvent = (RaiseEvent)_objectIdMenu[idProp];
                    break;
 
                default:
                    // Commented out to remove annoying asserts temporarily. 
                    // (See work item PS1254940.) 
                    //System.Diagnostics.Debug.Assert(false, "Unexpected idObject " + idObject);
                    return; 
            }


            if (raiseEvent != null) 
            {
                raiseEvent(el, hwnd, eventId); 
            } 
            else
            { 
                // If there is no delegate then we need to handle this property genericly by just getting the property value
                // and raising the a property changed event.
                AutomationProperty property = idProp as AutomationProperty;
                if (property == null) 
                {
                    System.Diagnostics.Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Unexpected idProp {0} for idOject 0x{1:x8} on element {2} for event {3}", idProp, idObject, el, eventId)); 
                    return; 
                }
 
                object propertyValue = ((IRawElementProviderSimple)el).GetPropertyValue(property.Id);

                RaisePropertyChangedEvent(el, property,  propertyValue);
            } 
        }
 
        #endregion 

        //------------------------------------------------------ 
        //
        //  Private Methods
        //
        //------------------------------------------------------ 

        #region Private Methods 
 
        private static void HandleIsReadOnlyProperty(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            // Special call for the ReadOnly Proxperty. If a Windows, becomes
            // enabled/disabled, all of its non hwnd children should become
            // change the read only state.
            if (eventId == NativeMethods.EventObjectStateChange) 
            {
                bool fIsReadOnly = SafeNativeMethods.IsWindowEnabled(hwnd); 
 
                el.RecursiveRaiseEvents(ValuePattern.IsReadOnlyProperty, new AutomationPropertyChangedEventArgs(ValuePattern.IsReadOnlyProperty, null, fIsReadOnly));
            } 

        }

        private static void HandleStructureChangedEventWindow(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            if (eventId == NativeMethods.EventObjectReorder) 
            { 
                AutomationInteropProvider.RaiseStructureChangedEvent( el, new StructureChangedEventArgs( StructureChangeType.ChildrenReordered, el.MakeRuntimeId() ) );
            } 
        }

        private static void HandleCanMinimizeProperty(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            if (eventId == NativeMethods.EventObjectLocationChange)
            { 
                WindowVisualState wvs = GetWindowVisualState(hwnd); 

                bool canMinimize = wvs != WindowVisualState.Minimized; 
                RaisePropertyChangedEvent(el, WindowPattern.CanMinimizeProperty, canMinimize);
            }
        }
 
        private static void HandleCanMaximizeProperty(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            if (eventId == NativeMethods.EventObjectLocationChange) 
            {
                WindowVisualState wvs = GetWindowVisualState(hwnd); 

                bool canMaximize = wvs != WindowVisualState.Maximized;
                RaisePropertyChangedEvent(el, WindowPattern.CanMaximizeProperty, canMaximize);
            } 
        }
 
        private static void HandleValueProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IValueProvider value = el.GetPatternProvider(ValuePattern.Pattern) as IValueProvider; 
            if (value == null)
                return;

            RaisePropertyChangedEvent(el, ValuePattern.ValueProperty, value.Value); 
        }
 
        private static void HandleRangeValueProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IRangeValueProvider rangeValue = el.GetPatternProvider(RangeValuePattern.Pattern) as IRangeValueProvider; 
            if (rangeValue == null)
                return;

            RaisePropertyChangedEvent(el, RangeValuePattern.ValueProperty, rangeValue.Value); 
        }
 
        private static void HandleIsSelectedProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ISelectionItemProvider selectionItem = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider; 
            if (selectionItem == null)
                return;

            RaisePropertyChangedEvent(el, SelectionItemPattern.IsSelectedProperty, selectionItem.IsSelected); 
        }
 
        private static void HandleExpandCollapseStateProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IExpandCollapseProvider expandCollapse = el.GetPatternProvider(ExpandCollapsePattern.Pattern) as IExpandCollapseProvider; 
            if (expandCollapse == null)
                return;

            RaisePropertyChangedEvent(el, ExpandCollapsePattern.ExpandCollapseStateProperty, expandCollapse.ExpandCollapseState); 
        }
 
        private static void HandleColumnCountProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridProvider grid = el.GetPatternProvider(GridPattern.Pattern) as IGridProvider; 
            if (grid == null)
                return;

            RaisePropertyChangedEvent(el, GridPattern.ColumnCountProperty, grid.ColumnCount); 
        }
 
        private static void HandleRowCountProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridProvider grid = el.GetPatternProvider(GridPattern.Pattern) as IGridProvider; 
            if (grid == null)
                return;

            RaisePropertyChangedEvent(el, GridPattern.RowCountProperty,  grid.RowCount); 
        }
 
        private static void HandleColumnProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridItemProvider gridItem = el.GetPatternProvider(GridItemPattern.Pattern) as IGridItemProvider; 
            if (gridItem == null)
                return;

            RaisePropertyChangedEvent(el, GridItemPattern.ColumnProperty, gridItem.Column); 
        }
 
        private static void HandleRowProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridItemProvider gridItem = el.GetPatternProvider(GridItemPattern.Pattern) as IGridItemProvider; 
            if (gridItem == null)
                return;

            RaisePropertyChangedEvent(el, GridItemPattern.RowProperty, gridItem.Row); 
        }
 
        private static void HandleColumnHeadersProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ITableProvider table = el.GetPatternProvider(TablePattern.Pattern) as ITableProvider; 
            if (table == null)
                return;

            RaisePropertyChangedEvent(el, TablePattern.ColumnHeadersProperty, table.GetColumnHeaders()); 
        }
 
        private static void HandleRowHeadersProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ITableProvider table = el.GetPatternProvider(TablePattern.Pattern) as ITableProvider; 
            if (table == null)
                return;

            RaisePropertyChangedEvent(el, TablePattern.RowHeadersProperty, table.GetRowHeaders()); 
        }
 
        private static void HandleIsSelectionRequiredProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ISelectionProvider selection = el.GetPatternProvider(SelectionPattern.Pattern) as ISelectionProvider; 
            if (selection == null)
                return;

            RaisePropertyChangedEvent(el, SelectionPattern.IsSelectionRequiredProperty, selection.IsSelectionRequired); 
        }
 
        private static void HandleVerticalViewSizeProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider(ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null)
                return;

            RaisePropertyChangedEvent(el, ScrollPattern.VerticalViewSizeProperty, scroll.VerticalViewSize); 
        }
 
        private static void HandleHorizontalViewSizeProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider(ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null)
                return;

            RaisePropertyChangedEvent(el, ScrollPattern.HorizontalViewSizeProperty, scroll.HorizontalViewSize); 
        }
 
        private static void HandleToggleStateProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IToggleProvider toggle = el.GetPatternProvider(TogglePattern.Pattern) as IToggleProvider; 
            if (toggle == null)
                return;

            RaisePropertyChangedEvent(el, TogglePattern.ToggleStateProperty, toggle.ToggleState); 
        }
 
        private static void HandleInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IInvokeProvider invoke = el.GetPatternProvider(InvokePattern.Pattern) as IInvokeProvider; 
            if (invoke == null)
                return;

            if (eventId == NativeMethods.EventObjectInvoke || 
                eventId == NativeMethods.EventObjectStateChange ||
                eventId == NativeMethods.EventObjectSelection && el is ListViewItem) 
            { 
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent));
            } 
        }

        private static void HandleScrollInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            IInvokeProvider invoke = el.GetPatternProvider(InvokePattern.Pattern) as IInvokeProvider;
            if (invoke == null) 
                return; 

            if (eventId == NativeMethods.EventObjectStateChange) 
            {
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent));
            }
        } 

        private static void HandleWindowInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        { 
            IInvokeProvider invoke = el.GetPatternProvider(InvokePattern.Pattern) as IInvokeProvider;
            if (invoke == null) 
                return;

            if (eventId == NativeMethods.EventSystemCaptureEnd )
            { 
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent));
            } 
        } 

        private static void HandleMenuItemInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            // Skip the check for InvokePattern because el is just a wrapper on a dead element and
            // GetPatternProvider will fail to return the pattern.  Later, if the caller tries to
            // use this element most properties and methods will throw ElementNotAvailable. 
            if (eventId == NativeMethods.EventObjectInvoke)
            { 
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent)); 
            }
        } 

        private static void HandleElementSelectedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        {
            ISelectionItemProvider selProvider = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider; 
            if (selProvider == null)
                return; 
 
            if (eventId == NativeMethods.EventObjectSelection ||
                eventId == NativeMethods.EventObjectStateChange) 
            {
                AutomationInteropProvider.RaiseAutomationEvent(SelectionItemPattern.ElementSelectedEvent, el, new AutomationEventArgs(SelectionItemPattern.ElementSelectedEvent));
            }
        } 

        private static void HandleElementAddedToSelectionEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        { 
            ISelectionItemProvider selProvider = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider;
            if (selProvider == null) 
                return;

            if (eventId == NativeMethods.EventObjectSelectionAdd)
            { 
                AutomationInteropProvider.RaiseAutomationEvent(SelectionItemPattern.ElementAddedToSelectionEvent, el, new AutomationEventArgs(SelectionItemPattern.ElementAddedToSelectionEvent));
            } 
        } 

        private static void HandleElementRemovedFromSelectionEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ISelectionItemProvider selProvider = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider;
            if (selProvider == null)
                return; 

            if (eventId == NativeMethods.EventObjectSelectionRemove) 
            { 
                AutomationInteropProvider.RaiseAutomationEvent(SelectionItemPattern.ElementRemovedFromSelectionEvent, el, new AutomationEventArgs(SelectionItemPattern.ElementRemovedFromSelectionEvent));
            } 
        }

        private static void HandleStructureChangedEventClient(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            if (eventId == NativeMethods.EventObjectCreate)
            { 
                AutomationInteropProvider.RaiseStructureChangedEvent (el, new StructureChangedEventArgs (StructureChangeType.ChildAdded, el.MakeRuntimeId())); 
            }
            else if (eventId == NativeMethods.EventObjectDestroy) 
            {
                AutomationInteropProvider.RaiseStructureChangedEvent( el, new StructureChangedEventArgs( StructureChangeType.ChildRemoved, el.MakeRuntimeId() ) );
            }
            else if ( eventId == NativeMethods.EventObjectReorder ) 
            {
                IGridProvider grid = el.GetPatternProvider(GridPattern.Pattern) as IGridProvider; 
                if ( grid == null ) 
                    return;
                AutomationInteropProvider.RaiseStructureChangedEvent( el, new StructureChangedEventArgs( StructureChangeType.ChildrenInvalidated, el.MakeRuntimeId() ) ); 
            }
        }

        private static void HandleVerticalScrollPercentProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider (ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null || scroll.VerticalScrollPercent == ScrollPattern.NoScroll) 
                return;
 
            RaisePropertyChangedEvent(el, ScrollPattern.VerticalScrollPercentProperty, scroll.VerticalScrollPercent);
        }

        private static void HandleHorizontalScrollPercentProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider (ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null || scroll.HorizontalScrollPercent == ScrollPattern.NoScroll) 
                return;
 
            RaisePropertyChangedEvent(el, ScrollPattern.HorizontalScrollPercentProperty, scroll.HorizontalScrollPercent);
        }

 
        private static void HandleInvalidatedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            AutomationInteropProvider.RaiseAutomationEvent(SelectionPattern.InvalidatedEvent, el, new AutomationEventArgs(SelectionPattern.InvalidatedEvent)); 
        }
 
        private static void RaisePropertyChangedEvent(ProxySimple el, AutomationProperty property, object propertyValue)
        {
            if (propertyValue != null && propertyValue != AutomationElement.NotSupported)
            { 
                AutomationInteropProvider.RaiseAutomationPropertyChangedEvent(el, new AutomationPropertyChangedEventArgs(property, null, propertyValue));
            } 
        } 

        private static WindowVisualState GetWindowVisualState(IntPtr hwnd) 
        {
            int style = Misc.GetWindowStyle(hwnd);

            // How do you return Invisable? 
            if (Misc.IsBitSet(style, NativeMethods.WS_MAXIMIZE))
            { 
                return WindowVisualState.Maximized; 
            }
            else if (Misc.IsBitSet(style, NativeMethods.WS_MINIMIZE)) 
            {
                return WindowVisualState.Minimized;
            }
            else 
            {
                return WindowVisualState.Normal; 
            } 
        }
 
        private static void HandleTextSelectionChangedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        {
            ITextProvider textProvider = el.GetPatternProvider(TextPattern.Pattern) as ITextProvider;
            if (textProvider == null) 
                return;
 
            if (eventId == NativeMethods.EventObjectLocationChange) 
            {
                // We do not want to raise the EventObjectLocationChange when it is caused by a scroll.  To do this 
                // store the previous range and compare it to the current range.  The range will not change when scrolling.
                ITextRangeProvider[] currentRanges = textProvider.GetSelection();
                ITextRangeProvider currentRange = null;
                if (currentRanges != null && currentRanges.Length > 0) 
                    currentRange = currentRanges[0];
 
                if (hwnd == _hwndLast && currentRange != null) 
                {
                    if (_lastSelection != null && !currentRange.Compare(_lastSelection)) 
                    {
                        AutomationInteropProvider.RaiseAutomationEvent(TextPattern.TextSelectionChangedEvent, el, new AutomationEventArgs(TextPattern.TextSelectionChangedEvent));
                    }
                } 
                else
                { 
                    AutomationInteropProvider.RaiseAutomationEvent(TextPattern.TextSelectionChangedEvent, el, new AutomationEventArgs(TextPattern.TextSelectionChangedEvent)); 
                }
 
                //store the current range and window handle.
                _hwndLast = hwnd;
                _lastSelection = currentRange;
            } 
            else if (eventId == NativeMethods.EventObjectTextSelectionChanged)
            { 
                AutomationInteropProvider.RaiseAutomationEvent( 
                    TextPattern.TextSelectionChangedEvent, el,
                    new AutomationEventArgs(TextPattern.TextSelectionChangedEvent)); 
            }
        }

        private static void InitObjectIdWindow() 
        {
            _objectIdWindow = new Hashtable(7, .1f); 
            _objectIdWindow.Add(ValuePattern.IsReadOnlyProperty,                   new RaiseEvent(HandleIsReadOnlyProperty)); 
            _objectIdWindow.Add(AutomationElement.StructureChangedEvent,           new RaiseEvent(HandleStructureChangedEventWindow));
            _objectIdWindow.Add(WindowPattern.CanMaximizeProperty,                 new RaiseEvent(HandleCanMaximizeProperty)); 
            _objectIdWindow.Add(WindowPattern.CanMinimizeProperty,                 new RaiseEvent(HandleCanMinimizeProperty));
            _objectIdWindow.Add(TogglePattern.ToggleStateProperty,                 new RaiseEvent(HandleToggleStateProperty));
            _objectIdWindow.Add(InvokePattern.InvokedEvent,                        new RaiseEvent(HandleWindowInvokedEvent));
        } 

        private static void InitObjectIdClient() 
        { 
            _objectIdClient = new Hashtable(20, .1f);
            _objectIdClient.Add(ValuePattern.ValueProperty,                        new RaiseEvent(HandleValueProperty)); 
            _objectIdClient.Add(RangeValuePattern.ValueProperty,                   new RaiseEvent(HandleRangeValueProperty));
            _objectIdClient.Add(SelectionItemPattern.IsSelectedProperty,           new RaiseEvent(HandleIsSelectedProperty));
            _objectIdClient.Add(ExpandCollapsePattern.ExpandCollapseStateProperty, new RaiseEvent(HandleExpandCollapseStateProperty));
            _objectIdClient.Add(GridPattern.ColumnCountProperty,                   new RaiseEvent(HandleColumnCountProperty)); 
            _objectIdClient.Add(GridPattern.RowCountProperty,                      new RaiseEvent(HandleRowCountProperty));
            _objectIdClient.Add(GridItemPattern.ColumnProperty,                    new RaiseEvent(HandleColumnProperty)); 
            _objectIdClient.Add(GridItemPattern.RowProperty,                       new RaiseEvent(HandleRowProperty)); 
            _objectIdClient.Add(TablePattern.ColumnHeadersProperty,                new RaiseEvent(HandleColumnHeadersProperty));
            _objectIdClient.Add(TablePattern.RowHeadersProperty,                   new RaiseEvent(HandleRowHeadersProperty)); 
            _objectIdClient.Add(SelectionPattern.IsSelectionRequiredProperty,      new RaiseEvent(HandleIsSelectionRequiredProperty));
            _objectIdClient.Add(ScrollPattern.VerticalViewSizeProperty,            new RaiseEvent(HandleVerticalViewSizeProperty));
            _objectIdClient.Add(ScrollPattern.HorizontalViewSizeProperty,          new RaiseEvent(HandleHorizontalViewSizeProperty));
            _objectIdClient.Add(InvokePattern.InvokedEvent,                        new RaiseEvent(HandleInvokedEvent)); 
            _objectIdClient.Add(SelectionItemPattern.ElementSelectedEvent,         new RaiseEvent(HandleElementSelectedEvent));
            _objectIdClient.Add(SelectionItemPattern.ElementAddedToSelectionEvent, new RaiseEvent(HandleElementAddedToSelectionEvent)); 
            _objectIdClient.Add(SelectionItemPattern.ElementRemovedFromSelectionEvent, new RaiseEvent(HandleElementRemovedFromSelectionEvent)); 
            _objectIdClient.Add(AutomationElement.StructureChangedEvent,           new RaiseEvent(HandleStructureChangedEventClient));
            _objectIdClient.Add(SelectionPattern.InvalidatedEvent,                 new RaiseEvent(HandleInvalidatedEvent)); 
            _objectIdClient.Add(TogglePattern.ToggleStateProperty,                 new RaiseEvent(HandleToggleStateProperty));
            _objectIdClient.Add(TextPattern.TextSelectionChangedEvent,             new RaiseEvent(HandleTextSelectionChangedEvent));
        }
 
        private static void InitObjectIdScroll()
        { 
            _objectIdScroll = new Hashtable(3, .1f); 
            _objectIdScroll.Add(ScrollPattern.VerticalScrollPercentProperty,       new RaiseEvent(HandleVerticalScrollPercentProperty));
            _objectIdScroll.Add(ScrollPattern.HorizontalScrollPercentProperty,     new RaiseEvent(HandleHorizontalScrollPercentProperty)); 
            _objectIdScroll.Add(InvokePattern.InvokedEvent,                        new RaiseEvent(HandleScrollInvokedEvent));
        }

        private static void InitObjectIdCaret() 
        {
            _objectIdCaret = new Hashtable(1, .1f); 
            _objectIdCaret.Add(TextPattern.TextSelectionChangedEvent,              new RaiseEvent(HandleTextSelectionChangedEvent)); 
        }
 
        private static void InitObjectIdMenu()
        {
            _objectIdMenu = new Hashtable(1, .1f);
            _objectIdMenu.Add(InvokePattern.InvokedEvent, new RaiseEvent(HandleMenuItemInvokedEvent)); 
        }
 
        #endregion 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------ 

        #region Private Fields 
 
        private delegate void RaiseEvent (ProxySimple el, IntPtr hwnd, int eventId);
 
        private static Hashtable _objectIdWindow;
        private static Hashtable _objectIdClient;
        private static Hashtable _objectIdScroll;
        private static Hashtable _objectIdCaret; 
        private static Hashtable _objectIdMenu;
        private static object _classLock = new object();   // use lock object vs typeof(class) for perf 
 
        // The hwndLast and objLast is to allow limited filtering of events.
        private static IntPtr _hwndLast = IntPtr.Zero; 
        private static ITextRangeProvider _lastSelection = null;

        #endregion
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: Class to manage UIAutomation events and how they relate to winevents 
//
// 
// History:
//  08/25/2004 : preid Created
//---------------------------------------------------------------------------
using System; 
using System.Text;
using System.Windows.Automation; 
using System.Windows.Automation.Provider; 
using System.Runtime.InteropServices;
using System.ComponentModel; 
using System.Collections;
using Accessibility;
using System.Windows;
using System.Windows.Input; 
using System.Globalization;
using MS.Win32; 
 
namespace MS.Internal.AutomationProxies
{ 
    // Class to manage UIAutomation events and how they relate to winevents
    static class EventManager
    {
        // ----------------------------------------------------- 
        //
        // Constructors 
        // 
        // -----------------------------------------------------
 
        #region Constructors


        #endregion 

        //------------------------------------------------------ 
        // 
        //  Internal Methods
        // 
        //-----------------------------------------------------

        #region Internal Methods
 
        internal static void DispatchEvent(ProxySimple el, IntPtr hwnd, int eventId, object idProp, int idObject)
        { 
            // This logic uses a hastables in order to get to a delegate that will raise the correct Automation event 
            // that may be a property change event a Automation event or a structure changed event.
            // There are three hashtables one for each idObject we support.  Depending on the idObject that gets 
            // passed in we access one of these hashtables with a key of an automation identifier and then retrieve
            // the data which ia a delegate of type RasieEvent.  This delegate is called to raise the correct type of event.
            RaiseEvent raiseEvent = null;
 
            switch (idObject)
            { 
                case NativeMethods.OBJID_WINDOW: 
                    lock (_classLock)
                    { 
                        if (_objectIdWindow == null)
                            InitObjectIdWindow();
                    }
 
                    raiseEvent = (RaiseEvent)_objectIdWindow[idProp];
                    break; 
 
                case NativeMethods.OBJID_CLIENT:
                    lock (_classLock) 
                    {
                        if (_objectIdClient == null)
                            InitObjectIdClient();
                    } 

                    raiseEvent = (RaiseEvent)_objectIdClient[idProp]; 
                    break; 

                case NativeMethods.OBJID_VSCROLL: 
                case NativeMethods.OBJID_HSCROLL:
                    lock (_classLock)
                    {
                        if (_objectIdScroll == null) 
                            InitObjectIdScroll();
                    } 
 
                    raiseEvent = (RaiseEvent)_objectIdScroll[idProp];
                    break; 

                case NativeMethods.OBJID_CARET:
                    lock (_classLock)
                    { 
                        if (_objectIdCaret == null)
                            InitObjectIdCaret(); 
                    } 

                    raiseEvent = (RaiseEvent)_objectIdCaret[idProp]; 
                    break;

                case NativeMethods.OBJID_SYSMENU:
                case NativeMethods.OBJID_MENU: 
                    lock (_classLock)
                    { 
                        if (_objectIdMenu == null) 
                            InitObjectIdMenu();
                    } 

                    raiseEvent = (RaiseEvent)_objectIdMenu[idProp];
                    break;
 
                default:
                    // Commented out to remove annoying asserts temporarily. 
                    // (See work item PS1254940.) 
                    //System.Diagnostics.Debug.Assert(false, "Unexpected idObject " + idObject);
                    return; 
            }


            if (raiseEvent != null) 
            {
                raiseEvent(el, hwnd, eventId); 
            } 
            else
            { 
                // If there is no delegate then we need to handle this property genericly by just getting the property value
                // and raising the a property changed event.
                AutomationProperty property = idProp as AutomationProperty;
                if (property == null) 
                {
                    System.Diagnostics.Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Unexpected idProp {0} for idOject 0x{1:x8} on element {2} for event {3}", idProp, idObject, el, eventId)); 
                    return; 
                }
 
                object propertyValue = ((IRawElementProviderSimple)el).GetPropertyValue(property.Id);

                RaisePropertyChangedEvent(el, property,  propertyValue);
            } 
        }
 
        #endregion 

        //------------------------------------------------------ 
        //
        //  Private Methods
        //
        //------------------------------------------------------ 

        #region Private Methods 
 
        private static void HandleIsReadOnlyProperty(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            // Special call for the ReadOnly Proxperty. If a Windows, becomes
            // enabled/disabled, all of its non hwnd children should become
            // change the read only state.
            if (eventId == NativeMethods.EventObjectStateChange) 
            {
                bool fIsReadOnly = SafeNativeMethods.IsWindowEnabled(hwnd); 
 
                el.RecursiveRaiseEvents(ValuePattern.IsReadOnlyProperty, new AutomationPropertyChangedEventArgs(ValuePattern.IsReadOnlyProperty, null, fIsReadOnly));
            } 

        }

        private static void HandleStructureChangedEventWindow(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            if (eventId == NativeMethods.EventObjectReorder) 
            { 
                AutomationInteropProvider.RaiseStructureChangedEvent( el, new StructureChangedEventArgs( StructureChangeType.ChildrenReordered, el.MakeRuntimeId() ) );
            } 
        }

        private static void HandleCanMinimizeProperty(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            if (eventId == NativeMethods.EventObjectLocationChange)
            { 
                WindowVisualState wvs = GetWindowVisualState(hwnd); 

                bool canMinimize = wvs != WindowVisualState.Minimized; 
                RaisePropertyChangedEvent(el, WindowPattern.CanMinimizeProperty, canMinimize);
            }
        }
 
        private static void HandleCanMaximizeProperty(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            if (eventId == NativeMethods.EventObjectLocationChange) 
            {
                WindowVisualState wvs = GetWindowVisualState(hwnd); 

                bool canMaximize = wvs != WindowVisualState.Maximized;
                RaisePropertyChangedEvent(el, WindowPattern.CanMaximizeProperty, canMaximize);
            } 
        }
 
        private static void HandleValueProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IValueProvider value = el.GetPatternProvider(ValuePattern.Pattern) as IValueProvider; 
            if (value == null)
                return;

            RaisePropertyChangedEvent(el, ValuePattern.ValueProperty, value.Value); 
        }
 
        private static void HandleRangeValueProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IRangeValueProvider rangeValue = el.GetPatternProvider(RangeValuePattern.Pattern) as IRangeValueProvider; 
            if (rangeValue == null)
                return;

            RaisePropertyChangedEvent(el, RangeValuePattern.ValueProperty, rangeValue.Value); 
        }
 
        private static void HandleIsSelectedProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ISelectionItemProvider selectionItem = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider; 
            if (selectionItem == null)
                return;

            RaisePropertyChangedEvent(el, SelectionItemPattern.IsSelectedProperty, selectionItem.IsSelected); 
        }
 
        private static void HandleExpandCollapseStateProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IExpandCollapseProvider expandCollapse = el.GetPatternProvider(ExpandCollapsePattern.Pattern) as IExpandCollapseProvider; 
            if (expandCollapse == null)
                return;

            RaisePropertyChangedEvent(el, ExpandCollapsePattern.ExpandCollapseStateProperty, expandCollapse.ExpandCollapseState); 
        }
 
        private static void HandleColumnCountProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridProvider grid = el.GetPatternProvider(GridPattern.Pattern) as IGridProvider; 
            if (grid == null)
                return;

            RaisePropertyChangedEvent(el, GridPattern.ColumnCountProperty, grid.ColumnCount); 
        }
 
        private static void HandleRowCountProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridProvider grid = el.GetPatternProvider(GridPattern.Pattern) as IGridProvider; 
            if (grid == null)
                return;

            RaisePropertyChangedEvent(el, GridPattern.RowCountProperty,  grid.RowCount); 
        }
 
        private static void HandleColumnProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridItemProvider gridItem = el.GetPatternProvider(GridItemPattern.Pattern) as IGridItemProvider; 
            if (gridItem == null)
                return;

            RaisePropertyChangedEvent(el, GridItemPattern.ColumnProperty, gridItem.Column); 
        }
 
        private static void HandleRowProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IGridItemProvider gridItem = el.GetPatternProvider(GridItemPattern.Pattern) as IGridItemProvider; 
            if (gridItem == null)
                return;

            RaisePropertyChangedEvent(el, GridItemPattern.RowProperty, gridItem.Row); 
        }
 
        private static void HandleColumnHeadersProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ITableProvider table = el.GetPatternProvider(TablePattern.Pattern) as ITableProvider; 
            if (table == null)
                return;

            RaisePropertyChangedEvent(el, TablePattern.ColumnHeadersProperty, table.GetColumnHeaders()); 
        }
 
        private static void HandleRowHeadersProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ITableProvider table = el.GetPatternProvider(TablePattern.Pattern) as ITableProvider; 
            if (table == null)
                return;

            RaisePropertyChangedEvent(el, TablePattern.RowHeadersProperty, table.GetRowHeaders()); 
        }
 
        private static void HandleIsSelectionRequiredProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ISelectionProvider selection = el.GetPatternProvider(SelectionPattern.Pattern) as ISelectionProvider; 
            if (selection == null)
                return;

            RaisePropertyChangedEvent(el, SelectionPattern.IsSelectionRequiredProperty, selection.IsSelectionRequired); 
        }
 
        private static void HandleVerticalViewSizeProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider(ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null)
                return;

            RaisePropertyChangedEvent(el, ScrollPattern.VerticalViewSizeProperty, scroll.VerticalViewSize); 
        }
 
        private static void HandleHorizontalViewSizeProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider(ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null)
                return;

            RaisePropertyChangedEvent(el, ScrollPattern.HorizontalViewSizeProperty, scroll.HorizontalViewSize); 
        }
 
        private static void HandleToggleStateProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IToggleProvider toggle = el.GetPatternProvider(TogglePattern.Pattern) as IToggleProvider; 
            if (toggle == null)
                return;

            RaisePropertyChangedEvent(el, TogglePattern.ToggleStateProperty, toggle.ToggleState); 
        }
 
        private static void HandleInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IInvokeProvider invoke = el.GetPatternProvider(InvokePattern.Pattern) as IInvokeProvider; 
            if (invoke == null)
                return;

            if (eventId == NativeMethods.EventObjectInvoke || 
                eventId == NativeMethods.EventObjectStateChange ||
                eventId == NativeMethods.EventObjectSelection && el is ListViewItem) 
            { 
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent));
            } 
        }

        private static void HandleScrollInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            IInvokeProvider invoke = el.GetPatternProvider(InvokePattern.Pattern) as IInvokeProvider;
            if (invoke == null) 
                return; 

            if (eventId == NativeMethods.EventObjectStateChange) 
            {
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent));
            }
        } 

        private static void HandleWindowInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        { 
            IInvokeProvider invoke = el.GetPatternProvider(InvokePattern.Pattern) as IInvokeProvider;
            if (invoke == null) 
                return;

            if (eventId == NativeMethods.EventSystemCaptureEnd )
            { 
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent));
            } 
        } 

        private static void HandleMenuItemInvokedEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            // Skip the check for InvokePattern because el is just a wrapper on a dead element and
            // GetPatternProvider will fail to return the pattern.  Later, if the caller tries to
            // use this element most properties and methods will throw ElementNotAvailable. 
            if (eventId == NativeMethods.EventObjectInvoke)
            { 
                AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, el, new AutomationEventArgs(InvokePattern.InvokedEvent)); 
            }
        } 

        private static void HandleElementSelectedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        {
            ISelectionItemProvider selProvider = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider; 
            if (selProvider == null)
                return; 
 
            if (eventId == NativeMethods.EventObjectSelection ||
                eventId == NativeMethods.EventObjectStateChange) 
            {
                AutomationInteropProvider.RaiseAutomationEvent(SelectionItemPattern.ElementSelectedEvent, el, new AutomationEventArgs(SelectionItemPattern.ElementSelectedEvent));
            }
        } 

        private static void HandleElementAddedToSelectionEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        { 
            ISelectionItemProvider selProvider = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider;
            if (selProvider == null) 
                return;

            if (eventId == NativeMethods.EventObjectSelectionAdd)
            { 
                AutomationInteropProvider.RaiseAutomationEvent(SelectionItemPattern.ElementAddedToSelectionEvent, el, new AutomationEventArgs(SelectionItemPattern.ElementAddedToSelectionEvent));
            } 
        } 

        private static void HandleElementRemovedFromSelectionEvent(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            ISelectionItemProvider selProvider = el.GetPatternProvider(SelectionItemPattern.Pattern) as ISelectionItemProvider;
            if (selProvider == null)
                return; 

            if (eventId == NativeMethods.EventObjectSelectionRemove) 
            { 
                AutomationInteropProvider.RaiseAutomationEvent(SelectionItemPattern.ElementRemovedFromSelectionEvent, el, new AutomationEventArgs(SelectionItemPattern.ElementRemovedFromSelectionEvent));
            } 
        }

        private static void HandleStructureChangedEventClient(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            if (eventId == NativeMethods.EventObjectCreate)
            { 
                AutomationInteropProvider.RaiseStructureChangedEvent (el, new StructureChangedEventArgs (StructureChangeType.ChildAdded, el.MakeRuntimeId())); 
            }
            else if (eventId == NativeMethods.EventObjectDestroy) 
            {
                AutomationInteropProvider.RaiseStructureChangedEvent( el, new StructureChangedEventArgs( StructureChangeType.ChildRemoved, el.MakeRuntimeId() ) );
            }
            else if ( eventId == NativeMethods.EventObjectReorder ) 
            {
                IGridProvider grid = el.GetPatternProvider(GridPattern.Pattern) as IGridProvider; 
                if ( grid == null ) 
                    return;
                AutomationInteropProvider.RaiseStructureChangedEvent( el, new StructureChangedEventArgs( StructureChangeType.ChildrenInvalidated, el.MakeRuntimeId() ) ); 
            }
        }

        private static void HandleVerticalScrollPercentProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider (ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null || scroll.VerticalScrollPercent == ScrollPattern.NoScroll) 
                return;
 
            RaisePropertyChangedEvent(el, ScrollPattern.VerticalScrollPercentProperty, scroll.VerticalScrollPercent);
        }

        private static void HandleHorizontalScrollPercentProperty(ProxySimple el, IntPtr hwnd, int eventId) 
        {
            IScrollProvider scroll = el.GetPatternProvider (ScrollPattern.Pattern) as IScrollProvider; 
            if (scroll == null || scroll.HorizontalScrollPercent == ScrollPattern.NoScroll) 
                return;
 
            RaisePropertyChangedEvent(el, ScrollPattern.HorizontalScrollPercentProperty, scroll.HorizontalScrollPercent);
        }

 
        private static void HandleInvalidatedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        { 
            AutomationInteropProvider.RaiseAutomationEvent(SelectionPattern.InvalidatedEvent, el, new AutomationEventArgs(SelectionPattern.InvalidatedEvent)); 
        }
 
        private static void RaisePropertyChangedEvent(ProxySimple el, AutomationProperty property, object propertyValue)
        {
            if (propertyValue != null && propertyValue != AutomationElement.NotSupported)
            { 
                AutomationInteropProvider.RaiseAutomationPropertyChangedEvent(el, new AutomationPropertyChangedEventArgs(property, null, propertyValue));
            } 
        } 

        private static WindowVisualState GetWindowVisualState(IntPtr hwnd) 
        {
            int style = Misc.GetWindowStyle(hwnd);

            // How do you return Invisable? 
            if (Misc.IsBitSet(style, NativeMethods.WS_MAXIMIZE))
            { 
                return WindowVisualState.Maximized; 
            }
            else if (Misc.IsBitSet(style, NativeMethods.WS_MINIMIZE)) 
            {
                return WindowVisualState.Minimized;
            }
            else 
            {
                return WindowVisualState.Normal; 
            } 
        }
 
        private static void HandleTextSelectionChangedEvent(ProxySimple el, IntPtr hwnd, int eventId)
        {
            ITextProvider textProvider = el.GetPatternProvider(TextPattern.Pattern) as ITextProvider;
            if (textProvider == null) 
                return;
 
            if (eventId == NativeMethods.EventObjectLocationChange) 
            {
                // We do not want to raise the EventObjectLocationChange when it is caused by a scroll.  To do this 
                // store the previous range and compare it to the current range.  The range will not change when scrolling.
                ITextRangeProvider[] currentRanges = textProvider.GetSelection();
                ITextRangeProvider currentRange = null;
                if (currentRanges != null && currentRanges.Length > 0) 
                    currentRange = currentRanges[0];
 
                if (hwnd == _hwndLast && currentRange != null) 
                {
                    if (_lastSelection != null && !currentRange.Compare(_lastSelection)) 
                    {
                        AutomationInteropProvider.RaiseAutomationEvent(TextPattern.TextSelectionChangedEvent, el, new AutomationEventArgs(TextPattern.TextSelectionChangedEvent));
                    }
                } 
                else
                { 
                    AutomationInteropProvider.RaiseAutomationEvent(TextPattern.TextSelectionChangedEvent, el, new AutomationEventArgs(TextPattern.TextSelectionChangedEvent)); 
                }
 
                //store the current range and window handle.
                _hwndLast = hwnd;
                _lastSelection = currentRange;
            } 
            else if (eventId == NativeMethods.EventObjectTextSelectionChanged)
            { 
                AutomationInteropProvider.RaiseAutomationEvent( 
                    TextPattern.TextSelectionChangedEvent, el,
                    new AutomationEventArgs(TextPattern.TextSelectionChangedEvent)); 
            }
        }

        private static void InitObjectIdWindow() 
        {
            _objectIdWindow = new Hashtable(7, .1f); 
            _objectIdWindow.Add(ValuePattern.IsReadOnlyProperty,                   new RaiseEvent(HandleIsReadOnlyProperty)); 
            _objectIdWindow.Add(AutomationElement.StructureChangedEvent,           new RaiseEvent(HandleStructureChangedEventWindow));
            _objectIdWindow.Add(WindowPattern.CanMaximizeProperty,                 new RaiseEvent(HandleCanMaximizeProperty)); 
            _objectIdWindow.Add(WindowPattern.CanMinimizeProperty,                 new RaiseEvent(HandleCanMinimizeProperty));
            _objectIdWindow.Add(TogglePattern.ToggleStateProperty,                 new RaiseEvent(HandleToggleStateProperty));
            _objectIdWindow.Add(InvokePattern.InvokedEvent,                        new RaiseEvent(HandleWindowInvokedEvent));
        } 

        private static void InitObjectIdClient() 
        { 
            _objectIdClient = new Hashtable(20, .1f);
            _objectIdClient.Add(ValuePattern.ValueProperty,                        new RaiseEvent(HandleValueProperty)); 
            _objectIdClient.Add(RangeValuePattern.ValueProperty,                   new RaiseEvent(HandleRangeValueProperty));
            _objectIdClient.Add(SelectionItemPattern.IsSelectedProperty,           new RaiseEvent(HandleIsSelectedProperty));
            _objectIdClient.Add(ExpandCollapsePattern.ExpandCollapseStateProperty, new RaiseEvent(HandleExpandCollapseStateProperty));
            _objectIdClient.Add(GridPattern.ColumnCountProperty,                   new RaiseEvent(HandleColumnCountProperty)); 
            _objectIdClient.Add(GridPattern.RowCountProperty,                      new RaiseEvent(HandleRowCountProperty));
            _objectIdClient.Add(GridItemPattern.ColumnProperty,                    new RaiseEvent(HandleColumnProperty)); 
            _objectIdClient.Add(GridItemPattern.RowProperty,                       new RaiseEvent(HandleRowProperty)); 
            _objectIdClient.Add(TablePattern.ColumnHeadersProperty,                new RaiseEvent(HandleColumnHeadersProperty));
            _objectIdClient.Add(TablePattern.RowHeadersProperty,                   new RaiseEvent(HandleRowHeadersProperty)); 
            _objectIdClient.Add(SelectionPattern.IsSelectionRequiredProperty,      new RaiseEvent(HandleIsSelectionRequiredProperty));
            _objectIdClient.Add(ScrollPattern.VerticalViewSizeProperty,            new RaiseEvent(HandleVerticalViewSizeProperty));
            _objectIdClient.Add(ScrollPattern.HorizontalViewSizeProperty,          new RaiseEvent(HandleHorizontalViewSizeProperty));
            _objectIdClient.Add(InvokePattern.InvokedEvent,                        new RaiseEvent(HandleInvokedEvent)); 
            _objectIdClient.Add(SelectionItemPattern.ElementSelectedEvent,         new RaiseEvent(HandleElementSelectedEvent));
            _objectIdClient.Add(SelectionItemPattern.ElementAddedToSelectionEvent, new RaiseEvent(HandleElementAddedToSelectionEvent)); 
            _objectIdClient.Add(SelectionItemPattern.ElementRemovedFromSelectionEvent, new RaiseEvent(HandleElementRemovedFromSelectionEvent)); 
            _objectIdClient.Add(AutomationElement.StructureChangedEvent,           new RaiseEvent(HandleStructureChangedEventClient));
            _objectIdClient.Add(SelectionPattern.InvalidatedEvent,                 new RaiseEvent(HandleInvalidatedEvent)); 
            _objectIdClient.Add(TogglePattern.ToggleStateProperty,                 new RaiseEvent(HandleToggleStateProperty));
            _objectIdClient.Add(TextPattern.TextSelectionChangedEvent,             new RaiseEvent(HandleTextSelectionChangedEvent));
        }
 
        private static void InitObjectIdScroll()
        { 
            _objectIdScroll = new Hashtable(3, .1f); 
            _objectIdScroll.Add(ScrollPattern.VerticalScrollPercentProperty,       new RaiseEvent(HandleVerticalScrollPercentProperty));
            _objectIdScroll.Add(ScrollPattern.HorizontalScrollPercentProperty,     new RaiseEvent(HandleHorizontalScrollPercentProperty)); 
            _objectIdScroll.Add(InvokePattern.InvokedEvent,                        new RaiseEvent(HandleScrollInvokedEvent));
        }

        private static void InitObjectIdCaret() 
        {
            _objectIdCaret = new Hashtable(1, .1f); 
            _objectIdCaret.Add(TextPattern.TextSelectionChangedEvent,              new RaiseEvent(HandleTextSelectionChangedEvent)); 
        }
 
        private static void InitObjectIdMenu()
        {
            _objectIdMenu = new Hashtable(1, .1f);
            _objectIdMenu.Add(InvokePattern.InvokedEvent, new RaiseEvent(HandleMenuItemInvokedEvent)); 
        }
 
        #endregion 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------ 

        #region Private Fields 
 
        private delegate void RaiseEvent (ProxySimple el, IntPtr hwnd, int eventId);
 
        private static Hashtable _objectIdWindow;
        private static Hashtable _objectIdClient;
        private static Hashtable _objectIdScroll;
        private static Hashtable _objectIdCaret; 
        private static Hashtable _objectIdMenu;
        private static object _classLock = new object();   // use lock object vs typeof(class) for perf 
 
        // The hwndLast and objLast is to allow limited filtering of events.
        private static IntPtr _hwndLast = IntPtr.Zero; 
        private static ITextRangeProvider _lastSelection = null;

        #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