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

        #region Private Methods

        private void OnStateChange(IntPtr hwnd, int idObject, int idChild)
        {
            NativeMethods.HWND nativeHwnd = NativeMethods.HWND.Cast(hwnd);

            // Ignore windows that have been destroyed
            if (!SafeNativeMethods.IsWindow(nativeHwnd))
            {
                return;
            }

            AutomationElement rawEl = AutomationElement.FromHandle(hwnd);

            try
            {
                rawEl.GetCurrentPattern(WindowPattern.Pattern);
            }
            catch (InvalidOperationException)
            {
                // Only raise this event for elements with the WindowPattern.
                return;
            }

            Object windowInteractionState = rawEl.GetPatternPropertyValue(WindowPattern.WindowInteractionStateProperty, false);

            // if has no state value just return
            if (!(windowInteractionState is WindowInteractionState))
            {
                return;
            }

            WindowInteractionState state = (WindowInteractionState)windowInteractionState;

            // Filter... avoid duplicate events
            if (hwnd == _lastHwnd && state == _lastState)
            {
                return;
            }

            AutomationPropertyChangedEventArgs e = new AutomationPropertyChangedEventArgs(
                WindowPattern.WindowInteractionStateProperty,
                hwnd == _lastHwnd ? _lastState : WindowInteractionState.Running,
                state);

            ClientEventManager.RaiseEventInThisClientOnly(AutomationElement.AutomationPropertyChangedEvent, rawEl, e);

            // save the last hwnd/rect for filtering out duplicates
            _lastHwnd  = hwnd;
            _lastState = state;
        }
예제 #2
0
        private void HandleBoundingRectChange(IntPtr hwnd)
        {
            NativeMethods.HWND nativeHwnd = NativeMethods.HWND.Cast(hwnd);
            NativeMethods.RECT rc32       = new NativeMethods.RECT(0, 0, 0, 0);

            // if GetWindwRect fails, most likely the nativeHwnd is an invalid window, so just return.
            if (!Misc.GetWindowRect(nativeHwnd, out rc32))
            {
                return;
            }

            // Filter... avoid duplicate events
            if (hwnd == _lastHwnd && Compare(rc32, _lastRect))
            {
                return;
            }

            AutomationElement rawEl = AutomationElement.FromHandle(hwnd);

            // Problem with Avalon combo box & menus:
            // There was a windows issue where we get two events.  One for the hwnd (LocationChange WinEvent)
            // and one for the [usually] DockPanel (Avalon BoundingRectangleProperty change). Both have the
            // same Rect value. It's unclear is this issue is still occuring and what (if anything) needs to be done.
            // Waiting for WPP redesign to investigate further how to filter out the duplicate which
            // happens to be the first (hwnd-based) event.
            //
            AutomationPropertyChangedEventArgs e = new AutomationPropertyChangedEventArgs(
                AutomationElement.BoundingRectangleProperty,
                Rect.Empty,
                new Rect(rc32.left, rc32.top, rc32.right - rc32.left, rc32.bottom - rc32.top));

            // In the case of HWND hosted Avalon content, we will get a LocationChange WinEvent for the host
            // window when it's bounding rect changes (e.g. an Avalon window is resized) and we won't (that I've seen)
            // get a BoundingRect property change from the Avalon content.  Therefore, we need to map the WinEvent.
            // In this case, rawEl is already the remote object. It's ol to call this locally since this is called
            // to handle a WinEvent (e.g. always called on client-side). Since rawEl may be local (proxied) or
            // remote (native) impl then use that version of RaiseEventInThisClientOnly
            ClientEventManager.RaiseEventInThisClientOnly(AutomationElement.AutomationPropertyChangedEvent, rawEl, e);

            // save the last hwnd/rect for filtering out duplicates
            _lastHwnd = hwnd;
            _lastRect = rc32;
        }
예제 #3
0
        private void HandleBoundingRectChange(IntPtr hwnd)
        {
            NativeMethods.HWND nativeHwnd = NativeMethods.HWND.Cast(hwnd);
            NativeMethods.RECT rc32       = new NativeMethods.RECT(0, 0, 0, 0);

            // if GetWindwRect fails, most likely the nativeHwnd is an invalid window, so just return.
            if (!Misc.GetWindowRect(nativeHwnd, out rc32))
            {
                return;
            }

            // Filter... avoid duplicate events
            if (hwnd == _lastHwnd && Compare(rc32, _lastRect))
            {
                return;
            }

            AutomationElement rawEl = AutomationElement.FromHandle(hwnd);

            //
            //



            AutomationPropertyChangedEventArgs e = new AutomationPropertyChangedEventArgs(
                AutomationElement.BoundingRectangleProperty,
                Rect.Empty,
                new Rect(rc32.left, rc32.top, rc32.right - rc32.left, rc32.bottom - rc32.top));

            //



            ClientEventManager.RaiseEventInThisClientOnly(AutomationElement.AutomationPropertyChangedEvent, rawEl, e);

            // save the last hwnd/rect for filtering out duplicates
            _lastHwnd = hwnd;
            _lastRect = rc32;
        }
예제 #4
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        // HandleFocusChange - Called when a WinEvent we're listening to indicates the
        // focus has changed.  This is where the callback to the client is queued.
        private void HandleFocusChange(IntPtr hwnd, Accessible acc, int idObject, int idChild, uint eventTime)
        {
            // If there is an hwnd then notify of a focus change
            if (hwnd != IntPtr.Zero)
            {
                Debug.Assert(acc != null, "HandleFocusChange got hwnd and null IAccessible");

                // Create an event args and get the source logical element
                AutomationFocusChangedEventArgs e = new InternalAutomationFocusChangedEventArgs(idObject, idChild, eventTime);
                AutomationElement srcEl           = GetFocusedElementFromWinEvent(hwnd, idObject, idChild);
                if (srcEl == null)
                {
                    // Don't raise focus change events for UI that is gone.  This has been seen when toolbar menus are
                    // being manipulated (e.g. mnu.SubMenu("File").MenuItems("Close").Click() in MITA).  We should be
                    // seeing another focus change soon and with that event we can re-establish focus.
                    return;
                }

                // Check that item is actually focused
                // Don't do this for statics - the controls in the color picker are statics, and
                // they get focus, but OLEACC assumes statics don't get focus, so never sets the
                // focus bit. So, for now, assume statics that send focus do actually have focus.
                if (!Accessible.IsStatic(hwnd) && !Accessible.IsComboDropdown(hwnd))
                {
                    // instead of depending on oleacc to see if something has focus ask provider
                    if (!(bool)srcEl.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty))
                    {
                        return;
                    }
                }

                // Do notifies
                ClientEventManager.RaiseEventInThisClientOnly(AutomationElement.AutomationFocusChangedEvent, srcEl, e);
            }

            // Keep track of where we are right now (may be unknown/null)
            _accCurrent = acc;
        }