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
- Version.cs
- DataControlButton.cs
- DefaultMergeHelper.cs
- LookupBindingPropertiesAttribute.cs
- TextInfo.cs
- EndpointInfo.cs
- HttpCapabilitiesEvaluator.cs
- PeerChannelListener.cs
- UxThemeWrapper.cs
- XPathAxisIterator.cs
- FieldToken.cs
- ProfileManager.cs
- OleDbRowUpdatedEvent.cs
- SafeNativeMethods.cs
- GuidConverter.cs
- ObjectDataSource.cs
- EntitySqlQueryBuilder.cs
- ActionMessageFilter.cs
- ListViewItemSelectionChangedEvent.cs
- TextWriterTraceListener.cs
- __Error.cs
- HttpFileCollection.cs
- WebConfigurationFileMap.cs
- DateTimeOffsetAdapter.cs
- COM2FontConverter.cs
- IsolatedStoragePermission.cs
- dbdatarecord.cs
- DoubleUtil.cs
- Transactions.cs
- XmlNotation.cs
- XmlRawWriterWrapper.cs
- AxParameterData.cs
- SamlAuthorityBinding.cs
- RecognitionEventArgs.cs
- WsiProfilesElementCollection.cs
- HttpDebugHandler.cs
- StandardToolWindows.cs
- TableLayoutPanelCellPosition.cs
- CollectionConverter.cs
- WindowsEditBox.cs
- TransportOutputChannel.cs
- SiblingIterators.cs
- Single.cs
- ContentPlaceHolder.cs
- ViewgenGatekeeper.cs
- IResourceProvider.cs
- CodeObject.cs
- BaseCodeDomTreeGenerator.cs
- EventMemberCodeDomSerializer.cs
- DescendentsWalkerBase.cs
- InitializationEventAttribute.cs
- IndexedString.cs
- RuntimeEnvironment.cs
- ValueSerializer.cs
- SqlConnectionStringBuilder.cs
- OneOfScalarConst.cs
- Paragraph.cs
- GenerateTemporaryAssemblyTask.cs
- BaseConfigurationRecord.cs
- HtmlAnchor.cs
- StringInfo.cs
- SiteMapSection.cs
- DataGridColumnDropSeparator.cs
- AsymmetricKeyExchangeFormatter.cs
- FlatButtonAppearance.cs
- SafeHandle.cs
- GatewayDefinition.cs
- AesCryptoServiceProvider.cs
- QueuePropertyVariants.cs
- ParentQuery.cs
- FactoryId.cs
- COM2Properties.cs
- CodeMemberMethod.cs
- XmlCompatibilityReader.cs
- GlobalizationAssembly.cs
- RawStylusSystemGestureInputReport.cs
- SvcFileManager.cs
- AsyncSerializedWorker.cs
- DefaultPropertyAttribute.cs
- BinaryUtilClasses.cs
- DetailsViewUpdatedEventArgs.cs
- WorkflowDesigner.cs
- DbConnectionPoolGroup.cs
- FormViewInsertedEventArgs.cs
- DataGridViewCellValueEventArgs.cs
- WebPartConnectionsConfigureVerb.cs
- ToolStripControlHost.cs
- ListComponentEditor.cs
- RadialGradientBrush.cs
- LineVisual.cs
- DataRowCollection.cs
- Matrix3DStack.cs
- ChannelDispatcher.cs
- ApplicationServicesHostFactory.cs
- _KerberosClient.cs
- ItemAutomationPeer.cs
- GridViewColumnCollection.cs
- util.cs
- WindowsIdentity.cs
- PickDesigner.xaml.cs