// Sets the text of the edit part of the Combo void IValueProvider.SetValue(string str) { // Ensure that the window and all its parents are enabled. Misc.CheckEnabled(_hwnd); // piggy-back on win32editbox proxy NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (GetComboInfo(_hwnd, ref cbInfo) && SafeNativeMethods.IsWindowVisible(cbInfo.hwndItem)) { WindowsEditBox editBox = new WindowsEditBox(cbInfo.hwndItem, null, -1); IValueProvider valueProvider = (IValueProvider)editBox.GetPatternProvider(ValuePattern.Pattern); // try to set user-provided text valueProvider.SetValue(str); // Let the parent know that the value has change, to allow the parent to do any processing it needs // to do on value change. IntPtr hwndParent = Misc.GetParent(_hwnd); if (hwndParent != IntPtr.Zero) { int id = Misc.GetWindowId(_hwnd); IntPtr wParam = new IntPtr(NativeMethods.Util.MAKELONG(id, NativeMethods.CBN_EDITUPDATE)); Misc.ProxySendMessage(hwndParent, NativeMethods.WM_COMMAND, wParam, _hwnd); } return; } throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); }
// 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); } }
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); } }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint(int x, int y) { NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (GetComboInfo(_hwnd, ref cbInfo)) { // check for button if (Misc.MapWindowPoints(_hwnd, IntPtr.Zero, ref cbInfo.rcButton, 2)) { if (Misc.PtInRect(ref cbInfo.rcButton, x, y)) { return(new WindowsComboButton(_hwnd, this, (int)ComboChildren.Button)); } } // check for list if (SafeNativeMethods.IsWindowVisible(cbInfo.hwndList)) { NativeMethods.Win32Rect rcList = NativeMethods.Win32Rect.Empty; if (Misc.GetWindowRect(cbInfo.hwndList, ref rcList) && Misc.PtInRect(ref rcList, x, y)) { ProxySimple el = CreateListBox(cbInfo.hwndList); return(((WindowsListBox)el).ElementProviderFromPoint(x, y)); } } } return(this); }
// create list portion of combo box private ProxySimple CreateListBox() { NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (GetComboInfo(_hwnd, ref cbInfo) && (IntPtr.Zero != cbInfo.hwndList)) { return(new WindowsListBox(cbInfo.hwndList, this, (int)ComboChildren.List, true)); } return(null); }
protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); var info = new NativeMethods.COMBOBOXINFO(); info.cbSize = Marshal.SizeOf(info); NativeMethods.GetComboBoxInfo(this.Handle, ref info); listBoxHelper = new NativeMethods.ListBoxHelper(info.hwndList); }
private void Control_HandleCreated(object sender, EventArgs e) { base.OnVisibleChanged(e); var info = new NativeMethods.COMBOBOXINFO(); info.cbSize = Marshal.SizeOf(info); NativeMethods.GetComboBoxInfo(this.Control.Handle, ref info); listBoxHelper = new NativeMethods.ListBoxHelper(info.hwndList); }
// create combo button private ProxySimple CreateComboButton() { NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (GetComboInfo(_hwnd, ref cbInfo) && cbInfo.stateButton != NativeMethods.STATE_SYSTEM_INVISIBLE) { return(new WindowsComboButton(_hwnd, this, (int)ComboChildren.Button)); } return(null); }
public static void SetCueBanner(ToolStripComboBox tb, string strText) { try { NativeMethods.COMBOBOXINFO cbi = new NativeMethods.COMBOBOXINFO(); cbi.cbSize = Marshal.SizeOf(cbi); NativeMethods.GetComboBoxInfo(tb.ComboBox.Handle, ref cbi); SetCueBanner(cbi.hwndEdit, strText); } catch (Exception) { Debug.Assert(false); } }
// expand the list portion static internal void Expand(IntPtr hwnd) { IntPtr hwndFocused = Misc.GetFocusedWindow(); NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); GetComboInfo(hwnd, ref cbInfo); // if the combobox does not already have focus, set the focus. if (hwndFocused != hwnd && hwndFocused != cbInfo.hwndCombo && hwndFocused != cbInfo.hwndItem && hwndFocused != cbInfo.hwndList) { Misc.SetFocus(hwnd); } Misc.ProxySendMessage(hwnd, NativeMethods.CB_SHOWDROPDOWN, new IntPtr(1), IntPtr.Zero); }
internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild) { bool parentedByCombo = false; ProxyFragment parent = null; int item = 0; try { int style = Misc.GetWindowStyle(hwnd); // If can not get windows style the hwnd is bad so do not create a proxy for it. if (style == 0) { return(null); } if (Misc.IsBitSet(style, NativeMethods.LBS_COMBOBOX)) { // List portion of combo box NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (WindowsComboBox.GetComboInfo(hwnd, ref cbInfo) && (cbInfo.hwndCombo != IntPtr.Zero)) { parent = (ProxyFragment)WindowsComboBox.Create(cbInfo.hwndCombo, 0); parentedByCombo = true; item = (int)WindowsComboBox.ComboChildren.List; } } } catch (ElementNotAvailableException) { return(null); } WindowsListBox listbox = new WindowsListBox(hwnd, parent, item, parentedByCombo); if (idChild == 0) { return(listbox); } else { return(listbox.CreateListboxItem(idChild - 1)); } }
private bool IsInsideOfCombo() { IntPtr hwndParent = NativeMethodsSetLastError.GetAncestor(_hwnd, NativeMethods.GA_PARENT); if (hwndParent == IntPtr.Zero) { return(false); } // Test for combo NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (WindowsComboBox.GetComboInfo(hwndParent, ref cbInfo) && cbInfo.hwndItem == _hwnd) { return(true); } return(false); }
// Wrapper on top of Win32's GetComboInfo static internal bool GetComboInfo(IntPtr hwnd, ref NativeMethods.COMBOBOXINFO cbInfo) { bool result = Misc.GetComboBoxInfo(hwnd, ref cbInfo); if (result) { // some combo boxes do not have an edit portion // instead they return combo hwnd in the item // to make our life easier set hwndItem to IntPtr.Zero if (cbInfo.hwndItem == cbInfo.hwndCombo) { cbInfo.hwndItem = IntPtr.Zero; } // Possible that Combo is hosted by ComboboxEx32 // hence GetComboBoxInfo did not provide us with edit. // We should try to detect it ourselves if (cbInfo.hwndItem == IntPtr.Zero && IsComboEx(NativeMethodsSetLastError.GetAncestor(hwnd, NativeMethods.GA_PARENT))) { cbInfo.hwndItem = Misc.FindWindowEx(hwnd, IntPtr.Zero, "EDIT", null); if (cbInfo.hwndItem != IntPtr.Zero) { result = Misc.GetWindowRect(cbInfo.hwndItem, ref cbInfo.rcItem); if (result) { result = Misc.MapWindowPoints(_hwndDesktop, hwnd, ref cbInfo.rcItem, 2); } if (!result) { cbInfo.rcItem = NativeMethods.Win32Rect.Empty; } } } } return(result); }
internal override void AdviseEventRemoved(AutomationEvent eventId, AutomationProperty [] aidProps) { // remove combo-related events base.AdviseEventRemoved(eventId, aidProps); NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (GetComboInfo(_hwnd, ref cbInfo)) { // remove edit and list specific events that got remapped into combo's events if (eventId == AutomationElement.AutomationPropertyChangedEvent) { // ComboBoxEx32 controls with the style CBS_DROPDOWNLIST are still editable. if (cbInfo.hwndItem != IntPtr.Zero && IsEditableCombo()) { // un-subscribe from edit-specific notifications // ValueAsString, ValueAsObject, IsReadOnly // create array containing events from which user wants to unsubscribe WinEventTracker.EvtIdProperty [] editPortionEvents; int counter; CreateEditPortionEvents(out editPortionEvents, out counter, aidProps); if (counter > 0) { WinEventTracker.RemoveToNotificationList(cbInfo.hwndItem, editPortionEvents, null, counter); } } } // Need to also remove the advise from the list portions of the combobox. if (cbInfo.hwndList != IntPtr.Zero) { WindowsListBox listbox = new WindowsListBox(cbInfo.hwndList, this, 0, true); listbox.AdviseEventRemoved(eventId, aidProps); } } }
// override the default implementation so we can handle the WinEvents that are send to the edit // portion of ComboBox (Combo proxy will hide edit portion from the user, but will take care of all // the features/functionality that Edit presents) and some(show, hide) events that are send to the List portion of combo // In both cases this events will be presented to the user as Combo's LE events internal override void AdviseEventAdded(AutomationEvent eventId, AutomationProperty [] aidProps) { // call the base class implementation first to add combo-specific things and register combo specific callback base.AdviseEventAdded(eventId, aidProps); NativeMethods.COMBOBOXINFO cbInfo = new NativeMethods.COMBOBOXINFO(NativeMethods.comboboxInfoSize); if (GetComboInfo(_hwnd, ref cbInfo)) { if (eventId == AutomationElement.AutomationPropertyChangedEvent) { // ComboBoxEx32 controls with the style CBS_DROPDOWNLIST are still editable. if (cbInfo.hwndItem != IntPtr.Zero && IsEditableCombo()) { // subscribe to edit-specific notifications, that would be presented as combo le event // ValueAsString, ValueAsObject, IsReadOnly // create array containing events that user is interested in WinEventTracker.EvtIdProperty [] editPortionEvents; int counter; CreateEditPortionEvents(out editPortionEvents, out counter, aidProps); if (counter > 0) { WinEventTracker.AddToNotificationList(cbInfo.hwndItem, new WinEventTracker.ProxyRaiseEvents(EditPortionEvents), editPortionEvents, counter); } } } // Need to also advise the list portions of the combobox so that it can raise events. if (cbInfo.hwndList != IntPtr.Zero) { WindowsListBox listbox = new WindowsListBox(cbInfo.hwndList, this, 0, true); listbox.AdviseEventAdded(eventId, aidProps); } } }
internal static extern bool GetComboBoxInfo(IntPtr hwnd, [In, Out] ref NativeMethods.COMBOBOXINFO cbInfo);