ComponentDispatcher.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / System / Windows / Interop / ComponentDispatcher.cs / 1305600 / ComponentDispatcher.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

using System; 
using System.Threading; 
using System.Diagnostics.CodeAnalysis;
using System.Security; 
using System.Security.Permissions;
using MS.Internal;
using MS.Win32;
using MS.Internal.WindowsBase; 

namespace System.Windows.Interop 
{ 
    /// 
    ///     This is the delegate used for registering with the 
    ///     ThreadFilterMessage and ThreadPreprocessMessage Events.
    ///
    [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
    public delegate void ThreadMessageEventHandler(ref MSG msg, ref bool handled); 

    ///  
    /// This is a static class used to share control of the message pump. 
    /// Whomever is pumping (i.e. calling GetMessage()) will also send
    /// the messages to RaiseThreadKeyMessage() which will dispatch them to 
    /// the ThreadFilterMessage and then (if not handled) to the ThreadPreprocessMessage
    /// delegates.  That way everyone can be included in the message loop.
    /// Currently only Keyboard messages are supported.
    /// There are also Events for Idle and facilities for Thread-Modal operation. 
    ///
    public static class ComponentDispatcher 
    { 
        static ComponentDispatcher()
        { 
            _threadSlot = Thread.AllocateDataSlot();
        }

        private static ComponentDispatcherThread CurrentThreadData 
        {
            get 
            { 
                ComponentDispatcherThread data;
                object obj = Thread.GetData(_threadSlot); 
                if(null == obj)
                {
                    data = new ComponentDispatcherThread();
                    Thread.SetData(_threadSlot, data); 
                }
                else 
                { 
                    data = (ComponentDispatcherThread) obj;
                } 
                return data;
            }
        }
 
        // Properties
 
        ///  
        /// Returns true if one or more components has gone modal.
        /// Although once one component is modal a 2nd shouldn't. 
        ///
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API.
        ///  
        /// 
        ///     Critical: This is blocked off as defense in depth 
        ///     PublicOk: There is a demand here 
        /// 
        public static bool IsThreadModal 
        {
            [SecurityCritical]
            get
            { 
                SecurityHelper.DemandUnrestrictedUIPermission();
                ComponentDispatcherThread data = ComponentDispatcher.CurrentThreadData; 
                return data.IsThreadModal; 
            }
        } 

        /// 
        /// Returns "current" message.   More exactly the last MSG Raised.
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        ///  
        /// 
        ///     Critical: This is blocked off as defense in depth 
        ///     PublicOk: There is a demand here
        /// 
        public static MSG CurrentKeyboardMessage
        { 
            [SecurityCritical]
            get 
            { 
                SecurityHelper.DemandUnrestrictedUIPermission();
                return ComponentDispatcher.CurrentThreadData.CurrentKeyboardMessage; 
            }
        }

        ///  
        /// Returns "current" message.   More exactly the last MSG Raised.
        /// 
        ///  
        ///     Critical: This is blocked off as defense in depth
        ///  
        internal static MSG UnsecureCurrentKeyboardMessage
        {
            [FriendAccessAllowed] // Built into Base, used by Core or Framework.
            [SecurityCritical] 
            get
            { 
                return ComponentDispatcher.CurrentThreadData.CurrentKeyboardMessage; 
            }
 
            [FriendAccessAllowed] // Built into Base, used by Core or Framework.
            [SecurityCritical]
            set
            { 
                ComponentDispatcher.CurrentThreadData.CurrentKeyboardMessage = value;
            } 
        } 

        // Methods 

        /// 
        /// A component calls this to go modal.  Current thread wide only.
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        ///  
        /// 
        ///     Critical: This is blocked off as defense in depth 
        ///     PublicOk: There is a demand here
        /// 
        [SecurityCritical]
        public static void PushModal() 
        {
            SecurityHelper.DemandUnrestrictedUIPermission(); 
            CriticalPushModal(); 
        }
 
        /// 
        /// A component calls this to go modal.  Current thread wide only.
        ///
        ///  
        ///     Critical: This bypasses the demand for unrestricted UIPermission.
        ///  
        [SecurityCritical] 
        internal static void CriticalPushModal()
        { 
            ComponentDispatcherThread data = ComponentDispatcher.CurrentThreadData;
            data.PushModal();
        }
 
        /// 
        /// A component calls this to end being modal. 
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        /// 
        /// 
        ///     Critical: This is blocked off as defense in depth
        ///     PublicOk: There is a demand here 
        /// 
        [SecurityCritical] 
        public static void PopModal() 
        {
            SecurityHelper.DemandUnrestrictedUIPermission(); 
            CriticalPopModal();
        }

        ///  
        /// A component calls this to end being modal.
        /// 
        ///  
        ///     Critical: This bypasses the demand for unrestricted UIPermission.
        ///  
        [SecurityCritical]
        internal static void CriticalPopModal()
        {
            ComponentDispatcherThread data = ComponentDispatcher.CurrentThreadData; 
            data.PopModal();
        } 
 
        /// 
        /// The message loop pumper calls this when it is time to do idle processing. 
        ///
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API.
        ///  
        /// 
        ///     Critical: This is blocked off as defense in depth 
        ///     PublicOk: There is a demand here 
        /// 
        [SecurityCritical] 
        [UIPermissionAttribute(SecurityAction.LinkDemand,Unrestricted=true)]
        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
        public static void RaiseIdle()
        { 
            ComponentDispatcherThread data = ComponentDispatcher.CurrentThreadData;
            data.RaiseIdle(); 
        } 

        ///  
        /// The message loop pumper calls this for every keyboard message.
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        /// 
        ///  
        ///     Critical: This is blocked off as defense in depth 
        ///     PublicOk: There is a demand here
        ///  
        [SecurityCritical]
        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
        [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
        [UIPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] 
        public static bool RaiseThreadMessage(ref MSG msg)
        { 
            ComponentDispatcherThread data = ComponentDispatcher.CurrentThreadData; 
            return data.RaiseThreadMessage(ref msg);
        } 

        // Events

        ///  
        /// Components register delegates with this event to handle
        /// thread idle processing. 
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        /// 
        /// 
        ///     Critical: This is blocked off as defense in depth
        ///     PublicOk: There is a demand here 
        /// 
        public static event EventHandler ThreadIdle 
        { 
            [SecurityCritical]
            add { 
                SecurityHelper.DemandUnrestrictedUIPermission();
                ComponentDispatcher.CurrentThreadData.ThreadIdle += value;
            }
            [SecurityCritical] 
            remove {
                SecurityHelper.DemandUnrestrictedUIPermission(); 
                ComponentDispatcher.CurrentThreadData.ThreadIdle -= value; 
            }
        } 

        /// 
        /// Components register delegates with this event to handle
        /// Keyboard Messages (first chance processing). 
        ///
        ///  
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        /// 
        ///  
        ///     Critical: This is blocked off as defense in depth
        ///     PublicOk: There is a demand here
        /// 
        [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] 
        public static event ThreadMessageEventHandler ThreadFilterMessage
        { 
            [SecurityCritical] 
            add {
                SecurityHelper.DemandUnrestrictedUIPermission(); 
                ComponentDispatcher.CurrentThreadData.ThreadFilterMessage += value;
            }
            [SecurityCritical]
            remove { 
                SecurityHelper.DemandUnrestrictedUIPermission();
                ComponentDispatcher.CurrentThreadData.ThreadFilterMessage -= value; 
            } 
        }
 
        /// 
        /// Components register delegates with this event to handle
        /// Keyboard Messages (second chance processing).
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        ///  
        /// 
        ///     Critical: Exposing the raw input enables tampering. (The MSG structure is passed by-ref.) 
        ///     PublicOk: There is a demand here
        /// 
        [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
        public static event ThreadMessageEventHandler ThreadPreprocessMessage 
        {
            [UIPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] 
            [SecurityCritical] 
            add
            { 
                ComponentDispatcher.CurrentThreadData.ThreadPreprocessMessage += value;
            }
            [UIPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
            [SecurityCritical] 
            remove {
                ComponentDispatcher.CurrentThreadData.ThreadPreprocessMessage -= value; 
            } 
        }
 
        /// 
        ///     Adds the specified handler to the front of the invocation list
        ///     of the PreprocessMessage event.
        ///  
        /// 
        ///     Critical: Not to expose raw input, which may be destined for a 
        ///     window in another security context. Also, MSG contains a window 
        ///     handle, which we don't want to expose.
        ///  
        [SecurityCritical]
        internal static void CriticalAddThreadPreprocessMessageHandlerFirst(ThreadMessageEventHandler handler)
        {
            ComponentDispatcher.CurrentThreadData.AddThreadPreprocessMessageHandlerFirst(handler); 
        }
 
        ///  
        ///     Removes the first occurance of the specified handler from the
        ///     invocation list of the PreprocessMessage event. 
        /// 
        /// 
        ///     Critical: Not to expose raw input, which may be destined for a
        ///     window in another security context. Also, MSG contains a window 
        ///     handle, which we don't want to expose.
        ///  
        [SecurityCritical] 
        internal static void CriticalRemoveThreadPreprocessMessageHandlerFirst(ThreadMessageEventHandler handler)
        { 
            ComponentDispatcher.CurrentThreadData.RemoveThreadPreprocessMessageHandlerFirst(handler);
        }

        ///  
        /// Components register delegates with this event to handle
        /// a component on this thread has "gone modal", when previously none were. 
        /// 
        /// 
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        /// 
        /// 
        ///     Critical: This is blocked off as defense in depth
        ///     PublicOk: There is a demand here 
        /// 
        public static event EventHandler EnterThreadModal 
        { 
            [SecurityCritical]
            add { 
                SecurityHelper.DemandUnrestrictedUIPermission();
                ComponentDispatcher.CurrentThreadData.EnterThreadModal += value;
            }
            [SecurityCritical] 
            remove {
                SecurityHelper.DemandUnrestrictedUIPermission(); 
                ComponentDispatcher.CurrentThreadData.EnterThreadModal -= value; 
            }
        } 

        /// 
        /// Components register delegates with this event to handle
        /// all components on this thread are done being modal. 
        ///
        ///  
        ///     Callers must have UIPermission(PermissionState.Unrestricted) to call this API. 
        /// 
        ///  
        ///     Critical: This is blocked off as defense in depth
        ///     PublicOk: There is a demand here
        /// 
        public static event EventHandler LeaveThreadModal 
        {
            [SecurityCritical] 
            add 
            {
                SecurityHelper.DemandUnrestrictedUIPermission(); 
                ComponentDispatcher.CurrentThreadData.LeaveThreadModal += value;
            }
            [SecurityCritical]
            remove { 
                SecurityHelper.DemandUnrestrictedUIPermission();
                ComponentDispatcher.CurrentThreadData.LeaveThreadModal -= value; 
            } 
        }
 
        // member data
        private static System.LocalDataStoreSlot _threadSlot;
    }
}; 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK