Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / AccessibleTech / longhorn / Automation / UIAutomationClient / System / Windows / Automation / CacheRequest.cs / 1 / CacheRequest.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: Class that describes the data to be pre-fected in Automation // element operations, and manange the current request. // // History: // 02/05/2004 : [....] Ported to WCP // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Diagnostics; using System.Windows.Automation; using MS.Internal.Automation; namespace System.Windows.Automation { ////// Specified type of reference to use when returning AutomationElements /// ////// AutomationElementMode.Full is the default, and specified that returned AutomationElements /// contain a full reference to the underlying UI. /// /// AutomationElementMode.None specifies taht the returned AutomationElements have no /// reference to the underlying UI, and contain only cached information. /// /// Certain operations on AutomationElements, such as GetCurrentProperty /// or SetFocus require a full reference; attempting to perform these on an /// AutomationElement that has AutomationElementMode.None will result in an /// InvalidOperationException being thrown. /// /// Using AutomationElementMode.None can be more efficient when only properties are needed, /// as it avoids the overhead involved in setting up full references. /// #if (INTERNAL_COMPILE) internal enum AutomationElementMode #else public enum AutomationElementMode #endif { ////// Specifies that returned AutomationElements have no reference to the /// underlying UI, and contain only cached information. /// None, ////// Specifies that returned AutomationElements have a full reference to the /// underlying UI. /// Full } // Implementation notes: // // CacheRequest is the user-facing class that is used to build up // cache requests, using Add and the other properties. When activated, // the data is gathered into a UiaCacheRequest instance, which is // immutable - these are what the rest of UIA uses internally. // // The default cache request - which appears to be always at the bottom // of the stack and which cannot be moved - is not actually part of the // stack. Instead, current returns it whever the stack is empty. ////// Class used to specify the properties and patterns that should be /// prefetched by UIAutomation when returning AutomationElements. /// #if (INTERNAL_COMPILE) internal sealed class CacheRequest #else public sealed class CacheRequest #endif { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Create a new CacheRequest with default values. /// ////// A Thread's current CacheRequest determins which properties, /// patterns and relative elements - if any - are pre-fetched by /// AutomationElement. /// /// A default cache request works on the Control view of the tree, /// and does not prefetch any properties or patterns. /// /// Use .Push or .Activate to make the CacheRequest the current active /// CacheRequest for the current thread. /// public CacheRequest() { _instanceLock = new object(); _viewCondition = Automation.ControlViewCondition; _scope = TreeScope.Element; _properties = new ArrayList(); _patterns = new ArrayList(); _automationElementMode = AutomationElementMode.Full; // We always want RuntimeID to be available... _properties.Add(AutomationElement.RuntimeIdProperty); _uiaCacheRequest = DefaultUiaCacheRequest; } // Private ctor used by Clone() private CacheRequest( Condition viewCondition, TreeScope scope, ArrayList properties, ArrayList patterns, AutomationElementMode automationElementMode, UiaCoreApi.UiaCacheRequest uiaCacheRequest) { _instanceLock = new object(); _viewCondition = viewCondition; _scope = scope; _properties = properties; _patterns = patterns; _automationElementMode = automationElementMode; _uiaCacheRequest = uiaCacheRequest; } #endregion Constructors //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Public Methods ////// Push this CacheRequest onto this thread's stack of CacheRequests, /// making it the current CacheRequest for this thread. /// ////// Use Pop to remove this CacheRequest from the stack, making the previously /// active CacheRequest active again. CacheRequests can be pushed multiple times, /// and on multiple threads; but for each thread, must be popped off in the /// same order as they were pushed. /// /// A CacheRequest cannot be modified while it is pushed on any thread; attempting /// to modify it will generate an InvalidOperationException. /// public void Push() { // pushing multiple times is legal, // and pushing on different threads is also legal, // so no preconditions to check for here. AutomationProperty[] propertyArray = (AutomationProperty[])_properties.ToArray(typeof(AutomationProperty)); AutomationPattern[] patternArray = (AutomationPattern[])_patterns.ToArray(typeof(AutomationPattern)); // _threadStack is thread local storage (TLS) based, so can be // accessed outside of the lock. if (_threadStack == null) { _threadStack = new Stack(); } _threadStack.Push(this); lock (_instanceLock) { _refCount++; // Generate a new UiaCacheRequest if (_uiaCacheRequest == null) { _uiaCacheRequest = new UiaCoreApi.UiaCacheRequest(_viewCondition, _scope, propertyArray, patternArray, _automationElementMode); } } } ////// Pop this CacheRequest from the current thread's stack of CacheRequests, /// restoring the previously active CacheRequest. /// ////// Only the currently active CacheRequest can be popped, attempting to pop /// a CacheRequest which is not the current one will result in an InvalidOperation /// Exception. /// /// The CacheRequest stack initially contains a default CacheRequest, which /// cannot be popped off the stack. /// public void Pop() { // ensure that this is top of stack // (no lock needed here, since this is per-thread state) if (_threadStack == null || _threadStack.Count == 0 || _threadStack.Peek() != this) { throw new InvalidOperationException(SR.Get(SRID.CacheReqestCanOnlyPopTop)); } _threadStack.Pop(); lock (_instanceLock) { _refCount--; } } ////// Make this the currenly active CacheRequest. /// ////// Returns an IDisposable which should be disposed /// when finished using this CacheRequest to deactivate it. /// This method is designed for use within a 'using' clause. /// public IDisposable Activate() { Push(); return new CacheRequestActivation(this); } ////// Clone this CacheRequest /// ////// The returned CacheRequest contains the same request information, but is not /// pushed on the state of any thread. /// public CacheRequest Clone() { // New copy contains only temp state, not any locking state (_refCount) return new CacheRequest(_viewCondition, _scope, (ArrayList)_properties.Clone(), (ArrayList)_patterns.Clone(), _automationElementMode, _uiaCacheRequest); } ////// Add an AutomationProperty to this CacheRequest /// /// The identifier of the property to add to this CacheRequest public void Add(AutomationProperty property) { Misc.ValidateArgumentNonNull(property, "property"); lock (_instanceLock) { CheckAccess(); if (!_properties.Contains(property)) { _properties.Add(property); Invalidate(); } } } ////// Add an AutomationPattern to this CacheRequest /// /// The identifier of the pattern to add to this CacheRequest public void Add(AutomationPattern pattern) { Misc.ValidateArgumentNonNull(pattern, "pattern"); lock (_instanceLock) { CheckAccess(); if (!_patterns.Contains(pattern)) { _patterns.Add(pattern); Invalidate(); } } } #endregion Public Methods //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties ////// Indicate which nodes should be pre-fetched /// ////// At least one or more of of TreeScope.Element, TreeScope.Children or /// TreeScope.Descendants must be specified. /// /// TreeScope.Parent and TreeScope.Ancestors are not supported. /// public TreeScope TreeScope { get { return _scope; } set { if (value == 0) { throw new ArgumentException(SR.Get(SRID.TreeScopeNeedAtLeastOne)); } if ((value & ~(TreeScope.Element | TreeScope.Children | TreeScope.Descendants)) != 0) { throw new ArgumentException(SR.Get(SRID.TreeScopeElementChildrenDescendantsOnly)); } lock (_instanceLock) { CheckAccess(); if (_scope != value) { _scope = value; Invalidate(); } } } } ////// Indicates the view to use when prefetching relative nodes /// ///Defaults to Automation.ControlViewCondition public Condition TreeFilter { get { return _viewCondition; } set { Misc.ValidateArgumentNonNull(value, "TreeFilter"); lock (_instanceLock) { CheckAccess(); if (_viewCondition != value) { _viewCondition = value; Invalidate(); } } } } ////// Specifies whether returned AutomationElements should contain /// full references to the underlying UI, or only cached information. /// public AutomationElementMode AutomationElementMode { get { return _automationElementMode; } set { lock (_instanceLock) { CheckAccess(); if (_automationElementMode != value) { _automationElementMode = value; Invalidate(); } } } } ////// Return the most recent CacheRequest which has been activated /// by teh calling thread. /// public static CacheRequest Current { get { if ( _threadStack == null || _threadStack.Count == 0 ) return DefaultCacheRequest; return (CacheRequest)_threadStack.Peek(); } } #endregion Public Properties //----------------------------------------------------- // // Internal Properties // //------------------------------------------------------ #region Internal Properties internal static UiaCoreApi.UiaCacheRequest DefaultUiaCacheRequest { get { if(_defaultUiaCacheRequest == null) { _defaultUiaCacheRequest = new UiaCoreApi.UiaCacheRequest(Automation.ControlViewCondition, TreeScope.Element, new AutomationProperty[] { AutomationElement.RuntimeIdProperty }, new AutomationPattern[] { }, AutomationElementMode.Full); } return _defaultUiaCacheRequest; } } #endregion Internal Properties //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods internal UiaCoreApi.UiaCacheRequest GetUiaCacheRequest() { if (_uiaCacheRequest == null) { AutomationProperty[] propertiesArray = (AutomationProperty[])_properties.ToArray(typeof(AutomationProperty)); AutomationPattern[] patternsArray = (AutomationPattern[])_patterns.ToArray(typeof(AutomationPattern)); lock (_instanceLock) { _uiaCacheRequest = new UiaCoreApi.UiaCacheRequest(_viewCondition, _scope, propertiesArray, patternsArray, _automationElementMode); } } return _uiaCacheRequest; } static internal UiaCoreApi.UiaCacheRequest CurrentUiaCacheRequest { get { // No need to lock here, since this only uses thread state, // and the UiaCacheRequests are generated within a lock in Push. CacheRequest current = Current; return current._uiaCacheRequest; } } #endregion Internal Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods // Ensure that this CacheRequest isn't currently in use // Must be called within a lock(_instanceLock) to ensure // thread consistency void CheckAccess() { // Make sure this isn't being used by any thread's // CacheRequest stacks by using a refcount: // (Also check for defaultCacheRequest explicitly, since it // is never explicitly added to the stack) if (_refCount != 0 || this == DefaultCacheRequest) { throw new InvalidOperationException(SR.Get(SRID.CacheReqestCantModifyWhileActive)); } } // Called when state changes - sets _uiaCacheRequest to null // to ensure that a clean one is generated next time Push is called void Invalidate() { _uiaCacheRequest = null; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ #region Private Fields //--- Instance state --- // Current mutable state... Condition _viewCondition; TreeScope _scope; ArrayList _properties; ArrayList _patterns; AutomationElementMode _automationElementMode; // When we Push, the current state is bundled into this, which is // immutable. This is what the underlying requesting mechanism uses UiaCoreApi.UiaCacheRequest _uiaCacheRequest; // Used to track whether this instance is in use - inc'd on Push, // dec'd on Pop... int _refCount = 0; // Used to lock on this instance... object _instanceLock = null; //--- Per-Thread state --- // The stack of CacheRequests for this thread. Note that these need to be inited // on-demand, as static initialization does not work with [ThreadStatic] members - // it only applies to the first thread. Treat null as being the same as a stack with // just DefaultCacheRequest on it. [ThreadStatic] private static Stack _threadStack; //--- Global/Static state --- internal static readonly CacheRequest DefaultCacheRequest = new CacheRequest(); internal static UiaCoreApi.UiaCacheRequest _defaultUiaCacheRequest; #endregion Private Fields } //------------------------------------------------------ // // Related utility classe // //----------------------------------------------------- // Helper class returned by Access() - a using() block // will call Dispose() on this when it goes out of scope. internal class CacheRequestActivation : IDisposable { internal CacheRequestActivation(CacheRequest request) { _request = request; } public void Dispose() { Debug.Assert( _request != null ); if( _request != null ) { _request.Pop(); _request = null; } } // No finalizer - usually Dispose is used with a finalizer, // but in this case, IDisposable is being used to manage scoping, // not ensure that resources are freed. private CacheRequest _request; } } // 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
- MaskedTextProvider.cs
- CellIdBoolean.cs
- PeerCollaboration.cs
- SymbolType.cs
- ScriptingAuthenticationServiceSection.cs
- DSASignatureFormatter.cs
- GiveFeedbackEventArgs.cs
- XamlToRtfWriter.cs
- LinkedList.cs
- SafeCryptHandles.cs
- InertiaTranslationBehavior.cs
- ThreadAttributes.cs
- HttpRuntimeSection.cs
- FontSizeConverter.cs
- StateInitializationDesigner.cs
- MasterPage.cs
- CommonGetThemePartSize.cs
- _SSPISessionCache.cs
- CodePropertyReferenceExpression.cs
- DialogResultConverter.cs
- AnimationException.cs
- HtmlInputControl.cs
- SubpageParagraph.cs
- DesignerTransactionCloseEvent.cs
- RepeatBehavior.cs
- ServiceModelConfigurationSectionGroup.cs
- DefaultShape.cs
- DetailsViewInsertedEventArgs.cs
- GroupDescription.cs
- ByteRangeDownloader.cs
- HyperlinkAutomationPeer.cs
- COAUTHINFO.cs
- Separator.cs
- ElementAtQueryOperator.cs
- TransformationRules.cs
- SchemaComplexType.cs
- DoubleIndependentAnimationStorage.cs
- BitmapDecoder.cs
- BindingContext.cs
- EditorZoneAutoFormat.cs
- TextTrailingCharacterEllipsis.cs
- PersonalizablePropertyEntry.cs
- Context.cs
- ProcessModule.cs
- CodeDelegateInvokeExpression.cs
- XmlNodeWriter.cs
- BmpBitmapEncoder.cs
- FamilyMap.cs
- CheckedListBox.cs
- FrameworkTemplate.cs
- CryptoProvider.cs
- ExpressionBindingCollection.cs
- xsdvalidator.cs
- SiteOfOriginPart.cs
- JsonSerializer.cs
- ByteStorage.cs
- ForEach.cs
- XhtmlConformanceSection.cs
- RowsCopiedEventArgs.cs
- QuaternionKeyFrameCollection.cs
- Style.cs
- DomNameTable.cs
- KeyTime.cs
- ArraySortHelper.cs
- ApplicationServicesHostFactory.cs
- WinEventWrap.cs
- MetadataArtifactLoaderCompositeResource.cs
- LinearQuaternionKeyFrame.cs
- InfoCardSymmetricCrypto.cs
- MouseDevice.cs
- AssemblyAttributesGoHere.cs
- AttributeAction.cs
- ConnectionStringSettingsCollection.cs
- DocumentGrid.cs
- StreamInfo.cs
- BlurBitmapEffect.cs
- DataServiceHostWrapper.cs
- xamlnodes.cs
- UnsafePeerToPeerMethods.cs
- BaseCollection.cs
- XmlTextWriter.cs
- SimplePropertyEntry.cs
- ComponentChangingEvent.cs
- DatagridviewDisplayedBandsData.cs
- Debug.cs
- SQLMembershipProvider.cs
- Collection.cs
- _ListenerAsyncResult.cs
- RadioButtonFlatAdapter.cs
- SafeNativeMethodsOther.cs
- SelectionEditingBehavior.cs
- SpecularMaterial.cs
- TargetControlTypeAttribute.cs
- AnnotationHelper.cs
- XPathNavigatorKeyComparer.cs
- BinaryMethodMessage.cs
- CustomAttribute.cs
- UnsafeNetInfoNativeMethods.cs
- Screen.cs
- AssertFilter.cs