Beispiel #1
0
        public override void RaiseAutomationPropertyChangedEvent(AutomationPropertyChangedEventArgs e)
        {
            if (e.Property == AutomationElementIdentifiers.ControlTypeProperty)
            {
                //We remove the current Adapter and add it again to reflect the ControlType change
                StructureChangedEventArgs args
                    = new StructureChangedEventArgs(StructureChangeType.ChildRemoved,
                                                    new int[] { 0 });                      //TODO: Fix ?
                AutomationInteropProvider.RaiseStructureChangedEvent(Provider,
                                                                     args);

                args = new StructureChangedEventArgs(StructureChangeType.ChildAdded,
                                                     new int[] { 0 });                  //TODO: Fix ?
                AutomationInteropProvider.RaiseStructureChangedEvent(Provider,
                                                                     args);
            }
            if (e.Property == TogglePatternIdentifiers.ToggleStateProperty)
            {
                //if it's a toggle, it should not be a basic Button class, but CheckBox or other
                throw new NotSupportedException("Toggle events should not land here (should not be reached)");
            }
            else
            {
                base.RaiseAutomationPropertyChangedEvent(e);
            }
        }
Beispiel #2
0
 private static void HandleStructureChangedEventWindow(ProxySimple el, IntPtr hwnd, int eventId)
 {
     if (eventId == NativeMethods.EventObjectReorder)
     {
         AutomationInteropProvider.RaiseStructureChangedEvent(el, new StructureChangedEventArgs(StructureChangeType.ChildrenReordered, el.MakeRuntimeId()));
     }
 }
Beispiel #3
0
        internal static void RaiseStructureChangedEvent(StructureChangeType type,
                                                        IRawElementProviderFragment provider)
        {
            if (AutomationInteropProvider.ClientsAreListening)
            {
                int [] runtimeId = null;
                if (type == StructureChangeType.ChildRemoved)
                {
                    if (provider.FragmentRoot == null)                     //FIXME: How to fix it?
                    {
                        runtimeId = provider.GetRuntimeId();
                    }
                    else
                    {
                        runtimeId = provider.FragmentRoot.GetRuntimeId();
                    }
                }
                else if (type == StructureChangeType.ChildrenBulkAdded ||
                         type == StructureChangeType.ChildrenBulkRemoved)
                {
                    runtimeId = new int[] { 0 }
                }
                ;
                else
                {
                    runtimeId = provider.GetRuntimeId();
                }

                var invalidatedArgs = new StructureChangedEventArgs(type, runtimeId);
                AutomationInteropProvider.RaiseStructureChangedEvent(provider, invalidatedArgs);
            }
        }
 /// <summary>
 /// Responds to a removal from the UI Automation tree structure
 /// by raising an event.
 /// </summary>
 /// <param name="list">
 /// The list from which the item was removed.
 /// </param>
 /// <remarks>
 /// For the runtime Id of the list, pass 0 because the provider cannot know
 /// what its actual runtime ID is.
 /// </remarks>
 public static void OnStructureChangeRemove(CustomListControl list)
 {
     if (AutomationInteropProvider.ClientsAreListening)
     {
         int[] fakeRuntimeId            = { 0 };
         StructureChangedEventArgs args =
             new StructureChangedEventArgs(StructureChangeType.ChildrenBulkRemoved,
                                           fakeRuntimeId);
         AutomationInteropProvider.RaiseStructureChangedEvent(
             (IRawElementProviderSimple)list.Provider, args);
     }
 }
Beispiel #5
0
 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()));
     }
 }
Beispiel #6
0
        public override void RaiseAutomationPropertyChangedEvent(AutomationPropertyChangedEventArgs e)
        {
            if (e.Property == AutomationElementIdentifiers.ControlTypeProperty)
            {
                //We remove the current Adapter and add it again to reflect the ControlType change
                StructureChangedEventArgs args
                    = new StructureChangedEventArgs(StructureChangeType.ChildRemoved,
                                                    new int[] { 0 });                      //TODO: Fix ?
                AutomationInteropProvider.RaiseStructureChangedEvent(Provider,
                                                                     args);

                args = new StructureChangedEventArgs(StructureChangeType.ChildAdded,
                                                     new int[] { 0 });                  //TODO: Fix ?
                AutomationInteropProvider.RaiseStructureChangedEvent(Provider,
                                                                     args);
            }
            else
            {
                base.RaiseAutomationPropertyChangedEvent(e);
            }
        }
        // fire the structure change event if there is a client listening for it.
        private void MaybeFireStructureChangeEvent(int eventId, Hashtable eventTable, IntPtr hwnd, int idObject, int idChild)
        {
            // if the 2-nd level table contains an entry for this event and element is not the root
            // (the host hwnd provider takes care of structure changed events for the root.)
            if (eventTable.ContainsKey(AutomationElement.StructureChangedEvent) && !IsClientObject(idObject, idChild))
            {
                // Note: src element for ChildRemoved cases needs to be the parent, but the runtime id is the child!

                // the type of structure changed event that we will fire depends on which event we are receiving.
                // the type then determines the src element -- either the parent or the child -- and the runtime id
                // -- either the parent or the child -- for the event arguments.
                IRawElementProviderFragment srcElement;
                int[] runtimeId          = null;
                StructureChangeType type = StructureChangeType.ChildAdded; // Actual value is assigned below; any value will do here, to init the var
                switch (eventId)
                {
                case NativeMethods.EVENT_OBJECT_CREATE:
                case NativeMethods.EVENT_OBJECT_SHOW:
                    // src element is child. runtime id is child.
                    srcElement = (IRawElementProviderFragment)MsaaNativeProvider.Create(hwnd, idChild, idObject);
                    if (srcElement != null)
                    {
                        runtimeId = srcElement.GetRuntimeId();
                        type      = StructureChangeType.ChildAdded;
                    }
                    break;

                //case NativeMethods.EVENT_OBJECT_DESTROY:
                // src element is parent. runtime id is child.

                // There is nothing we can do in this case. Since the object is destroyed we can't instantiate
                // it in order to get its runtime ID. Even if it had a non-zero child id such that we could
                // instantiate its parent we still couldn't determine the runtime ID of the child that was destroyed.
                // There's also no guarantee that an EVENT_OBJECT_DESTROY will have a corresponding EVENT_OBJECT_CREATE
                // and even if it did it might use a different object id so we can't cache the information either.
                // (Trident for example uses a cyclic counter to generate object ids so the object id can vary for
                // the same object from one event to the next!)

                case NativeMethods.EVENT_OBJECT_HIDE:
                    // src element is parent. runtime id is child.
                    srcElement = (IRawElementProviderFragment)MsaaNativeProvider.Create(hwnd, idChild, idObject);
                    if (srcElement != null)
                    {
                        runtimeId  = srcElement.GetRuntimeId();
                        srcElement = (IRawElementProviderFragment)srcElement.Navigate(NavigateDirection.Parent);
                        type       = StructureChangeType.ChildRemoved;
                    }
                    break;

                default:
                    Debug.Assert(eventId == NativeMethods.EVENT_OBJECT_REORDER);
                    // src element is parent. runtime id is parent.
                    srcElement = (IRawElementProviderFragment)MsaaNativeProvider.Create(hwnd, idChild, idObject);
                    if (srcElement != null)
                    {
                        runtimeId = srcElement.GetRuntimeId();
                        type      = StructureChangeType.ChildrenReordered;
                    }
                    break;
                }

                if (srcElement != null)
                {
                    // fire the event
                    StructureChangedEventArgs eventArgs = new StructureChangedEventArgs(type, runtimeId);
                    //Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Firing structure change event for {0}", hwnd), "NativeMsaaProxy");
                    AutomationInteropProvider.RaiseStructureChangedEvent(srcElement, eventArgs);
                }
            }
        }
Beispiel #8
0
        private static void RaiseEventsOnClient(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild)
        {
            ProxySimple el = null;

            WindowsListBox wlb = (WindowsListBox)WindowsListBox.Create(hwnd, 0);

            // Upon creation, a single selection Listbox can have no selection to start with
            // however once an item has been selection, the selection cannot be removed.
            // This WinEvent can only be received once, on the first selection.
            // Once the notification is received the notification handler is removed to not get it a
            // second time.
            if ((eventId == NativeMethods.EventObjectSelection || eventId == NativeMethods.EventObjectSelectionAdd) && (idProp as AutomationProperty) == SelectionPattern.IsSelectionRequiredProperty)
            {
                // This array must be kept in sync with the array in PropertyToWinEvent
                WinEventTracker.EvtIdProperty[] aEvtIdProperties = new WinEventTracker.EvtIdProperty[] { new WinEventTracker.EvtIdProperty(NativeMethods.EventObjectSelection, SelectionPattern.IsSelectionRequiredProperty) };

                WinEventTracker.RemoveToNotificationList(hwnd, aEvtIdProperties, null, aEvtIdProperties.Length);
                el = wlb;
            }
            else if (eventId == NativeMethods.EventObjectSelection || eventId == NativeMethods.EventObjectSelectionRemove || eventId == NativeMethods.EventObjectSelectionAdd)
            {
                bool isMultipleSelection = wlb.IsMultipleSelection();

                // User should send SelectionAdd for a Multiselect listbox but it sends instead
                // Selection. The code below fixes the
                if (eventId == NativeMethods.EventObjectSelection && isMultipleSelection && wlb.HasOtherSelections(idChild - 1))
                {
                    eventId = NativeMethods.EventObjectSelectionAdd;
                }

                // The spec says a ElementSelectionEvent should be fired when action causes only one
                // selection.
                if ((eventId == NativeMethods.EventObjectSelectionRemove || eventId == NativeMethods.EventObjectSelectionAdd) &&
                    isMultipleSelection && wlb.GetSelectionCount() == 1)
                {
                    // The net result of the user action is that there is only one item selected in the
                    // listbox, so change the event to an EventObjectSelected.
                    idProp  = SelectionItemPattern.ElementSelectedEvent;
                    eventId = NativeMethods.EventObjectSelection;

                    // Now need to find what item is selected.
                    int selection = wlb.GetOtherSelection(idChild - 1);
                    if (selection != NativeMethods.LB_ERR)
                    {
                        idChild = selection;
                    }
                }

                el = wlb.CreateListboxItem(idChild - 1);
            }
            else
            {
                el = wlb;
            }

            // Special case for logical element change for listbox item
            if ((idProp as AutomationEvent) == AutomationElement.StructureChangedEvent &&
                (eventId == NativeMethods.EventObjectDestroy || eventId == NativeMethods.EventObjectCreate))
            {
                // Since children are referenced by position in the tree, addition and removal
                // of items leads to different results when asking properties for the same element
                // On removal, item + 1 is now item!
                // Use Children Invalidated to let the client knows that all the cached
                AutomationInteropProvider.RaiseStructureChangedEvent(wlb, new StructureChangedEventArgs(StructureChangeType.ChildrenInvalidated, wlb.MakeRuntimeId()));
                return;
            }

            if (el != null)
            {
                el.DispatchEvents(eventId, idProp, idObject, idChild);
            }
        }
 private void AddProvider(IRawElementProviderSimple provider)
 {
     AutomationInteropProvider.RaiseStructureChangedEvent(provider,
                                                          new StructureChangedEventArgs(StructureChangeType.ChildAdded, new int [0]));
 }