示例#1
0
        // RemoveAllListeners - Removes all listeners from this client and notifies the
        // UIAccess server
        internal static void RemoveAllListeners()
        {
            lock (_classLock)
            {
                if (_listeners == null)
                {
                    return;
                }

                // Stop all WinEvent tracking
                StopWinEventTracking();

                // Must remove from back to front when calling RemoveAt because ArrayList
                // elements are compressed after each RemoveAt.
                for (int i = _listeners.Count - 1; i >= 0; i--)
                {
                    EventListenerClientSide ec = (EventListenerClientSide)_listeners[i];

                    // Notify the server-side UIAccess that this event is no longer interesting
                    EventListener l = ec.EventListener;
                    // Only advise UI contexts of events being removed if the event might be raised by
                    // a provider.  TopLevelWindow event is raised by UI Automation framework.
                    if (ShouldAdviseProviders(l.EventId))
                    {
                        ec.EventHandle.Dispose(); // Calls RemoveEvent
                    }
                    // delete this one
                    _listeners.RemoveAt(i);
                }

                _listeners = null;
                CheckStopCallbackQueueing();
            }
        }
示例#2
0
        // AddListener - Adds a listener for this client and notifies the UIA server.  All event
        // handler additions call through to this method.
        internal static void AddListener(AutomationElement rawEl, Delegate eventCallback, EventListener l)
        {
            lock (_classLock)
            {
                // If we are adding a listener then a proxy could be created as a result of an event so make sure they are loaded
                ProxyManager.LoadDefaultProxies();

                if (_listeners == null)
                {
                    // enough space for 16 AddXxxListeners (100 bytes)
                    _listeners = new ArrayList(16);
                }

                // Start the callback queue that gets us off the server's
                // UI thread when events arrive cross-proc
                CheckStartCallbackQueueing();

                //
                // The framework handles some events on behalf of providers; do those here
                //

                // If listening for BoundingRectangleProperty then may need to start listening on the
                // client-side for LocationChange WinEvent (only use *one* BoundingRectTracker instance).
                if (_winEventTrackers[(int)Tracker.BoundingRect] == null && HasProperty(AutomationElement.BoundingRectangleProperty, l.Properties))
                {
                    // 







                    AddWinEventListener(Tracker.BoundingRect, new BoundingRectTracker());
                }

                // Start listening for menu event in order to raise MenuOpened/Closed events.
                if ( _winEventTrackers [(int)Tracker.MenuOpenedOrClosed] == null && (l.EventId == AutomationElement.MenuOpenedEvent || l.EventId == AutomationElement.MenuClosedEvent) )
                {
                    AddWinEventListener( Tracker.MenuOpenedOrClosed, new MenuTracker( new MenuHandler( OnMenuEvent ) ) );
                }

                // Begin watching for hwnd open/close/show/hide so can advise of what events are being listened for.
                // Only advise UI contexts of events being added if the event might be raised by a provider.
                // TopLevelWindow event is raised by UI Automation framework so no need to track new UI.
                // 
                if (_winEventTrackers[(int)Tracker.WindowShowOrOpen] == null )
                {
                    AddWinEventListener( Tracker.WindowShowOrOpen, new WindowShowOrOpenTracker( new WindowShowOrOpenHandler( OnWindowShowOrOpen ) ) );
                    AddWinEventListener( Tracker.WindowHideOrClose, new WindowHideOrCloseTracker( new WindowHideOrCloseHandler( OnWindowHideOrClose ) ) );
                }

                // If listening for WindowInteractionStateProperty then may need to start listening on the
                // client-side for ObjectStateChange WinEvent.
                if (_winEventTrackers[(int)Tracker.WindowInteractionState] == null && HasProperty(WindowPattern.WindowInteractionStateProperty, l.Properties))
                {
                    AddWinEventListener(Tracker.WindowInteractionState, new WindowInteractionStateTracker());
                }

                // If listening for WindowVisualStateProperty then may need to start listening on the
                // client-side for ObjectLocationChange WinEvent.
                if (_winEventTrackers[(int)Tracker.WindowVisualState] == null && HasProperty(WindowPattern.WindowVisualStateProperty, l.Properties))
                {
                    AddWinEventListener(Tracker.WindowVisualState, new WindowVisualStateTracker());
                }

                // Wrap and store this record on the client...
                EventListenerClientSide ec = new EventListenerClientSide(rawEl, eventCallback, l);
                _listeners.Add(ec);

                // Only advise UI contexts of events being added if the event might be raised by
                // a provider.  TopLevelWindow event is raised by UI Automation framework.
                if (ShouldAdviseProviders( l.EventId ))
                {
                    // .. then let the server know about this listener
                    ec.EventHandle = UiaCoreApi.UiaAddEvent(rawEl.RawNode, l.EventId.Id, ec.CallbackDelegate, l.TreeScope, PropertyArrayToIntArray(l.Properties), l.CacheRequest);
                }
            }
        }
示例#3
0
        // OnWindowShowOrOpen - Called by the WindowShowOrOpenTracker class when UI is shown or created
        private static void OnWindowShowOrOpen(IntPtr hwnd, AutomationElement rawEl)
        {
            bool doWindowOpenedEvent     = false;
            bool doStructureChangedEvent = false;

            lock ( _classLock )
            {
                if (_listeners != null)
                {
                    // if rawEl is w/in the scope of any listeners then register for events in the new UI
                    for (int i = 0; i < _listeners.Count; i++)
                    {
                        EventListenerClientSide ec = (EventListenerClientSide)_listeners[i];

                        EventListener l = ec.EventListener;
                        if (l.EventId == WindowPattern.WindowOpenedEvent)
                        {
                            doWindowOpenedEvent = true;
                        }
                        if (l.EventId == AutomationElement.StructureChangedEvent)
                        {
                            doStructureChangedEvent = true;
                        }

                        // Only advise UI contexts if the provider might raise that event.
                        if (!ShouldAdviseProviders(l.EventId))
                        {
                            continue;
                        }

                        // Only advise UI contexts if the element is w/in scope of the reference element
                        if (!ec.WithinScope(rawEl))
                        {
                            continue;
                        }

                        // Notify the server side
                        UiaCoreApi.UiaEventAddWindow(ec.EventHandle, hwnd);
                    }
                }
            }

            // Piggy-back on the listener for Windows hiding or closing to raise WindowClosed and StructureChanged events.
            if (doWindowOpenedEvent)
            {
                if (HwndProxyElementProvider.IsWindowPatternWindow(NativeMethods.HWND.Cast(hwnd)))
                {
                    // Go ahead and raise a client-side only WindowOpenedEvent (if anyone is listening)
                    AutomationEventArgs e = new AutomationEventArgs(WindowPattern.WindowOpenedEvent);
                    RaiseEventInThisClientOnly(WindowPattern.WindowOpenedEvent, rawEl, e);
                }
            }
            if (doStructureChangedEvent)
            {
                // Filter on the control elements.  Otherwise, this is extremely noisy.  Consider not filtering if there is feedback.
                //ControlType ct = (ControlType)rawEl.GetPropertyValue( AutomationElement.ControlTypeProperty );
                //if ( ct != null )
                {
                    // Last,raise an event for structure changed
                    StructureChangedEventArgs e = new StructureChangedEventArgs(StructureChangeType.ChildAdded, rawEl.GetRuntimeId());
                    RaiseEventInThisClientOnly(AutomationElement.StructureChangedEvent, rawEl, e);
                }
            }
        }
示例#4
0
        // AddListener - Adds a listener for this client and notifies the UIA server.  All event
        // handler additions call through to this method.
        internal static void AddListener(AutomationElement rawEl, Delegate eventCallback, EventListener l)
        {
            lock (_classLock)
            {
                // If we are adding a listener then a proxy could be created as a result of an event so make sure they are loaded
                ProxyManager.LoadDefaultProxies();

                if (_listeners == null)
                {
                    // enough space for 16 AddXxxListeners (100 bytes)
                    _listeners = new ArrayList(16);
                }

                // Start the callback queue that gets us off the server's
                // UI thread when events arrive cross-proc
                CheckStartCallbackQueueing();

                //
                // The framework handles some events on behalf of providers; do those here
                //

                // If listening for BoundingRectangleProperty then may need to start listening on the
                // client-side for LocationChange WinEvent (only use *one* BoundingRectTracker instance).
                if (_winEventTrackers[(int)Tracker.BoundingRect] == null && HasProperty(AutomationElement.BoundingRectangleProperty, l.Properties))
                {
                    // There may be special cases to not map BoundingRect to WinEvent. One may be
                    // where rawEl is a non-top-level native implementation and TreeScope == Element.
                    // Another may be if rawEl is a native impl and TreeScope includes descendents then
                    // may not need to worry about BoundingRect prop change on hosted Win32 UI? I think the
                    // answer is 'yes' because BoundingRectangleProperty should fire events for the top-most
                    // element that moved in the hierarchy.  So if hosted Win32 content Rect changes w/o
                    // the host changing then it would fire this event.
                    // Note: Part of cleaning up WinEvent listeners is to move away from WinEvent handlers calling UIA client handlers
                    AddWinEventListener(Tracker.BoundingRect, new BoundingRectTracker());
                }

                // Start listening for menu event in order to raise MenuOpened/Closed events.
                if (_winEventTrackers [(int)Tracker.MenuOpenedOrClosed] == null && (l.EventId == AutomationElement.MenuOpenedEvent || l.EventId == AutomationElement.MenuClosedEvent))
                {
                    AddWinEventListener(Tracker.MenuOpenedOrClosed, new MenuTracker(new MenuHandler(OnMenuEvent)));
                }

                // Begin watching for hwnd open/close/show/hide so can advise of what events are being listened for.
                // Only advise UI contexts of events being added if the event might be raised by a provider.
                // TopLevelWindow event is raised by UI Automation framework so no need to track new UI.
                // Are there other events like this where Advise can be skipped?
                if (_winEventTrackers[(int)Tracker.WindowShowOrOpen] == null)
                {
                    AddWinEventListener(Tracker.WindowShowOrOpen, new WindowShowOrOpenTracker(new WindowShowOrOpenHandler(OnWindowShowOrOpen)));
                    AddWinEventListener(Tracker.WindowHideOrClose, new WindowHideOrCloseTracker(new WindowHideOrCloseHandler(OnWindowHideOrClose)));
                }

                // If listening for WindowInteractionStateProperty then may need to start listening on the
                // client-side for ObjectStateChange WinEvent.
                if (_winEventTrackers[(int)Tracker.WindowInteractionState] == null && HasProperty(WindowPattern.WindowInteractionStateProperty, l.Properties))
                {
                    AddWinEventListener(Tracker.WindowInteractionState, new WindowInteractionStateTracker());
                }

                // If listening for WindowVisualStateProperty then may need to start listening on the
                // client-side for ObjectLocationChange WinEvent.
                if (_winEventTrackers[(int)Tracker.WindowVisualState] == null && HasProperty(WindowPattern.WindowVisualStateProperty, l.Properties))
                {
                    AddWinEventListener(Tracker.WindowVisualState, new WindowVisualStateTracker());
                }

                // Wrap and store this record on the client...
                EventListenerClientSide ec = new EventListenerClientSide(rawEl, eventCallback, l);
                _listeners.Add(ec);

                // Only advise UI contexts of events being added if the event might be raised by
                // a provider.  TopLevelWindow event is raised by UI Automation framework.
                if (ShouldAdviseProviders(l.EventId))
                {
                    // .. then let the server know about this listener
                    ec.EventHandle = UiaCoreApi.UiaAddEvent(rawEl.RawNode, l.EventId.Id, ec.CallbackDelegate, l.TreeScope, PropertyArrayToIntArray(l.Properties), l.CacheRequest);
                }
            }
        }
示例#5
0
        // OnWindowHideOrClose - Called by the WindowHideOrCloseTracker class when UI is hidden or destroyed
        private static void OnWindowHideOrClose(IntPtr hwnd, AutomationElement rawEl, int [] runtimeId)
        {
            bool doWindowClosedEvent     = false;
            bool doStructureChangedEvent = false;

            lock ( _classLock )
            {
                if (_listeners != null)
                {
                    // if an hwnd is hidden or closed remove event listeners for the window's provider
                    for (int i = 0; i < _listeners.Count; i++)
                    {
                        EventListenerClientSide ec = (EventListenerClientSide)_listeners[i];

                        EventListener l = ec.EventListener;
                        if (l.EventId == WindowPattern.WindowClosedEvent)
                        {
                            doWindowClosedEvent = true;
                        }
                        if (l.EventId == AutomationElement.StructureChangedEvent)
                        {
                            doStructureChangedEvent = true;
                        }

                        // Only advise UI contexts if the provider still exists
                        // (but keep looking to see if need to do a WindowClosedEvent)
                        if (rawEl == null)
                        {
                            continue;
                        }

                        // Only advise UI contexts if the provider might raise that event.
                        if (!ShouldAdviseProviders(l.EventId))
                        {
                            continue;
                        }

                        // Only advise UI contexts if the element is w/in scope of the reference element
                        if (!ec.WithinScope(rawEl))
                        {
                            continue;
                        }

                        // Notify the server-side that this event is no longer interesting
                        UiaCoreApi.UiaEventRemoveWindow(ec.EventHandle, hwnd);
                    }
                }
            }

            // Piggy-back on the listener for Windows hiding or closing to raise WindowClosed and StructureChanged events.
            // When the hwnd behind rawEl is being destroyed, it can't be determined that rawEl once had the
            // WindowPattern interface.  Therefore raise an event for any window close.
            if (doWindowClosedEvent)
            {
                // When the hwnd is just hidden, rawEl will not be null, so can test if this would support WindowPattern
                // and throw this event away if the window doesn't support that CP
                if (rawEl != null && !HwndProxyElementProvider.IsWindowPatternWindow(NativeMethods.HWND.Cast(hwnd)))
                {
                    return;
                }

                // Go ahead and raise a client-side only WindowClosedEvent (if anyone is listening)
                WindowClosedEventArgs e = new WindowClosedEventArgs(runtimeId);
                RaiseEventInThisClientOnly(WindowPattern.WindowClosedEvent, runtimeId, e);
            }
            if (doStructureChangedEvent)
            {
                // Raise an event for structure changed.  This element has essentially gone away so there isn't an
                // opportunity to do filtering here.  So, just like WindowClosed, this event will be very noisy.
                StructureChangedEventArgs e = new StructureChangedEventArgs(StructureChangeType.ChildRemoved, runtimeId);
                RaiseEventInThisClientOnly(AutomationElement.StructureChangedEvent, runtimeId, e);
            }
        }
示例#6
0
        // RemoveListener - Removes a listener from this client and notifies the UIAutomation server-side
        internal static void RemoveListener(AutomationEvent eventId, AutomationElement el, Delegate eventCallback)
        {
            lock ( _classLock )
            {
                if (_listeners != null)
                {
                    bool boundingRectListeners       = false; // if not removing BoundingRect listeners no need to do check below
                    bool menuListeners               = false; // if not removing MenuOpenedOrClosed listeners no need to do check below
                    bool windowInteracationListeners = false; // if not removing WindowsIntercation listeners no need to do check below
                    bool windowVisualListeners       = false; // if not removing WindowsVisual listeners no need to do check below

                    for (int i = _listeners.Count - 1; i >= 0; i--)
                    {
                        EventListenerClientSide ec = (EventListenerClientSide)_listeners[i];
                        if (ec.IsListeningFor(eventId, el, eventCallback))
                        {
                            EventListener l = ec.EventListener;

                            // Only advise UI contexts of events being removed if the event might be raised by
                            // a provider.  TopLevelWindow event is raised by UI Automation framework.
                            if (ShouldAdviseProviders(eventId))
                            {
                                // Notify the server-side that this event is no longer interesting
                                try
                                {
                                    ec.EventHandle.Dispose(); // Calls UiaCoreApi.UiaRemoveEvent
                                }
// PRESHARP: Warning - Catch statements should not have empty bodies
#pragma warning disable 6502
                                catch (ElementNotAvailableException)
                                {
                                    // the element is gone already; continue on and remove the listener
                                }
#pragma warning restore 6502
                                finally
                                {
                                    ec.Dispose();
                                }
                            }

                            // before removing, check if this delegate was listening for the below events
                            // and see if we can stop clientside WinEvent trackers.
                            if (HasProperty(AutomationElement.BoundingRectangleProperty, l.Properties))
                            {
                                boundingRectListeners = true;
                            }

                            if (eventId == AutomationElement.MenuOpenedEvent || eventId == AutomationElement.MenuClosedEvent)
                            {
                                menuListeners = true;
                            }

                            if (HasProperty(WindowPattern.WindowInteractionStateProperty, l.Properties))
                            {
                                windowInteracationListeners = true;
                            }

                            if (HasProperty(WindowPattern.WindowVisualStateProperty, l.Properties))
                            {
                                windowVisualListeners = true;
                            }

                            // delete this one
                            _listeners.RemoveAt(i);
                        }
                    }

                    // Check listeners bools to see if clientside listeners can be removed
                    if (boundingRectListeners)
                    {
                        RemovePropertyTracker(AutomationElement.BoundingRectangleProperty, Tracker.BoundingRect);
                    }

                    if (menuListeners)
                    {
                        RemoveMenuListeners();
                    }

                    if (windowInteracationListeners)
                    {
                        RemovePropertyTracker(WindowPattern.WindowInteractionStateProperty, Tracker.WindowInteractionState);
                    }

                    if (windowVisualListeners)
                    {
                        RemovePropertyTracker(WindowPattern.WindowVisualStateProperty, Tracker.WindowVisualState);
                    }

                    // See if we can cleanup completely
                    if (_listeners.Count == 0)
                    {
                        // as long as OnWindowShowOrOpen is static can just use new here and get same object instance
                        // (if there's no WindowShowOrOpen listener, this method just returns)
                        RemoveWinEventListener(Tracker.WindowShowOrOpen, new WindowShowOrOpenHandler(OnWindowShowOrOpen));
                        RemoveWinEventListener(Tracker.WindowHideOrClose, new WindowHideOrCloseHandler(OnWindowHideOrClose));

                        _listeners = null;
                    }
                }
            }
        }
        // AddListener - Adds a listener for this client and notifies the UIA server.  All event
        // handler additions call through to this method.
        internal static void AddListener(AutomationElement rawEl, Delegate eventCallback, EventListener l)
        {
            lock (_classLock)
            {
                // If we are adding a listener then a proxy could be created as a result of an event so make sure they are loaded
                ProxyManager.LoadDefaultProxies();

                if (_listeners == null)
                {
                    // enough space for 16 AddXxxListeners (100 bytes)
                    _listeners = new ArrayList(16);
                }

                // Start the callback queue that gets us off the server's
                // UI thread when events arrive cross-proc
                CheckStartCallbackQueueing();

                //
                // The framework handles some events on behalf of providers; do those here
                //

                // If listening for BoundingRectangleProperty then may need to start listening on the
                // client-side for LocationChange WinEvent (only use *one* BoundingRectTracker instance).
                if (_winEventTrackers[(int)Tracker.BoundingRect] == null && HasProperty(AutomationElement.BoundingRectangleProperty, l.Properties))
                {
                    //



                    AddWinEventListener(Tracker.BoundingRect, new BoundingRectTracker());
                }

                // Start listening for menu event in order to raise MenuOpened/Closed events.
                if (_winEventTrackers [(int)Tracker.MenuOpenedOrClosed] == null && (l.EventId == AutomationElement.MenuOpenedEvent || l.EventId == AutomationElement.MenuClosedEvent))
                {
                    AddWinEventListener(Tracker.MenuOpenedOrClosed, new MenuTracker(new MenuHandler(OnMenuEvent)));
                }

                // Begin watching for hwnd open/close/show/hide so can advise of what events are being listened for.
                // Only advise UI contexts of events being added if the event might be raised by a provider.
                // TopLevelWindow event is raised by UI Automation framework so no need to track new UI.
                //
                if (_winEventTrackers[(int)Tracker.WindowShowOrOpen] == null)
                {
                    AddWinEventListener(Tracker.WindowShowOrOpen, new WindowShowOrOpenTracker(new WindowShowOrOpenHandler(OnWindowShowOrOpen)));
                    AddWinEventListener(Tracker.WindowHideOrClose, new WindowHideOrCloseTracker(new WindowHideOrCloseHandler(OnWindowHideOrClose)));
                }

                // If listening for WindowInteractionStateProperty then may need to start listening on the
                // client-side for ObjectStateChange WinEvent.
                if (_winEventTrackers[(int)Tracker.WindowInteractionState] == null && HasProperty(WindowPattern.WindowInteractionStateProperty, l.Properties))
                {
                    AddWinEventListener(Tracker.WindowInteractionState, new WindowInteractionStateTracker());
                }

                // If listening for WindowVisualStateProperty then may need to start listening on the
                // client-side for ObjectLocationChange WinEvent.
                if (_winEventTrackers[(int)Tracker.WindowVisualState] == null && HasProperty(WindowPattern.WindowVisualStateProperty, l.Properties))
                {
                    AddWinEventListener(Tracker.WindowVisualState, new WindowVisualStateTracker());
                }

                // Wrap and store this record on the client...
                EventListenerClientSide ec = new EventListenerClientSide(rawEl, eventCallback, l);
                _listeners.Add(ec);

                // Only advise UI contexts of events being added if the event might be raised by
                // a provider.  TopLevelWindow event is raised by UI Automation framework.
                if (ShouldAdviseProviders(l.EventId))
                {
                    // .. then let the server know about this listener
                    ec.EventHandle = UiaCoreApi.UiaAddEvent(rawEl.RawNode, l.EventId.Id, ec.CallbackDelegate, l.TreeScope, PropertyArrayToIntArray(l.Properties), l.CacheRequest);
                }
            }
        }