Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / PresentationSource.cs / 1 / PresentationSource.cs
using System; using System.Collections; using System.Diagnostics; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Threading; using System.Security; using System.Security.Permissions; using System.Windows.Media; using System.Windows.Media.Media3D; using System.Windows.Markup; using System.Windows.Input; using MS.Win32; using MS.Utility; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows { ////// PresentationSource is the abstract base for classes that /// present content in another technology. In addition, this /// class provides static methods for working with these sources. /// ////// We currently have one implementation - HwndSource - that /// presents content in a Win32 HWND. /// ////// Keep this from being derived from in partial-trust code. /// [UIPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)] public abstract class PresentationSource : DispatcherObject { //------------------------------------------------------ // // Constructors // //----------------------------------------------------- #region Constructors ////// Constructs an instance of the PresentationSource object. /// ////// This is protected since this is an abstract base class. /// protected PresentationSource() { } ////// This constructor exists since the code gen for managed code generates a static constructor /// and in that code it initializes a critical field which causes an fxcop violation for the codegen /// constructor. /// [SecurityCritical] static PresentationSource() { } #endregion //----------------------------------------------------- // // Public Methods // //----------------------------------------------------- #region Public Methods ////// InputProvider given the Device type. /// ////// Critical: Sub classing this can let you provide fake input providers which /// can compromise the input system /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)] internal virtual IInputProvider GetInputProvider(Type inputDevice) { return null; } #endregion //------------------------------------------------------ // // Public Static Methods // //----------------------------------------------------- #region Public Static Methods ////// Returns the source in which the visual is being presented. /// /// The visual to find the source for. ///The source in which the visual is being presented. ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical - calls CriticalFromVisual. and returns the PresentationSource /// PublicOK: There exists a demand /// [SecurityCritical] public static PresentationSource FromVisual(Visual visual) { SecurityHelper.DemandUIWindowPermission(); return CriticalFromVisual(visual); } ////// Returns the source in which the Visual or Visual3D is being presented. /// /// The dependency object to find the source for. ///The source in which the dependency object is being presented. ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical - calls CriticalFromVisual. and returns the PresentationSource /// PublicOK: There exists a demand /// [SecurityCritical] public static PresentationSource FromDependencyObject(DependencyObject dependencyObject) { SecurityHelper.DemandUIWindowPermission(); return CriticalFromVisual(dependencyObject); } ////// Adds a handler for the SourceChanged event to the element. /// /// The element to add the handler too. /// The hander to add. ////// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement AddHandler() method. /// 2) Class handlers are not allowed. /// 3) The handlers will receive the SourceChanged event even if it was handled. /// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical: This code lets you get access to a presentationSource object. Here the link demand /// is defense in depth since , the object by itself has all public properties blocked off. Also this /// is part of startup code. /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] public static void AddSourceChangedHandler(IInputElement element, SourceChangedEventHandler handler) { if (element == null) { throw new ArgumentNullException("element"); } // Either UIElement or ContentElement if (!InputElement.IsValid(element)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "element"); } DependencyObject o = (DependencyObject)element; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectListinfo; if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.AddHandler(SourceChangedEvent, handler); info = uie.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { uie.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged); AddElementToWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.AddHandler(SourceChangedEvent, handler); info = uie3D.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { uie3D.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged); AddElementToWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.AddHandler(SourceChangedEvent, handler); info = ce.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) AddElementToWatchList(ce); } } } /// /// Removes a handler for the SourceChanged event to the element. /// /// The element to remove the handler from. /// The hander to remove. ////// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement RemoveHandler() method. /// public static void RemoveSourceChangedHandler(IInputElement e, SourceChangedEventHandler handler) { if (e == null) { throw new ArgumentNullException("e"); } if (!InputElement.IsValid(e)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "e"); } DependencyObject o = (DependencyObject)e; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectListinfo = null; EventHandlersStore store; // Either UIElement or ContentElement. if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.RemoveHandler(SourceChangedEvent, handler); store = uie.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged); ; RemoveElementFromWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.RemoveHandler(SourceChangedEvent, handler); store = uie3D.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie3D.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged); ; RemoveElementFromWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.RemoveHandler(SourceChangedEvent, handler); store = ce.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { RemoveElementFromWatchList(ce); } } } } /// /// Called by FrameworkElements when a framework ancenstor link of /// ContentElement has changed. /// /// /// The element whose ancestory may have changed. /// ////// This API is not available in the internet zone.It was protected /// as defense in depth since we did not want the PresentationSource /// surface to be exposed. /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] [FriendAccessAllowed] // Built into Core, also used by Framework. internal static void OnAncestorChanged(ContentElement ce) { if (ce == null) { throw new ArgumentNullException("ce"); } if (true == (bool)ce.GetValue(GetsSourceChangedEventProperty)) { UpdateSourceOfElement(ce, null, null); } } #endregion //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties ////// The visual target for the visuals being presented in the source. /// ////// Critical: Calls GetCompositionTargetCore() and returns a CompositionTarget object, which is considered critical. /// PublicOk: Protected by a LinkDemand /// public CompositionTarget CompositionTarget { [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] [SecurityCritical] get { return GetCompositionTargetCore(); } } ////// The root visual being presented in the source. /// ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical: This code is not safe to expose publicly since it lets you /// change rootvisual which puts popup code at risk /// PublicOK: Inheritance demand prevents random subclassing in partial trust /// and Linkdemand prevents unauthorized public callers /// public abstract Visual RootVisual { get; [SecurityCritical] [UIPermissionAttribute(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)] [UIPermissionAttribute(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)] set; } ////// Whether or not the object is disposed. /// public abstract bool IsDisposed { get; } #endregion //----------------------------------------------------- // // Public Static Properties // //------------------------------------------------------ #region Public Static Properties ////// Return a WeakReferenceList which supports returning an Enumerator /// over a ReadOnly SnapShot of the List of sources. The Enumerator /// skips over the any dead weak references in the list. /// ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical: This code exposes the sources which are deemed as critical. This is defense in depth. /// PublicOK: There exists a demand in this code /// public static IEnumerable CurrentSources { [SecurityCritical] get { SecurityHelper.DemandUIWindowPermission(); return CriticalCurrentSources; } } #endregion //----------------------------------------------------- // // Public Events // //----------------------------------------------------- #region Public Events ////// This event fires when content is rendered and ready for user interaction. /// public event EventHandler ContentRendered; #endregion //----------------------------------------------------- // // Protected Methods // //------------------------------------------------------ #region Protected Methods ////// Returns visual target for the given source. Implemented by /// the derived class. /// protected abstract CompositionTarget GetCompositionTargetCore(); // [SecurityCritical, SecurityTreatAsSafe] protected void RootChanged(Visual oldRoot, Visual newRoot) { PresentationSource oldSource = null; if (oldRoot == newRoot) { return; } // Always clear the RootSourceProperty on the old root. if (oldRoot != null) { oldSource = CriticalGetPresentationSourceFromElement(oldRoot, RootSourceProperty); oldRoot.ClearValue(RootSourceProperty); } // Always set the SourceProperty on the new root. if (newRoot != null) { newRoot.SetValue(RootSourceProperty, new SecurityCriticalDataForMultipleGetAndSet(this)); } UIElement oldRootUIElement = oldRoot as UIElement; UIElement newRootUIElement = newRoot as UIElement; // The IsVisible property can only be true if root visual is connected to a presentation source. // For Read-Only force-inherited properties, use a private update method. if(oldRootUIElement != null) { oldRootUIElement.UpdateIsVisibleCache(); } if(newRootUIElement != null) { newRootUIElement.UpdateIsVisibleCache(); } // Broadcast the Unloaded event starting at the old root visual if (oldRootUIElement != null) { oldRootUIElement.OnPresentationSourceChanged(false); } // Broadcast the Loaded event starting at the root visual if (newRootUIElement != null) { newRootUIElement.OnPresentationSourceChanged(true); } // To fire PresentationSourceChanged when the RootVisual changes; // rather than simulate a "parent" pointer change, we just walk the // collection of all nodes that need the event. foreach (DependencyObject element in _watchers) { // We only need to update those elements that are in the // same context as this presentation source. if (element.Dispatcher == Dispatcher) { PresentationSource testSource = CriticalGetPresentationSourceFromElement(element,CachedSourceProperty); // 1) If we are removing the rootvisual, then fire on any node whos old // PresetationSource was the oldSource. // 2) If we are attaching a rootvisual then fire on any node whos old // PresentationSource is null; if (oldSource == testSource || null == testSource) { UpdateSourceOfElement(element, null, null); } } } } /// /// Called by derived classes to indicate that they need to be tracked. /// protected void AddSource() { _sources.Add(this); } ////// Called by derived classes to indicate that they no longer need to be tracked. /// protected void RemoveSource() { _sources.Remove(this); } ////// Sets the ContentRendered event to null. /// protected void ClearContentRenderedListeners() { ContentRendered = null; } #endregion //----------------------------------------------------- // // Internal Methods // //------------------------------------------------------ // None //------------------------------------------------------ // // Internal Static Methods // //----------------------------------------------------- #region Internal Static Methods ////// Called by UIElement(3D)s when a visual ancestor link has changed. /// /// The UIElement whose ancestory may have changed. /// Event Args. ////// Critical: This code calls into a critical code path UpdateSourceOfElement. /// TreatAsSafe: This code does not access any critical data itself and does not expose /// anything /// [SecurityCritical, SecurityTreatAsSafe] internal static void OnVisualAncestorChanged(DependencyObject uie, AncestorChangedEventArgs e) { Debug.Assert(InputElement.IsUIElement3D(uie) || InputElement.IsUIElement(uie)); if (true == (bool)uie.GetValue(GetsSourceChangedEventProperty)) { UpdateSourceOfElement(uie, e.Ancestor, e.OldParent); } } ////// Critical - Returns the PresentationSource /// [FriendAccessAllowed] // To allow internal code paths to access this function [SecurityCritical] internal static PresentationSource CriticalFromVisual(DependencyObject v) { return CriticalFromVisual(v, true /* enable2DTo3DTransition */); } ////// Critical - uses RootSourceProperty. and returns the PresentationSource /// /// The dependency object to find the source for /// /// Determines whether when walking the tree to enable transitioning from a 2D child /// to a 3D parent or to stop once a 3D parent is encountered. /// [FriendAccessAllowed] // To allow internal code paths to access this function [SecurityCritical] internal static PresentationSource CriticalFromVisual(DependencyObject v, bool enable2DTo3DTransition) { if (v == null) { throw new ArgumentNullException("v"); } PresentationSource source = FindSource(v, enable2DTo3DTransition); // Don't hand out a disposed source. if (null != source && source.IsDisposed) { source = null; } return source; } ////// Fire the event when content is rendered and ready for user interaction. /// /// internal static object FireContentRendered(object arg) { PresentationSource ps = (PresentationSource)arg; if (ps.ContentRendered != null) { ps.ContentRendered(arg, EventArgs.Empty); } return null; } #endregion //------------------------------------------------------ // // Internal Properties // //----------------------------------------------------- // None //----------------------------------------------------- // // Internal Events // //----------------------------------------------------- // None //------------------------------------------------------ // // Private Static Methods // //----------------------------------------------------- #region Private Static Methods ////// Return a WeakReferenceList which supports returning an Enumerator /// over a ReadOnly SnapShot of the List of sources. The Enumerator /// skips over the any dead weak references in the list. /// ////// Critical: This code exposes the sources which are deemed as critical. This is internal access point. /// Public consumers should use CurrentSources /// internal static IEnumerable CriticalCurrentSources { [SecurityCritical] get { return (IEnumerable)_sources; } } ////// Critical: Returns a presentationsource given a canister /// [SecurityCritical] private static PresentationSource CriticalGetPresentationSourceFromElement(DependencyObject dObject,DependencyProperty dp) { PresentationSource testSource; SecurityCriticalDataForMultipleGetAndSettempCriticalDataWrapper = (SecurityCriticalDataForMultipleGetAndSet < PresentationSource > ) dObject.GetValue(dp); if (tempCriticalDataWrapper == null || tempCriticalDataWrapper.Value == null) { testSource = null; } else { testSource = tempCriticalDataWrapper.Value; } return testSource; } /// /// Critical: This code acceses PresentationSource and stores it. /// [SecurityCritical] private static void AddElementToWatchList(DependencyObject element) { if(_watchers.Add(element)) { element.SetValue(CachedSourceProperty,new SecurityCriticalDataForMultipleGetAndSet(PresentationSource.FindSource(element))); element.SetValue(GetsSourceChangedEventProperty, true); } } /// /// Critical: This code acceses PresentationSource /// TreatAsSafe: This code is safe to expose. /// [SecurityCritical,SecurityTreatAsSafe] private static void RemoveElementFromWatchList(DependencyObject element) { if(_watchers.Remove(element)) { element.ClearValue(CachedSourceProperty); element.ClearValue(GetsSourceChangedEventProperty); } } ////// Critical - Returns a PresentationSource. /// [SecurityCritical] private static PresentationSource FindSource(DependencyObject o) { return FindSource(o, true /* enable2DTo3DTransition */); } ////// Critical - uses RootSourceProperty and returns the PresentationSource /// /// The dependency object to find the source for /// /// Determines whether when walking the tree to enable transitioning from a 2D child /// to a 3D parent or to stop once a 3D parent is encountered. /// [SecurityCritical] private static PresentationSource FindSource(DependencyObject o, bool enable2DTo3DTransition) { PresentationSource source = null; // For "Visual" nodes GetRootVisual() climbs to the top of the // visual tree (parent==null) // For "ContentElements" it climbs the logical parent until it // reaches a visual then climbs to the top of the visual tree. DependencyObject v = InputElement.GetRootVisual(o, enable2DTo3DTransition); if (v != null) { source = CriticalGetPresentationSourceFromElement(v, RootSourceProperty); } return source; } ////// Critical: This code accesses PresentationSource which is a critical resource. It then /// packages it into an event args and fires it into the tree. /// [SecurityCritical] private static bool UpdateSourceOfElement(DependencyObject doTarget, DependencyObject doAncestor, DependencyObject doOldParent) { bool calledOut = false; PresentationSource realSource = FindSource(doTarget); PresentationSource cachedSource = CriticalGetPresentationSourceFromElement(doTarget, CachedSourceProperty); if (cachedSource != realSource) { doTarget.SetValue(CachedSourceProperty, new SecurityCriticalDataForMultipleGetAndSet(realSource)); SourceChangedEventArgs args = new SourceChangedEventArgs(cachedSource, realSource); args.RoutedEvent=SourceChangedEvent; if (InputElement.IsUIElement(doTarget)) { ((UIElement)doTarget).RaiseEvent(args); } else if (InputElement.IsContentElement(doTarget)) { ((ContentElement)doTarget).RaiseEvent(args); } else { ((UIElement3D)doTarget).RaiseEvent(args); } calledOut = true; } return calledOut; } #endregion //------------------------------------------------------ // // Private Static Members // //------------------------------------------------------ #region Private Static Members // We use a private DP for the RootSource (the connection from the root // element in a tree to the source it is displayed in). Use the public // API FromVisual to get the source that a visual is displayed in. /// /// Critical - used to store PresentationSource /// [SecurityCritical] private static readonly DependencyProperty RootSourceProperty = DependencyProperty.RegisterAttached("RootSource", typeof(SecurityCriticalDataForMultipleGetAndSet), typeof(PresentationSource), new PropertyMetadata((SecurityCriticalDataForMultipleGetAndSet )null)); // We use a private DP for the CachedSource (stored on the elements // that we are watching, so that we can send a change notification). // Use the public API FromVisual to get the source that a visual is // displayed in. /// /// Critical - used to store PresentationSource /// [SecurityCritical] private static readonly DependencyProperty CachedSourceProperty = DependencyProperty.RegisterAttached("CachedSource", typeof(SecurityCriticalDataForMultipleGetAndSet), typeof(PresentationSource), new PropertyMetadata((SecurityCriticalDataForMultipleGetAndSet )null)); // We use a private DP to mark elements that we are watchin. private static readonly DependencyProperty GetsSourceChangedEventProperty = DependencyProperty.RegisterAttached("IsBeingWatched", typeof(bool), typeof(PresentationSource), new PropertyMetadata((bool)false)); // We use a private direct-only event to notify elements of when the // source changes. Use the public APIs AddSourceChangedHandler and // RemoveSourceChangedHandler to listen to this event. private static readonly RoutedEvent SourceChangedEvent = EventManager.RegisterRoutedEvent("SourceChanged", RoutingStrategy.Direct, typeof(SourceChangedEventHandler), typeof(PresentationSource)); // The lock we use to protect our static data. private static object _globalLock = new object(); // An array of weak-references to sources that we know about. private static WeakReferenceList _sources = new WeakReferenceList(_globalLock); // An array of weak-references to elements that need to know // about source changes. private static WeakReferenceList _watchers = new WeakReferenceList(_globalLock); #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections; using System.Diagnostics; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Threading; using System.Security; using System.Security.Permissions; using System.Windows.Media; using System.Windows.Media.Media3D; using System.Windows.Markup; using System.Windows.Input; using MS.Win32; using MS.Utility; using MS.Internal; using MS.Internal.PresentationCore; // SecurityHelper using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows { /// /// PresentationSource is the abstract base for classes that /// present content in another technology. In addition, this /// class provides static methods for working with these sources. /// ////// We currently have one implementation - HwndSource - that /// presents content in a Win32 HWND. /// ////// Keep this from being derived from in partial-trust code. /// [UIPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)] public abstract class PresentationSource : DispatcherObject { //------------------------------------------------------ // // Constructors // //----------------------------------------------------- #region Constructors ////// Constructs an instance of the PresentationSource object. /// ////// This is protected since this is an abstract base class. /// protected PresentationSource() { } ////// This constructor exists since the code gen for managed code generates a static constructor /// and in that code it initializes a critical field which causes an fxcop violation for the codegen /// constructor. /// [SecurityCritical] static PresentationSource() { } #endregion //----------------------------------------------------- // // Public Methods // //----------------------------------------------------- #region Public Methods ////// InputProvider given the Device type. /// ////// Critical: Sub classing this can let you provide fake input providers which /// can compromise the input system /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)] internal virtual IInputProvider GetInputProvider(Type inputDevice) { return null; } #endregion //------------------------------------------------------ // // Public Static Methods // //----------------------------------------------------- #region Public Static Methods ////// Returns the source in which the visual is being presented. /// /// The visual to find the source for. ///The source in which the visual is being presented. ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical - calls CriticalFromVisual. and returns the PresentationSource /// PublicOK: There exists a demand /// [SecurityCritical] public static PresentationSource FromVisual(Visual visual) { SecurityHelper.DemandUIWindowPermission(); return CriticalFromVisual(visual); } ////// Returns the source in which the Visual or Visual3D is being presented. /// /// The dependency object to find the source for. ///The source in which the dependency object is being presented. ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical - calls CriticalFromVisual. and returns the PresentationSource /// PublicOK: There exists a demand /// [SecurityCritical] public static PresentationSource FromDependencyObject(DependencyObject dependencyObject) { SecurityHelper.DemandUIWindowPermission(); return CriticalFromVisual(dependencyObject); } ////// Adds a handler for the SourceChanged event to the element. /// /// The element to add the handler too. /// The hander to add. ////// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement AddHandler() method. /// 2) Class handlers are not allowed. /// 3) The handlers will receive the SourceChanged event even if it was handled. /// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical: This code lets you get access to a presentationSource object. Here the link demand /// is defense in depth since , the object by itself has all public properties blocked off. Also this /// is part of startup code. /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] public static void AddSourceChangedHandler(IInputElement element, SourceChangedEventHandler handler) { if (element == null) { throw new ArgumentNullException("element"); } // Either UIElement or ContentElement if (!InputElement.IsValid(element)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "element"); } DependencyObject o = (DependencyObject)element; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectListinfo; if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.AddHandler(SourceChangedEvent, handler); info = uie.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { uie.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged); AddElementToWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.AddHandler(SourceChangedEvent, handler); info = uie3D.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { uie3D.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged); AddElementToWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.AddHandler(SourceChangedEvent, handler); info = ce.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) AddElementToWatchList(ce); } } } /// /// Removes a handler for the SourceChanged event to the element. /// /// The element to remove the handler from. /// The hander to remove. ////// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement RemoveHandler() method. /// public static void RemoveSourceChangedHandler(IInputElement e, SourceChangedEventHandler handler) { if (e == null) { throw new ArgumentNullException("e"); } if (!InputElement.IsValid(e)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "e"); } DependencyObject o = (DependencyObject)e; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectListinfo = null; EventHandlersStore store; // Either UIElement or ContentElement. if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.RemoveHandler(SourceChangedEvent, handler); store = uie.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged); ; RemoveElementFromWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.RemoveHandler(SourceChangedEvent, handler); store = uie3D.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie3D.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged); ; RemoveElementFromWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.RemoveHandler(SourceChangedEvent, handler); store = ce.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { RemoveElementFromWatchList(ce); } } } } /// /// Called by FrameworkElements when a framework ancenstor link of /// ContentElement has changed. /// /// /// The element whose ancestory may have changed. /// ////// This API is not available in the internet zone.It was protected /// as defense in depth since we did not want the PresentationSource /// surface to be exposed. /// [SecurityCritical] [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] [FriendAccessAllowed] // Built into Core, also used by Framework. internal static void OnAncestorChanged(ContentElement ce) { if (ce == null) { throw new ArgumentNullException("ce"); } if (true == (bool)ce.GetValue(GetsSourceChangedEventProperty)) { UpdateSourceOfElement(ce, null, null); } } #endregion //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ #region Public Properties ////// The visual target for the visuals being presented in the source. /// ////// Critical: Calls GetCompositionTargetCore() and returns a CompositionTarget object, which is considered critical. /// PublicOk: Protected by a LinkDemand /// public CompositionTarget CompositionTarget { [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] [SecurityCritical] get { return GetCompositionTargetCore(); } } ////// The root visual being presented in the source. /// ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical: This code is not safe to expose publicly since it lets you /// change rootvisual which puts popup code at risk /// PublicOK: Inheritance demand prevents random subclassing in partial trust /// and Linkdemand prevents unauthorized public callers /// public abstract Visual RootVisual { get; [SecurityCritical] [UIPermissionAttribute(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)] [UIPermissionAttribute(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)] set; } ////// Whether or not the object is disposed. /// public abstract bool IsDisposed { get; } #endregion //----------------------------------------------------- // // Public Static Properties // //------------------------------------------------------ #region Public Static Properties ////// Return a WeakReferenceList which supports returning an Enumerator /// over a ReadOnly SnapShot of the List of sources. The Enumerator /// skips over the any dead weak references in the list. /// ////// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// ////// Critical: This code exposes the sources which are deemed as critical. This is defense in depth. /// PublicOK: There exists a demand in this code /// public static IEnumerable CurrentSources { [SecurityCritical] get { SecurityHelper.DemandUIWindowPermission(); return CriticalCurrentSources; } } #endregion //----------------------------------------------------- // // Public Events // //----------------------------------------------------- #region Public Events ////// This event fires when content is rendered and ready for user interaction. /// public event EventHandler ContentRendered; #endregion //----------------------------------------------------- // // Protected Methods // //------------------------------------------------------ #region Protected Methods ////// Returns visual target for the given source. Implemented by /// the derived class. /// protected abstract CompositionTarget GetCompositionTargetCore(); // [SecurityCritical, SecurityTreatAsSafe] protected void RootChanged(Visual oldRoot, Visual newRoot) { PresentationSource oldSource = null; if (oldRoot == newRoot) { return; } // Always clear the RootSourceProperty on the old root. if (oldRoot != null) { oldSource = CriticalGetPresentationSourceFromElement(oldRoot, RootSourceProperty); oldRoot.ClearValue(RootSourceProperty); } // Always set the SourceProperty on the new root. if (newRoot != null) { newRoot.SetValue(RootSourceProperty, new SecurityCriticalDataForMultipleGetAndSet(this)); } UIElement oldRootUIElement = oldRoot as UIElement; UIElement newRootUIElement = newRoot as UIElement; // The IsVisible property can only be true if root visual is connected to a presentation source. // For Read-Only force-inherited properties, use a private update method. if(oldRootUIElement != null) { oldRootUIElement.UpdateIsVisibleCache(); } if(newRootUIElement != null) { newRootUIElement.UpdateIsVisibleCache(); } // Broadcast the Unloaded event starting at the old root visual if (oldRootUIElement != null) { oldRootUIElement.OnPresentationSourceChanged(false); } // Broadcast the Loaded event starting at the root visual if (newRootUIElement != null) { newRootUIElement.OnPresentationSourceChanged(true); } // To fire PresentationSourceChanged when the RootVisual changes; // rather than simulate a "parent" pointer change, we just walk the // collection of all nodes that need the event. foreach (DependencyObject element in _watchers) { // We only need to update those elements that are in the // same context as this presentation source. if (element.Dispatcher == Dispatcher) { PresentationSource testSource = CriticalGetPresentationSourceFromElement(element,CachedSourceProperty); // 1) If we are removing the rootvisual, then fire on any node whos old // PresetationSource was the oldSource. // 2) If we are attaching a rootvisual then fire on any node whos old // PresentationSource is null; if (oldSource == testSource || null == testSource) { UpdateSourceOfElement(element, null, null); } } } } /// /// Called by derived classes to indicate that they need to be tracked. /// protected void AddSource() { _sources.Add(this); } ////// Called by derived classes to indicate that they no longer need to be tracked. /// protected void RemoveSource() { _sources.Remove(this); } ////// Sets the ContentRendered event to null. /// protected void ClearContentRenderedListeners() { ContentRendered = null; } #endregion //----------------------------------------------------- // // Internal Methods // //------------------------------------------------------ // None //------------------------------------------------------ // // Internal Static Methods // //----------------------------------------------------- #region Internal Static Methods ////// Called by UIElement(3D)s when a visual ancestor link has changed. /// /// The UIElement whose ancestory may have changed. /// Event Args. ////// Critical: This code calls into a critical code path UpdateSourceOfElement. /// TreatAsSafe: This code does not access any critical data itself and does not expose /// anything /// [SecurityCritical, SecurityTreatAsSafe] internal static void OnVisualAncestorChanged(DependencyObject uie, AncestorChangedEventArgs e) { Debug.Assert(InputElement.IsUIElement3D(uie) || InputElement.IsUIElement(uie)); if (true == (bool)uie.GetValue(GetsSourceChangedEventProperty)) { UpdateSourceOfElement(uie, e.Ancestor, e.OldParent); } } ////// Critical - Returns the PresentationSource /// [FriendAccessAllowed] // To allow internal code paths to access this function [SecurityCritical] internal static PresentationSource CriticalFromVisual(DependencyObject v) { return CriticalFromVisual(v, true /* enable2DTo3DTransition */); } ////// Critical - uses RootSourceProperty. and returns the PresentationSource /// /// The dependency object to find the source for /// /// Determines whether when walking the tree to enable transitioning from a 2D child /// to a 3D parent or to stop once a 3D parent is encountered. /// [FriendAccessAllowed] // To allow internal code paths to access this function [SecurityCritical] internal static PresentationSource CriticalFromVisual(DependencyObject v, bool enable2DTo3DTransition) { if (v == null) { throw new ArgumentNullException("v"); } PresentationSource source = FindSource(v, enable2DTo3DTransition); // Don't hand out a disposed source. if (null != source && source.IsDisposed) { source = null; } return source; } ////// Fire the event when content is rendered and ready for user interaction. /// /// internal static object FireContentRendered(object arg) { PresentationSource ps = (PresentationSource)arg; if (ps.ContentRendered != null) { ps.ContentRendered(arg, EventArgs.Empty); } return null; } #endregion //------------------------------------------------------ // // Internal Properties // //----------------------------------------------------- // None //----------------------------------------------------- // // Internal Events // //----------------------------------------------------- // None //------------------------------------------------------ // // Private Static Methods // //----------------------------------------------------- #region Private Static Methods ////// Return a WeakReferenceList which supports returning an Enumerator /// over a ReadOnly SnapShot of the List of sources. The Enumerator /// skips over the any dead weak references in the list. /// ////// Critical: This code exposes the sources which are deemed as critical. This is internal access point. /// Public consumers should use CurrentSources /// internal static IEnumerable CriticalCurrentSources { [SecurityCritical] get { return (IEnumerable)_sources; } } ////// Critical: Returns a presentationsource given a canister /// [SecurityCritical] private static PresentationSource CriticalGetPresentationSourceFromElement(DependencyObject dObject,DependencyProperty dp) { PresentationSource testSource; SecurityCriticalDataForMultipleGetAndSettempCriticalDataWrapper = (SecurityCriticalDataForMultipleGetAndSet < PresentationSource > ) dObject.GetValue(dp); if (tempCriticalDataWrapper == null || tempCriticalDataWrapper.Value == null) { testSource = null; } else { testSource = tempCriticalDataWrapper.Value; } return testSource; } /// /// Critical: This code acceses PresentationSource and stores it. /// [SecurityCritical] private static void AddElementToWatchList(DependencyObject element) { if(_watchers.Add(element)) { element.SetValue(CachedSourceProperty,new SecurityCriticalDataForMultipleGetAndSet(PresentationSource.FindSource(element))); element.SetValue(GetsSourceChangedEventProperty, true); } } /// /// Critical: This code acceses PresentationSource /// TreatAsSafe: This code is safe to expose. /// [SecurityCritical,SecurityTreatAsSafe] private static void RemoveElementFromWatchList(DependencyObject element) { if(_watchers.Remove(element)) { element.ClearValue(CachedSourceProperty); element.ClearValue(GetsSourceChangedEventProperty); } } ////// Critical - Returns a PresentationSource. /// [SecurityCritical] private static PresentationSource FindSource(DependencyObject o) { return FindSource(o, true /* enable2DTo3DTransition */); } ////// Critical - uses RootSourceProperty and returns the PresentationSource /// /// The dependency object to find the source for /// /// Determines whether when walking the tree to enable transitioning from a 2D child /// to a 3D parent or to stop once a 3D parent is encountered. /// [SecurityCritical] private static PresentationSource FindSource(DependencyObject o, bool enable2DTo3DTransition) { PresentationSource source = null; // For "Visual" nodes GetRootVisual() climbs to the top of the // visual tree (parent==null) // For "ContentElements" it climbs the logical parent until it // reaches a visual then climbs to the top of the visual tree. DependencyObject v = InputElement.GetRootVisual(o, enable2DTo3DTransition); if (v != null) { source = CriticalGetPresentationSourceFromElement(v, RootSourceProperty); } return source; } ////// Critical: This code accesses PresentationSource which is a critical resource. It then /// packages it into an event args and fires it into the tree. /// [SecurityCritical] private static bool UpdateSourceOfElement(DependencyObject doTarget, DependencyObject doAncestor, DependencyObject doOldParent) { bool calledOut = false; PresentationSource realSource = FindSource(doTarget); PresentationSource cachedSource = CriticalGetPresentationSourceFromElement(doTarget, CachedSourceProperty); if (cachedSource != realSource) { doTarget.SetValue(CachedSourceProperty, new SecurityCriticalDataForMultipleGetAndSet(realSource)); SourceChangedEventArgs args = new SourceChangedEventArgs(cachedSource, realSource); args.RoutedEvent=SourceChangedEvent; if (InputElement.IsUIElement(doTarget)) { ((UIElement)doTarget).RaiseEvent(args); } else if (InputElement.IsContentElement(doTarget)) { ((ContentElement)doTarget).RaiseEvent(args); } else { ((UIElement3D)doTarget).RaiseEvent(args); } calledOut = true; } return calledOut; } #endregion //------------------------------------------------------ // // Private Static Members // //------------------------------------------------------ #region Private Static Members // We use a private DP for the RootSource (the connection from the root // element in a tree to the source it is displayed in). Use the public // API FromVisual to get the source that a visual is displayed in. /// /// Critical - used to store PresentationSource /// [SecurityCritical] private static readonly DependencyProperty RootSourceProperty = DependencyProperty.RegisterAttached("RootSource", typeof(SecurityCriticalDataForMultipleGetAndSet), typeof(PresentationSource), new PropertyMetadata((SecurityCriticalDataForMultipleGetAndSet )null)); // We use a private DP for the CachedSource (stored on the elements // that we are watching, so that we can send a change notification). // Use the public API FromVisual to get the source that a visual is // displayed in. /// /// Critical - used to store PresentationSource /// [SecurityCritical] private static readonly DependencyProperty CachedSourceProperty = DependencyProperty.RegisterAttached("CachedSource", typeof(SecurityCriticalDataForMultipleGetAndSet), typeof(PresentationSource), new PropertyMetadata((SecurityCriticalDataForMultipleGetAndSet )null)); // We use a private DP to mark elements that we are watchin. private static readonly DependencyProperty GetsSourceChangedEventProperty = DependencyProperty.RegisterAttached("IsBeingWatched", typeof(bool), typeof(PresentationSource), new PropertyMetadata((bool)false)); // We use a private direct-only event to notify elements of when the // source changes. Use the public APIs AddSourceChangedHandler and // RemoveSourceChangedHandler to listen to this event. private static readonly RoutedEvent SourceChangedEvent = EventManager.RegisterRoutedEvent("SourceChanged", RoutingStrategy.Direct, typeof(SourceChangedEventHandler), typeof(PresentationSource)); // The lock we use to protect our static data. private static object _globalLock = new object(); // An array of weak-references to sources that we know about. private static WeakReferenceList _sources = new WeakReferenceList(_globalLock); // An array of weak-references to elements that need to know // about source changes. private static WeakReferenceList _watchers = new WeakReferenceList(_globalLock); #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
- DeferredSelectedIndexReference.cs
- XmlCharacterData.cs
- CodeExporter.cs
- State.cs
- oledbmetadatacolumnnames.cs
- PolyBezierSegment.cs
- AssociationTypeEmitter.cs
- XamlStream.cs
- GAC.cs
- ConfigurationManagerHelper.cs
- Latin1Encoding.cs
- NonPrimarySelectionGlyph.cs
- ListViewAutomationPeer.cs
- EventRouteFactory.cs
- AssociationType.cs
- Comparer.cs
- RouteData.cs
- HandleRef.cs
- NestPullup.cs
- LineServicesCallbacks.cs
- CustomAttribute.cs
- AttributeParameterInfo.cs
- ActivityContext.cs
- ComponentChangingEvent.cs
- HashSetEqualityComparer.cs
- Matrix3D.cs
- EllipseGeometry.cs
- FastEncoder.cs
- PasswordBox.cs
- HighlightComponent.cs
- RemoteArgument.cs
- SettingsPropertyValue.cs
- SchemaTypeEmitter.cs
- Stream.cs
- DataStreams.cs
- UrlParameterReader.cs
- LabelAutomationPeer.cs
- ForceCopyBuildProvider.cs
- PanelDesigner.cs
- CodeAttributeArgument.cs
- TrackPoint.cs
- CodeTypeParameterCollection.cs
- TextContainer.cs
- HttpProfileGroupBase.cs
- altserialization.cs
- XmlSecureResolver.cs
- HttpDebugHandler.cs
- CacheMode.cs
- ProtocolImporter.cs
- FileCodeGroup.cs
- ToolStripMenuItem.cs
- PermissionSet.cs
- SvcMapFileSerializer.cs
- ContainerControl.cs
- AllMembershipCondition.cs
- CssTextWriter.cs
- Timer.cs
- MediaTimeline.cs
- DataGridViewColumnTypeEditor.cs
- LogManagementAsyncResult.cs
- DemultiplexingDispatchMessageFormatter.cs
- UnicodeEncoding.cs
- Listbox.cs
- DataControlButton.cs
- TextRunTypographyProperties.cs
- ToolStripDropDown.cs
- StrokeRenderer.cs
- SystemInfo.cs
- RemoteWebConfigurationHost.cs
- WebBrowser.cs
- NullableDecimalMinMaxAggregationOperator.cs
- GeometryModel3D.cs
- NamespaceCollection.cs
- _WinHttpWebProxyDataBuilder.cs
- LinkedResourceCollection.cs
- XhtmlBasicImageAdapter.cs
- ConditionCollection.cs
- ExpressionDumper.cs
- TextServicesPropertyRanges.cs
- ListControlConvertEventArgs.cs
- DifferencingCollection.cs
- ListItemParagraph.cs
- IdentityModelDictionary.cs
- SchemaImporterExtensionElement.cs
- TemplateLookupAction.cs
- ModelUtilities.cs
- GeneralTransformGroup.cs
- RemotingSurrogateSelector.cs
- Int32EqualityComparer.cs
- SQLBinaryStorage.cs
- AnimationTimeline.cs
- StrongNameMembershipCondition.cs
- AppearanceEditorPart.cs
- ClientApiGenerator.cs
- InvalidPrinterException.cs
- ApplicationCommands.cs
- CodeVariableDeclarationStatement.cs
- PasswordRecovery.cs
- FileDialogCustomPlace.cs
- SoapAttributeOverrides.cs