Пример #1
0
        // 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);
            }
        }
Пример #2
0
            //------------------------------------------------------
            //
            //  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);
                        }
                    }
                }
            }
Пример #3
0
        internal static IRawElementProviderSimple Create(IntPtr hwnd, int idChild)
        {
            if (!UnsafeNativeMethods.IsWindow(hwnd))
            {
                return(null);
            }

            System.Diagnostics.Debug.Assert(idChild == 0, string.Format(CultureInfo.CurrentCulture, "Invalid Child Id, idChild == {2}\n\rClassName: \"{0}\"\n\rhwnd = 0x{1:x8}", Misc.ProxyGetClassName(hwnd), hwnd.ToInt32(), idChild));

            NativeMethods.Win32Rect clientRect = new NativeMethods.Win32Rect();
            NativeMethods.Win32Rect windowRect = new NativeMethods.Win32Rect();

            try
            {
                bool hasNonClientControls =
                    // Note: GetClientRect will do MapWindowsPoints
                    Misc.GetClientRectInScreenCoordinates(hwnd, ref clientRect) &&
                    Misc.GetWindowRect(hwnd, ref windowRect) &&
                    !windowRect.Equals(clientRect);

                if (hasNonClientControls || WindowsFormsHelper.IsWindowsFormsControl(hwnd))
                {
                    return(new NonClientArea(hwnd));
                }
                return(null);
            }
            catch (ElementNotAvailableException)
            {
                return(null);
            }
        }
Пример #4
0
 private bool IsWinFormCheckedListBox()
 {
     if (WindowsFormsHelper.IsWindowsFormsControl(_hwnd))
     {
         return(((WindowStyle & NativeMethods.LBS_OWNERDRAWFIXED) == NativeMethods.LBS_OWNERDRAWFIXED) &&
                ((WindowStyle & NativeMethods.LBS_WANTKEYBOARDINPUT) == NativeMethods.LBS_WANTKEYBOARDINPUT));
     }
     return(false);
 }
Пример #5
0
        private static IRawElementProviderSimple Create(IntPtr hwnd, int idChild)
        {
            // Something is wrong if idChild is not zero
            if (idChild != 0)
            {
                System.Diagnostics.Debug.Assert(idChild == 0, "Invalid Child Id, idChild != 0");
                throw new ArgumentOutOfRangeException("idChild", idChild, SR.Get(SRID.ShouldBeZero));
            }

            ButtonType type;
            int        style;

            try
            {
                if (WindowsFormsHelper.IsWindowsFormsControl(hwnd))
                {
                    return(WindowsFormsHelper.CreateButton(hwnd));
                }

                style = Misc.GetWindowStyle(hwnd) & NativeMethods.BS_TYPEMASK;

                switch (style)
                {
                case NativeMethods.BS_PUSHBUTTON:
                case NativeMethods.BS_DEFPUSHBUTTON:
                case NativeMethods.BS_OWNERDRAW:
                case NativeMethods.BS_SPLITBUTTON:     // explore back and forward buttons
                    type = ButtonType.PushButton;
                    break;

                case NativeMethods.BS_CHECKBOX:
                case NativeMethods.BS_AUTOCHECKBOX:
                case NativeMethods.BS_3STATE:
                case NativeMethods.BS_AUTO3STATE:
                    type = ButtonType.CheckBox;
                    break;

                case NativeMethods.BS_RADIOBUTTON:
                case NativeMethods.BS_AUTORADIOBUTTON:
                    type = ButtonType.RadioButton;
                    break;

                case NativeMethods.BS_GROUPBOX:
                    type = ButtonType.GroupBox;
                    break;

                default:
                    return(null);
                }
            }
            catch (ElementNotAvailableException)
            {
                return(null);
            }

            return(new WindowsButton(hwnd, null, type, style, null));
        }
Пример #6
0
        unsafe private bool ContainsRadioButtons()
        {
            bool radiobuttonChildFound = false;

            // WinForm GroupBoxes have a parent/child relationship.  Win32 GroupBoxes do not.
            if (WindowsFormsHelper.IsWindowsFormsControl(_hwnd, ref _windowsForms))
            {
                Misc.EnumChildWindows(_hwnd, new NativeMethods.EnumChildrenCallbackVoid(FindRadioButtonChild), (void *)&radiobuttonChildFound);
            }
            return(radiobuttonChildFound);
        }
Пример #7
0
        private unsafe IntPtr GetSelection()
        {
            // WinForm GroupBoxes have a parent/child relationship.  Win32 GroupBoxes do not.
            if (WindowsFormsHelper.IsWindowsFormsControl(_hwnd, ref _windowsForms))
            {
                IntPtr selectedRadiobutton = new IntPtr(0);
                Misc.EnumChildWindows(_hwnd, new NativeMethods.EnumChildrenCallbackVoid(FindSelectedRadioButtonChild), (void *)&selectedRadiobutton);
                return(selectedRadiobutton);
            }

            return(IntPtr.Zero);
        }
Пример #8
0
        internal override object GetElementProperty(AutomationProperty idProp)
        {
            if (idProp == AutomationElement.IsControlElementProperty)
            {
                // Hide spin portion in the logical tree
                // in the case when it is embedded inside of a Microsoft spinner
                if (WindowsFormsHelper.IsWindowsFormsControl(_hwnd) && IsWinformUpdown(_hwnd))
                {
                    return(false);
                }
            }

            return(base.GetElementProperty(idProp));
        }
Пример #9
0
        private static IRawElementProviderSimple Create(IntPtr hwnd, int idChild)
        {
            // This proxy should not be created with idChild != 0,
            // unless it is a link label.
            if (idChild != 0 && !IsLinkLabel(hwnd))
            {
                System.Diagnostics.Debug.Assert(idChild == 0, "Invalid Child Id, idChild != 0");
                throw new ArgumentOutOfRangeException("idChild", idChild, SR.Get(SRID.ShouldBeZero));
            }

            StaticType type;
            int        style;

            try
            {
                string className = Misc.GetClassName(hwnd).ToLower(System.Globalization.CultureInfo.InvariantCulture);

                // Both labels and linklabels have "STATIC" class names
                if (WindowsFormsHelper.IsWindowsFormsControl(className))
                {
                    if (IsLinkLabel(hwnd))
                    {
                        // Use a different proxy for LinkLabel.
                        return(FormsLink.Create(hwnd, 0));
                    }
                }
                else
                {
                    // if it's not a Windows Forms control, we didn't want substring matching
                    if (className != "static")
                    {
                        return(null);
                    }
                }

                style = Misc.GetWindowStyle(hwnd) & NativeMethods.SS_TYPEMASK;
                type  = GetStaticTypeFromStyle(style);
                if (type == StaticType.Unsupported)
                {
                    return(null);
                }
            }
            catch (ElementNotAvailableException)
            {
                return(null);
            }

            return(new WindowsStatic(hwnd, null, type, style));
        }
        // Sets the text of the edit.
        void IValueProvider.SetValue(string str)
        {
            // Check if the window is disabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            if (Misc.IsBitSet(WindowStyle, NativeMethods.ES_READONLY))
            {
                throw new InvalidOperationException(SR.Get(SRID.ValueReadonly));
            }

            // check if control only accepts numbers
            if (Misc.IsBitSet(WindowStyle, NativeMethods.ES_NUMBER) && !WindowsFormsHelper.IsWindowsFormsControl(_hwnd))
            {
                // check if string contains any non-numeric characters.
                foreach (char ch in str)
                {
                    if (char.IsLetter(ch))
                    {
                        throw new ArgumentException(SR.Get(SRID.NotAValidValue, str), "val");
                    }
                }
            }

            // Text/edit box should not enter more characters than what is allowed through keyboard.
            // Determine the max number of chars this editbox accepts

            int result = Misc.ProxySendMessageInt(_hwnd, NativeMethods.EM_GETLIMITTEXT, IntPtr.Zero, IntPtr.Zero);

            if (result < str.Length)
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            // Send the message...
            result = Misc.ProxySendMessageInt(_hwnd, NativeMethods.WM_SETTEXT, IntPtr.Zero, new StringBuilder(str));
            if (result != 1)
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
        }
Пример #11
0
        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);
        }
Пример #13
0
        // Process all the Logical and Raw Element Properties
        internal override object GetElementProperty(AutomationProperty idProp)
        {
            if (idProp == AutomationElement.AccessKeyProperty)
            {
                // Special handling for forms
                if (!WindowsFormsHelper.IsWindowsFormsControl(_hwnd, ref _windowsForms) && IsStartButton())
                {
                    // Hard coded shortcut for the start button
                    return(ST.Get(STID.KeyCtrl) + " + " + ST.Get(STID.KeyEsc));
                }
                return(Misc.AccessKey(Misc.ProxyGetText(_hwnd)));
            }
            else if (idProp == AutomationElement.IsEnabledProperty)
            {
                if (InShellTray())
                {
                    return(SafeNativeMethods.IsWindowVisible(_hwnd));
                }
            }

            return(base.GetElementProperty(idProp));
        }
Пример #14
0
        // Process all the Element Properties
        internal override object GetElementProperty(AutomationProperty idProp)
        {
            // if the hwnd is a winform, then return the Winform id otherwise let
            // UIAutomation do the job
            if (idProp == AutomationElement.AutomationIdProperty)
            {
                // Winforms have a special way to obtain the id
                if (WindowsFormsHelper.IsWindowsFormsControl(_hwnd, ref _windowsForms))
                {
                    string sPersistentID = WindowsFormsHelper.WindowsFormsID(_hwnd);
                    return(string.IsNullOrEmpty(sPersistentID) ? null : sPersistentID);
                }
            }
            else if (idProp == AutomationElement.NameProperty)
            {
                string name;
                // If this is a winforms control and the AccessibleName is set, use it.
                if (WindowsFormsHelper.IsWindowsFormsControl(_hwnd, ref _windowsForms))
                {
                    name = GetAccessibleName(NativeMethods.CHILD_SELF);

                    if (!string.IsNullOrEmpty(name))
                    {
                        return(name);
                    }
                }

                // Only hwnd's can be labeled.
                name = LocalizedName;

                // PerSharp/PreFast will flag this as a warning 6507/56507: Prefer 'string.IsNullOrEmpty(name)' over checks for null and/or emptiness.
                // It is valid to set LocalizedName to an empty string.  LocalizedName being an
                // empty string will prevent the SendMessage(WM_GETTEXT) call.
#pragma warning suppress 6507
                if (name == null && GetParent() == null)
                {
                    if (_fControlHasLabel)
                    {
                        IntPtr label = Misc.GetLabelhwnd(_hwnd);
                        name = Misc.GetControlName(label, true);
                        if (!string.IsNullOrEmpty(name))
                        {
                            _controlLabel = label;
                        }
                    }
                    else
                    {
                        name = Misc.ProxyGetText(_hwnd);
                    }
                }


                // If name is still null, and we have an IAccessible, try it:
                // this picks up names on HWNDs set through Dynamic Annotation
                // (eg. on the richedits in Windows Mail), and holds us over till
                // we add DA support to UIA properly.
                if (String.IsNullOrEmpty(name))
                {
                    name = GetAccessibleName(NativeMethods.CHILD_SELF);
                }
                return(name);
            }
            // Only hwnd's can be labeled.
            else if (idProp == AutomationElement.LabeledByProperty && _fControlHasLabel)
            {
                // This is called to make sure that _controlLabel gets set.
                object name = GetElementProperty(AutomationElement.NameProperty);

                // If a control has a LocalizedName, the _controlLabel will not get set.
                // So look for it now.
                if (_controlLabel == IntPtr.Zero && name != null && GetParent() == null)
                {
                    _controlLabel = Misc.GetLabelhwnd(_hwnd);
                }

                // If we have a cached _controlLabel that means that the name property we just got
                // was retreived from the label of the control and not its text or something else.  If this
                // is the case expose it as the label.
                if (_controlLabel != IntPtr.Zero)
                {
                    return(AutomationInteropProvider.HostProviderFromHandle(_controlLabel));
                }
            }
            else if (idProp == AutomationElement.IsOffscreenProperty)
            {
                if (!SafeNativeMethods.IsWindowVisible(_hwnd))
                {
                    return(true);
                }

                IntPtr hwndParent = Misc.GetParent(_hwnd);
                // Check if rect is within rect of parent. Don't do this for top-level windows,
                // however, since the win32 desktop hwnd claims to have a rect only as large as the
                // primary monitor, making hwnds on other monitors seem clipped.
                if (hwndParent != IntPtr.Zero && hwndParent != UnsafeNativeMethods.GetDesktopWindow())
                {
                    NativeMethods.Win32Rect parentRect = NativeMethods.Win32Rect.Empty;
                    if (Misc.GetClientRectInScreenCoordinates(hwndParent, ref parentRect) && !parentRect.IsEmpty)
                    {
                        Rect itemRect = BoundingRectangle;

                        if (!itemRect.IsEmpty && !Misc.IsItemVisible(ref parentRect, ref itemRect))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(base.GetElementProperty(idProp));
        }
        // Process all the Element Properties
        internal virtual object GetElementProperty(AutomationProperty idProp)
        {
            // we can handle some properties locally
            if (idProp == AutomationElement.LocalizedControlTypeProperty)
            {
                return(_sType);
            }
            else if (idProp == AutomationElement.ControlTypeProperty)
            {
                return(_cControlType != null ? (object)_cControlType.Id : null);
            }
            else if (idProp == AutomationElement.IsContentElementProperty)
            {
                return(_item >= 0 && _fIsContent);
            }
            else if (idProp == AutomationElement.NameProperty)
            {
                return(LocalizedName);
            }
            else if (idProp == AutomationElement.AccessKeyProperty)
            {
                return(GetAccessKey());
            }
            else if (idProp == AutomationElement.IsEnabledProperty)
            {
                return(Misc.IsEnabled(_hwnd));
            }
            else if (idProp == AutomationElement.IsKeyboardFocusableProperty)
            {
                return(IsKeyboardFocusable());
            }
            else if (idProp == AutomationElement.ProcessIdProperty)
            {
                // Get the pid of the process that the HWND lives in, not the
                // pid that this proxy lives in
                uint pid;
                Misc.GetWindowThreadProcessId(_hwnd, out pid);
                return((int)pid);
            }
            else if (idProp == AutomationElement.ClickablePointProperty)
            {
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point();

                if (GetClickablePoint(out pt, !IsHwndElement()))
                {
                    // Due to P/Invoke marshalling issues, the reurn value is in the
                    // form of a {x,y} array instead of using the Point datatype
                    return(new double[] { pt.x, pt.y });
                }

                return(AutomationElement.NotSupported);
            }
            else if (idProp == AutomationElement.HasKeyboardFocusProperty)
            {
                // Check first if the hwnd has the Focus
                // Punt if not the case, drill down otherwise
                // If already focused, leave as-is. Calling SetForegroundWindow
                // on an already focused HWND will remove focus!
                return(Misc.GetFocusedWindow() == _hwnd?IsFocused() : false);
            }
            else if (idProp == AutomationElement.AutomationIdProperty)
            {
                // PerSharp/PreFast will flag this as a warning 6507/56507: Prefer 'string.IsNullOrEmpty(_sAutomationId)' over checks for null and/or emptiness.
                // _sAutomationId being null is invalid, while being empty is a valid state.
                // The use of IsNullOrEmpty while hide this.
#pragma warning suppress 6507
                System.Diagnostics.Debug.Assert(_sAutomationId != null, "_sAutomationId is null!");
#pragma warning suppress 6507
                return(_sAutomationId.Length > 0 ? _sAutomationId : null);
            }
            else if (idProp == AutomationElement.IsOffscreenProperty)
            {
                return(IsOffscreen());
            }
            else if (idProp == AutomationElement.HelpTextProperty)
            {
                return(HelpText);
            }
            else if (idProp == AutomationElement.FrameworkIdProperty)
            {
                return(WindowsFormsHelper.IsWindowsFormsControl(_hwnd) ? "WinForm" : "Win32");
            }

            return(null);
        }