// ------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors static WindowsListView () { _groupEvents = new WinEventTracker.EvtIdProperty [3]; _groupEvents [0]._evtId = NativeMethods.EventObjectReorder; _groupEvents [1]._evtId = NativeMethods.EventObjectHide; _groupEvents [2]._evtId = NativeMethods.EventObjectDestroy; _groupEvents [0]._idProp = _groupEvents [1]._idProp = _groupEvents [2]._idProp = 0; }
// Builds a list of Win32 WinEvents to process changes in properties changes values. // Returns an array of Events to Set. The number of valid entries in this array is pass back in cEvents private WinEventTracker.EvtIdProperty [] PropertyToWinEvent(AutomationProperty [] aProps, out int cEvent) { ArrayList alEvents = new ArrayList(16); foreach (AutomationProperty idProp in aProps) { int [] evtId = PropertyToWinEvent(idProp); for (int i = 0; evtId != null && i < evtId.Length; i++) { alEvents.Add(new WinEventTracker.EvtIdProperty(evtId [i], idProp)); } } WinEventTracker.EvtIdProperty [] aEvtIdProperties = new WinEventTracker.EvtIdProperty [alEvents.Count]; cEvent = alEvents.Count; for (int i = 0; i < cEvent; i++) { aEvtIdProperties [i] = (WinEventTracker.EvtIdProperty)alEvents [i]; } return(aEvtIdProperties); }
// Return an array that contains combo's edit portion specific events // These events will be remapped as combo box events private static void CreateEditPortionEvents(out WinEventTracker.EvtIdProperty [] editPortionEvents, out int counter, AutomationProperty [] aidProps) { // count how many events to pass back for the edit part of combo int c = 0; foreach (AutomationProperty p in aidProps) { if (p == ValuePattern.ValueProperty || p == ValuePattern.IsReadOnlyProperty) { c++; } } if (c == 0) { editPortionEvents = null; counter = 0; return; } // allocate array with the number of events from above editPortionEvents = new WinEventTracker.EvtIdProperty[c]; c = 0; foreach (AutomationProperty p in aidProps) { if (p == ValuePattern.ValueProperty || p == ValuePattern.IsReadOnlyProperty) { editPortionEvents[c]._idProp = p; editPortionEvents[c]._evtId = (p == ValuePattern.ValueProperty) ? NativeMethods.EventObjectValueChange : NativeMethods.EventObjectStateChange; c++; } } counter = c; }
static WindowsTab() { _upDownEvents = new WinEventTracker.EvtIdProperty [1]; _upDownEvents[0]._evtId = NativeMethods.EventObjectValueChange; _upDownEvents[0]._idProp = ScrollPattern.HorizontalScrollPercentProperty; }
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); } }
static WindowsTab () { _upDownEvents = new WinEventTracker.EvtIdProperty [1]; _upDownEvents[0]._evtId = NativeMethods.EventObjectValueChange; _upDownEvents[0]._idProp = ScrollPattern.HorizontalScrollPercentProperty; }
// Builds a list of Win32 WinEvents to process changes in properties changes values. // Returns an array of Events to Set. The number of valid entries in this array is pass back in cEvents private WinEventTracker.EvtIdProperty [] PropertyToWinEvent (AutomationProperty [] aProps, out int cEvent) { ArrayList alEvents = new ArrayList (16); foreach (AutomationProperty idProp in aProps) { int [] evtId = PropertyToWinEvent (idProp); for (int i = 0; evtId != null && i < evtId.Length; i++) { alEvents.Add (new WinEventTracker.EvtIdProperty (evtId [i], idProp)); } } WinEventTracker.EvtIdProperty [] aEvtIdProperties = new WinEventTracker.EvtIdProperty [alEvents.Count]; cEvent = alEvents.Count; for (int i = 0; i < cEvent; i++) { aEvtIdProperties [i] = (WinEventTracker.EvtIdProperty) alEvents [i]; } return aEvtIdProperties; }
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 [....] 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 bug in User 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); } }
internal override void AdviseEventRemoved (AutomationEvent eventId, AutomationProperty [] aidProps) { if (aidProps != null) { for (int i = 0, c = aidProps.Length; i < c; i++) { if (aidProps [i] == TablePattern.ColumnHeadersProperty) { // Return array of the HeaderItems IntPtr hwndHeader = ListViewGetHeader (_hwnd); if (hwndHeader != IntPtr.Zero && SafeNativeMethods.IsWindowVisible (hwndHeader)) { WindowsSysHeader header = (WindowsSysHeader) WindowsSysHeader.Create (hwndHeader, 0); WinEventTracker.EvtIdProperty[] aEvents = new WinEventTracker.EvtIdProperty[] { new WinEventTracker.EvtIdProperty(NativeMethods.EventObjectCreate, TablePattern.ColumnHeadersProperty) }; WinEventTracker.RemoveToNotificationList (hwndHeader, aEvents, header._createOnEvent, 1); } } } } if (eventId == InvokePattern.InvokedEvent) { WinEventTracker.EvtIdProperty[] aEvents = new WinEventTracker.EvtIdProperty[] { new WinEventTracker.EvtIdProperty(NativeMethods.EventObjectSelection, eventId) }; WinEventTracker.AddToNotificationList(_hwnd, _createOnEvent, aEvents, 1); } base.AdviseEventRemoved(eventId, aidProps); }
// Return an array that contains combo's edit portion specific events // These events will be remapped as combo box events private static void CreateEditPortionEvents (out WinEventTracker.EvtIdProperty [] editPortionEvents, out int counter, AutomationProperty [] aidProps) { // count how many events to pass back for the edit part of combo int c = 0; foreach ( AutomationProperty p in aidProps ) { if ( p == ValuePattern.ValueProperty || p == ValuePattern.IsReadOnlyProperty ) { c++; } } if (c == 0) { editPortionEvents = null; counter = 0; return; } // allocate array with the number of events from above editPortionEvents = new WinEventTracker.EvtIdProperty[c]; c = 0; foreach ( AutomationProperty p in aidProps ) { if ( p == ValuePattern.ValueProperty || p == ValuePattern.IsReadOnlyProperty ) { editPortionEvents[c]._idProp = p; editPortionEvents[c]._evtId = (p == ValuePattern.ValueProperty) ? NativeMethods.EventObjectValueChange : NativeMethods.EventObjectStateChange; c++; } } counter = c; }