// Static Create method called by UIAutomation to create a Button proxy for [....] Buttons. // returns null if unsuccessful internal static IRawElementProviderSimple CreateButton(IntPtr hwnd) { // Currently there is an issue with CLR remoting that causes Accessible.CreateNativeFromEvent() to fail // for [....] controls. Until that is resolved use AccessibleObjectFromWindow() instead. It will // return a Native IAccessble and not a OleAcc implementaion. [....] does provide a Native IAccessible. Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) != NativeMethods.S_OK || acc == null) { return(null); } switch (acc.Role) { case AccessibleRole.CheckButton: return(new WindowsButton(hwnd, null, WindowsButton.ButtonType.CheckBox, Misc.GetWindowStyle(hwnd) & NativeMethods.BS_TYPEMASK, acc)); case AccessibleRole.Grouping: return(new WindowsButton(hwnd, null, WindowsButton.ButtonType.GroupBox, Misc.GetWindowStyle(hwnd) & NativeMethods.BS_TYPEMASK, acc)); case AccessibleRole.PushButton: return(new WindowsButton(hwnd, null, WindowsButton.ButtonType.PushButton, Misc.GetWindowStyle(hwnd) & NativeMethods.BS_TYPEMASK, acc)); case AccessibleRole.RadioButton: return(new WindowsButton(hwnd, null, WindowsButton.ButtonType.RadioButton, Misc.GetWindowStyle(hwnd) & NativeMethods.BS_TYPEMASK, acc)); default: break; } return(null); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // Retrieves the bounding rectangle of the Status Bar Pane. static internal Rect GetBoundingRectangle(IntPtr hwnd, int item) { if (!WindowsFormsHelper.IsWindowsFormsControl(hwnd)) { return(XSendMessage.GetItemRect(hwnd, NativeMethods.SB_GETRECT, item)); } else { Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) != NativeMethods.S_OK || acc == null) { return(Rect.Empty); } else { // OLEACC's Win32 proxy does use a 1, 2, 3... scheme, but the [....] // controls in some cases supply their own children, using a different scheme. // Using the "ByIndex" approach avoids having to know what the underlying // object's idChild scheme is. acc = Accessible.GetFullAccessibleChildByIndex(acc, item); if (acc == null) { return(Rect.Empty); } else { return(acc.Location); } } } }
// Method that verifies if window or one of its intermediate children (in terms of IAccessible tree) is a Spinner internal static bool IsWinformUpdown(IntPtr hwnd) { Accessible acc = null; int hr = Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc); // Verify the role return(hr == NativeMethods.S_OK && acc != null ? acc.Role == AccessibleRole.SpinButton : false); }
// ------------------------------------------------------ // // Private Methods // // ------------------------------------------------------ #region Private Methods private static bool IsLinkLabel(IntPtr hwnd) { // [Microsoft]: // could be a label or a linklabel // we differentiate based on whether the item has children or not Accessible acc = null; return(Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) == NativeMethods.S_OK && acc != null && acc.ChildCount > 0); }
private static IRawElementProviderSimple Create(IntPtr hwnd, int idChild) { // Get Accessible Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) != NativeMethods.S_OK) { acc = null; } return(new SuperGridProvider(hwnd, null, acc)); }
// Static Create method called by UIAutomation to create proxies for [....] controls. // returns null if unsuccessful internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild, int idObject) { // Currently there is an issue with CLR remoting that causes Accessible.CreateNativeFromEvent() to fail // for [....] controls. Until that is resolved use AccessibleObjectFromWindow() instead. It will // return a Native IAccessble and not a OleAcc implementaion. [....] does provide a Native IAccessible. Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, idObject, ref acc) != NativeMethods.S_OK || acc == null) { return(null); } switch (acc.Role) { // ============================================================ // WinformsSpinner controls are not identifiable by classname or // other simple properties. The following case calls the // WinformsSpinner constructor which in turn tries to establish // the class of the control as a fact or returns null. case AccessibleRole.Combobox: return(WinformsSpinner.Create(hwnd, idChild, idObject)); // ============================================================ case AccessibleRole.SpinButton: return(WindowsUpDown.Create(hwnd, idChild, idObject)); case AccessibleRole.Grouping: return(new WindowsButton(hwnd, null, WindowsButton.ButtonType.GroupBox, Misc.GetWindowStyle(hwnd) & NativeMethods.BS_TYPEMASK, acc)); case AccessibleRole.StatusBar: WindowsStatusBar sb = new WindowsStatusBar(hwnd, null, 0, acc); if (sb == null) { return(null); } return(idChild == NativeMethods.CHILD_SELF ? sb : sb.CreateStatusBarPane(idChild)); default: break; } return(null); }
unsafe private bool FindRadioButtonChild(IntPtr hwnd, void *lParam) { // Only be concerned with [....] child controls. if (!WindowsFormsHelper.IsWindowsFormsControl(hwnd)) { return(true); } Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) == NativeMethods.S_OK && acc != null && acc.Role == AccessibleRole.RadioButton) { *(bool *)lParam = true; return(false); } return(true); }
private unsafe bool FindSelectedRadioButtonChild(IntPtr hwnd, void *lParam) { // Only be concerned with Winforms child controls. if (!WindowsFormsHelper.IsWindowsFormsControl(hwnd)) { return(true); } Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) == NativeMethods.S_OK && acc != null && acc.Role == AccessibleRole.RadioButton && acc.HasState(AccessibleState.Checked)) { *(IntPtr *)lParam = hwnd; return(false); } return(true); }
// Returns an enumerator over the current selection. IRawElementProviderSimple[] ISelectionProvider.GetSelection() { IRawElementProviderSimple[] selection = null; Accessible accRadioButton = null; IntPtr hwndRadioButton = GetSelection(); if (hwndRadioButton == IntPtr.Zero || Accessible.AccessibleObjectFromWindow(hwndRadioButton, NativeMethods.OBJID_CLIENT, ref accRadioButton) != NativeMethods.S_OK || accRadioButton == null) { // framework will handle this one correctly return(null); } else { selection = new IRawElementProviderSimple[] { new WindowsButton(hwndRadioButton, null, ButtonType.RadioButton, Misc.GetWindowStyle(hwndRadioButton) & NativeMethods.BS_TYPEMASK, accRadioButton) }; } return(selection); }
internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild) { // If idChild is not zero this can't be a [....] spinner. The way this // code is called, the passed in hwnd could be some other control and in // that case the calling code should continue looking for a valid proxy. if (idChild != 0) { return(null); } try { // // A winform spinner control can only have 2 children - An Edit and an UpDown. // // First child IntPtr hwndFirstChild = Misc.GetWindow(hwnd, NativeMethods.GW_CHILD); if (hwndFirstChild == IntPtr.Zero) { return(null); } // Last child IntPtr hwndLastChild = Misc.GetWindow(hwndFirstChild, NativeMethods.GW_HWNDLAST); if (hwndLastChild == IntPtr.Zero) { return(null); } // No children in the middle if (Misc.GetWindow(hwndFirstChild, NativeMethods.GW_HWNDNEXT) != hwndLastChild) { return(null); } // We need to positively identify the two children as Edit and UpDown controls IntPtr hwndEdit; IntPtr hwndSpin; // Find the Edit control. Typically the UpDown is first so we'll start with the other window. if (Misc.ProxyGetClassName(hwndLastChild).IndexOf("Edit", StringComparison.OrdinalIgnoreCase) != -1) { hwndEdit = hwndLastChild; hwndSpin = hwndFirstChild; } else { // Haven't seen this but suppose it's possible. Subsequent test will confirm. if (Misc.ProxyGetClassName(hwndFirstChild).IndexOf("Edit", StringComparison.OrdinalIgnoreCase) != -1) { hwndEdit = hwndFirstChild; hwndSpin = hwndLastChild; } else { // Must contain an Edit/UpDown control pair return(null); } } // // A winform UpDown control can only have 2 children, both spin buttons. // // Use IAccessible implementation to confirm the spinner & children Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwndSpin, NativeMethods.OBJID_CLIENT, ref acc) != NativeMethods.S_OK || acc == null) { return(null); } if ((acc.Role != AccessibleRole.SpinButton) || (acc.ChildCount != 2)) { return(null); } // Confirmed spinner return(new WinformsSpinner(hwnd, hwndEdit, hwndSpin, null, 0)); } catch (ElementNotAvailableException) { // Ignore ElementNotAvailableExceptions and return null return(null); } }