Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / UIAutomation / Win32Providers / MS / Internal / AutomationProxies / ProxyHwnd.cs / 1 / ProxyHwnd.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Base class for all the Win32 and office Controls. // // // Only true ROOT object should derive from this class // NOTE: In the case when ProxyHwnd.ElementProviderFromPoint // returns provider of type ProxyFragment we MUST do the further drilling ourselves // since UIAutomation will not (and correctly!!!) do it. (see ProxyFragment's // comments on how to implement this and WindowsListView.cs for example) // // Class ProxyHwnd: ProxyFragment, IRawElementProviderAdviseEvents // AdviseEventAdded // AdviseEventRemoved // // // // History: // 07/01/2003 : a-jeanp Created // 08/21/03: alexsn Class explanations // //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using System; using System.Text; using System.Windows; using System.Windows.Automation; using System.Windows.Automation.Provider; using System.Collections; using System.Collections.Specialized; using System.Runtime.InteropServices; using System.Globalization; using System.ComponentModel; using MS.Win32; namespace MS.Internal.AutomationProxies { #region ProxyHwnd // Base Class for all the Windows Control that handle context. // Implements the default behavior class ProxyHwnd : ProxyFragment, IRawElementProviderAdviseEvents { // ----------------------------------------------------- // // Constructors // // ----------------------------------------------------- #region Constructors internal ProxyHwnd (IntPtr hwnd, ProxyFragment parent, int item) : base (hwnd, parent, item) { } #endregion //------------------------------------------------------ // // Patterns Implementation // //----------------------------------------------------- #region ProxyHwnd Methods // ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ // Advises proxy that an event has been added. // Maps the Automation Events into WinEvents and add those to the list of WinEvents notification hooks internal virtual void AdviseEventAdded (AutomationEvent eventId, AutomationProperty [] aidProps) { // No RawElementBase creation callback, exit from here if (_createOnEvent == null) { return; } int cEvents = 0; WinEventTracker.EvtIdProperty [] aEvents; // Gets an Array of WinEvents to trap on a per window handle basis if (eventId == AutomationElement.AutomationPropertyChangedEvent) { aEvents = PropertyToWinEvent (aidProps, out cEvents); } else { aEvents = EventToWinEvent (eventId, out cEvents); } // If we have WinEvents to trap, add those to the list of WinEvent // notification list if (cEvents > 0) { WinEventTracker.AddToNotificationList (_hwnd, _createOnEvent, aEvents, cEvents); } } // Advises proxy that an event has been removed. internal virtual void AdviseEventRemoved(AutomationEvent eventId, AutomationProperty [] aidProps) { // No RawElementBase creation callback, exit from here if (_createOnEvent == null) { return; } int cEvents; WinEventTracker.EvtIdProperty [] aEvents; // Gets an Array of WinEvents to trap on a per window handle basis if (eventId == AutomationElement.AutomationPropertyChangedEvent) { aEvents = PropertyToWinEvent (aidProps, out cEvents); } else { aEvents = EventToWinEvent (eventId, out cEvents); } // If we have WinEvents to remove, remive those to the list of WinEvent // notification list if (cEvents > 0) { WinEventTracker.RemoveToNotificationList (_hwnd, aEvents, null, cEvents); } } // Returns a proxy element corresponding to the specified screen coordinates. // For an hwnd element, the default behavior is to let UIAutomation do the work. internal override ProxySimple ElementProviderFromPoint (int x, int y) { // Optimisation. If the point is within the client area return this, otherwise it could the the // non client area. It would be better to return null all the time but this will lead to // object to be created twice. return PtInClientRect (_hwnd, x, y) ? this : null; } internal override string GetAccessKey() { string accessKey = base.GetAccessKey(); if ((bool)GetElementProperty(AutomationElement.IsKeyboardFocusableProperty)) { if (string.IsNullOrEmpty(accessKey)) { accessKey = GetLabelAccessKey(_hwnd); } } return accessKey; } // 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); } // Gets the controls help text internal override string HelpText { get { int idChild = Misc.GetWindowId(_hwnd); string text = Misc.GetItemToolTipText(_hwnd, IntPtr.Zero, idChild); if (string.IsNullOrEmpty(text)) { text = Misc.GetItemToolTipText(_hwnd, IntPtr.Zero, 0); } if (string.IsNullOrEmpty(text)) { Accessible acc = Accessible.Wrap(AccessibleObject); if (acc != null) { text = acc.Description; } } return text; } } #endregion #region IRawElementProviderAdviseEvents Interface // ----------------------------------------------------- // // IRawElementProviderAdviseEvents interface implementation // // ------------------------------------------------------ // Advises event sinks that an event has been added. void IRawElementProviderAdviseEvents.AdviseEventAdded(int eventIdAsInt, int[] propertiesAsInts) { AutomationEvent eventId = AutomationEvent.LookupById(eventIdAsInt); AutomationProperty [] properties = null; if (propertiesAsInts != null) { properties = new AutomationProperty[propertiesAsInts.Length]; for (int i = 0; i < propertiesAsInts.Length; i++) { properties[i] = AutomationProperty.LookupById(propertiesAsInts[i]); } } //ProxyHwnd.AdviseEventAdded AdviseEventAdded (eventId, properties); } // Advises event sinks that an event has been removed. void IRawElementProviderAdviseEvents.AdviseEventRemoved(int eventIdAsInt, int[] propertiesAsInts) { AutomationEvent eventId = AutomationEvent.LookupById(eventIdAsInt); AutomationProperty [] properties = null; if (propertiesAsInts != null) { properties = new AutomationProperty[propertiesAsInts.Length]; for (int i = 0; i < propertiesAsInts.Length; i++) { properties[i] = AutomationProperty.LookupById(propertiesAsInts[i]); } } //ProxyHwnd.AdviseEventRemoved AdviseEventRemoved (eventId, properties); } #endregion // ----------------------------------------------------- // // Internal Fields // // ----------------------------------------------------- #region Internal Fields // Callback into the Proxy code to create a raw element based on a WinEvent callback parameters internal WinEventTracker.ProxyRaiseEvents _createOnEvent = null; #endregion // ----------------------------------------------------- // // Protected Methods // // ------------------------------------------------------ #region Protected Methods // Picks a WinEvent to track for a UIA property protected virtual int [] PropertyToWinEvent (AutomationProperty idProp) { if (idProp == AutomationElement.HasKeyboardFocusProperty) { return new int [] { NativeMethods.EventObjectFocus }; } else if (idProp == AutomationElement.NameProperty) { return new int[] { NativeMethods.EventObjectNameChange }; } else if (idProp == ValuePattern.ValueProperty || idProp == RangeValuePattern.ValueProperty) { return new int[] { NativeMethods.EventObjectValueChange }; } else if (idProp == AutomationElement.IsOffscreenProperty) { return new int[] { NativeMethods.EventObjectLocationChange }; } else if (idProp == ExpandCollapsePattern.ExpandCollapseStateProperty) { return new int [] { NativeMethods.EventObjectStateChange, NativeMethods.EventObjectShow, NativeMethods.EventObjectHide}; } // Windows sent OBJECT_VALUECHANGE for changes in the scroll bar with the idObject set to the scroll bar id of the originator else if ((idProp == ScrollPattern.HorizontalScrollPercentProperty || idProp == ScrollPattern.VerticalScrollPercentProperty) || idProp == ScrollPattern.HorizontalViewSizeProperty || idProp == ScrollPattern.VerticalViewSizeProperty ) { return new int [] { NativeMethods.EventObjectValueChange }; } else if (idProp == SelectionItemPattern.IsSelectedProperty) { return new int [] { NativeMethods.EventObjectSelectionAdd, NativeMethods.EventObjectSelectionRemove, NativeMethods.EventObjectSelection}; } else if (idProp == TogglePattern.ToggleStateProperty) { return new int[] { NativeMethods.EventSystemCaptureEnd, NativeMethods.EventObjectStateChange }; } return null; } // Builds a list of Win32 WinEvents to process a UIAutomation Event. protected virtual WinEventTracker.EvtIdProperty [] EventToWinEvent (AutomationEvent idEvent, out int cEvent) { // Fill this variable with a WinEvent id if found int idWinEvent = 0; if (idEvent == SelectionItemPattern.ElementSelectedEvent) { cEvent = 2; return new WinEventTracker.EvtIdProperty[2] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectSelection, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectStateChange, idEvent) }; } else if (idEvent == SelectionItemPattern.ElementAddedToSelectionEvent) { // For some control, the Event Selection is sent instead of SelectionAdd // Trap both. cEvent = 2; return new WinEventTracker.EvtIdProperty [2] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectSelectionAdd, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectSelection, idEvent) }; } else if (idEvent == SelectionItemPattern.ElementRemovedFromSelectionEvent) { idWinEvent = NativeMethods.EventObjectSelectionRemove; } else if (idEvent == SelectionPattern.InvalidatedEvent) { idWinEvent = NativeMethods.EventObjectSelectionWithin; } else if (idEvent == InvokePattern.InvokedEvent) { cEvent = 4; return new WinEventTracker.EvtIdProperty[4] { new WinEventTracker.EvtIdProperty (NativeMethods.EventSystemCaptureEnd, idEvent), // For SysHeaders new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectStateChange, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectValueChange, idEvent), // For WindowsScrollBarBits new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectInvoke, idEvent) }; } else if (idEvent == AutomationElement.StructureChangedEvent) { cEvent = 3; return new WinEventTracker.EvtIdProperty[3] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectCreate, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectDestroy, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectReorder, idEvent) }; } else if (idEvent == TextPattern.TextSelectionChangedEvent) { cEvent = 2; return new WinEventTracker.EvtIdProperty[2] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectLocationChange, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectTextSelectionChanged, idEvent) }; } else { cEvent = 0; return null; } // found one and only one cEvent = 1; return new WinEventTracker.EvtIdProperty [1] { new WinEventTracker.EvtIdProperty (idWinEvent, idEvent) }; } // Check if a point is within the client Rect of a window static protected bool PtInClientRect (IntPtr hwnd, int x, int y) { NativeMethods.Win32Rect rc = new NativeMethods.Win32Rect (); if (!Misc.GetClientRect(hwnd, ref rc)) { return false; } if (!Misc.MapWindowPoints(hwnd, IntPtr.Zero, ref rc, 2)) { return false; } return x >= rc.left && x < rc.right && y >= rc.top && y < rc.bottom; } #endregion // ----------------------------------------------------- // // Private Methods // // ------------------------------------------------------ #region Private Methods // Get the access key of the associated label (if there is // an associated label). static protected string GetLabelAccessKey(IntPtr hwnd) { string accessKey = string.Empty; IntPtr label = Misc.GetLabelhwnd(hwnd); if (label != IntPtr.Zero) { string labelText = Misc.ProxyGetText(label); if (!string.IsNullOrEmpty(labelText)) { accessKey = Misc.AccessKey(labelText); } } return accessKey; } // 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; } #endregion // ------------------------------------------------------ // // Private Fields // // ----------------------------------------------------- #region Private Fields // True if the control has an associated label. protected bool _fControlHasLabel = true; // The hwnd of static text that is functioning as a label for a control. // This is initialized in GetElementProperty for the Name property and // used by the LabeledBy property. // If !_fControlHasLabel, _controlLabel will be IntPtr.Zero. private IntPtr _controlLabel; #endregion } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Base class for all the Win32 and office Controls. // // // Only true ROOT object should derive from this class // NOTE: In the case when ProxyHwnd.ElementProviderFromPoint // returns provider of type ProxyFragment we MUST do the further drilling ourselves // since UIAutomation will not (and correctly!!!) do it. (see ProxyFragment's // comments on how to implement this and WindowsListView.cs for example) // // Class ProxyHwnd: ProxyFragment, IRawElementProviderAdviseEvents // AdviseEventAdded // AdviseEventRemoved // // // // History: // 07/01/2003 : a-jeanp Created // 08/21/03: alexsn Class explanations // //--------------------------------------------------------------------------- // PRESHARP: In order to avoid generating warnings about unkown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 using System; using System.Text; using System.Windows; using System.Windows.Automation; using System.Windows.Automation.Provider; using System.Collections; using System.Collections.Specialized; using System.Runtime.InteropServices; using System.Globalization; using System.ComponentModel; using MS.Win32; namespace MS.Internal.AutomationProxies { #region ProxyHwnd // Base Class for all the Windows Control that handle context. // Implements the default behavior class ProxyHwnd : ProxyFragment, IRawElementProviderAdviseEvents { // ----------------------------------------------------- // // Constructors // // ----------------------------------------------------- #region Constructors internal ProxyHwnd (IntPtr hwnd, ProxyFragment parent, int item) : base (hwnd, parent, item) { } #endregion //------------------------------------------------------ // // Patterns Implementation // //----------------------------------------------------- #region ProxyHwnd Methods // ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ // Advises proxy that an event has been added. // Maps the Automation Events into WinEvents and add those to the list of WinEvents notification hooks internal virtual void AdviseEventAdded (AutomationEvent eventId, AutomationProperty [] aidProps) { // No RawElementBase creation callback, exit from here if (_createOnEvent == null) { return; } int cEvents = 0; WinEventTracker.EvtIdProperty [] aEvents; // Gets an Array of WinEvents to trap on a per window handle basis if (eventId == AutomationElement.AutomationPropertyChangedEvent) { aEvents = PropertyToWinEvent (aidProps, out cEvents); } else { aEvents = EventToWinEvent (eventId, out cEvents); } // If we have WinEvents to trap, add those to the list of WinEvent // notification list if (cEvents > 0) { WinEventTracker.AddToNotificationList (_hwnd, _createOnEvent, aEvents, cEvents); } } // Advises proxy that an event has been removed. internal virtual void AdviseEventRemoved(AutomationEvent eventId, AutomationProperty [] aidProps) { // No RawElementBase creation callback, exit from here if (_createOnEvent == null) { return; } int cEvents; WinEventTracker.EvtIdProperty [] aEvents; // Gets an Array of WinEvents to trap on a per window handle basis if (eventId == AutomationElement.AutomationPropertyChangedEvent) { aEvents = PropertyToWinEvent (aidProps, out cEvents); } else { aEvents = EventToWinEvent (eventId, out cEvents); } // If we have WinEvents to remove, remive those to the list of WinEvent // notification list if (cEvents > 0) { WinEventTracker.RemoveToNotificationList (_hwnd, aEvents, null, cEvents); } } // Returns a proxy element corresponding to the specified screen coordinates. // For an hwnd element, the default behavior is to let UIAutomation do the work. internal override ProxySimple ElementProviderFromPoint (int x, int y) { // Optimisation. If the point is within the client area return this, otherwise it could the the // non client area. It would be better to return null all the time but this will lead to // object to be created twice. return PtInClientRect (_hwnd, x, y) ? this : null; } internal override string GetAccessKey() { string accessKey = base.GetAccessKey(); if ((bool)GetElementProperty(AutomationElement.IsKeyboardFocusableProperty)) { if (string.IsNullOrEmpty(accessKey)) { accessKey = GetLabelAccessKey(_hwnd); } } return accessKey; } // 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); } // Gets the controls help text internal override string HelpText { get { int idChild = Misc.GetWindowId(_hwnd); string text = Misc.GetItemToolTipText(_hwnd, IntPtr.Zero, idChild); if (string.IsNullOrEmpty(text)) { text = Misc.GetItemToolTipText(_hwnd, IntPtr.Zero, 0); } if (string.IsNullOrEmpty(text)) { Accessible acc = Accessible.Wrap(AccessibleObject); if (acc != null) { text = acc.Description; } } return text; } } #endregion #region IRawElementProviderAdviseEvents Interface // ----------------------------------------------------- // // IRawElementProviderAdviseEvents interface implementation // // ------------------------------------------------------ // Advises event sinks that an event has been added. void IRawElementProviderAdviseEvents.AdviseEventAdded(int eventIdAsInt, int[] propertiesAsInts) { AutomationEvent eventId = AutomationEvent.LookupById(eventIdAsInt); AutomationProperty [] properties = null; if (propertiesAsInts != null) { properties = new AutomationProperty[propertiesAsInts.Length]; for (int i = 0; i < propertiesAsInts.Length; i++) { properties[i] = AutomationProperty.LookupById(propertiesAsInts[i]); } } //ProxyHwnd.AdviseEventAdded AdviseEventAdded (eventId, properties); } // Advises event sinks that an event has been removed. void IRawElementProviderAdviseEvents.AdviseEventRemoved(int eventIdAsInt, int[] propertiesAsInts) { AutomationEvent eventId = AutomationEvent.LookupById(eventIdAsInt); AutomationProperty [] properties = null; if (propertiesAsInts != null) { properties = new AutomationProperty[propertiesAsInts.Length]; for (int i = 0; i < propertiesAsInts.Length; i++) { properties[i] = AutomationProperty.LookupById(propertiesAsInts[i]); } } //ProxyHwnd.AdviseEventRemoved AdviseEventRemoved (eventId, properties); } #endregion // ----------------------------------------------------- // // Internal Fields // // ----------------------------------------------------- #region Internal Fields // Callback into the Proxy code to create a raw element based on a WinEvent callback parameters internal WinEventTracker.ProxyRaiseEvents _createOnEvent = null; #endregion // ----------------------------------------------------- // // Protected Methods // // ------------------------------------------------------ #region Protected Methods // Picks a WinEvent to track for a UIA property protected virtual int [] PropertyToWinEvent (AutomationProperty idProp) { if (idProp == AutomationElement.HasKeyboardFocusProperty) { return new int [] { NativeMethods.EventObjectFocus }; } else if (idProp == AutomationElement.NameProperty) { return new int[] { NativeMethods.EventObjectNameChange }; } else if (idProp == ValuePattern.ValueProperty || idProp == RangeValuePattern.ValueProperty) { return new int[] { NativeMethods.EventObjectValueChange }; } else if (idProp == AutomationElement.IsOffscreenProperty) { return new int[] { NativeMethods.EventObjectLocationChange }; } else if (idProp == ExpandCollapsePattern.ExpandCollapseStateProperty) { return new int [] { NativeMethods.EventObjectStateChange, NativeMethods.EventObjectShow, NativeMethods.EventObjectHide}; } // Windows sent OBJECT_VALUECHANGE for changes in the scroll bar with the idObject set to the scroll bar id of the originator else if ((idProp == ScrollPattern.HorizontalScrollPercentProperty || idProp == ScrollPattern.VerticalScrollPercentProperty) || idProp == ScrollPattern.HorizontalViewSizeProperty || idProp == ScrollPattern.VerticalViewSizeProperty ) { return new int [] { NativeMethods.EventObjectValueChange }; } else if (idProp == SelectionItemPattern.IsSelectedProperty) { return new int [] { NativeMethods.EventObjectSelectionAdd, NativeMethods.EventObjectSelectionRemove, NativeMethods.EventObjectSelection}; } else if (idProp == TogglePattern.ToggleStateProperty) { return new int[] { NativeMethods.EventSystemCaptureEnd, NativeMethods.EventObjectStateChange }; } return null; } // Builds a list of Win32 WinEvents to process a UIAutomation Event. protected virtual WinEventTracker.EvtIdProperty [] EventToWinEvent (AutomationEvent idEvent, out int cEvent) { // Fill this variable with a WinEvent id if found int idWinEvent = 0; if (idEvent == SelectionItemPattern.ElementSelectedEvent) { cEvent = 2; return new WinEventTracker.EvtIdProperty[2] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectSelection, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectStateChange, idEvent) }; } else if (idEvent == SelectionItemPattern.ElementAddedToSelectionEvent) { // For some control, the Event Selection is sent instead of SelectionAdd // Trap both. cEvent = 2; return new WinEventTracker.EvtIdProperty [2] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectSelectionAdd, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectSelection, idEvent) }; } else if (idEvent == SelectionItemPattern.ElementRemovedFromSelectionEvent) { idWinEvent = NativeMethods.EventObjectSelectionRemove; } else if (idEvent == SelectionPattern.InvalidatedEvent) { idWinEvent = NativeMethods.EventObjectSelectionWithin; } else if (idEvent == InvokePattern.InvokedEvent) { cEvent = 4; return new WinEventTracker.EvtIdProperty[4] { new WinEventTracker.EvtIdProperty (NativeMethods.EventSystemCaptureEnd, idEvent), // For SysHeaders new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectStateChange, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectValueChange, idEvent), // For WindowsScrollBarBits new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectInvoke, idEvent) }; } else if (idEvent == AutomationElement.StructureChangedEvent) { cEvent = 3; return new WinEventTracker.EvtIdProperty[3] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectCreate, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectDestroy, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectReorder, idEvent) }; } else if (idEvent == TextPattern.TextSelectionChangedEvent) { cEvent = 2; return new WinEventTracker.EvtIdProperty[2] { new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectLocationChange, idEvent), new WinEventTracker.EvtIdProperty (NativeMethods.EventObjectTextSelectionChanged, idEvent) }; } else { cEvent = 0; return null; } // found one and only one cEvent = 1; return new WinEventTracker.EvtIdProperty [1] { new WinEventTracker.EvtIdProperty (idWinEvent, idEvent) }; } // Check if a point is within the client Rect of a window static protected bool PtInClientRect (IntPtr hwnd, int x, int y) { NativeMethods.Win32Rect rc = new NativeMethods.Win32Rect (); if (!Misc.GetClientRect(hwnd, ref rc)) { return false; } if (!Misc.MapWindowPoints(hwnd, IntPtr.Zero, ref rc, 2)) { return false; } return x >= rc.left && x < rc.right && y >= rc.top && y < rc.bottom; } #endregion // ----------------------------------------------------- // // Private Methods // // ------------------------------------------------------ #region Private Methods // Get the access key of the associated label (if there is // an associated label). static protected string GetLabelAccessKey(IntPtr hwnd) { string accessKey = string.Empty; IntPtr label = Misc.GetLabelhwnd(hwnd); if (label != IntPtr.Zero) { string labelText = Misc.ProxyGetText(label); if (!string.IsNullOrEmpty(labelText)) { accessKey = Misc.AccessKey(labelText); } } return accessKey; } // 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; } #endregion // ------------------------------------------------------ // // Private Fields // // ----------------------------------------------------- #region Private Fields // True if the control has an associated label. protected bool _fControlHasLabel = true; // The hwnd of static text that is functioning as a label for a control. // This is initialized in GetElementProperty for the Name property and // used by the LabeledBy property. // If !_fControlHasLabel, _controlLabel will be IntPtr.Zero. private IntPtr _controlLabel; #endregion } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpCookieCollection.cs
- CustomPopupPlacement.cs
- ValueCollectionParameterReader.cs
- TypedElement.cs
- RepeatButtonAutomationPeer.cs
- SecurityUtils.cs
- XmlDataFileEditor.cs
- DemultiplexingDispatchMessageFormatter.cs
- ContentType.cs
- ServerTooBusyException.cs
- dbdatarecord.cs
- ItemCollection.cs
- SqlBulkCopy.cs
- SchemaSetCompiler.cs
- ContextMenu.cs
- CorrelationToken.cs
- CompositionTarget.cs
- StatusBar.cs
- ProfessionalColorTable.cs
- DrawingImage.cs
- DefaultShape.cs
- DataControlCommands.cs
- UnsafeNativeMethods.cs
- WinFormsUtils.cs
- ConnectionPoint.cs
- BitVec.cs
- GridView.cs
- EnumValAlphaComparer.cs
- StateWorkerRequest.cs
- UrlMapping.cs
- HierarchicalDataBoundControl.cs
- OdbcParameterCollection.cs
- LineProperties.cs
- SqlStatistics.cs
- BuiltInPermissionSets.cs
- ScrollChrome.cs
- ChannelSinkStacks.cs
- MachineKeySection.cs
- IntPtr.cs
- SqlDependencyUtils.cs
- COM2ComponentEditor.cs
- XmlSerializableReader.cs
- ValueTable.cs
- EntityContainer.cs
- PathSegmentCollection.cs
- AudioStateChangedEventArgs.cs
- XmlSchemaSimpleTypeUnion.cs
- TypeConverterAttribute.cs
- ConfigPathUtility.cs
- EntitySetBase.cs
- ProcessHostServerConfig.cs
- Missing.cs
- SamlNameIdentifierClaimResource.cs
- ResourceReferenceExpression.cs
- Point3DAnimationUsingKeyFrames.cs
- FormParameter.cs
- SizeChangedInfo.cs
- NativeMethodsCLR.cs
- DataStorage.cs
- ConstraintStruct.cs
- Funcletizer.cs
- IisTraceListener.cs
- BaseParagraph.cs
- LingerOption.cs
- OrderToken.cs
- SecurityState.cs
- RepeaterItem.cs
- FlowDocumentPageViewerAutomationPeer.cs
- TemplateXamlParser.cs
- Menu.cs
- SingleAnimationUsingKeyFrames.cs
- IMembershipProvider.cs
- TemplateControlBuildProvider.cs
- XmlQualifiedName.cs
- CursorEditor.cs
- QilXmlReader.cs
- AuthenticationSection.cs
- InstanceCompleteException.cs
- SqlXml.cs
- SystemIcons.cs
- LaxModeSecurityHeaderElementInferenceEngine.cs
- Logging.cs
- IgnoreSection.cs
- ContentHostHelper.cs
- SqlResolver.cs
- DataGridViewRowHeaderCell.cs
- MediaElement.cs
- DateTimeSerializationSection.cs
- InvalidComObjectException.cs
- NodeLabelEditEvent.cs
- DynamicControl.cs
- ExpressionQuoter.cs
- EditorZoneBase.cs
- SqlDependencyUtils.cs
- PackagePart.cs
- ArrangedElementCollection.cs
- ExpressionBuilderContext.cs
- TypeDescriptionProviderAttribute.cs
- TextWriter.cs
- CompositeActivityTypeDescriptor.cs