// Combo-specific events static private void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { // ------------------------------------------------------///////////////////////////////////// // // Depending of the type of Combobox we will get different WinEvents // // Simple: No events // // DropDown: OBJ_STATECHANGE: for the dropbutton button (idChild == 2) // NOTE: that OBJECT_STATECHANGE will only be generated when user uses button to show the list // if user uses the button to hide the list, event will not be generated // // DropDownList: OBJ_STATECHANGE (same as above) // : OBJECT_VALUECHANGE - when using the keyboard to navigate between list children // - no need to handle it here, ListBox proxy will take care of that // // ------------------------------------------------------////////////////////////////////////// ProxySimple el = null; if (idProp is AutomationProperty && idProp == ExpandCollapsePattern.ExpandCollapseStateProperty) { // expand/collapse events are handled in WindowsListBox with the ComboLBox hwnd. // so just return here so we don't fire extraneous events return; } switch (idObject) { case NativeMethods.OBJID_CLIENT: { if (eventId == NativeMethods.EventObjectStateChange && idChild == 2) { // event came for combobutton // We will be getting 2 OBJECT_STATECHANGED event // one with button state pressed and another normal // both indicate the same invoke event // hence second event is a duplicate of the first one and we need to filter it out NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (WindowsComboBox.GetComboInfo(hwnd, ref cbInfo) && Misc.IsBitSet(NativeMethods.STATE_SYSTEM_PRESSED, cbInfo.stateButton)) { // The event could be for both the button and the combo WindowsComboBox cb = (WindowsComboBox)Create(hwnd, 0); cb.DispatchEvents(eventId, idProp, idObject, idChild); el = cb.CreateComboButton(); el.DispatchEvents(eventId, idProp, idObject, idChild); return; } } el = (ProxySimple)Create(hwnd, 0); break; } } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }
// Static Create method called by the event tracker system internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if (idObject != NativeMethods.OBJID_VSCROLL && idObject != NativeMethods.OBJID_HSCROLL) { bool isWinforms = WindowsFormsHelper.IsWindowsFormsControl(hwnd); ProxySimple el = isWinforms ? (ProxySimple)WindowsFormsHelper.Create(hwnd, 0, idObject) : (ProxySimple)Create(hwnd, 0); if (el == null) { // WindowsFormsHelper may return null if the MSAA Role for this hwnd isn't handled return; } if (idChild > 0) { if (eventId == NativeMethods.EventObjectNameChange && idChild == 1) { // Need to let the overall control process this event also. el.DispatchEvents(eventId, idProp, idObject, idChild); } el = ((WindowsStatusBar)el).CreateStatusBarPane(idChild - 1); } el.DispatchEvents(eventId, idProp, idObject, idChild); } }
private static void RaiseEventsOnWindow(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { AutomationProperty automationProperty = idProp as AutomationProperty; ProxySimple el = null; if ((eventId == NativeMethods.EventObjectShow || eventId == NativeMethods.EventObjectHide) && (automationProperty != null && automationProperty == ExpandCollapsePattern.ExpandCollapseStateProperty)) { if (Misc.IsBitSet(Misc.GetWindowStyle(hwnd), NativeMethods.LBS_COMBOBOX)) { // List portion of combo: We'll hit it in the case when user hovers over it NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (WindowsComboBox.GetComboInfo(hwnd, ref cbInfo) && (cbInfo.hwndCombo != IntPtr.Zero)) { WindowsComboBox cb = (WindowsComboBox)WindowsComboBox.Create(cbInfo.hwndCombo, 0); if (!cb.IsSimpleCombo()) { el = cb; } } } } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }
// Static Create method called by the event tracker system // WinEvents are one throwns because items exist. so it makes sense to create the item and // check for details afterward. internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { // NOTE: List may be a portion of the Combobox // Use WindowsListBox.Create in order to set-up a correct parenthood chain switch (idObject) { case NativeMethods.OBJID_WINDOW: RaiseEventsOnWindow(hwnd, eventId, idProp, idObject, idChild); break; case NativeMethods.OBJID_CLIENT: RaiseEventsOnClient(hwnd, eventId, idProp, idObject, idChild); break; case NativeMethods.OBJID_VSCROLL: case NativeMethods.OBJID_HSCROLL: break; default: ProxySimple el = (ProxyHwnd)WindowsListBox.Create(hwnd, 0); if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } break; } }
// Static create method called by the event tracker system. // WinEvents are raised only when a notification has been set for a // specific item. Create the item first and check for details afterward. internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { WindowsScrollBar wtv = new WindowsScrollBar(hwnd, null, -1, NativeMethods.SB_CTL); if (idChild == 0 && eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { // UIA works differently than MSAA. Events are set for elements rather than hwnd // Scroll bar are processed the same way whatever they are part of the non client area // or stand alone hwnd. OBJID_HSCROLL and OBJID_VSCROLL are mapped to OBJID_WINDOW // so they behave the same for NC and hwnd SB. // Parameters are setup so that the dispatch will send the proper notification and // recursively will send notifications to all of the children if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } } if (idChild == 0) { wtv.DispatchEvents(eventId, idProp, idObject, idChild); } else { // raise events for the children ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, wtv, idChild, NativeMethods.SB_CTL); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } }
private static void RaiseMenuEventsOnClient(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { ProxySimple el = WindowsMenu.CreateMenuItemFromEvent(hwnd, eventId, idChild, idObject); if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }
// Static Create method called by the event tracker system internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if (idObject != NativeMethods.OBJID_VSCROLL && idObject != NativeMethods.OBJID_HSCROLL) { ProxySimple el = (ProxyHwnd)WindowsAltTab.Create(hwnd, 0); if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } } }
private static void RaiseEventsOnClient(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if (Misc.GetClassName(hwnd) == "ComboLBox") { ProxySimple el = (ProxySimple)WindowsListBox.Create(hwnd, idChild); if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } } }
// Handles combo's edit portion specific events // as combo-specific events private static void EditPortionEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { // Get hwnd of the combo-box IntPtr hwndCombo = NativeMethodsSetLastError.GetAncestor(hwnd, NativeMethods.GA_PARENT); if (hwndCombo != IntPtr.Zero) { ProxySimple el = (ProxySimple)Create(hwndCombo, 0); el.DispatchEvents(eventId, idProp, idObject, idChild); } }
private static void RaiseInvokedEvent(IntPtr hwnd, int idObject, int idChild) { ProxySimple button = null; if (idChild == 1) { WindowsUpDown wtv = new WindowsUpDown(hwnd, null, -1); button = wtv.CreateSpinButtonItem(SpinItem.DownArrow); } else if (idChild == 2) { WindowsUpDown wtv = new WindowsUpDown(hwnd, null, -1); button = wtv.CreateSpinButtonItem(SpinItem.UpArrow); } if (button != null) { button.DispatchEvents(NativeMethods.EventObjectInvoke, InvokePattern.InvokedEvent, idObject, idChild); } }
// Static Create method called by the event tracker system internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if (idObject == NativeMethods.OBJID_VSCROLL || idObject == NativeMethods.OBJID_HSCROLL) { return; } // ChildId will be non-0 if the event is due to operating on the updown part of the spinner. // Events on non-content parts of a control are not necessary so don't raise an event in that case. if (idChild != 0) { return; } ProxySimple ps = (ProxySimple)Create(hwnd, idChild, idObject); if (ps == null) { return; } ps.DispatchEvents(eventId, idProp, idObject, idChild); }
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 static void RaiseEventsOnScroll(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if ((idProp == ScrollPattern.VerticalScrollPercentProperty && idObject != NativeMethods.OBJID_VSCROLL) || (idProp == ScrollPattern.HorizontalScrollPercentProperty && idObject != NativeMethods.OBJID_HSCROLL)) { return; } ProxyFragment el = new NonClientArea(hwnd); if (el == null) { return; } if (idProp == InvokePattern.InvokedEvent) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; int sbFlag = idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; ProxyFragment scrollBar = new WindowsScrollBar(hwnd, el, (int)item, sbFlag); if (scrollBar != null) { ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, scrollBar, idChild, sbFlag); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } return; } if (eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { if (idChild == 0) { // if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } el.DispatchEvents(eventId, idProp, idObject, idChild); } return; } if (idProp == ValuePattern.ValueProperty && eventId == NativeMethods.EVENT_OBJECT_VALUECHANGE) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; WindowsScrollBar scrollBar = new WindowsScrollBar(hwnd, el, (int)item, idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT); scrollBar.DispatchEvents(0, ValuePattern.ValueProperty, NativeMethods.OBJID_CLIENT, 0); return; } if (Misc.GetClassName(hwnd) == "ComboLBox") { el = (ProxyFragment)WindowsListBox.Create(hwnd, 0); } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }
private static void RaiseEventsOnScroll(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { if ((idProp == ScrollPattern.VerticalScrollPercentProperty && idObject != NativeMethods.OBJID_VSCROLL) || (idProp == ScrollPattern.HorizontalScrollPercentProperty && idObject != NativeMethods.OBJID_HSCROLL)) { return; } ProxyFragment el = new NonClientArea(hwnd); if (el == null) { return; } if (idProp == InvokePattern.InvokedEvent) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; int sbFlag = idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT; ProxyFragment scrollBar = new WindowsScrollBar(hwnd, el, (int)item, sbFlag); if (scrollBar != null) { ProxySimple scrollBarBit = WindowsScrollBarBits.CreateFromChildId(hwnd, scrollBar, idChild, sbFlag); if (scrollBarBit != null) { scrollBarBit.DispatchEvents(eventId, idProp, idObject, idChild); } } return; } if (eventId == NativeMethods.EventObjectStateChange && idProp == ValuePattern.IsReadOnlyProperty) { if (idChild == 0) { // This code is never exercised. The code in User needs to change to send // EventObjectStateChange with a client ID of zero // // UIA works differently than MSAA. Events are set for elements rather than hwnd // Scroll bar are processed the same way whatever they are part of the non client area // or stand alone hwnd. OBJID_HSCROLL and OBJID_VSCROLL are mapped to OBJID_WINDOW // so they behave the same for NC and hwnd SB. // Parameters are setup so that the dispatch will send the proper notification and // recursively will send notifications to all of the children if (idObject == NativeMethods.OBJID_HSCROLL || idObject == NativeMethods.OBJID_VSCROLL) { idObject = NativeMethods.OBJID_WINDOW; } el.DispatchEvents(eventId, idProp, idObject, idChild); } return; } if (idProp == ValuePattern.ValueProperty && eventId == NativeMethods.EVENT_OBJECT_VALUECHANGE) { NonClientItem item = idObject == NativeMethods.OBJID_HSCROLL ? NonClientItem.HScrollBar : NonClientItem.VScrollBar; WindowsScrollBar scrollBar = new WindowsScrollBar(hwnd, el, (int)item, idObject == NativeMethods.OBJID_HSCROLL ? NativeMethods.SB_HORZ : NativeMethods.SB_VERT); scrollBar.DispatchEvents(0, ValuePattern.ValueProperty, NativeMethods.OBJID_CLIENT, 0); return; } if (Misc.GetClassName(hwnd) == "ComboLBox") { el = (ProxyFragment)WindowsListBox.Create(hwnd, 0); } if (el != null) { el.DispatchEvents(eventId, idProp, idObject, idChild); } }