Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / UIAutomation / UIAutomationClient / MS / Internal / Automation / EventListenerClientSide.cs / 1 / EventListenerClientSide.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: This class wraps an event listener object on the client side. // // History: // 06/17/2003 : BrendanM Ported to WCP // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows.Automation; using System.ComponentModel; // needed by AsyncOperation using System.Runtime.InteropServices; using MS.Win32; namespace MS.Internal.Automation { // This class wraps an event listener object on the client side. internal class EventListenerClientSide : MarshalByRefObject { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors internal EventListenerClientSide(AutomationElement elRoot, Delegate clientCallback, EventListener l) { _eventListener = l; _refElement = elRoot; // Ensure that RuntimeId is cached on elRoot so that later compares can be done w/o accessing the native element _refRid = elRoot.GetRuntimeId(); _clientCallback = clientCallback; _callbackDelegate = new UiaCoreApi.UiaEventCallback(OnEvent); _gch = GCHandle.Alloc(_callbackDelegate); // } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods // Unmanaged DLL calls back on this to notify a UIAccess client of an event. internal void OnEvent(IntPtr argsAddr, object[,] requestedData, string treeStructure) { AutomationEventArgs e = UiaCoreApi.GetUiaEventArgs(argsAddr); if (e.EventId == AutomationElement.AutomationFocusChangedEvent) { uint eventTime = SafeNativeMethods.GetTickCount(); if (eventTime == 0) // 0 is used as a marker value, so bump up to 1 if we get it. eventTime = 1; // There's no FocusChangedEventArgs in core, but clients expect one, so substitute if needed... // (otherwise the cast in InvokeHandlers will fail...) e = new InternalAutomationFocusChangedEventArgs(0, 0, eventTime); } UiaCoreApi.UiaCacheResponse cacheResponse = new UiaCoreApi.UiaCacheResponse(requestedData, treeStructure, _eventListener.CacheRequest); // Invoke the listener's callback but not on this thread. Queuing this onto a worker thread allows // OnEvent to return (which allows the call on the server-side to complete) and avoids a deadlock // situation when the client accesses properties on the source element. ClientEventManager.CBQ.PostWorkItem(new CalloutQueueItem(_clientCallback, cacheResponse, e, _eventListener.CacheRequest)); } // IsListeningFor - called by UIAccess client during removal of listeners. Returns // true if rid, eventId and clientCallback represent this listener instance. internal bool IsListeningFor(AutomationEvent eventId, AutomationElement el, Delegate clientCallback) { // Removing the event handler using the element RuntimeId prevents problems with dead elements int[] rid = null; try { rid = el.GetRuntimeId(); } catch( ElementNotAvailableException ) { // This can't be the element this instance is holding because when // creating this instance we caused the RuntimeId to be cached. return false; } if( !Misc.Compare( _refRid, rid ) ) return false; if( _eventListener.EventId != eventId ) return false; if (_clientCallback != clientCallback) return false; return true; } // WithinScope - returns true if el is within the scope of this listener. internal bool WithinScope(AutomationElement el) { // Quick look: If want all elements then no compare is necessary if ((_eventListener.TreeScope & TreeScope.Subtree) == TreeScope.Subtree && Misc.Compare(_refRid, AutomationElement.RootElement.GetRuntimeId())) { return true; } // If our weak reference is still alive, then get it AutomationElement elThis = AutomationElement; if (elThis == null) { return false; // reference is no longer alive } // Quick look: If they want this element if ((_eventListener.TreeScope & TreeScope.Element) != 0 && Misc.Compare(el, elThis)) { return true; } AutomationElement elParent; // Quick look (sort of): If they want to include children if (((_eventListener.TreeScope & TreeScope.Children) != 0 || (_eventListener.TreeScope & TreeScope.Descendants) != 0)) { elParent = TreeWalker.RawViewWalker.GetParent(el); if (elParent != null && Misc.Compare(elParent, elThis)) return true; } // Quick look (sort of): If they want to include the parent if (((_eventListener.TreeScope & TreeScope.Parent) != 0 || (_eventListener.TreeScope & TreeScope.Ancestors) != 0)) { elParent = TreeWalker.RawViewWalker.GetParent(elThis); if (elParent != null && Misc.Compare(elParent, el)) return true; } // More work if they want to include any descendents of this element if ((_eventListener.TreeScope & TreeScope.Descendants) != 0 && IsChildOf(elThis, el)) { return true; } // More work if they want to include any anscestors of this element if ((_eventListener.TreeScope & TreeScope.Ancestors) != 0 && IsChildOf(el, elThis)) { return true; } return false; } // WithinScope - returns true if rid is the RuntimeId of this listener or listening for all elements. internal bool WithinScope( int [] rid ) { // Quick look: If want all elements then no compare is necessary if ((_eventListener.TreeScope & TreeScope.Subtree) == TreeScope.Subtree && Misc.Compare(_refRid, AutomationElement.RootElement.GetRuntimeId())) { return true; } // Can only determine if ref element is the element using RuntimeId; // can't determine other relationships. if ( ( _eventListener.TreeScope & TreeScope.Element ) == 0 ) { return false; } // Quick look: If they want this element but use our ref RuntimeId // since the weak reference may be gone. if ( Misc.Compare( rid, _refRid ) ) { return true; } // rid is not the ref element return false; } #endregion Internal Methods //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ #region Internal Properties internal EventListener EventListener { get { return _eventListener; } } internal Delegate ClientCallback { get { return _clientCallback; } } internal AutomationElement AutomationElement { get { return _refElement; } } internal UiaCoreApi.UiaEventCallback CallbackDelegate { get { return _callbackDelegate; } } internal SafeEventHandle EventHandle { get { return _eventHandle; } set { _eventHandle = value; } } #endregion Internal Properties //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods // return true if el is a child of elPossibleParent private bool IsChildOf(AutomationElement elPossibleParent, AutomationElement el) { // Do the work [slower] using the proxies if( ! Misc.Compare( el, elPossibleParent ) ) { AutomationElement elPossibleChild = TreeWalker.RawViewWalker.GetParent(el); while( elPossibleChild != null ) { if( Misc.Compare( elPossibleChild, elPossibleParent ) ) { return true; } elPossibleChild = TreeWalker.RawViewWalker.GetParent(elPossibleChild); } } return false; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields private EventListener _eventListener; private AutomationElement _refElement; private int [] _refRid; private Delegate _clientCallback; private UiaCoreApi.UiaEventCallback _callbackDelegate; private GCHandle _gch; // GCHandle to keep GCs from moving the callback private SafeEventHandle _eventHandle; #endregion Private Fields } } // 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: This class wraps an event listener object on the client side. // // History: // 06/17/2003 : BrendanM Ported to WCP // //--------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows.Automation; using System.ComponentModel; // needed by AsyncOperation using System.Runtime.InteropServices; using MS.Win32; namespace MS.Internal.Automation { // This class wraps an event listener object on the client side. internal class EventListenerClientSide : MarshalByRefObject { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors internal EventListenerClientSide(AutomationElement elRoot, Delegate clientCallback, EventListener l) { _eventListener = l; _refElement = elRoot; // Ensure that RuntimeId is cached on elRoot so that later compares can be done w/o accessing the native element _refRid = elRoot.GetRuntimeId(); _clientCallback = clientCallback; _callbackDelegate = new UiaCoreApi.UiaEventCallback(OnEvent); _gch = GCHandle.Alloc(_callbackDelegate); // } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods // Unmanaged DLL calls back on this to notify a UIAccess client of an event. internal void OnEvent(IntPtr argsAddr, object[,] requestedData, string treeStructure) { AutomationEventArgs e = UiaCoreApi.GetUiaEventArgs(argsAddr); if (e.EventId == AutomationElement.AutomationFocusChangedEvent) { uint eventTime = SafeNativeMethods.GetTickCount(); if (eventTime == 0) // 0 is used as a marker value, so bump up to 1 if we get it. eventTime = 1; // There's no FocusChangedEventArgs in core, but clients expect one, so substitute if needed... // (otherwise the cast in InvokeHandlers will fail...) e = new InternalAutomationFocusChangedEventArgs(0, 0, eventTime); } UiaCoreApi.UiaCacheResponse cacheResponse = new UiaCoreApi.UiaCacheResponse(requestedData, treeStructure, _eventListener.CacheRequest); // Invoke the listener's callback but not on this thread. Queuing this onto a worker thread allows // OnEvent to return (which allows the call on the server-side to complete) and avoids a deadlock // situation when the client accesses properties on the source element. ClientEventManager.CBQ.PostWorkItem(new CalloutQueueItem(_clientCallback, cacheResponse, e, _eventListener.CacheRequest)); } // IsListeningFor - called by UIAccess client during removal of listeners. Returns // true if rid, eventId and clientCallback represent this listener instance. internal bool IsListeningFor(AutomationEvent eventId, AutomationElement el, Delegate clientCallback) { // Removing the event handler using the element RuntimeId prevents problems with dead elements int[] rid = null; try { rid = el.GetRuntimeId(); } catch( ElementNotAvailableException ) { // This can't be the element this instance is holding because when // creating this instance we caused the RuntimeId to be cached. return false; } if( !Misc.Compare( _refRid, rid ) ) return false; if( _eventListener.EventId != eventId ) return false; if (_clientCallback != clientCallback) return false; return true; } // WithinScope - returns true if el is within the scope of this listener. internal bool WithinScope(AutomationElement el) { // Quick look: If want all elements then no compare is necessary if ((_eventListener.TreeScope & TreeScope.Subtree) == TreeScope.Subtree && Misc.Compare(_refRid, AutomationElement.RootElement.GetRuntimeId())) { return true; } // If our weak reference is still alive, then get it AutomationElement elThis = AutomationElement; if (elThis == null) { return false; // reference is no longer alive } // Quick look: If they want this element if ((_eventListener.TreeScope & TreeScope.Element) != 0 && Misc.Compare(el, elThis)) { return true; } AutomationElement elParent; // Quick look (sort of): If they want to include children if (((_eventListener.TreeScope & TreeScope.Children) != 0 || (_eventListener.TreeScope & TreeScope.Descendants) != 0)) { elParent = TreeWalker.RawViewWalker.GetParent(el); if (elParent != null && Misc.Compare(elParent, elThis)) return true; } // Quick look (sort of): If they want to include the parent if (((_eventListener.TreeScope & TreeScope.Parent) != 0 || (_eventListener.TreeScope & TreeScope.Ancestors) != 0)) { elParent = TreeWalker.RawViewWalker.GetParent(elThis); if (elParent != null && Misc.Compare(elParent, el)) return true; } // More work if they want to include any descendents of this element if ((_eventListener.TreeScope & TreeScope.Descendants) != 0 && IsChildOf(elThis, el)) { return true; } // More work if they want to include any anscestors of this element if ((_eventListener.TreeScope & TreeScope.Ancestors) != 0 && IsChildOf(el, elThis)) { return true; } return false; } // WithinScope - returns true if rid is the RuntimeId of this listener or listening for all elements. internal bool WithinScope( int [] rid ) { // Quick look: If want all elements then no compare is necessary if ((_eventListener.TreeScope & TreeScope.Subtree) == TreeScope.Subtree && Misc.Compare(_refRid, AutomationElement.RootElement.GetRuntimeId())) { return true; } // Can only determine if ref element is the element using RuntimeId; // can't determine other relationships. if ( ( _eventListener.TreeScope & TreeScope.Element ) == 0 ) { return false; } // Quick look: If they want this element but use our ref RuntimeId // since the weak reference may be gone. if ( Misc.Compare( rid, _refRid ) ) { return true; } // rid is not the ref element return false; } #endregion Internal Methods //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ #region Internal Properties internal EventListener EventListener { get { return _eventListener; } } internal Delegate ClientCallback { get { return _clientCallback; } } internal AutomationElement AutomationElement { get { return _refElement; } } internal UiaCoreApi.UiaEventCallback CallbackDelegate { get { return _callbackDelegate; } } internal SafeEventHandle EventHandle { get { return _eventHandle; } set { _eventHandle = value; } } #endregion Internal Properties //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ #region Private Methods // return true if el is a child of elPossibleParent private bool IsChildOf(AutomationElement elPossibleParent, AutomationElement el) { // Do the work [slower] using the proxies if( ! Misc.Compare( el, elPossibleParent ) ) { AutomationElement elPossibleChild = TreeWalker.RawViewWalker.GetParent(el); while( elPossibleChild != null ) { if( Misc.Compare( elPossibleChild, elPossibleParent ) ) { return true; } elPossibleChild = TreeWalker.RawViewWalker.GetParent(elPossibleChild); } } return false; } #endregion Private Methods //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- #region Private Fields private EventListener _eventListener; private AutomationElement _refElement; private int [] _refRid; private Delegate _clientCallback; private UiaCoreApi.UiaEventCallback _callbackDelegate; private GCHandle _gch; // GCHandle to keep GCs from moving the callback private SafeEventHandle _eventHandle; #endregion Private Fields } } // 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
- HtmlProps.cs
- SequenceNumber.cs
- CmsUtils.cs
- EUCJPEncoding.cs
- UIElementPropertyUndoUnit.cs
- DataGridViewRowsAddedEventArgs.cs
- Processor.cs
- WindowsImpersonationContext.cs
- PageContent.cs
- FlowDocumentReaderAutomationPeer.cs
- IndexerNameAttribute.cs
- TemplatePartAttribute.cs
- WriteLineDesigner.xaml.cs
- SharedStatics.cs
- SystemColorTracker.cs
- SmtpException.cs
- SignerInfo.cs
- ProviderIncompatibleException.cs
- CollectionBuilder.cs
- FormViewUpdatedEventArgs.cs
- SchemaImporterExtensionElementCollection.cs
- ToolStripPanelDesigner.cs
- SoapInteropTypes.cs
- SelectionRangeConverter.cs
- ListViewVirtualItemsSelectionRangeChangedEvent.cs
- DocumentGrid.cs
- metadatamappinghashervisitor.cs
- CookieParameter.cs
- TableFieldsEditor.cs
- serverconfig.cs
- EndEvent.cs
- MethodBody.cs
- CodeArrayIndexerExpression.cs
- HttpBufferlessInputStream.cs
- RsaKeyGen.cs
- RewritingPass.cs
- QueryResult.cs
- SqlCommandBuilder.cs
- ToggleButton.cs
- DBDataPermissionAttribute.cs
- TransformDescriptor.cs
- DataGridViewEditingControlShowingEventArgs.cs
- MouseDevice.cs
- ValidationHelper.cs
- loginstatus.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- LightweightCodeGenerator.cs
- ScrollableControl.cs
- DesignerHelpers.cs
- UserInitiatedRoutedEventPermission.cs
- IPEndPointCollection.cs
- GridViewSelectEventArgs.cs
- RelationshipEndMember.cs
- GraphicsPath.cs
- ChannelManager.cs
- DataGridLengthConverter.cs
- RectangleConverter.cs
- ResourceKey.cs
- EdmProperty.cs
- PrefixHandle.cs
- PickDesigner.xaml.cs
- SystemEvents.cs
- SimpleTextLine.cs
- DispatchChannelSink.cs
- DashStyles.cs
- BaseDataBoundControl.cs
- SpecialFolderEnumConverter.cs
- QueryInterceptorAttribute.cs
- FileLoadException.cs
- TreeNodeCollection.cs
- MaskedTextBox.cs
- ZipIOCentralDirectoryBlock.cs
- SQLInt32.cs
- ObjectDataSourceMethodEventArgs.cs
- InputDevice.cs
- OutOfMemoryException.cs
- PropertyDescriptorComparer.cs
- XmlCharacterData.cs
- GeometryCombineModeValidation.cs
- CompressEmulationStream.cs
- XmlUtf8RawTextWriter.cs
- DesignTable.cs
- IProvider.cs
- Splitter.cs
- MdiWindowListItemConverter.cs
- XPathConvert.cs
- QuadraticBezierSegment.cs
- EditCommandColumn.cs
- SoapTypeAttribute.cs
- StringPropertyBuilder.cs
- MatchAllMessageFilter.cs
- TransformValueSerializer.cs
- StylusPointDescription.cs
- Visual.cs
- RealizedColumnsBlock.cs
- ConfigurationElementCollection.cs
- OutputCacheSection.cs
- SessionSwitchEventArgs.cs
- TextServicesProperty.cs
- NativeMethods.cs