HwndSource.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / System / Windows / InterOp / HwndSource.cs / 3 / HwndSource.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2004
//
//  File: HwndSource.cs 
//-----------------------------------------------------------------------------
 
using System.Collections; 
using System.Collections.Generic;
using System.Threading; 
using System.Windows.Threading;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Interop; 
using System.Runtime.InteropServices;
using MS.Win32; 
using MS.Utility; 
using MS.Internal;
using MS.Internal.PresentationCore;                        // SecurityHelper 
using Microsoft.Win32;
using System.Diagnostics;
using System.ComponentModel;
using System; 
using System.Security;
using System.Security.Permissions; 
using System.IO; 

using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings
 
namespace System.Windows.Interop
{ 
    ///  
    ///     The HwndSource class presents content within a Win32 HWND.
    ///  
    public class HwndSource : PresentationSource, IDisposable, IWin32Window, IKeyboardInputSink
    {
        /// 
        ///     Critical: This code calls into RegisterWindowMesssage which is critical 
        ///     TreatAsSafe: This is safe to call as no external parameters are taken in
        ///  
        [SecurityCritical,SecurityTreatAsSafe] 
        static HwndSource()
        { 
            _threadSlot = Thread.AllocateDataSlot();
        }

        ///  
        ///    Constructs an instance of the HwndSource class that will always resize to its content size.
        ///  
        ///  
        ///     The Win32 class styles for this window.
        ///  
        /// 
        ///     The Win32 styles for this window.
        /// 
        ///  
        ///     The extended Win32 styles for this window.
        ///  
        ///  
        ///     The position of the left edge of this window.
        ///  
        /// 
        ///     The position of the upper edge of this window.
        /// 
        ///  
        ///     The name of this window.
        ///  
        ///  
        ///     The Win32 window that should be the parent of this window.
        ///  
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// 
        ///  
        ///     Added a demand - so that this API does not work in InternetZone.
        ///     Critical: This accesses critical code Initialize 
        ///     PublicOK: This code has a demand which will ensure that it does 
        ///     not work in partial trust without the correct permissions
        ///  
        [SecurityCritical]
        public HwndSource(
            int classStyle,
            int style, 
            int exStyle,
            int x, 
            int y, 
            string name,
            IntPtr parent) 
        {
            SecurityHelper.DemandUIWindowPermission();

            HwndSourceParameters param = new HwndSourceParameters(name); 
            param.WindowClassStyle = classStyle;
            param.WindowStyle = style; 
            param.ExtendedWindowStyle = exStyle; 
            param.SetPosition(x, y);
            param.ParentWindow = parent; 
            Initialize(param);
        }

        ///  
        ///    Constructs an instance of the HwndSource class. This version requires an
        ///    explicit width and height be sepecified. 
        ///  
        /// 
        ///     The Win32 class styles for this window. 
        /// 
        /// 
        ///     The Win32 styles for this window.
        ///  
        /// 
        ///     The extended Win32 styles for this window. 
        ///  
        /// 
        ///     The position of the left edge of this window. 
        /// 
        /// 
        ///     The position of the upper edge of this window.
        ///  
        /// 
        ///     The width of this window. 
        ///  
        /// 
        ///     The height of this window. 
        /// 
        /// 
        ///     The name of this window.
        ///  
        /// 
        ///     The Win32 window that should be the parent of this window. 
        ///  
        /// 
        ///     Indicates that HwndSource should include the non-client area 
        ///     of the hwnd when it calls the Layout Manager
        /// 
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        /// 
        ///  
        ///     Added a demand - so that this API does not work in InternetZone. 
        ///     Critical: This acceses critical code Initialize
        ///     PublicOK: This code has a demand which will ensure that it does 
        ///     not work in partial trust without the correct permissions
        /// 
        [SecurityCritical]
        public HwndSource(int classStyle, 
                          int style,
                          int exStyle, 
                          int x, 
                          int y,
                          int width, 
                          int height,
                          string name,
                          IntPtr parent,
                          bool adjustSizingForNonClientArea) 
        {
            SecurityHelper.DemandUIWindowPermission(); 
 
            HwndSourceParameters parameters = new HwndSourceParameters(name, width, height);
            parameters.WindowClassStyle = classStyle; 
            parameters.WindowStyle = style;
            parameters.ExtendedWindowStyle = exStyle;
            parameters.SetPosition(x, y);
            parameters.ParentWindow = parent; 
            parameters.AdjustSizingForNonClientArea = adjustSizingForNonClientArea;
            Initialize(parameters); 
        } 

        ///  
        ///    Constructs an instance of the HwndSource class. This version requires an
        ///    explicit width and height be sepecified.
        /// 
        ///  
        ///     The Win32 class styles for this window.
        ///  
        ///  
        ///     The Win32 styles for this window.
        ///  
        /// 
        ///     The extended Win32 styles for this window.
        /// 
        ///  
        ///     The position of the left edge of this window.
        ///  
        ///  
        ///     The position of the upper edge of this window.
        ///  
        /// 
        ///     The width of this window.
        /// 
        ///  
        ///     The height of this window.
        ///  
        ///  
        ///     The name of this window.
        ///  
        /// 
        ///     The Win32 window that should be the parent of this window.
        /// 
        ///  
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        ///  
        ///  
        ///     Added a demand - so that this API does not work in InternetZone.
        ///     Critical: This accesses critical code Initialize 
        ///     PublicOK: This code has a demand which will ensure that it does
        ///     not work in partial trust without the correct permissions
        /// 
        [SecurityCritical] 
        public HwndSource(
            int classStyle, 
            int style, 
            int exStyle,
            int x, 
            int y,
            int width,
            int height,
            string name, 
            IntPtr parent)
        { 
            SecurityHelper.DemandUIWindowPermission(); 

            HwndSourceParameters parameters = new HwndSourceParameters(name, width, height); 
            parameters.WindowClassStyle = classStyle;
            parameters.WindowStyle = style;
            parameters.ExtendedWindowStyle = exStyle;
            parameters.SetPosition(x, y); 
            parameters.ParentWindow = parent;
            Initialize(parameters); 
        } 

        ///  
        ///    HwndSource Ctor
        /// 
        ///  parameter block 
        ///  
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        ///  
        ///  
        ///     Critical: This acceses critical code Initialize
        ///  
        [SecurityCritical]
        [UIPermissionAttribute(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)]
        public HwndSource(HwndSourceParameters parameters)
        { 
            Initialize(parameters);
        } 
        ///  
        ///    HwndSource Ctor
        ///  
        ///  parameter block 
        /// 
        ///     Critical: This code access critical (HwndMouseInputProvider, HwndKeyboardInputProvider
        ///     ,HwndStylusInputProvider and the various hooks)objects and creates the 
        ///     providers under elevation.
        ///  
        [SecurityCritical] 
        private void Initialize(HwndSourceParameters parameters)
        { 
            _mouse = new SecurityCriticalDataClass(new HwndMouseInputProvider(this));
            _keyboard = new SecurityCriticalDataClass(new HwndKeyboardInputProvider(this));
            _layoutHook = new HwndWrapperHook(LayoutFilterMessage);
            _inputHook = new HwndWrapperHook(InputFilterMessage); 
            _hwndTargetHook = new HwndWrapperHook(HwndTargetFilterMessage);
 
            _publicHook = new HwndWrapperHook(PublicHooksFilterMessage); 

            // When processing WM_SIZE, LayoutFilterMessage must be invoked before 
            // HwndTargetFilterMessage. This way layout will be updated before resizing
            // HwndTarget, resulting in single render per resize. This means that
            // layout hook should appear before HwndTarget hook in the wrapper hooks
            // list. If this is done the other way around, first HwndTarget resize will 
            // force re-render, then layout will be updated according to the new size,
            // scheduling another render. 
            HwndWrapperHook[] wrapperHooks = { _hwndTargetHook, _layoutHook, _inputHook, null }; 

            if(null != parameters.HwndSourceHook) 
            {
                _hooks = new ArrayList(8);
                _hooks.Insert(0, parameters.HwndSourceHook);
                wrapperHooks[3] = _publicHook; 
            }
 
            // A window must be marked WS_EX_LAYERED if (and only if): 
            // 1) it is not a child window
            //    -- AND -- 
            // 2) a color-key is specified
            // 3) or an opacity other than 1.0 is specified
            // 4) or per-pixel alpha is requested.
            if((parameters.WindowStyle & NativeMethods.WS_CHILD) == 0 && 
               ( //parameters.ColorKey != null ||
                 //!MS.Internal.DoubleUtil.AreClose(parameters.Opacity, 1.0) || 
                parameters.UsesPerPixelOpacity)) 
            {
                parameters.ExtendedWindowStyle |= NativeMethods.WS_EX_LAYERED; 
            }
            else
            {
                parameters.ExtendedWindowStyle &= (~NativeMethods.WS_EX_LAYERED); 
            }
 
 
            _constructionParameters = parameters;
            _hwndWrapper = new HwndWrapper(parameters.WindowClassStyle, 
                                       parameters.WindowStyle,
                                       parameters.ExtendedWindowStyle,
                                       parameters.PositionX,
                                       parameters.PositionY, 
                                       parameters.Width,
                                       parameters.Height, 
                                       parameters.WindowName, 
                                       parameters.ParentWindow,
                                       wrapperHooks); 

            _hwndTarget = new HwndTarget(_hwndWrapper.Handle);
            //_hwndTarget.ColorKey = parameters.ColorKey;
            //_hwndTarget.Opacity = parameters.Opacity; 
            _hwndTarget.UsesPerPixelOpacity = parameters.UsesPerPixelOpacity;
            if(_hwndTarget.UsesPerPixelOpacity) 
            { 
                _hwndTarget.BackgroundColor = Colors.Transparent;
 
                // Prevent this window from being themed.
                UnsafeNativeMethods.CriticalSetWindowTheme(new HandleRef(this, _hwndWrapper.Handle), "", "");
            }
            _constructionParameters = null; 

            if (!parameters.HasAssignedSize) 
                _sizeToContent = SizeToContent.WidthAndHeight; 
            _adjustSizingForNonClientArea = parameters.AdjustSizingForNonClientArea;
 
            // Listen to the UIContext.Disposed event so we can clean up.
            // The HwndTarget cannot work without a MediaContext which
            // is disposed when the UIContext is disposed.  So we need to
            // dispose the HwndTarget and also never use it again (to 
            // paint or process input).  The easiest way to do this is to just
            // dispose the HwndSource at the same time. 
            _weakShutdownHandler = new WeakEventDispatcherShutdown(this, this.Dispatcher); 

            // Listen to the HwndWrapper.Disposed event so we can clean up. 
            // The HwndTarget cannot work without a live HWND, and since
            // the HwndSource represents an HWND, we make sure we dispose
            // ourselves if the HWND is destroyed out from underneath us.
            _hwndWrapper.Disposed += new EventHandler(OnHwndDisposed); 

            _stylus = new SecurityCriticalDataClass(new HwndStylusInputProvider(this)); 
 
            // WM_APPCOMMAND events are handled thru this.
            _appCommand = new SecurityCriticalDataClass(new HwndAppCommandInputProvider(this)); 

            // Register the top level source with the ComponentDispatcher.
            if (parameters.TreatAsInputRoot)
            { 
                _weakPreprocessMessageHandler = new WeakEventPreprocessMessage(this);
            } 
            AddSource(); 

            // Register dropable window. 
            // The checking CallerHasPermissionWithAppDomainOptimization will call RegisterDropTarget
            // safely without the security exception in case of no unmanaged code permission.
            // So RegisterDropTarget will be called safely in case of having the unmanged code permission.
            // Otherwise, the security exception cause System.Printing to be instatiated which will 
            // load system.drawing module.
            if (_hwndWrapper.Handle != IntPtr.Zero && 
                SecurityHelper.CallerHasPermissionWithAppDomainOptimization(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode))) 
            {
                // This call is safe since DragDrop.RegisterDropTarget is checking the unmanged 
                // code permission.
                DragDrop.RegisterDropTarget(_hwndWrapper.Handle);
                _registeredDropTargetCount++;
            } 
        }
 
        ///  
        ///     Disposes the object
        ///  
        ///
        /// This API is not available in Internet Zone.
        ///
        public void Dispose() 
        {
            Dispose(true); 
            GC.SuppressFinalize(this); 
        }
 
        /// 
        ///     Adds a hook that gets called for every window message.
        /// 
        ///  
        ///     The hook to add.
        ///  
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// 
        ///
        /// Critical - uses a critical field.
        /// PublicOK - as there's a demand.
        /// 
        [SecurityCritical ]
        public void AddHook(HwndSourceHook hook) 
        { 
            SecurityHelper.DemandUIWindowPermission();
 
            CheckDisposed(true);

            if(_hooks == null)
            { 
                _hooks = new ArrayList(8);
                _hwndWrapper.AddHook(_publicHook); 
            } 
            _hooks.Insert(0, hook);
        } 

        /// 
        ///     Removes a hook that was previously added.
        ///  
        /// 
        ///     The hook to remove. 
        ///  
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        ///
        ///
        /// Critical - accesses a crtical field - _publicHook
        /// PublicOK - performs a demand. 
        ///
        [SecurityCritical ] 
        public void RemoveHook(HwndSourceHook hook) 
        {
            SecurityHelper.DemandUIWindowPermission(); 

            //this.VerifyAccess();

            if(_hooks != null) 
            {
                _hooks.Remove(hook); 
                if(_hooks.Count == 0) 
                {
                    _hooks = null; 
                    _hwndWrapper.RemoveHook(_publicHook);
                }
            }
        } 

        ///  
        /// GetInputProvider - Given a InputDevice, returns corresponding Provider 
        /// 
        /// InputDevice for which we need InputProvider 
        /// InputProvider, if known
        ///
        /// This API is not available in Internet Zone.
        /// 
        /// 
        ///     Critical: This code accesses and returns critical data *providers* 
        ///  
        [SecurityCritical]
        internal override IInputProvider GetInputProvider(Type inputDevice) 
        {
            if (inputDevice == typeof(MouseDevice))
                return (_mouse    != null ?    _mouse.Value : null);
 
            if (inputDevice == typeof(KeyboardDevice))
                return (_keyboard != null ? _keyboard.Value : null); 
 
            if (inputDevice == typeof(StylusDevice))
                return (_stylus   != null ?   _stylus.Value : null); 

            return null;
        }
 
        /// 
        ///     Announces when this source is disposed. 
        ///  
        public event EventHandler Disposed;
 
        /// 
        ///     Announces when the SizeToContent property changes on this source.
        /// 
        public event EventHandler SizeToContentChanged; 

        ///  
        ///     Whether or not the object is disposed. 
        /// 
        public override bool IsDisposed {get {return _isDisposed;}} 

        /// 
        /// The Root Visual for this window. If it is a UIElement
        ///  
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        ///  
        /// 
        ///     Critical: This code sets a rootvisual which is risky to do because 
        ///     it can destabilize assumptions made in popup code
        ///     PublicOK: The getter is safe and the setter has a link demand to block unwarrented
        ///     public use
        ///  
        public override Visual RootVisual
        { 
            [SecurityCritical] 
            get
            { 
                if (_isDisposed)
                    return null;
                return (_rootVisual.Value);
            } 
            [SecurityCritical]
            [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] 
            set 
            {
                CheckDisposed(true); 

                RootVisualInternal = value;
            }
        } 

        ///  
        /// Critical: Acceses KeyboardInputProvider which is considered as critical data 
        /// also it can be used to set root visual which is deemed as an unsafe operation
        ///  
        private Visual RootVisualInternal
        {
            [SecurityCritical]
            set 
            {
                if (_rootVisual.Value != value) 
                { 
                    Visual oldRoot = _rootVisual.Value;
 
                    if(value != null)
                    {
                        _rootVisual.Value = value;
 
                        if(_rootVisual.Value is UIElement)
                        { 
                            ((UIElement)(_rootVisual.Value)).LayoutUpdated += new EventHandler(OnLayoutUpdated); 
                        }
 
                        if (_hwndTarget != null && _hwndTarget.IsDisposed == false)
                        {
                            _hwndTarget.RootVisual = _rootVisual.Value;
                        } 

                        UIElement.PropagateResumeLayout(null, value); 
                    } 
                    else
                    { 
                        _rootVisual.Value = null;
                        if (_hwndTarget != null && !_hwndTarget.IsDisposed)
                        {
                            _hwndTarget.RootVisual = null; 
                        }
                    } 
 
                    if(oldRoot != null)
                    { 
                        if(oldRoot is UIElement)
                        {
                            ((UIElement)oldRoot).LayoutUpdated -= new EventHandler(OnLayoutUpdated);
                        } 

                        UIElement.PropagateSuspendLayout(oldRoot); 
                    } 

                    RootChanged(oldRoot, _rootVisual.Value); 

                    if (IsLayoutActive() == true)
                    {
                        // Call the helper method SetLayoutSize to set Layout's size 
                        SetLayoutSize();
 
                        // Post the firing of ContentRendered as Input priority work item so that ContentRendered will be 
                        // fired after render query empties.
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new DispatcherOperationCallback(FireContentRendered), this); 
                    }
                    else
                    {
                        // Even though layout won't run (the root visual is either null or not 
                        // a UIElement), the hit-test results will certainly have changed.
                        InputManager.SafeCurrentNotifyHitTestInvalidated(); 
                    } 

                    // It is possible that someone would have closed the window in one of the 
                    // previous callouts - such as during RootChanged or during the layout
                    // we syncronously invoke.  In such cases, the state of this object would
                    // have been torn down.  We just need to protect against that.
                    if(_keyboard != null) 
                    {
                        _keyboard.Value.OnRootChanged(oldRoot, _rootVisual.Value); 
                    } 
                }
            } 
        }

        /// 
        ///     Returns the HwndSource that corresponds to the specified window. 
        /// 
        /// The window. 
        /// The source that corresponds to the specified window. 
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        ///
        /// 
        ///     Critical: This information is not ok to expose since this HwndSource
        ///     is deemed critical to expose 
        ///     PublicOK: There is a demand on this method that prevents this
        ///     from working in partial trust unless you have the right permissions. 
        ///  
        [SecurityCritical]
        public static HwndSource FromHwnd(IntPtr hwnd) 
        {
            SecurityHelper.DemandUIWindowPermission();
            return CriticalFromHwnd(hwnd);
        } 

        ///  
        ///    Critical: This code extracts the HwndSource for an HWND 
        ///    This function is only for internal consumption
        ///  
        [SecurityCritical]
        internal static HwndSource CriticalFromHwnd(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero) 
            {
                throw new ArgumentException(SR.Get(SRID.NullHwnd)); 
            } 
            HwndSource hwndSource = null;
            foreach (PresentationSource source in PresentationSource.CriticalCurrentSources) 
            {
                HwndSource test = source as HwndSource;
                if (test != null && test.CriticalHandle == hwnd)
                { 
                    // Don't hand out a disposed source.
                    if (!test.IsDisposed) 
                        hwndSource = test; 
                    break;
                } 
            }
            return hwndSource;
        }
 

        ///  
        ///     The visual manager for the visuals being presented in the source. 
        ///     Type-specific version of the CompositionTarget property for this source.
        ///  
        /// 
        ///     Critical: Accesses hwndTarget and returns it
        ///     PublicOk: Protected by a LinkDemand
        ///  
        public new HwndTarget CompositionTarget
        { 
            [SecurityCritical] 
            [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)]
            get 
            {
                if (_isDisposed)
                    return null;
 
                // Even though we created the HwndTarget, it can get disposed out from
                // underneath us. 
                if (_hwndTarget!= null && _hwndTarget.IsDisposed == true) 
                {
                    return null; 
                }

                return _hwndTarget;
            } 
        }
 
        ///  
        ///     Returns visual target for this source.
        ///  
        /// 
        ///     Critical: calls get_CompositionTarget() and returns its value.
        /// 
        [SecurityCritical] 
        protected override CompositionTarget GetCompositionTargetCore()
        { 
            return CompositionTarget; 
        }
 
        /// 
        ///     Event invoked when the layout causes the HwndSource to resize automatically.
        /// 
        public event AutoResizedEventHandler AutoResized; 

        ///  
        /// Handler for LayoutUpdated event of a rootVisual. 
        /// 
        ///  
        ///     Critical: This code causes resize of window and accesses HwndTarget
        /// 
        [SecurityCritical]
        private void OnLayoutUpdated(object obj, EventArgs args) 
        {
            UIElement root = _rootVisual.Value as UIElement; 
 
            if(root != null)
            { 
                Size newSize = root.RenderSize;
                if (   _previousSize == null
                    || !DoubleUtil.AreClose(_previousSize.Value.Width, newSize.Width)
                    || !DoubleUtil.AreClose(_previousSize.Value.Height, newSize.Height)) 
                {
                    // We should update _previousSize, even if the hwnd is not 
                    // sizing to content.  This fixes the scenario where: 
                    //
                    // 1) hwnd is sized to content to say a, b 
                    // 2) hwnd is resize to a bigger size
                    // 3) hwnd is sized to content to a, b again
                    _previousSize = newSize;
 
                    //
                    // Don't resize while the Window is in Minimized mode. 
                    // 
                    if (_sizeToContent != SizeToContent.Manual && !_isWindowInMinimizeState )
                    { 
                        Resize(newSize);
                    }
                }
            } 
        }
 
        ///  
        /// This is called when LayoutManager was updated and its size (the layout size of top element) changed.
        /// Ask LayoutManager.Size to see what the new value is. 
        /// 
        /// 
        ///     Critical: This code causes resize of window and accesses HwndTarget
        ///     TreatAsSafe: In RBW the resize values are clamped also one cannot construct or get to a HwndSource in partial trust 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void Resize(Size newSize) 
        {
            try 
            {
                _myOwnUpdate = true;

                if (IsUsable) 
                {
                    NativeMethods.RECT rect = AdjustWindowSize(newSize); 
 
                    int newWidth = rect.right - rect.left;
                    int newHeight = rect.bottom - rect.top; 

                    // Set the new window size
                    UnsafeNativeMethods.SetWindowPos(new HandleRef(this,_hwndWrapper.Handle), new HandleRef(null,IntPtr.Zero),
                                                   0, 0, newWidth, newHeight, 
                                                   NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
 
                    if (AutoResized != null) 
                    {
                        AutoResized(this, new AutoResizedEventArgs(newSize)); 
                    }
                }
            }
            finally 
            {
                _myOwnUpdate = false; 
            } 
        }
 
        /// 
        ///     Critical: This code accesses critical member _hwndTarget.
        ///     TreatAsSafe: It calculates the hwnd size without changing it.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private NativeMethods.RECT AdjustWindowSize(Size newSize) 
        { 
            // Gather the new client dimensions
            // The dimension WPF uses is logical unit. We need to convert to device unit first. 
            Point pt = _hwndTarget.TransformToDevice.Transform(new Point(newSize.Width, newSize.Height));
            RoundDeviceSize(ref pt);
            NativeMethods.RECT rect = new NativeMethods.RECT(0, 0, (int)pt.X, (int)pt.Y);
 
            // If we're here, and it is the Window case (_adjustSizingForNonClientArea == true)
            // we get the size which includes the outside size of the window.  For browser case, 
            // we don't support SizeToContent, so we don't take care of this condition. 
            // For non-Window cases, we need to calculate the outside size of the window
            // 
            // For windows with UsesPerPixelOpacity, we force the client to
            // fill the window, so we don't need to add in any frame space.
            //
            if (_adjustSizingForNonClientArea == false && !UsesPerPixelOpacity) 
            {
                int style = NativeMethods.IntPtrToInt32((IntPtr)SafeNativeMethods.GetWindowStyle(new HandleRef(this, _hwndWrapper.Handle), false)); 
                int styleEx = NativeMethods.IntPtrToInt32((IntPtr)SafeNativeMethods.GetWindowStyle(new HandleRef(this, _hwndWrapper.Handle), true)); 

                SafeNativeMethods.AdjustWindowRectEx(ref rect, style, false, styleEx); 
            }
            return rect;
        }
 
        // If the root element has Pixel snapping enabled, round the window size to the
        // nearest int.  Otherwise round the size up to the next int. 
        private void RoundDeviceSize(ref Point size) 
        {
            UIElement root = _rootVisual.Value as UIElement; 
            if (root != null && root.SnapsToDevicePixels)
            {
                size = new Point(DoubleUtil.DoubleToInt(size.X), DoubleUtil.DoubleToInt(size.Y));
            } 
            else
            { 
                size = new Point(Math.Ceiling(size.X), Math.Ceiling(size.Y)); 
            }
        } 

        /// 
        /// Returns the hwnd handle to the window.
        ///  
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        /// 
        /// 
        ///     Critical:This is not safe to expose in internet zone, it returns a window handle 
        ///     PublicOK: There exists a demand on this code
        /// 
        public IntPtr Handle
        { 
            [SecurityCritical]
            get 
            { 
                SecurityHelper.DemandUIWindowPermission();
                return CriticalHandle; 
            }
        }

        ///  
        ///     Critical:Internal helper to retrieve handle for security purposes only Please
        ///     DO NOT USE THIS TO  EXPOSE HANDLE TO OUTSIDE WORLD 
        ///  
        internal IntPtr CriticalHandle
        { 
            [FriendAccessAllowed]
            [SecurityCritical]
            get
            { 
                if (null != _hwndWrapper)
                    return _hwndWrapper.Handle; 
                return IntPtr.Zero; 
            }
        } 

        /// 
        ///     Critical: returns the critical _hwndWrapper.
        ///  
        internal HwndWrapper HwndWrapper
        { 
            [SecurityCritical] 
            get { return _hwndWrapper; }
        } 

        // Return whether this presentation source has capture.
        /// 
        ///     Critical: calls CriticalHandle 
        ///     TreatAsSafe: Returning whether a presentation source has capture is considered safe.
        ///  
        internal bool HasCapture 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            {
                IntPtr capture = SafeNativeMethods.GetCapture();
 
                return ( capture == CriticalHandle );
            } 
        } 

        /// 
        ///     Critical - accesses _hwndWrapper.
        ///     TreatAsSafe - checking for null is considered safe.
        ///
        internal bool IsHandleNull 
        {
            [SecurityCritical, SecurityTreatAsSafe ] 
            get 
            {
                return _hwndWrapper.Handle == IntPtr.Zero ; 
            }
        }

        ///  
        /// Returns the hwnd handle to the window.
        ///  
        public HandleRef CreateHandleRef() 
        {
            return new HandleRef(this,Handle); 
        }


        ///  
        /// SizeToContent on HwndSource
        ///  
        ///  
        /// The default value is SizeToContent.Manual
        ///  
        public SizeToContent SizeToContent
        {
            get
            { 
                CheckDisposed(true);
                return _sizeToContent; 
            } 

            set 
            {
                CheckDisposed(true);

                if (IsValidSizeToContent(value) != true) 
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(SizeToContent)); 
                } 

                if (_sizeToContent == value) 
                {
                    return;
                }
 
                _sizeToContent = value;
 
                // we only raise SizeToContentChanged when user interaction caused the change; 
                // if a developer goes directly to HwndSource and sets SizeToContent, we will
                // not notify the wrapping Window 

                if (IsLayoutActive() == true)
                {
                    // Call the helper method SetLayoutSize to set Layout's size 
                    SetLayoutSize();
                } 
            } 
        }
 
        /// 
        ///     Critical: This code elevates to access hwndtarget
        ///     TreatAsSafe: ok to expose
        ///  
        [SecurityCritical,SecurityTreatAsSafe]
        private bool IsLayoutActive() 
        { 

            if ((_rootVisual.Value is UIElement) && _hwndTarget!= null && _hwndTarget.IsDisposed == false) 
            {
                return true;
            }
 
            return false;
        } 
 
        /// 
        /// This is the helper method that sets Layout's size basing it on 
        /// the current value of SizeToContent.
        /// 
        ///
        ///  TreatAsSafe: This API could be public in terms of security. 
        ///  It does three calls to UnsafeNativeMethods all in a safe way
        ///  Critical: Makes 3 calls to UnsafeNativeMethods 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void SetLayoutSize() 
        {
            Debug.Assert(_hwndTarget!= null, "HwndTarget is null");
            Debug.Assert(_hwndTarget.IsDisposed == false, "HwndTarget is disposed");
 
            UIElement rootUIElement = null;
            rootUIElement = _rootVisual.Value as UIElement; 
            if (rootUIElement == null) return; 

            // hamidm - 11/01/2005 
            // InvalidateMeasure() call is necessary in the following scenario
            //
            // Window w = new Window();
            // w.Measure(new Size(x,y)); 
            // w.Width = x;
            // w.Height = y; 
            // w.Show() 
            //
            // In the above scenario, the Measure call from SetLayoutSize will be opt out 
            // and window will not receive the MeasureOverride call.  As such, the hwnd min/max
            // restrictions will not be applied since MeasureOverride did not happen after hwnd
            // creation.  Thus, we call InvalidatMeasure() to ensure MeasureOverride call on
            // Window after hwnd creation. 

            rootUIElement.InvalidateMeasure(); 
 
            bool etwEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal);
            int  ctxHashCode = 0; 

            if (_sizeToContent == SizeToContent.WidthAndHeight)
            {
                //setup constraints for measure-to-content 
                Size sz = new Size(double.PositiveInfinity, double.PositiveInfinity);
 
                if (etwEnabled) 
                {
                    ctxHashCode = this.Dispatcher.GetHashCode(); 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.StartEvent, ctxHashCode);

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                } 

                rootUIElement.Measure(sz); 
 
                if (etwEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.EndEvent);

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                } 

                rootUIElement.Arrange(new Rect(new Point(), rootUIElement.DesiredSize)); 
 
                if (etwEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.EndEvent);

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.EndEvent);
                } 
            }
            else 
            { 
                // GetSizeFromHwnd sets either the outside size or the client size of the hwnd based on
                // _adjustSizeingForNonClientArea flag in logical units. 
                Size sizeFromHwndLogicalUnits = GetSizeFromHwnd();
                Size sz = new Size(
                        (_sizeToContent == SizeToContent.Width ? double.PositiveInfinity : sizeFromHwndLogicalUnits.Width),
                        (_sizeToContent == SizeToContent.Height ? double.PositiveInfinity : sizeFromHwndLogicalUnits.Height)); 

                if (etwEnabled) 
                { 
                    ctxHashCode = this.Dispatcher.GetHashCode();
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.StartEvent, ctxHashCode); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                }
 
                rootUIElement.Measure(sz);
 
                if (etwEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.EndEvent); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                }
 
                if (_sizeToContent == SizeToContent.Width) sz = new Size(rootUIElement.DesiredSize.Width, sizeFromHwndLogicalUnits.Height);
                else if(_sizeToContent == SizeToContent.Height) sz = new Size(sizeFromHwndLogicalUnits.Width, rootUIElement.DesiredSize.Height); 
                else sz = sizeFromHwndLogicalUnits; 

                rootUIElement.Arrange(new Rect(new Point(), sz)); 

                if (etwEnabled)
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.EndEvent); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.EndEvent); 
                } 
            }
            rootUIElement.UpdateLayout(); 
        }

        // /// 
        // ///     Specifies the color to display as transparent. 
        // /// 
        // ///  
        // ///     Use null to indicate that no color should be transparent. 
        // /// 
        // public Nullable ColorKey 
        // {
        //     get
        //     {
        //         CheckDisposed(true); 
        //
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed 
        //         if(_hwndTarget != null) 
        //         {
        //             return _hwndTarget.ColorKey; 
        //         }
        //         else
        //         {
        //             return null; 
        //         }
        //     } 
        // 
        //     set
        //     { 
        //         CheckDisposed(true);
        //
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed
        //         if(_hwndTarget != null) 
        //         {
        //             _hwndTarget.ColorKey = value; 
        //         } 
        //     }
        // } 

        // /// 
        // ///     Specifies the constant opacity to apply to the window.
        // ///  
        // /// 
        // ///     The valid values range from [0..1].  Values outside of this range are clamped. 
        // ///  
        // public double Opacity
        // { 
        //     get
        //     {
        //         CheckDisposed(true);
        // 
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed
        //         if(_hwndTarget != null) 
        //         { 
        //             return _hwndTarget.Opacity;
        //         } 
        //         else
        //         {
        //             return 1.0;
        //         } 
        //     }
        // 
        //     set 
        //     {
        //         CheckDisposed(true); 
        //
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed
        //         if(_hwndTarget != null)
        //         { 
        //             _hwndTarget.Opacity = value;
        //         } 
        //     } 
        // }
 
        /// 
        ///     Specifies whether or not the per-pixel opacity of the window content
        ///     is respected.
        ///  
        /// 
        ///     By enabling per-pixel opacity, the system will no longer draw the non-client area. 
        ///  
        /// 
        ///     Critical: Because it accesses _hwndTarget 
        ///     PublicOK: We don't pass it out; it is just used to query UsesPerPixelOpacity
        /// 
        public bool UsesPerPixelOpacity
        { 
            [SecurityCritical]
            get 
            { 
                CheckDisposed(true);
 
                HwndTarget hwndTarget = CompositionTarget; // checks for disposed
                if(_hwndTarget != null)
                {
                    return _hwndTarget.UsesPerPixelOpacity; 
                }
                else 
                { 
                    return false;
                } 
            }

/* Not allowing this to change at run-time yet.
            [SecurityCritical] 
            set
            { 
                CheckDisposed(true); 

                HwndTarget hwndTarget = CompositionTarget; // checks for disposed 
                if(_hwndTarget != null)
                {
                    _hwndTarget.UsesPerPixelOpacity = value;
                } 
            }
*/ 
        } 

        ///  
        ///     Critical: Because it accesses _hwndTarget
        ///     TreatAsSafe: We don't pass it out; it is just used to convert to logical units
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private Size GetSizeFromHwnd()
        { 
            // Compute View's size and set 
            NativeMethods.RECT rc = new NativeMethods.RECT(0, 0, 0, 0);
 
            if (_adjustSizingForNonClientArea == true)
            {
                // get correct size for avalon Window (standalone and browser case)
                GetSizeForWindowObject(ref rc); 
            }
            else 
            { 
                SafeNativeMethods.GetClientRect(new HandleRef(this,_hwndWrapper.Handle), ref rc);
            } 

            Point convertedPt = _hwndTarget.TransformFromDevice.Transform(new Point(rc.right - rc.left, rc.bottom - rc.top));
            return new Size(convertedPt.X, convertedPt.Y);
        } 

        ///  
        ///     Critical: This code can be used to spoof input 
        /// 
        [SecurityCritical] 
        private IntPtr HwndTargetFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            IntPtr result = IntPtr.Zero ;
 
            if (IsUsable)
            { 
                HwndTarget hwndTarget = _hwndTarget; 
                if (hwndTarget != null)
                { 
                    result = hwndTarget.HandleMessage(msg, wParam, lParam);
                    if (result != IntPtr.Zero)
                    {
                        handled = true; 
                    }
                } 
 
            }
 
            return result;
        }

        ///  
        /// Critical:These hooks can all be used for input spoofing
        ///  
        [SecurityCritical] 
        private IntPtr LayoutFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        { 
            IntPtr result = IntPtr.Zero ;

            // We have to revalidate everything because the Access() call
            // could have caused the CLR to enter a nested message pump, 
            // during which almost anything could have happened that might
            // invalidate our checks. 
            UIElement rootUIElement=null; 
            rootUIElement = _rootVisual.Value as UIElement;
            if (IsUsable && rootUIElement != null) 
            {
                switch (msg)
                {
                    // A window receives this message when the user chooses a command from 
                    // the Window menu or when the user chooses the maximize button, minimize
                    // button, restore button, or close button. 
                    case NativeMethods.WM_SYSCOMMAND: 
                        {
                            // The four low-order bits of the wParam parameter are used 
                            // internally by the system.
                            Int32 sysCommand = NativeMethods.IntPtrToInt32(wParam) & 0xFFF0;

                            // Turn off SizeToContent if user chooses to maximize or resize. 
                            if ((sysCommand == NativeMethods.SC_MAXIMIZE) ||
                                (sysCommand == NativeMethods.SC_SIZE)) 
                            { 
                                DisableSizeToContent(rootUIElement, hwnd);
                            } 
                        }
                        break;

                    // We get WM_SIZING. It means that user starts resizing the window. 
                    // It is the first notification sent when user resizes (before WM_WINDOWPOSCHANGING)
                    // and it's not sent if window is resized programmatically. 
                    // SizeToContent is turned off after user resizes. 
                    case NativeMethods.WM_SIZING:
                        DisableSizeToContent(rootUIElement, hwnd); 
                        break;

                    // The WM_WINDOWPOSCHANGING message is sent
                    // 1. when the size, position, or place in the Z order is about to change as a result of a call to 
                    //    the SetWindowPos function or other window-management functions. SizeToContent orverrides all in this case.
                    // 2. when user resizes window. If it's user resize, we have turned SizeToContent off when we get WM_SIZING. 
                    // It is sent before WM_SIZE. 
                    // We can't use WM_GETMINMAXINFO, because if there is no window size change (we still need to make sure
                    // the client size not change), that notification wouldnt be sent. 
                    case NativeMethods.WM_WINDOWPOSCHANGING:
                        Process_WM_WINDOWPOSCHANGING(rootUIElement, hwnd, msg, wParam, lParam);
                        break;
 
                    // WM_SIZE message is sent after the size has changed.
                    // lParam has the new width and height of client area. 
                    // root element's size should be adjust based on the new width and height and SizeToContent's value. 
                    case NativeMethods.WM_SIZE:
                        Process_WM_SIZE(rootUIElement, hwnd, msg, wParam, lParam); 
                        break;
                }
            }
 
            // Certain messages need to be processed while we are in the middle
            // of construction - and thus an HwndTarget is not available. 
            if(!handled && (_constructionParameters != null || IsUsable)) 
            {
                // Get the usesPerPixelOpacity from either the constructor parameters or the HwndTarget. 
                bool usesPerPixelOpacity = _constructionParameters != null ? ((HwndSourceParameters)_constructionParameters).UsesPerPixelOpacity : _hwndTarget.UsesPerPixelOpacity;

                switch(msg)
                { 
                    case NativeMethods.WM_NCCALCSIZE:
                        { 
                            // Windows that use per-pixel opacity don't get 
                            // their frames drawn by the system.  Generally
                            // this is OK, as users of per-pixel alpha tend 
                            // to be doing customized UI anyways.  But we
                            // don't render correctly if we leave a non-client
                            // area, so here we expand the client area to
                            // cover any non-client area. 
                            //
                            if(usesPerPixelOpacity) 
                            { 
                                if(wParam == IntPtr.Zero)
                                { 
                                    // If wParam is FALSE, lParam points to a RECT
                                    // structure. On entry, the structure contains
                                    // the proposed window rectangle for the
                                    // window. On exit, the structure should 
                                    // contain the screen coordinates of the
                                    // corresponding window client area. 
                                    // 
                                    // Since all we want to do is make the client
                                    // rect the same as the window rect, we don't 
                                    // have to do anything.
                                    //
                                    result = IntPtr.Zero;
                                    handled = true; 
                                }
                                else 
                                { 
                                    // If wParam is TRUE, lParam points to an
                                    // NCCALCSIZE_PARAMS structure that contains 
                                    // information an application can use to
                                    // calculate the new size and position of
                                    // the client rectangle.
                                    // 
                                    // When Windows sends the WM_NCCALCSIZE
                                    // message, the NCCALCSIZE_PARAMS structure 
                                    // is filled out like this: 
                                    //
                                    // rgrc[0] = new window rectangle (in parent coordinates) 
                                    // rgrc[1] = old window rectangle (in parent coordinates)
                                    // rgrc[2] = old client rectangle (in parent coordinates)
                                    //
                                    // Notice that the client rectangle is given 
                                    // in parent coordinates, not in client
                                    // coordinates. 
                                    // 
                                    // When your window procedure returns, Windows
                                    // expects the NCCALCSIZE_PARAMS structure to 
                                    // be filled out like this:
                                    //
                                    // rgrc[0] = new client rectangle (in parent coordinates)
                                    // 
                                    // Furthermore, if you return anything other
                                    // than 0, Windows expects the remaining two 
                                    // rectangles to be filled out like this: 
                                    //
                                    // rgrc[1] = destination rectangle (in parent coordinates) 
                                    // rgrc[2] = source rectangle (in parent coordinates)
                                    //
                                    // (If you return 0, then Windows assumes that
                                    // the destination rectangle equals the new 
                                    // client rectangle and the source rectangle
                                    // equals the old client rectangle.) 
                                    // 
                                    // Since all we want to do is make the client
                                    // rect the same as the window rect, we don't 
                                    // have to do anything.
                                    //
                                    result = IntPtr.Zero;
                                    handled = true; 
                                }
                            } 
                        } 
                        break;
                } 
            }

            return result;
        } 

        ///  
        /// Critical: Because it uses _hwndTarget 
        /// 
        [SecurityCritical] 
        private void Process_WM_WINDOWPOSCHANGING(UIElement rootUIElement, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            // Only if SizeToContent overrides Win32 sizing change calls.
            // If it's coming from OnResize (_myOwnUpdate != true), it means we are adjusting 
            // to the right size; don't need to do anything here.
            if ((_myOwnUpdate != true) && (SizeToContent != SizeToContent.Manual)) 
            { 
                // Get the current style and calculate the size to be with the new style.
                // If WM_WINDOWPOSCHANGING is sent because of style changes, WM_STYLECHANGED is sent 
                // before this. The style bits we get here are updated ones, but haven't been applied
                // to Window yet. For example, when the window is changing to borderless, without updating the window size,
                // the window size will remain the same but the client area will be bigger. So when SizeToContent is on, we calculate
                // the window size to be with the new style using AdustWindowRectEx and adjust it to make sure client area is not affected. 
                NativeMethods.RECT rect = AdjustWindowSize(rootUIElement.RenderSize);
 
                int newCX = rect.right - rect.left; 
                int newCY = rect.bottom - rect.top;
 
                // Get WINDOWPOS structure data from lParam; it contains information about the window's
                // new size and position.
                NativeMethods.WINDOWPOS windowPos = (NativeMethods.WINDOWPOS)UnsafeNativeMethods.PtrToStructure(lParam, typeof(NativeMethods.WINDOWPOS));
 
                bool sizeChanged = false;
 
                // If SWP_NOSIZE is set to ignore cx, cy. It could be a style or position change. 
                if ((windowPos.flags & NativeMethods.SWP_NOSIZE) == NativeMethods.SWP_NOSIZE)
                { 
                    NativeMethods.RECT windowRect = new NativeMethods.RECT(0, 0, 0, 0);

                    // Get the current Window rect
                    SafeNativeMethods.GetWindowRect(new HandleRef(this, _hwndWrapper.Handle), ref windowRect); 

                    // If there is no size change with the new style we don't need to do anything. 
                    if ((newCX != (windowRect.right - windowRect.left)) || 
                        (newCY != (windowRect.bottom - windowRect.top)))
                    { 
                        // Otherwise unmark the flag to make our changes effective.
                        windowPos.flags &= ~NativeMethods.SWP_NOSIZE;

                        // When SWP_NOSIZE is on, the size info in cx and cy is bogus. They are ignored. 
                        // When we turn it off, we need to provide valid value for both of them.
                        windowPos.cx = newCX; 
                        windowPos.cy = newCY; 
                        sizeChanged = true;
                    } 
                }
                else
                {
                    // We have excluded SizeToContent == SizeToContent.Manual before entering this. 
                    bool sizeToWidth = (SizeToContent == SizeToContent.Height) ? false : true;
                    bool sizeToHeight = (SizeToContent == SizeToContent.Width) ? false : true; 
 
                    // Update WindowPos with the size we want.
                    if ((sizeToWidth) && (windowPos.cx != newCX)) 
                    {
                        windowPos.cx = newCX;
                        sizeChanged = true;
                    } 

                    if ((sizeToHeight) && (windowPos.cy != newCY)) 
                    { 
                        windowPos.cy = newCY;
                        sizeChanged = true; 
                    }
                }

                // Marshal the structure back only when changed 
                if (sizeChanged)
                { 
                    Marshal.StructureToPtr(windowPos, lParam, true); 
                }
            } 
        }

        /// 
        /// Critical: Because it uses _hwndTarget 
        /// 
        [SecurityCritical] 
        private void Process_WM_SIZE(UIElement rootUIElement, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) 
        {
            int x = NativeMethods.SignedLOWORD(lParam); 
            int y = NativeMethods.SignedHIWORD(lParam);
            Point pt = new Point(x, y);
            bool etwEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal);
            int  ctxHashCode = 0; 

            // 1. If it's coming from Layout (_myOwnUpdate), it means we are adjusting 
            // to the right size; don't need to do anything here. 
            // 2. If SizeToContent is set to WidthAndHeight, then we maintain the current hwnd size
            // in WM_WINDOWPOSCHANGING, so we don't need to re-layout here.  If SizeToContent 
            // is set to Width or Height and developer calls SetWindowPos to set a new
            // Width/Height, we need to do a layout.
            // 3. We also don't need to do anything if it's minimized.
 
            // Keeps the status of whether the Window is in Minimized state or not.
            _isWindowInMinimizeState = (NativeMethods.IntPtrToInt32(wParam) == NativeMethods.SIZE_MINIMIZED) ? true : false; 
 
            if ((!_myOwnUpdate) && (_sizeToContent != SizeToContent.WidthAndHeight) && !_isWindowInMinimizeState)
            { 
                Point relevantPt = new Point(pt.X, pt.Y);

                // WM_SIZE has the client size of the window.
                // for appmodel window case, get the outside size of the hwnd. 
                if (_adjustSizingForNonClientArea == true)
                { 
                    NativeMethods.RECT rect = new NativeMethods.RECT(0, 0, (int)pt.X, (int)pt.Y); 
                    GetSizeForWindowObject(ref rect);
                    relevantPt.X = rect.right - rect.left; 
                    relevantPt.Y = rect.bottom - rect.top;
                }

                // The lParam/wParam size and the GetSizeForWindowObject size are 
                // both in device co-ods, thus we convert to Measure co-ods here.
                relevantPt = _hwndTarget.TransformFromDevice.Transform(relevantPt); 
 
                Size sz = new Size(
                    (_sizeToContent == SizeToContent.Width ? double.PositiveInfinity : relevantPt.X), 
                    (_sizeToContent == SizeToContent.Height ? double.PositiveInfinity : relevantPt.Y));

                // NOTE: hamidm -- 6/03/04
                // 962884 Avalon content does not resize when the favorites 
                // (or other side pane) is closed
                // 
                // The issue is that when the browser shows favorites window, avalon 
                // window is resized and we get WM_SIZE.  Here, we pass the IE window's
                // size to Measure so that Computed[Width/Height] gets the correct 
                // IE window dimensions.  Since, IE window's size may not change, the
                // call to Measure is optimized out and no layout happens.  Invalidating
                // layout here ensures that we do layout.
                // This can happen only in the Window case 
                if (_adjustSizingForNonClientArea == true)
                { 
                    rootUIElement.InvalidateMeasure(); 
                }
 
                if (etwEnabled)
                {
                    ctxHashCode = this.Dispatcher.GetHashCode();
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.StartEvent, ctxHashCode); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.StartEvent, ctxHashCode); 
                } 

                rootUIElement.Measure(sz); 

                if (_sizeToContent == SizeToContent.Width) sz = new Size(rootUIElement.DesiredSize.Width, relevantPt.Y);
                else if (_sizeToContent == SizeToContent.Height) sz = new Size(relevantPt.X, rootUIElement.DesiredSize.Height);
                else sz = new Size(relevantPt.X, relevantPt.Y); 

                if (etwEnabled) 
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.EndEvent);
 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                }

                rootUIElement.Arrange(new Rect(new Point(), sz)); 

                if (etwEnabled) 
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.EndEvent);
 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.EndEvent);
                }
                rootUIElement.UpdateLayout(); //finalizes layout
 
            }
        } 
 
        /// 
        /// Critical: Because it uses _hwndTarget 
        /// 
        [SecurityCritical]
        private void DisableSizeToContent(UIElement rootUIElement, IntPtr hwnd)
        { 
            if (_sizeToContent != SizeToContent.Manual)
            { 
                _sizeToContent = SizeToContent.Manual; 

                // hamidm - 10/27/2005 
                // 1348020 Window expereience layout issue when SizeToContent is being turned
                // off by user interaction
                // This bug was caused b/c we were giving rootUIElement.DesiredSize as input
                // to Measure/Arrange below.  That is incorrect since rootUIElement.DesiredSize may not 
                // cover the entire hwnd client area.
 
                // GetSizeFromHwnd returns either the outside size or the client size of the hwnd based on 
                // _adjustSizeingForNonClientArea flag in logical units.
                Size sizeLogicalUnits = GetSizeFromHwnd(); 
                rootUIElement.Measure(sizeLogicalUnits);
                rootUIElement.Arrange(new Rect(new Point(), sizeLogicalUnits));

                rootUIElement.UpdateLayout(); //finalizes layout 

 
                if (SizeToContentChanged != null) 
                {
                    SizeToContentChanged(this, EventArgs.Empty); 
                }
            }
        }
 
        // This method makes sure that we get the size from the correct
        // hwnd for the browser case. 
        ///  
        /// Critical - calls critical methods (HwndSourceHelper.GetHandle and GetAncestor)
        /// TreatAsSafe - it's ok to return size of window. it doesn't return info gotten through critical calls. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void GetSizeForWindowObject(ref NativeMethods.RECT rc)
        { 
            IntPtr hwndRoot = UnsafeNativeMethods.GetAncestor(new HandleRef(this, CriticalHandle), NativeMethods.GA_ROOT);
            SafeNativeMethods.GetWindowRect(new HandleRef(this, hwndRoot), ref rc); 
        } 

        ///  
        ///     Critical: This is a hook that gets called back with information about messages related to input
        ///     Calling this from outside or causing this to be invoked could yield risky situations
        /// 
        [SecurityCritical] 
        private IntPtr InputFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        { 
            IntPtr result = IntPtr.Zero ; 

            // NOTE (alexz): invoke _stylus.FilterMessage before _mouse.FilterMessage 
            // to give _stylus a chance to eat mouse message generated by stylus
            if (!_isDisposed && _stylus != null && !handled)
            {
                result = _stylus.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled); 
            }
 
            if (!_isDisposed && _mouse != null && !handled) 
            {
                result = _mouse.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled); 
            }

            if (!_isDisposed && _keyboard != null && !handled)
            { 
                result = _keyboard.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled);
            } 
 
            if (!_isDisposed && _appCommand != null && !handled)
            { 
                result = _appCommand.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled);
            }

            return result; 
        }
 
        ///  
        ///    Called from HwndWrapper on all window messages.
        ///  
        // assumes Context.Access() is held.
        private IntPtr PublicHooksFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            // The default result for messages we handle is 0. 
            IntPtr result = IntPtr.Zero ;
 
            // Call all of the public hooks 
            // We do this even if we are disposed because otherwise the hooks
            // would never see the WM_DESTROY etc. message. 
            if (_hooks != null)
            {
                for (int i = 0, nCount = _hooks.Count; i < nCount; i++)
                { 
                    result = ((HwndSourceHook)_hooks[i])(hwnd, msg, wParam, lParam, ref handled);
                    if(handled) 
                    { 
                        break;
                    } 
                }
            }
            if (NativeMethods.WM_NCDESTROY == msg)
            { 
                // We delivered the message to the hooks and the message
                // is WM_NCDESTROY, so our commitments should be finished 
                // we can do final teardown. (like disposing the _hooks) 
                OnNoMoreWindowMessages();
            } 

            return result;
        }
 
#region IKeyboardInputSink
        private class MSGDATA 
        { 
            public MSG msg;
            public bool handled; 
        }

        /// 
        /// HwndSource keyboard input is sent through this delegate to check for 
        /// Child Hwnd interop requirments.  If there are no child hwnds or focus
        /// is on this non-child hwnd then normal Avalon processing is done. 
        ///  
        ///
        /// Critical - This can be used to spoof input 
        /// 
        [SecurityCritical]
        private void OnPreprocessMessageThunk(ref MSG msg, ref bool handled)
        { 
//             VerifyAccess();
 
            if (handled) 
            {
                return; 
            }

            // We only do these message.
            switch (msg.message) 
            {
            case NativeMethods.WM_KEYUP: 
            case NativeMethods.WM_KEYDOWN: 
            case NativeMethods.WM_SYSKEYUP:
            case NativeMethods.WM_SYSKEYDOWN: 
            case NativeMethods.WM_CHAR:
            case NativeMethods.WM_SYSCHAR:
            case NativeMethods.WM_DEADCHAR:
            case NativeMethods.WM_SYSDEADCHAR: 
                MSGDATA msgdata = new MSGDATA();
                msgdata.msg = msg; 
                msgdata.handled = handled; 

                // Do this under the exception filter/handlers of the 
                // dispatcher for this thread.
                //
                // NOTE: we lose the "perf optimization" of passing everything
                // around by-ref since we have to call through a delegate. 
                object result = Dispatcher.CurrentDispatcher.Invoke(
                    DispatcherPriority.Send, 
                    new DispatcherOperationCallback(OnPreprocessMessage), 
                    msgdata);
 
                if (result != null)
                {
                    handled = (bool)result;
                } 

                // the semantics dictate that the callers could change this data. 
                msg = msgdata.msg; 
                break;
            } 
        }


        ///  
        /// Critical - Can be used to spoof input
        ///     Asserts UnmanagedCode permission to call IKeyboardInputSink methods. 
        ///  
        [SecurityCritical]
        private object OnPreprocessMessage(object param) 
        {
            MSGDATA msgdata = (MSGDATA) param;

            // At the top level check if someone below us has Focus. 
            // Mnemonics are broadcast to all branches of the window tree; even
            // those that don't have focus.  BUT! at least someone under this 
            // TopLevel window must have focus. 
            if (!((IKeyboardInputSink)this).HasFocusWithin())
            { 
                return msgdata.handled;
            }

            ModifierKeys modifierKeys = HwndKeyboardInputProvider.GetSystemModifierKeys(); 

            // Interop with the Interop layer 
            // 
            switch (msgdata.msg.message)
            { 
            case NativeMethods.WM_SYSKEYDOWN:
            case NativeMethods.WM_KEYDOWN:
                // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS
                // In case a nested message pump is used before we return 
                // from processing this message, we disable processing the
                // next WM_CHAR message because if the code pumps messages 
                // it should really mark the message as handled. 
                _eatCharMessages = true;
                DispatcherOperation restoreCharMessages = Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(RestoreCharMessages), null); 

                msgdata.handled = CriticalTranslateAccelerator(ref msgdata.msg, modifierKeys);
                if(!msgdata.handled)
                { 
                    // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS
                    // We did not handle the WM_KEYDOWN, so it is OK to process WM_CHAR messages. 
                    // We can also abort the pending restore operation since we don't need it. 
                    _eatCharMessages = false;
                    restoreCharMessages.Abort(); 
                }
                break;

            case NativeMethods.WM_SYSKEYUP: 
            case NativeMethods.WM_KEYUP:
                msgdata.handled = CriticalTranslateAccelerator(ref msgdata.msg, modifierKeys); 
                break; 

            case NativeMethods.WM_CHAR: 
            case NativeMethods.WM_SYSCHAR:
            case NativeMethods.WM_DEADCHAR:
            case NativeMethods.WM_SYSDEADCHAR:
                // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
                if(!_eatCharMessages)
                { 
                    // IKIS implementation does a demand. 
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
                    try 
                    {
                        msgdata.handled = ((IKeyboardInputSink)this).TranslateChar(ref msgdata.msg, modifierKeys);

                        if (!msgdata.handled) 
                        {
                            msgdata.handled = ((IKeyboardInputSink)this).OnMnemonic(ref msgdata.msg, modifierKeys); 
                        } 
                    }
                    finally 
                    {
                        SecurityPermission.RevertAssert();
                    }
 
                    if (!msgdata.handled)
                    { 
                        _keyboard.Value.ProcessTextInputAction(msgdata.msg.hwnd, msgdata.msg.message, 
                                                               msgdata.msg.wParam, msgdata.msg.lParam, ref msgdata.handled);
                    } 
                }
                break;
            }
            return msgdata.handled; 
        }
 
        ///  
        ///     Registers a child KeyboardInputSink with this sink.  A site
        ///     is returned. 
        /// 
        ///
        /// This API requires unrestricted UI Window permission.
        /// 
        /// 
        ///     Critical: This API can be used for input spoofing 
        ///     PublicOK: This method has a demand on it. 
        /// 
        [SecurityCritical, UIPermissionAttribute(SecurityAction.Demand, Unrestricted=true)] 
        IKeyboardInputSite IKeyboardInputSink.RegisterKeyboardInputSink(IKeyboardInputSink sink)
        {
            CheckDisposed(true);
 
            if (sink == null)
            { 
                throw new ArgumentNullException("sink"); 
            }
 
            if (sink.KeyboardInputSite != null)
            {
                throw new ArgumentException(SR.Get(SRID.KeyboardSinkAlreadyOwned));
            } 

            HwndSourceKeyboardInputSite site = new HwndSourceKeyboardInputSite(this, sink); 
 
            if (_keyboardInputSinkChildren == null)
                _keyboardInputSinkChildren = new List(); 
            _keyboardInputSinkChildren.Add(site);

            return site;
        } 

        ///  
        ///     Gives the component a chance to process keyboard input. 
        ///     Return value is true if handled, false if not.  Components
        ///     will generally call a child component's TranslateAccelerator 
        ///     if they can't handle the input themselves.  The message must
        ///     either be WM_KEYDOWN or WM_SYSKEYDOWN.  It is illegal to
        ///     modify the MSG structure, it's passed by reference only as
        ///     a performance optimization. 
        /// 
        /// 
        /// This API is not available in Internet Zone. 
        ///
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     TreatAsSafe: This method has a demand on it.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        bool IKeyboardInputSink.TranslateAccelerator(ref MSG msg, ModifierKeys modifiers)
        { 
            SecurityHelper.DemandUnmanagedCode(); 
//             VerifyAccess();
 
            return CriticalTranslateAccelerator(ref msg, modifiers);
        }

        ///  
        ///     Set focus to the first or last tab stop (according to the
        ///     TraversalRequest).  If it can't, because it has no tab stops, 
        ///     the return value is false. 
        /// 
        bool IKeyboardInputSink.TabInto(TraversalRequest request) 
        {
            bool traversed = false;

            if(request == null) 
            {
                throw new ArgumentNullException("request"); 
            } 

            UIElement root =_rootVisual.Value as UIElement; 
            if(root != null)
            {
                // atanask:
                // request.Mode == FocusNavigationDirection.First will navigate to the fist tabstop including root 
                // request.Mode == FocusNavigationDirection.Last will navigate to the last tabstop including root
                traversed = root.MoveFocus(request); 
            } 

            return traversed; 
        }

        /// 
        ///     The property should start with a null value.  The component's 
        ///     container will set this property to a non-null value before
        ///     any other methods are called.  It may be set multiple times, 
        ///     and should be set to null before disposal. 
        /// 
        /// 
        /// Setting KeyboardInputSite is not available in Internet Zone.
        ///
        /// 
        ///     Critical: This API can be used for input spoofing 
        ///     PublicOK: This method has a demand on it.
        ///  
        IKeyboardInputSite IKeyboardInputSink.KeyboardInputSite 
        {
            [SecurityCritical] 
            get
            {
                SecurityHelper.DemandUnmanagedCode();
                return _keyboardInputSite; 
            }
 
            [SecurityCritical] 
            set
            { 
                SecurityHelper.DemandUnmanagedCode();

                _keyboardInputSite = value;
            } 
        }
 
        ///  
        ///     This method is called whenever one of the component's
        ///     mnemonics is invoked.  The message must either be WM_KEYDOWN 
        ///     or WM_SYSKEYDOWN.  It's illegal to modify the MSG structrure,
        ///     it's passed by reference only as a performance optimization.
        ///     If this component contains child components, the container
        ///     OnMnemonic will need to call the child's OnMnemonic method. 
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing 
        ///     TreatAsSafe: This method has a demand on it.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        bool IKeyboardInputSink.OnMnemonic(ref MSG msg, ModifierKeys modifiers)
        {
//             VerifyAccess(); 
            SecurityHelper.DemandUnmanagedCode();
            switch(msg.message) 
            { 
                case NativeMethods.WM_SYSCHAR:
                case NativeMethods.WM_SYSDEADCHAR: 
                    string text = new string((char)msg.wParam, 1);
                    if ((text != null) && (text.Length > 0))
                    {
                        if (AccessKeyManager.IsKeyRegistered(this, text)) 
                        {
                            AccessKeyManager.ProcessKey(this, text, false); 
 
                            //
                            return true; 
                        }
                    }
                    // these are OK
                    break; 

                case NativeMethods.WM_CHAR: 
                case NativeMethods.WM_DEADCHAR: 
                    // these are OK
                    break; 

                default:
                    throw new ArgumentException(SR.Get(SRID.OnlyAcceptsKeyMessages));
            } 

            // We record the last message that was processed by us. 
            // This is also checked in WndProc processing to prevent double processing. 
            _lastKeyboardMessage = msg;
 
            // The Avalon bubble will take care of access key processing for this HWND
            // So now we just call the children.
            if (null == _keyboardInputSinkChildren)
                return false; 

            foreach ( HwndSourceKeyboardInputSite childSite in _keyboardInputSinkChildren ) 
            { 
                if (((IKeyboardInputSite)childSite).Sink.OnMnemonic(ref msg, modifiers))
                    return true; 
            }
            return false;
        }
 
        /// 
        ///     Gives the component a chance to process keyboard input messages 
        ///     WM_CHAR, WM_SYSCHAR, WM_DEADCHAR or WM_SYSDEADCHAR before calling OnMnemonic. 
        ///     Will return true if "handled" meaning don't pass it to OnMnemonic.
        ///     The message must be WM_CHAR, WM_SYSCHAR, WM_DEADCHAR or WM_SYSDEADCHAR. 
        ///     It is illegal to modify the MSG structure, it's passed by reference
        ///     only as a performance optimization.
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     TreatAsSafe: This method has a demand on it. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        bool IKeyboardInputSink.TranslateChar(ref MSG msg, ModifierKeys modifiers) 
        {
            SecurityHelper.DemandUnmanagedCode();
            if(HasFocus)
                return false; 

            IKeyboardInputSink focusSink = this.ChildSinkWithFocus; 
            if(null != focusSink) 
            {
                return focusSink.TranslateChar(ref msg, modifiers); 
            }
            return false;
        }
 
        /// 
        /// 
        ///  
        bool IKeyboardInputSink.HasFocusWithin()
        { 
            if(HasFocus)
            {
                return true;
            } 
            else
            { 
                if (null == _keyboardInputSinkChildren) 
                    return false;
 
                foreach (HwndSourceKeyboardInputSite site in _keyboardInputSinkChildren)
                {
                    if (((IKeyboardInputSite)site).Sink.HasFocusWithin())
                    { 
                        return true;
                    } 
                } 
                return false;
            } 
        }

        /// 
        ///   The method is not part of the interface (IKeyboardInputSink). 
        /// 
        /// The Site that containes the sink to unregister 
        ///  
        ///     Critical - calls critical methods.
        ///  
        [ SecurityCritical ]
        internal void CriticalUnregisterKeyboardInputSink(HwndSourceKeyboardInputSite site)
        {
            if(_isDisposed) 
                return;
 
            if (null != _keyboardInputSinkChildren) 
            {
                if (!_keyboardInputSinkChildren.Remove(site)) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.KeyboardSinkNotAChild));
                }
            } 
        }
 
        IKeyboardInputSink ChildSinkWithFocus 
        {
            get 
            {
                IKeyboardInputSink ikis=null;

                if(null == _keyboardInputSinkChildren) 
                    return null;
 
                foreach (HwndSourceKeyboardInputSite site in _keyboardInputSinkChildren) 
                {
                    IKeyboardInputSite isite = (IKeyboardInputSite)site; 

                    if (isite.Sink.HasFocusWithin())
                    {
                        ikis = isite.Sink; 
                        break;
                    } 
                } 
                // This private property should only be called correctly.
                Debug.Assert(null!=ikis, "ChildSinkWithFocus called when none had focus"); 
                return ikis;
            }
        }
 
        /// 
        ///     Critical: This API could be vulnerable to input spoofing. 
        ///  
        [SecurityCritical, FriendAccessAllowed]
        internal bool CriticalTranslateAccelerator(ref MSG msg, ModifierKeys modifiers) 
        {
            switch (msg.message)
            {
                case NativeMethods.WM_KEYUP: 
                case NativeMethods.WM_KEYDOWN:
                case NativeMethods.WM_SYSKEYUP: 
                case NativeMethods.WM_SYSKEYDOWN: 
                    // these are OK
                    break; 

                default:
                    throw new ArgumentException(SR.Get(SRID.OnlyAcceptsKeyMessages));
            } 

            if (_keyboard == null) 
                return false; 

            bool handled = false; 

            // TranslateAccelerator is called recursively on child Hwnds (Source & Host)
            // If this is the first Avalon TranslateAccelerator processing then we send the
            // key to be processed to the standard Avalon Input Filters and stuff. 
            if (PerThreadData.TranslateAcceleratorCallDepth == 0)
            { 
                // We record the last message that was processed by us. 
                // This is also checked in WndProc processing to prevent double processing.
                // TranslateAcclerator is called from the pump before DispatchMessage 
                // and the WndProc is called from DispatchMessage.   We have processing
                // in both places.  If we run the pump we process keyboard message here.
                // If we don't own the pump we process them in HwndKeyboardInputProvider.WndProc.
                _lastKeyboardMessage = msg; 

                //  NORMAL AVALON KEYBOARD INPUT CASE 
                // If this is the top most Avalon window (it might be a child Hwnd 
                // but no Avalon windows above it).  And focus is on this window then
                // do the Normal Avalon Keyboard input Processing. 
                if (HasFocus)
                {
                    _keyboard.Value.ProcessKeyAction(ref msg, ref handled);
                } 
                // ELSE the focus is in but not on this HwndSource.
                // Do the once only message input filters etc and Tunnel/Bubble down 
                // to the element that contains the child window with focus. 
                // The Child HwndHost object will hook OnPreviewKeyDown() etc
                // to make the transition to its TranslateAccelerator() between the 
                // tunnel and the bubble.
                else
                {
                    IKeyboardInputSink focusSink = ChildSinkWithFocus; 
                    IInputElement focusElement = (IInputElement)focusSink;
 
                    try { 
                        PerThreadData.TranslateAcceleratorCallDepth += 1;
                        Keyboard.PrimaryDevice.ForceTarget = focusElement; 
                       _keyboard.Value.ProcessKeyAction(ref msg, ref handled);
                    }
                    finally
                    { 
                        Keyboard.PrimaryDevice.ForceTarget = null;
                        PerThreadData.TranslateAcceleratorCallDepth -= 1; 
                    } 
                }
 
            }
            // ELSE we have seen this MSG before, we are HwndSource decendant of an
            // HwndSource (that ancestor presumably did the processing above).
            // Here we raise the tunnel/bubble events without the once only keyboard 
            // input filtering.
            else 
            { 
                int virtualKey = HwndKeyboardInputProvider.GetVirtualKey(msg.wParam, msg.lParam);
                int scanCode = HwndKeyboardInputProvider.GetScanCode(msg.wParam, msg.lParam); 
                bool isExtendedKey = HwndKeyboardInputProvider.IsExtendedKey(msg.lParam);
                Key key = KeyInterop.KeyFromVirtualKey(virtualKey);

                RoutedEvent keyPreviewEvent=null; 
                RoutedEvent keyEvent=null;
                switch (msg.message) 
                { 
                case NativeMethods.WM_KEYUP:
                case NativeMethods.WM_SYSKEYUP: 
                    keyPreviewEvent = Keyboard.PreviewKeyUpEvent;
                    keyEvent = Keyboard.KeyUpEvent;
                    break;
                case NativeMethods.WM_KEYDOWN: 
                case NativeMethods.WM_SYSKEYDOWN:
                    keyPreviewEvent = Keyboard.PreviewKeyDownEvent; 
                    keyEvent = Keyboard.KeyDownEvent; 
                    break;
                } 

                IKeyboardInputSink focusSink = HasFocus ? null : ChildSinkWithFocus;
                IInputElement focusElement = focusSink as IInputElement;
 
                // focusElement may be null, in which case Target is just "focus"
                try { 
                    Keyboard.PrimaryDevice.ForceTarget = focusElement; 
                    focusElement = Keyboard.PrimaryDevice.Target;
 
                    KeyEventArgs tunnelArgs = new KeyEventArgs(Keyboard.PrimaryDevice, this, msg.time, key);
                    tunnelArgs.ScanCode = scanCode;
                    tunnelArgs.IsExtendedKey = isExtendedKey;
                    tunnelArgs.RoutedEvent = keyPreviewEvent; 
                    focusElement.RaiseEvent(tunnelArgs);
 
                    handled = tunnelArgs.Handled; 
                    if (!handled)
                    { 
                        KeyEventArgs bubbleArgs = new KeyEventArgs(Keyboard.PrimaryDevice, this, msg.time, key);
                        bubbleArgs.ScanCode = scanCode;
                        bubbleArgs.IsExtendedKey = isExtendedKey;
                        bubbleArgs.RoutedEvent=keyEvent; 
                        focusElement.RaiseEvent(bubbleArgs);
 
                        handled = bubbleArgs.Handled; 
                        if (!handled)
                        { 
                            // Raise the TranslateAccelerator event on the
                            // InputManager to allow keyboard navigation to
                            // happen on a descendent HwndSource
                            InputManager.UnsecureCurrent.RaiseTranslateAccelerator(bubbleArgs); 
                            handled = bubbleArgs.Handled;
                        } 
                    } 
                }
                finally 
                {
                    Keyboard.PrimaryDevice.ForceTarget = null;
                }
            } 

            return handled; 
        } 

        // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
        // Go back to accepting character messages.  This method is posted
        // to the dispatcher when char messages are disable.
        internal static object RestoreCharMessages(object unused)
        { 
            _eatCharMessages = false;
            return null; 
        } 

#endregion IKeyboardInputSink 


        internal bool IsRepeatedKeyboardMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
        { 
            if (msg != _lastKeyboardMessage.message)
                return false; 
            if (hwnd != _lastKeyboardMessage.hwnd) 
                return false;
            if (wParam != _lastKeyboardMessage.wParam) 
                return false;
            if (lParam != _lastKeyboardMessage.lParam)
                return false;
            return true; 
        }
 
        ///  
        ///    This event handler is called from HwndWrapper when it is Disposing.
        ///  
        // This could happen if someone calls his Dispose before (or instead
        // of) our dispose.  Or, more likely, the real window was killed by
        // something like the user clicking the close box.
        private void OnHwndDisposed(object sender, EventArgs args) 
        {
            // This method is called from the HwndWrapper.Dispose(). 
            // So make sure we don't call HwndWrapper.Dispose(). 
            _inRealHwndDispose = true;
            Dispose(); 
        }

        /// 
        ///    Called after the last window message is processed. 
        /// 
 
        // HwndSource is required to continue certain operations while, 
        // and even after, Dispose runs.  HwndSource is resposible for
        // calling WndProcHooks with every message the window sees. 
        // Including: WM_CLOSE, WM_DESTROY, WM_NCDESTROY.  The doc says
        // WM_NCDESTROY is the very last message, so we can release the
        // Hooks after that.
        // This assumes the Context.Access() is held. 
        private void OnNoMoreWindowMessages()
        { 
            _hooks.Clear(); 
            _hooks = null;
        } 

        private void OnShutdownFinished(object sender, EventArgs args)
        {
            // Note: We are already in the context being disposed. 
            Dispose();
        } 
 
        //
        // NOTE: shutdown order is very important.  Review any changes 
        // carefully.
        //
        /// 
        ///     Critical: This accesses the various sites and providers 
        ///     Safe: Disposing the object is a safe operation.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private void Dispose(bool disposing)
        { 
            if(disposing)
            {
                // Make sure all access is synchronized.
//                 this.VerifyAccess(); 

                if (!_isDisposing) 
                { 
                    // _isDisposing is a guard against re-entery into this
                    // routine.  We fire Dispose and SourceChanged (RootVisual 
                    // change) events which could cause re-entery.
                    _isDisposing = true;

                    // Notify listeners that we are being disposed.  We do this 
                    // before we dispose our internal stuff, in case the event
                    // listener needs to access something. 
                    if(Disposed != null) 
                    {
                        try 
                        {
                            Disposed(this, EventArgs.Empty);
                        }
#pragma warning disable 56500 
                        // We can't tolerate an exception thrown by third-party code to
                        // abort our Dispose half-way through.  So we just eat it. 
                        catch 
                        {
                        } 
#pragma warning restore 56500
                        Disposed = null;
                    }
 
                    // Remove any listeners of the ContentRendered event
                    ClearContentRenderedListeners(); 
 
                    // Clear the root visual.  This will raise a SourceChanged
                    // event to registered listeners. 
                    RootVisualInternal = null;
                    RemoveSource();

                    // Unregister ourselves if we are a registered KeyboardInputSink. 
                    if(_keyboardInputSite != null)
                    { 
                        _keyboardInputSite.Unregister(); 
                        _keyboardInputSite = null;
                    } 
                    _keyboardInputSinkChildren = null;

                    // Dispose the HwndStylusInputProvider BEFORE we destroy the HWND.
                    // This us because the stylus provider has an async channel and 
                    // they don't want to process data after the HWND is destroyed.
                    if (_stylus != null) 
                    { 
                        _stylus.Value.Dispose();
                        _stylus = null; 
                    }

                    // Our general shut-down principle is to destroy the window
                    // and let the individual HwndXXX components respons to WM_DESTROY. 
                    //
                    // (see comment above about disposing the HwndStylusInputProvider) 
                    // 
                    {
                        if (_hwndTarget != null) 
                        {
                            _hwndTarget.Dispose();
                            _hwndTarget = null;
                        } 

                        if (_hwndWrapper != null) 
                        { 
                            // Revoke the drop target.
                            if (_hwndWrapper.Handle != IntPtr.Zero && _registeredDropTargetCount > 0) 
                            {
                                // This call is safe since DragDrop.RevokeDropTarget is checking the unmanged
                                // code permission.
                                DragDrop.RevokeDropTarget(_hwndWrapper.Handle); 
                                _registeredDropTargetCount--;
                            } 
 
                            // Remove our HwndWrapper.Dispose() hander.
                            _hwndWrapper.Disposed -= new EventHandler(OnHwndDisposed); 

                            if (!_inRealHwndDispose)
                                _hwndWrapper.Dispose();
 
                            // Don't null out _hwndWrapper after the Dispose().
                            // Dispose() will start destroying the Window but we 
                            // still need to talk to it during that process while 
                            // the WM_ msgs arrive.
                        } 
                    }

                    if(_mouse != null)
                    { 
                        _mouse.Value.Dispose();
                        _mouse = null; 
                    } 

                    if(_keyboard != null) 
                    {
                        _keyboard.Value.Dispose();
                        _keyboard = null;
                    } 

                    if (_appCommand != null) 
                    { 
                        _appCommand.Value.Dispose();
                        _appCommand = null; 
                    }

                    if(null != _weakShutdownHandler)
                    { 
                        _weakShutdownHandler.Dispose();
                        _weakShutdownHandler = null; 
                    } 

                    if(null != _weakPreprocessMessageHandler) 
                    {
                        _weakPreprocessMessageHandler.Dispose();
                        _weakPreprocessMessageHandler = null;
                    } 

                    // We wait to set the "_isDisposed" flag until after the 
                    // Disposed, SourceChange (RootVisual=null), etc. events 
                    // have fired.  We want to remain functional should their
                    // handlers call methods on us. 
                    //
                    // Note: as the HwndWrapper shuts down, the final few messages
                    // will continue to pass through our WndProc hook.
                    _isDisposed = true; 
                }
            } 
        } 

        private void CheckDisposed(bool verifyAccess) 
        {
            if(verifyAccess)
            {
//                 this.VerifyAccess(); 
            }
 
            if(_isDisposed) 
            {
                throw new ObjectDisposedException(null, SR.Get(SRID.HwndSourceDisposed)); 
            }
        }

        ///  
        ///     Critical: This code accesses hwndtarget
        ///     TreatAsSafe: Information is ok to expose 
        ///  
        private bool IsUsable
        { 
            [SecurityCritical,SecurityTreatAsSafe]
            get
            {
                return _isDisposed == false && 
                       _hwndTarget != null &&
                       _hwndTarget.IsDisposed == false; 
            } 
        }
 
        /// 
        ///     Critical - calls a method with an elevation ( GetFocus )
        ///     TreatAsSafe - determining whether you have focus within the window is considered safe.
        ///                   Worst case you can know whether keyboard/keypress events will go to the current window. 
        /// 
        private bool HasFocus 
        { 
            [SecurityCritical, SecurityTreatAsSafe]
            get 
            {
                return UnsafeNativeMethods.GetFocus() == CriticalHandle;
            }
        } 

        private static bool IsValidSizeToContent(SizeToContent value) 
        { 
            return value == SizeToContent.Manual ||
                   value == SizeToContent.Width  || 
                   value == SizeToContent.Height ||
                   value == SizeToContent.WidthAndHeight;
        }
 
        class ThreadDataBlob
        { 
            public int TranslateAcceleratorCallDepth; 
        }
 
        private static ThreadDataBlob PerThreadData
        {
            get
            { 
                ThreadDataBlob data;
                object obj = Thread.GetData(_threadSlot); 
                if(null == obj) 
                {
                    data = new ThreadDataBlob(); 
                    Thread.SetData(_threadSlot, data);
                }
                else
                { 
                    data = (ThreadDataBlob) obj;
                } 
                return data; 
            }
        } 

#region WeakEventHandlers

        private class WeakEventDispatcherShutdown: WeakReference 
        {
            public WeakEventDispatcherShutdown(HwndSource source, Dispatcher that): base(source) 
            { 
                _that = that;
                _that.ShutdownFinished += new EventHandler(this.OnShutdownFinished); 
            }

            public void OnShutdownFinished(object sender, EventArgs e)
            { 
                HwndSource source = this.Target as HwndSource;
                if(null != source) 
                { 
                    source.OnShutdownFinished(sender, e);
                } 
                else
                {
                    Dispose();
                } 
            }
 
            public void Dispose() 
            {
                if(null != _that) 
                {
                    _that.ShutdownFinished-= new EventHandler(this.OnShutdownFinished);
                }
            } 

            private Dispatcher _that; 
        } 

        private class WeakEventPreprocessMessage: WeakReference 
        {
            /// 
            ///     Critical: This code calls attaches an arbitrary window
            ///     to the call path for the component dispatcher call back 
            /// 
            [SecurityCritical] 
            public WeakEventPreprocessMessage(HwndSource source): base(source) 
            {
                ComponentDispatcher.ThreadPreprocessMessage += 
                                new ThreadMessageEventHandler(this.OnPreprocessMessage);
            }

            ///  
            ///     Critical: This can be used to spoof and change input
            ///  
            [SecurityCritical] 
            public void OnPreprocessMessage(ref MSG msg, ref bool handled)
            { 
                HwndSource source = this.Target as HwndSource;
                if(null != source)
                {
                    source.OnPreprocessMessageThunk(ref msg, ref handled); 
                }
                else 
                { 
                    Dispose();
                } 
            }


            ///  
            ///     Critical:This code calls into ComponentDispatcher
            ///     to disconnect a listener 
            ///     TreatAsSafe: This code is ok to call 
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            public void Dispose()
            {
                ComponentDispatcher.ThreadPreprocessMessage -=
                                new ThreadMessageEventHandler(this.OnPreprocessMessage); 
            }
        } 
 
#endregion WeakEventHandlers
 
        private object                      _constructionParameters; // boxed HwndSourceParameters

        private bool                        _isDisposed = false;
        private bool                        _isDisposing = false; 
        private bool                        _inRealHwndDispose = false;
        private bool                        _adjustSizingForNonClientArea; 
        private bool                        _myOwnUpdate; 
        private bool                        _isWindowInMinimizeState = false;
 
        private int                         _registeredDropTargetCount;

        private SizeToContent               _sizeToContent = SizeToContent.Manual;
        private Size?                       _previousSize; 

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical.
        ///  
        [SecurityCritical]
        private HwndWrapper                 _hwndWrapper;

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data is considered critical. 
        ///  
        [SecurityCritical]
        private HwndTarget                  _hwndTarget; 

        private SecurityCriticalDataForSet                      _rootVisual;

        private ArrayList                   _hooks; 
        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical. 
        /// 
        private SecurityCriticalDataClass      _mouse; 
        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data is considered critical.
        ///  
        private SecurityCriticalDataClass   _keyboard;
        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical.
        ///  
        private SecurityCriticalDataClass     _stylus;

        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical.
        ///  
        private SecurityCriticalDataClass _appCommand; 

        WeakEventDispatcherShutdown _weakShutdownHandler; 
        WeakEventPreprocessMessage _weakPreprocessMessageHandler;

        private static System.LocalDataStoreSlot _threadSlot;
 
        private MSG                         _lastKeyboardMessage;
        private List _keyboardInputSinkChildren; 
 
        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data can be used to spoof input
        /// 
        [SecurityCritical]
        private IKeyboardInputSite          _keyboardInputSite = null; 

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data can be used to spoof input
        ///  
        [SecurityCritical]
        private HwndWrapperHook             _layoutHook;

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data can be used to spoof input 
        ///  
        [SecurityCritical]
        private HwndWrapperHook             _inputHook; 

        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data can be used to spoof input 
        /// 
        [SecurityCritical] 
        private HwndWrapperHook             _hwndTargetHook; 

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data can be used to spoof input
        /// 
        [SecurityCritical] 
        private HwndWrapperHook             _publicHook;
 
        // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
        //
        // Avalon relies on the policy that if you handle the KeyDown 
        // event, you will not get the TextInput events caused by
        // pressing the key.  This is generally implemented because the
        // message pump calls ComponentDispatcher.RaiseThreadMessage and
        // we return whether or not the WM_KEYDOWN message was handled, 
        // and the message pump will only call TranslateMessage() if the
        // WM_KEYDOWN was not handled.  However, naive message pumps don't 
        // call ComponentDispatcher.RaiseThreadMessage, and always call 
        // TranslateMessage, so the WM_CHAR is generated no matter what.
        // The best work around we could think of was to eat the WM_CHAR 
        // messages and not report them to Avalon.
        //
        [ThreadStatic]
        internal static bool _eatCharMessages; // used from HwndKeyboardInputProvider 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2004
//
//  File: HwndSource.cs 
//-----------------------------------------------------------------------------
 
using System.Collections; 
using System.Collections.Generic;
using System.Threading; 
using System.Windows.Threading;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Interop; 
using System.Runtime.InteropServices;
using MS.Win32; 
using MS.Utility; 
using MS.Internal;
using MS.Internal.PresentationCore;                        // SecurityHelper 
using Microsoft.Win32;
using System.Diagnostics;
using System.ComponentModel;
using System; 
using System.Security;
using System.Security.Permissions; 
using System.IO; 

using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings
 
namespace System.Windows.Interop
{ 
    ///  
    ///     The HwndSource class presents content within a Win32 HWND.
    ///  
    public class HwndSource : PresentationSource, IDisposable, IWin32Window, IKeyboardInputSink
    {
        /// 
        ///     Critical: This code calls into RegisterWindowMesssage which is critical 
        ///     TreatAsSafe: This is safe to call as no external parameters are taken in
        ///  
        [SecurityCritical,SecurityTreatAsSafe] 
        static HwndSource()
        { 
            _threadSlot = Thread.AllocateDataSlot();
        }

        ///  
        ///    Constructs an instance of the HwndSource class that will always resize to its content size.
        ///  
        ///  
        ///     The Win32 class styles for this window.
        ///  
        /// 
        ///     The Win32 styles for this window.
        /// 
        ///  
        ///     The extended Win32 styles for this window.
        ///  
        ///  
        ///     The position of the left edge of this window.
        ///  
        /// 
        ///     The position of the upper edge of this window.
        /// 
        ///  
        ///     The name of this window.
        ///  
        ///  
        ///     The Win32 window that should be the parent of this window.
        ///  
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// 
        ///  
        ///     Added a demand - so that this API does not work in InternetZone.
        ///     Critical: This accesses critical code Initialize 
        ///     PublicOK: This code has a demand which will ensure that it does 
        ///     not work in partial trust without the correct permissions
        ///  
        [SecurityCritical]
        public HwndSource(
            int classStyle,
            int style, 
            int exStyle,
            int x, 
            int y, 
            string name,
            IntPtr parent) 
        {
            SecurityHelper.DemandUIWindowPermission();

            HwndSourceParameters param = new HwndSourceParameters(name); 
            param.WindowClassStyle = classStyle;
            param.WindowStyle = style; 
            param.ExtendedWindowStyle = exStyle; 
            param.SetPosition(x, y);
            param.ParentWindow = parent; 
            Initialize(param);
        }

        ///  
        ///    Constructs an instance of the HwndSource class. This version requires an
        ///    explicit width and height be sepecified. 
        ///  
        /// 
        ///     The Win32 class styles for this window. 
        /// 
        /// 
        ///     The Win32 styles for this window.
        ///  
        /// 
        ///     The extended Win32 styles for this window. 
        ///  
        /// 
        ///     The position of the left edge of this window. 
        /// 
        /// 
        ///     The position of the upper edge of this window.
        ///  
        /// 
        ///     The width of this window. 
        ///  
        /// 
        ///     The height of this window. 
        /// 
        /// 
        ///     The name of this window.
        ///  
        /// 
        ///     The Win32 window that should be the parent of this window. 
        ///  
        /// 
        ///     Indicates that HwndSource should include the non-client area 
        ///     of the hwnd when it calls the Layout Manager
        /// 
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        /// 
        ///  
        ///     Added a demand - so that this API does not work in InternetZone. 
        ///     Critical: This acceses critical code Initialize
        ///     PublicOK: This code has a demand which will ensure that it does 
        ///     not work in partial trust without the correct permissions
        /// 
        [SecurityCritical]
        public HwndSource(int classStyle, 
                          int style,
                          int exStyle, 
                          int x, 
                          int y,
                          int width, 
                          int height,
                          string name,
                          IntPtr parent,
                          bool adjustSizingForNonClientArea) 
        {
            SecurityHelper.DemandUIWindowPermission(); 
 
            HwndSourceParameters parameters = new HwndSourceParameters(name, width, height);
            parameters.WindowClassStyle = classStyle; 
            parameters.WindowStyle = style;
            parameters.ExtendedWindowStyle = exStyle;
            parameters.SetPosition(x, y);
            parameters.ParentWindow = parent; 
            parameters.AdjustSizingForNonClientArea = adjustSizingForNonClientArea;
            Initialize(parameters); 
        } 

        ///  
        ///    Constructs an instance of the HwndSource class. This version requires an
        ///    explicit width and height be sepecified.
        /// 
        ///  
        ///     The Win32 class styles for this window.
        ///  
        ///  
        ///     The Win32 styles for this window.
        ///  
        /// 
        ///     The extended Win32 styles for this window.
        /// 
        ///  
        ///     The position of the left edge of this window.
        ///  
        ///  
        ///     The position of the upper edge of this window.
        ///  
        /// 
        ///     The width of this window.
        /// 
        ///  
        ///     The height of this window.
        ///  
        ///  
        ///     The name of this window.
        ///  
        /// 
        ///     The Win32 window that should be the parent of this window.
        /// 
        ///  
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        ///  
        ///  
        ///     Added a demand - so that this API does not work in InternetZone.
        ///     Critical: This accesses critical code Initialize 
        ///     PublicOK: This code has a demand which will ensure that it does
        ///     not work in partial trust without the correct permissions
        /// 
        [SecurityCritical] 
        public HwndSource(
            int classStyle, 
            int style, 
            int exStyle,
            int x, 
            int y,
            int width,
            int height,
            string name, 
            IntPtr parent)
        { 
            SecurityHelper.DemandUIWindowPermission(); 

            HwndSourceParameters parameters = new HwndSourceParameters(name, width, height); 
            parameters.WindowClassStyle = classStyle;
            parameters.WindowStyle = style;
            parameters.ExtendedWindowStyle = exStyle;
            parameters.SetPosition(x, y); 
            parameters.ParentWindow = parent;
            Initialize(parameters); 
        } 

        ///  
        ///    HwndSource Ctor
        /// 
        ///  parameter block 
        ///  
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        ///  
        ///  
        ///     Critical: This acceses critical code Initialize
        ///  
        [SecurityCritical]
        [UIPermissionAttribute(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)]
        public HwndSource(HwndSourceParameters parameters)
        { 
            Initialize(parameters);
        } 
        ///  
        ///    HwndSource Ctor
        ///  
        ///  parameter block 
        /// 
        ///     Critical: This code access critical (HwndMouseInputProvider, HwndKeyboardInputProvider
        ///     ,HwndStylusInputProvider and the various hooks)objects and creates the 
        ///     providers under elevation.
        ///  
        [SecurityCritical] 
        private void Initialize(HwndSourceParameters parameters)
        { 
            _mouse = new SecurityCriticalDataClass(new HwndMouseInputProvider(this));
            _keyboard = new SecurityCriticalDataClass(new HwndKeyboardInputProvider(this));
            _layoutHook = new HwndWrapperHook(LayoutFilterMessage);
            _inputHook = new HwndWrapperHook(InputFilterMessage); 
            _hwndTargetHook = new HwndWrapperHook(HwndTargetFilterMessage);
 
            _publicHook = new HwndWrapperHook(PublicHooksFilterMessage); 

            // When processing WM_SIZE, LayoutFilterMessage must be invoked before 
            // HwndTargetFilterMessage. This way layout will be updated before resizing
            // HwndTarget, resulting in single render per resize. This means that
            // layout hook should appear before HwndTarget hook in the wrapper hooks
            // list. If this is done the other way around, first HwndTarget resize will 
            // force re-render, then layout will be updated according to the new size,
            // scheduling another render. 
            HwndWrapperHook[] wrapperHooks = { _hwndTargetHook, _layoutHook, _inputHook, null }; 

            if(null != parameters.HwndSourceHook) 
            {
                _hooks = new ArrayList(8);
                _hooks.Insert(0, parameters.HwndSourceHook);
                wrapperHooks[3] = _publicHook; 
            }
 
            // A window must be marked WS_EX_LAYERED if (and only if): 
            // 1) it is not a child window
            //    -- AND -- 
            // 2) a color-key is specified
            // 3) or an opacity other than 1.0 is specified
            // 4) or per-pixel alpha is requested.
            if((parameters.WindowStyle & NativeMethods.WS_CHILD) == 0 && 
               ( //parameters.ColorKey != null ||
                 //!MS.Internal.DoubleUtil.AreClose(parameters.Opacity, 1.0) || 
                parameters.UsesPerPixelOpacity)) 
            {
                parameters.ExtendedWindowStyle |= NativeMethods.WS_EX_LAYERED; 
            }
            else
            {
                parameters.ExtendedWindowStyle &= (~NativeMethods.WS_EX_LAYERED); 
            }
 
 
            _constructionParameters = parameters;
            _hwndWrapper = new HwndWrapper(parameters.WindowClassStyle, 
                                       parameters.WindowStyle,
                                       parameters.ExtendedWindowStyle,
                                       parameters.PositionX,
                                       parameters.PositionY, 
                                       parameters.Width,
                                       parameters.Height, 
                                       parameters.WindowName, 
                                       parameters.ParentWindow,
                                       wrapperHooks); 

            _hwndTarget = new HwndTarget(_hwndWrapper.Handle);
            //_hwndTarget.ColorKey = parameters.ColorKey;
            //_hwndTarget.Opacity = parameters.Opacity; 
            _hwndTarget.UsesPerPixelOpacity = parameters.UsesPerPixelOpacity;
            if(_hwndTarget.UsesPerPixelOpacity) 
            { 
                _hwndTarget.BackgroundColor = Colors.Transparent;
 
                // Prevent this window from being themed.
                UnsafeNativeMethods.CriticalSetWindowTheme(new HandleRef(this, _hwndWrapper.Handle), "", "");
            }
            _constructionParameters = null; 

            if (!parameters.HasAssignedSize) 
                _sizeToContent = SizeToContent.WidthAndHeight; 
            _adjustSizingForNonClientArea = parameters.AdjustSizingForNonClientArea;
 
            // Listen to the UIContext.Disposed event so we can clean up.
            // The HwndTarget cannot work without a MediaContext which
            // is disposed when the UIContext is disposed.  So we need to
            // dispose the HwndTarget and also never use it again (to 
            // paint or process input).  The easiest way to do this is to just
            // dispose the HwndSource at the same time. 
            _weakShutdownHandler = new WeakEventDispatcherShutdown(this, this.Dispatcher); 

            // Listen to the HwndWrapper.Disposed event so we can clean up. 
            // The HwndTarget cannot work without a live HWND, and since
            // the HwndSource represents an HWND, we make sure we dispose
            // ourselves if the HWND is destroyed out from underneath us.
            _hwndWrapper.Disposed += new EventHandler(OnHwndDisposed); 

            _stylus = new SecurityCriticalDataClass(new HwndStylusInputProvider(this)); 
 
            // WM_APPCOMMAND events are handled thru this.
            _appCommand = new SecurityCriticalDataClass(new HwndAppCommandInputProvider(this)); 

            // Register the top level source with the ComponentDispatcher.
            if (parameters.TreatAsInputRoot)
            { 
                _weakPreprocessMessageHandler = new WeakEventPreprocessMessage(this);
            } 
            AddSource(); 

            // Register dropable window. 
            // The checking CallerHasPermissionWithAppDomainOptimization will call RegisterDropTarget
            // safely without the security exception in case of no unmanaged code permission.
            // So RegisterDropTarget will be called safely in case of having the unmanged code permission.
            // Otherwise, the security exception cause System.Printing to be instatiated which will 
            // load system.drawing module.
            if (_hwndWrapper.Handle != IntPtr.Zero && 
                SecurityHelper.CallerHasPermissionWithAppDomainOptimization(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode))) 
            {
                // This call is safe since DragDrop.RegisterDropTarget is checking the unmanged 
                // code permission.
                DragDrop.RegisterDropTarget(_hwndWrapper.Handle);
                _registeredDropTargetCount++;
            } 
        }
 
        ///  
        ///     Disposes the object
        ///  
        ///
        /// This API is not available in Internet Zone.
        ///
        public void Dispose() 
        {
            Dispose(true); 
            GC.SuppressFinalize(this); 
        }
 
        /// 
        ///     Adds a hook that gets called for every window message.
        /// 
        ///  
        ///     The hook to add.
        ///  
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// 
        ///
        /// Critical - uses a critical field.
        /// PublicOK - as there's a demand.
        /// 
        [SecurityCritical ]
        public void AddHook(HwndSourceHook hook) 
        { 
            SecurityHelper.DemandUIWindowPermission();
 
            CheckDisposed(true);

            if(_hooks == null)
            { 
                _hooks = new ArrayList(8);
                _hwndWrapper.AddHook(_publicHook); 
            } 
            _hooks.Insert(0, hook);
        } 

        /// 
        ///     Removes a hook that was previously added.
        ///  
        /// 
        ///     The hook to remove. 
        ///  
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        ///
        ///
        /// Critical - accesses a crtical field - _publicHook
        /// PublicOK - performs a demand. 
        ///
        [SecurityCritical ] 
        public void RemoveHook(HwndSourceHook hook) 
        {
            SecurityHelper.DemandUIWindowPermission(); 

            //this.VerifyAccess();

            if(_hooks != null) 
            {
                _hooks.Remove(hook); 
                if(_hooks.Count == 0) 
                {
                    _hooks = null; 
                    _hwndWrapper.RemoveHook(_publicHook);
                }
            }
        } 

        ///  
        /// GetInputProvider - Given a InputDevice, returns corresponding Provider 
        /// 
        /// InputDevice for which we need InputProvider 
        /// InputProvider, if known
        ///
        /// This API is not available in Internet Zone.
        /// 
        /// 
        ///     Critical: This code accesses and returns critical data *providers* 
        ///  
        [SecurityCritical]
        internal override IInputProvider GetInputProvider(Type inputDevice) 
        {
            if (inputDevice == typeof(MouseDevice))
                return (_mouse    != null ?    _mouse.Value : null);
 
            if (inputDevice == typeof(KeyboardDevice))
                return (_keyboard != null ? _keyboard.Value : null); 
 
            if (inputDevice == typeof(StylusDevice))
                return (_stylus   != null ?   _stylus.Value : null); 

            return null;
        }
 
        /// 
        ///     Announces when this source is disposed. 
        ///  
        public event EventHandler Disposed;
 
        /// 
        ///     Announces when the SizeToContent property changes on this source.
        /// 
        public event EventHandler SizeToContentChanged; 

        ///  
        ///     Whether or not the object is disposed. 
        /// 
        public override bool IsDisposed {get {return _isDisposed;}} 

        /// 
        /// The Root Visual for this window. If it is a UIElement
        ///  
        /// 
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        ///  
        /// 
        ///     Critical: This code sets a rootvisual which is risky to do because 
        ///     it can destabilize assumptions made in popup code
        ///     PublicOK: The getter is safe and the setter has a link demand to block unwarrented
        ///     public use
        ///  
        public override Visual RootVisual
        { 
            [SecurityCritical] 
            get
            { 
                if (_isDisposed)
                    return null;
                return (_rootVisual.Value);
            } 
            [SecurityCritical]
            [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)] 
            set 
            {
                CheckDisposed(true); 

                RootVisualInternal = value;
            }
        } 

        ///  
        /// Critical: Acceses KeyboardInputProvider which is considered as critical data 
        /// also it can be used to set root visual which is deemed as an unsafe operation
        ///  
        private Visual RootVisualInternal
        {
            [SecurityCritical]
            set 
            {
                if (_rootVisual.Value != value) 
                { 
                    Visual oldRoot = _rootVisual.Value;
 
                    if(value != null)
                    {
                        _rootVisual.Value = value;
 
                        if(_rootVisual.Value is UIElement)
                        { 
                            ((UIElement)(_rootVisual.Value)).LayoutUpdated += new EventHandler(OnLayoutUpdated); 
                        }
 
                        if (_hwndTarget != null && _hwndTarget.IsDisposed == false)
                        {
                            _hwndTarget.RootVisual = _rootVisual.Value;
                        } 

                        UIElement.PropagateResumeLayout(null, value); 
                    } 
                    else
                    { 
                        _rootVisual.Value = null;
                        if (_hwndTarget != null && !_hwndTarget.IsDisposed)
                        {
                            _hwndTarget.RootVisual = null; 
                        }
                    } 
 
                    if(oldRoot != null)
                    { 
                        if(oldRoot is UIElement)
                        {
                            ((UIElement)oldRoot).LayoutUpdated -= new EventHandler(OnLayoutUpdated);
                        } 

                        UIElement.PropagateSuspendLayout(oldRoot); 
                    } 

                    RootChanged(oldRoot, _rootVisual.Value); 

                    if (IsLayoutActive() == true)
                    {
                        // Call the helper method SetLayoutSize to set Layout's size 
                        SetLayoutSize();
 
                        // Post the firing of ContentRendered as Input priority work item so that ContentRendered will be 
                        // fired after render query empties.
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new DispatcherOperationCallback(FireContentRendered), this); 
                    }
                    else
                    {
                        // Even though layout won't run (the root visual is either null or not 
                        // a UIElement), the hit-test results will certainly have changed.
                        InputManager.SafeCurrentNotifyHitTestInvalidated(); 
                    } 

                    // It is possible that someone would have closed the window in one of the 
                    // previous callouts - such as during RootChanged or during the layout
                    // we syncronously invoke.  In such cases, the state of this object would
                    // have been torn down.  We just need to protect against that.
                    if(_keyboard != null) 
                    {
                        _keyboard.Value.OnRootChanged(oldRoot, _rootVisual.Value); 
                    } 
                }
            } 
        }

        /// 
        ///     Returns the HwndSource that corresponds to the specified window. 
        /// 
        /// The window. 
        /// The source that corresponds to the specified window. 
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        ///
        /// 
        ///     Critical: This information is not ok to expose since this HwndSource
        ///     is deemed critical to expose 
        ///     PublicOK: There is a demand on this method that prevents this
        ///     from working in partial trust unless you have the right permissions. 
        ///  
        [SecurityCritical]
        public static HwndSource FromHwnd(IntPtr hwnd) 
        {
            SecurityHelper.DemandUIWindowPermission();
            return CriticalFromHwnd(hwnd);
        } 

        ///  
        ///    Critical: This code extracts the HwndSource for an HWND 
        ///    This function is only for internal consumption
        ///  
        [SecurityCritical]
        internal static HwndSource CriticalFromHwnd(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero) 
            {
                throw new ArgumentException(SR.Get(SRID.NullHwnd)); 
            } 
            HwndSource hwndSource = null;
            foreach (PresentationSource source in PresentationSource.CriticalCurrentSources) 
            {
                HwndSource test = source as HwndSource;
                if (test != null && test.CriticalHandle == hwnd)
                { 
                    // Don't hand out a disposed source.
                    if (!test.IsDisposed) 
                        hwndSource = test; 
                    break;
                } 
            }
            return hwndSource;
        }
 

        ///  
        ///     The visual manager for the visuals being presented in the source. 
        ///     Type-specific version of the CompositionTarget property for this source.
        ///  
        /// 
        ///     Critical: Accesses hwndTarget and returns it
        ///     PublicOk: Protected by a LinkDemand
        ///  
        public new HwndTarget CompositionTarget
        { 
            [SecurityCritical] 
            [UIPermissionAttribute(SecurityAction.LinkDemand,Window=UIPermissionWindow.AllWindows)]
            get 
            {
                if (_isDisposed)
                    return null;
 
                // Even though we created the HwndTarget, it can get disposed out from
                // underneath us. 
                if (_hwndTarget!= null && _hwndTarget.IsDisposed == true) 
                {
                    return null; 
                }

                return _hwndTarget;
            } 
        }
 
        ///  
        ///     Returns visual target for this source.
        ///  
        /// 
        ///     Critical: calls get_CompositionTarget() and returns its value.
        /// 
        [SecurityCritical] 
        protected override CompositionTarget GetCompositionTargetCore()
        { 
            return CompositionTarget; 
        }
 
        /// 
        ///     Event invoked when the layout causes the HwndSource to resize automatically.
        /// 
        public event AutoResizedEventHandler AutoResized; 

        ///  
        /// Handler for LayoutUpdated event of a rootVisual. 
        /// 
        ///  
        ///     Critical: This code causes resize of window and accesses HwndTarget
        /// 
        [SecurityCritical]
        private void OnLayoutUpdated(object obj, EventArgs args) 
        {
            UIElement root = _rootVisual.Value as UIElement; 
 
            if(root != null)
            { 
                Size newSize = root.RenderSize;
                if (   _previousSize == null
                    || !DoubleUtil.AreClose(_previousSize.Value.Width, newSize.Width)
                    || !DoubleUtil.AreClose(_previousSize.Value.Height, newSize.Height)) 
                {
                    // We should update _previousSize, even if the hwnd is not 
                    // sizing to content.  This fixes the scenario where: 
                    //
                    // 1) hwnd is sized to content to say a, b 
                    // 2) hwnd is resize to a bigger size
                    // 3) hwnd is sized to content to a, b again
                    _previousSize = newSize;
 
                    //
                    // Don't resize while the Window is in Minimized mode. 
                    // 
                    if (_sizeToContent != SizeToContent.Manual && !_isWindowInMinimizeState )
                    { 
                        Resize(newSize);
                    }
                }
            } 
        }
 
        ///  
        /// This is called when LayoutManager was updated and its size (the layout size of top element) changed.
        /// Ask LayoutManager.Size to see what the new value is. 
        /// 
        /// 
        ///     Critical: This code causes resize of window and accesses HwndTarget
        ///     TreatAsSafe: In RBW the resize values are clamped also one cannot construct or get to a HwndSource in partial trust 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private void Resize(Size newSize) 
        {
            try 
            {
                _myOwnUpdate = true;

                if (IsUsable) 
                {
                    NativeMethods.RECT rect = AdjustWindowSize(newSize); 
 
                    int newWidth = rect.right - rect.left;
                    int newHeight = rect.bottom - rect.top; 

                    // Set the new window size
                    UnsafeNativeMethods.SetWindowPos(new HandleRef(this,_hwndWrapper.Handle), new HandleRef(null,IntPtr.Zero),
                                                   0, 0, newWidth, newHeight, 
                                                   NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
 
                    if (AutoResized != null) 
                    {
                        AutoResized(this, new AutoResizedEventArgs(newSize)); 
                    }
                }
            }
            finally 
            {
                _myOwnUpdate = false; 
            } 
        }
 
        /// 
        ///     Critical: This code accesses critical member _hwndTarget.
        ///     TreatAsSafe: It calculates the hwnd size without changing it.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private NativeMethods.RECT AdjustWindowSize(Size newSize) 
        { 
            // Gather the new client dimensions
            // The dimension WPF uses is logical unit. We need to convert to device unit first. 
            Point pt = _hwndTarget.TransformToDevice.Transform(new Point(newSize.Width, newSize.Height));
            RoundDeviceSize(ref pt);
            NativeMethods.RECT rect = new NativeMethods.RECT(0, 0, (int)pt.X, (int)pt.Y);
 
            // If we're here, and it is the Window case (_adjustSizingForNonClientArea == true)
            // we get the size which includes the outside size of the window.  For browser case, 
            // we don't support SizeToContent, so we don't take care of this condition. 
            // For non-Window cases, we need to calculate the outside size of the window
            // 
            // For windows with UsesPerPixelOpacity, we force the client to
            // fill the window, so we don't need to add in any frame space.
            //
            if (_adjustSizingForNonClientArea == false && !UsesPerPixelOpacity) 
            {
                int style = NativeMethods.IntPtrToInt32((IntPtr)SafeNativeMethods.GetWindowStyle(new HandleRef(this, _hwndWrapper.Handle), false)); 
                int styleEx = NativeMethods.IntPtrToInt32((IntPtr)SafeNativeMethods.GetWindowStyle(new HandleRef(this, _hwndWrapper.Handle), true)); 

                SafeNativeMethods.AdjustWindowRectEx(ref rect, style, false, styleEx); 
            }
            return rect;
        }
 
        // If the root element has Pixel snapping enabled, round the window size to the
        // nearest int.  Otherwise round the size up to the next int. 
        private void RoundDeviceSize(ref Point size) 
        {
            UIElement root = _rootVisual.Value as UIElement; 
            if (root != null && root.SnapsToDevicePixels)
            {
                size = new Point(DoubleUtil.DoubleToInt(size.X), DoubleUtil.DoubleToInt(size.Y));
            } 
            else
            { 
                size = new Point(Math.Ceiling(size.X), Math.Ceiling(size.Y)); 
            }
        } 

        /// 
        /// Returns the hwnd handle to the window.
        ///  
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. 
        /// 
        /// 
        ///     Critical:This is not safe to expose in internet zone, it returns a window handle 
        ///     PublicOK: There exists a demand on this code
        /// 
        public IntPtr Handle
        { 
            [SecurityCritical]
            get 
            { 
                SecurityHelper.DemandUIWindowPermission();
                return CriticalHandle; 
            }
        }

        ///  
        ///     Critical:Internal helper to retrieve handle for security purposes only Please
        ///     DO NOT USE THIS TO  EXPOSE HANDLE TO OUTSIDE WORLD 
        ///  
        internal IntPtr CriticalHandle
        { 
            [FriendAccessAllowed]
            [SecurityCritical]
            get
            { 
                if (null != _hwndWrapper)
                    return _hwndWrapper.Handle; 
                return IntPtr.Zero; 
            }
        } 

        /// 
        ///     Critical: returns the critical _hwndWrapper.
        ///  
        internal HwndWrapper HwndWrapper
        { 
            [SecurityCritical] 
            get { return _hwndWrapper; }
        } 

        // Return whether this presentation source has capture.
        /// 
        ///     Critical: calls CriticalHandle 
        ///     TreatAsSafe: Returning whether a presentation source has capture is considered safe.
        ///  
        internal bool HasCapture 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            {
                IntPtr capture = SafeNativeMethods.GetCapture();
 
                return ( capture == CriticalHandle );
            } 
        } 

        /// 
        ///     Critical - accesses _hwndWrapper.
        ///     TreatAsSafe - checking for null is considered safe.
        ///
        internal bool IsHandleNull 
        {
            [SecurityCritical, SecurityTreatAsSafe ] 
            get 
            {
                return _hwndWrapper.Handle == IntPtr.Zero ; 
            }
        }

        ///  
        /// Returns the hwnd handle to the window.
        ///  
        public HandleRef CreateHandleRef() 
        {
            return new HandleRef(this,Handle); 
        }


        ///  
        /// SizeToContent on HwndSource
        ///  
        ///  
        /// The default value is SizeToContent.Manual
        ///  
        public SizeToContent SizeToContent
        {
            get
            { 
                CheckDisposed(true);
                return _sizeToContent; 
            } 

            set 
            {
                CheckDisposed(true);

                if (IsValidSizeToContent(value) != true) 
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(SizeToContent)); 
                } 

                if (_sizeToContent == value) 
                {
                    return;
                }
 
                _sizeToContent = value;
 
                // we only raise SizeToContentChanged when user interaction caused the change; 
                // if a developer goes directly to HwndSource and sets SizeToContent, we will
                // not notify the wrapping Window 

                if (IsLayoutActive() == true)
                {
                    // Call the helper method SetLayoutSize to set Layout's size 
                    SetLayoutSize();
                } 
            } 
        }
 
        /// 
        ///     Critical: This code elevates to access hwndtarget
        ///     TreatAsSafe: ok to expose
        ///  
        [SecurityCritical,SecurityTreatAsSafe]
        private bool IsLayoutActive() 
        { 

            if ((_rootVisual.Value is UIElement) && _hwndTarget!= null && _hwndTarget.IsDisposed == false) 
            {
                return true;
            }
 
            return false;
        } 
 
        /// 
        /// This is the helper method that sets Layout's size basing it on 
        /// the current value of SizeToContent.
        /// 
        ///
        ///  TreatAsSafe: This API could be public in terms of security. 
        ///  It does three calls to UnsafeNativeMethods all in a safe way
        ///  Critical: Makes 3 calls to UnsafeNativeMethods 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void SetLayoutSize() 
        {
            Debug.Assert(_hwndTarget!= null, "HwndTarget is null");
            Debug.Assert(_hwndTarget.IsDisposed == false, "HwndTarget is disposed");
 
            UIElement rootUIElement = null;
            rootUIElement = _rootVisual.Value as UIElement; 
            if (rootUIElement == null) return; 

            // hamidm - 11/01/2005 
            // InvalidateMeasure() call is necessary in the following scenario
            //
            // Window w = new Window();
            // w.Measure(new Size(x,y)); 
            // w.Width = x;
            // w.Height = y; 
            // w.Show() 
            //
            // In the above scenario, the Measure call from SetLayoutSize will be opt out 
            // and window will not receive the MeasureOverride call.  As such, the hwnd min/max
            // restrictions will not be applied since MeasureOverride did not happen after hwnd
            // creation.  Thus, we call InvalidatMeasure() to ensure MeasureOverride call on
            // Window after hwnd creation. 

            rootUIElement.InvalidateMeasure(); 
 
            bool etwEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal);
            int  ctxHashCode = 0; 

            if (_sizeToContent == SizeToContent.WidthAndHeight)
            {
                //setup constraints for measure-to-content 
                Size sz = new Size(double.PositiveInfinity, double.PositiveInfinity);
 
                if (etwEnabled) 
                {
                    ctxHashCode = this.Dispatcher.GetHashCode(); 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.StartEvent, ctxHashCode);

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                } 

                rootUIElement.Measure(sz); 
 
                if (etwEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.EndEvent);

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                } 

                rootUIElement.Arrange(new Rect(new Point(), rootUIElement.DesiredSize)); 
 
                if (etwEnabled)
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.EndEvent);

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.EndEvent);
                } 
            }
            else 
            { 
                // GetSizeFromHwnd sets either the outside size or the client size of the hwnd based on
                // _adjustSizeingForNonClientArea flag in logical units. 
                Size sizeFromHwndLogicalUnits = GetSizeFromHwnd();
                Size sz = new Size(
                        (_sizeToContent == SizeToContent.Width ? double.PositiveInfinity : sizeFromHwndLogicalUnits.Width),
                        (_sizeToContent == SizeToContent.Height ? double.PositiveInfinity : sizeFromHwndLogicalUnits.Height)); 

                if (etwEnabled) 
                { 
                    ctxHashCode = this.Dispatcher.GetHashCode();
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.StartEvent, ctxHashCode); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                }
 
                rootUIElement.Measure(sz);
 
                if (etwEnabled) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.EndEvent); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                }
 
                if (_sizeToContent == SizeToContent.Width) sz = new Size(rootUIElement.DesiredSize.Width, sizeFromHwndLogicalUnits.Height);
                else if(_sizeToContent == SizeToContent.Height) sz = new Size(sizeFromHwndLogicalUnits.Width, rootUIElement.DesiredSize.Height); 
                else sz = sizeFromHwndLogicalUnits; 

                rootUIElement.Arrange(new Rect(new Point(), sz)); 

                if (etwEnabled)
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.EndEvent); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.EndEvent); 
                } 
            }
            rootUIElement.UpdateLayout(); 
        }

        // /// 
        // ///     Specifies the color to display as transparent. 
        // /// 
        // ///  
        // ///     Use null to indicate that no color should be transparent. 
        // /// 
        // public Nullable ColorKey 
        // {
        //     get
        //     {
        //         CheckDisposed(true); 
        //
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed 
        //         if(_hwndTarget != null) 
        //         {
        //             return _hwndTarget.ColorKey; 
        //         }
        //         else
        //         {
        //             return null; 
        //         }
        //     } 
        // 
        //     set
        //     { 
        //         CheckDisposed(true);
        //
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed
        //         if(_hwndTarget != null) 
        //         {
        //             _hwndTarget.ColorKey = value; 
        //         } 
        //     }
        // } 

        // /// 
        // ///     Specifies the constant opacity to apply to the window.
        // ///  
        // /// 
        // ///     The valid values range from [0..1].  Values outside of this range are clamped. 
        // ///  
        // public double Opacity
        // { 
        //     get
        //     {
        //         CheckDisposed(true);
        // 
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed
        //         if(_hwndTarget != null) 
        //         { 
        //             return _hwndTarget.Opacity;
        //         } 
        //         else
        //         {
        //             return 1.0;
        //         } 
        //     }
        // 
        //     set 
        //     {
        //         CheckDisposed(true); 
        //
        //         HwndTarget hwndTarget = CompositionTarget; // checks for disposed
        //         if(_hwndTarget != null)
        //         { 
        //             _hwndTarget.Opacity = value;
        //         } 
        //     } 
        // }
 
        /// 
        ///     Specifies whether or not the per-pixel opacity of the window content
        ///     is respected.
        ///  
        /// 
        ///     By enabling per-pixel opacity, the system will no longer draw the non-client area. 
        ///  
        /// 
        ///     Critical: Because it accesses _hwndTarget 
        ///     PublicOK: We don't pass it out; it is just used to query UsesPerPixelOpacity
        /// 
        public bool UsesPerPixelOpacity
        { 
            [SecurityCritical]
            get 
            { 
                CheckDisposed(true);
 
                HwndTarget hwndTarget = CompositionTarget; // checks for disposed
                if(_hwndTarget != null)
                {
                    return _hwndTarget.UsesPerPixelOpacity; 
                }
                else 
                { 
                    return false;
                } 
            }

/* Not allowing this to change at run-time yet.
            [SecurityCritical] 
            set
            { 
                CheckDisposed(true); 

                HwndTarget hwndTarget = CompositionTarget; // checks for disposed 
                if(_hwndTarget != null)
                {
                    _hwndTarget.UsesPerPixelOpacity = value;
                } 
            }
*/ 
        } 

        ///  
        ///     Critical: Because it accesses _hwndTarget
        ///     TreatAsSafe: We don't pass it out; it is just used to convert to logical units
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        private Size GetSizeFromHwnd()
        { 
            // Compute View's size and set 
            NativeMethods.RECT rc = new NativeMethods.RECT(0, 0, 0, 0);
 
            if (_adjustSizingForNonClientArea == true)
            {
                // get correct size for avalon Window (standalone and browser case)
                GetSizeForWindowObject(ref rc); 
            }
            else 
            { 
                SafeNativeMethods.GetClientRect(new HandleRef(this,_hwndWrapper.Handle), ref rc);
            } 

            Point convertedPt = _hwndTarget.TransformFromDevice.Transform(new Point(rc.right - rc.left, rc.bottom - rc.top));
            return new Size(convertedPt.X, convertedPt.Y);
        } 

        ///  
        ///     Critical: This code can be used to spoof input 
        /// 
        [SecurityCritical] 
        private IntPtr HwndTargetFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            IntPtr result = IntPtr.Zero ;
 
            if (IsUsable)
            { 
                HwndTarget hwndTarget = _hwndTarget; 
                if (hwndTarget != null)
                { 
                    result = hwndTarget.HandleMessage(msg, wParam, lParam);
                    if (result != IntPtr.Zero)
                    {
                        handled = true; 
                    }
                } 
 
            }
 
            return result;
        }

        ///  
        /// Critical:These hooks can all be used for input spoofing
        ///  
        [SecurityCritical] 
        private IntPtr LayoutFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        { 
            IntPtr result = IntPtr.Zero ;

            // We have to revalidate everything because the Access() call
            // could have caused the CLR to enter a nested message pump, 
            // during which almost anything could have happened that might
            // invalidate our checks. 
            UIElement rootUIElement=null; 
            rootUIElement = _rootVisual.Value as UIElement;
            if (IsUsable && rootUIElement != null) 
            {
                switch (msg)
                {
                    // A window receives this message when the user chooses a command from 
                    // the Window menu or when the user chooses the maximize button, minimize
                    // button, restore button, or close button. 
                    case NativeMethods.WM_SYSCOMMAND: 
                        {
                            // The four low-order bits of the wParam parameter are used 
                            // internally by the system.
                            Int32 sysCommand = NativeMethods.IntPtrToInt32(wParam) & 0xFFF0;

                            // Turn off SizeToContent if user chooses to maximize or resize. 
                            if ((sysCommand == NativeMethods.SC_MAXIMIZE) ||
                                (sysCommand == NativeMethods.SC_SIZE)) 
                            { 
                                DisableSizeToContent(rootUIElement, hwnd);
                            } 
                        }
                        break;

                    // We get WM_SIZING. It means that user starts resizing the window. 
                    // It is the first notification sent when user resizes (before WM_WINDOWPOSCHANGING)
                    // and it's not sent if window is resized programmatically. 
                    // SizeToContent is turned off after user resizes. 
                    case NativeMethods.WM_SIZING:
                        DisableSizeToContent(rootUIElement, hwnd); 
                        break;

                    // The WM_WINDOWPOSCHANGING message is sent
                    // 1. when the size, position, or place in the Z order is about to change as a result of a call to 
                    //    the SetWindowPos function or other window-management functions. SizeToContent orverrides all in this case.
                    // 2. when user resizes window. If it's user resize, we have turned SizeToContent off when we get WM_SIZING. 
                    // It is sent before WM_SIZE. 
                    // We can't use WM_GETMINMAXINFO, because if there is no window size change (we still need to make sure
                    // the client size not change), that notification wouldnt be sent. 
                    case NativeMethods.WM_WINDOWPOSCHANGING:
                        Process_WM_WINDOWPOSCHANGING(rootUIElement, hwnd, msg, wParam, lParam);
                        break;
 
                    // WM_SIZE message is sent after the size has changed.
                    // lParam has the new width and height of client area. 
                    // root element's size should be adjust based on the new width and height and SizeToContent's value. 
                    case NativeMethods.WM_SIZE:
                        Process_WM_SIZE(rootUIElement, hwnd, msg, wParam, lParam); 
                        break;
                }
            }
 
            // Certain messages need to be processed while we are in the middle
            // of construction - and thus an HwndTarget is not available. 
            if(!handled && (_constructionParameters != null || IsUsable)) 
            {
                // Get the usesPerPixelOpacity from either the constructor parameters or the HwndTarget. 
                bool usesPerPixelOpacity = _constructionParameters != null ? ((HwndSourceParameters)_constructionParameters).UsesPerPixelOpacity : _hwndTarget.UsesPerPixelOpacity;

                switch(msg)
                { 
                    case NativeMethods.WM_NCCALCSIZE:
                        { 
                            // Windows that use per-pixel opacity don't get 
                            // their frames drawn by the system.  Generally
                            // this is OK, as users of per-pixel alpha tend 
                            // to be doing customized UI anyways.  But we
                            // don't render correctly if we leave a non-client
                            // area, so here we expand the client area to
                            // cover any non-client area. 
                            //
                            if(usesPerPixelOpacity) 
                            { 
                                if(wParam == IntPtr.Zero)
                                { 
                                    // If wParam is FALSE, lParam points to a RECT
                                    // structure. On entry, the structure contains
                                    // the proposed window rectangle for the
                                    // window. On exit, the structure should 
                                    // contain the screen coordinates of the
                                    // corresponding window client area. 
                                    // 
                                    // Since all we want to do is make the client
                                    // rect the same as the window rect, we don't 
                                    // have to do anything.
                                    //
                                    result = IntPtr.Zero;
                                    handled = true; 
                                }
                                else 
                                { 
                                    // If wParam is TRUE, lParam points to an
                                    // NCCALCSIZE_PARAMS structure that contains 
                                    // information an application can use to
                                    // calculate the new size and position of
                                    // the client rectangle.
                                    // 
                                    // When Windows sends the WM_NCCALCSIZE
                                    // message, the NCCALCSIZE_PARAMS structure 
                                    // is filled out like this: 
                                    //
                                    // rgrc[0] = new window rectangle (in parent coordinates) 
                                    // rgrc[1] = old window rectangle (in parent coordinates)
                                    // rgrc[2] = old client rectangle (in parent coordinates)
                                    //
                                    // Notice that the client rectangle is given 
                                    // in parent coordinates, not in client
                                    // coordinates. 
                                    // 
                                    // When your window procedure returns, Windows
                                    // expects the NCCALCSIZE_PARAMS structure to 
                                    // be filled out like this:
                                    //
                                    // rgrc[0] = new client rectangle (in parent coordinates)
                                    // 
                                    // Furthermore, if you return anything other
                                    // than 0, Windows expects the remaining two 
                                    // rectangles to be filled out like this: 
                                    //
                                    // rgrc[1] = destination rectangle (in parent coordinates) 
                                    // rgrc[2] = source rectangle (in parent coordinates)
                                    //
                                    // (If you return 0, then Windows assumes that
                                    // the destination rectangle equals the new 
                                    // client rectangle and the source rectangle
                                    // equals the old client rectangle.) 
                                    // 
                                    // Since all we want to do is make the client
                                    // rect the same as the window rect, we don't 
                                    // have to do anything.
                                    //
                                    result = IntPtr.Zero;
                                    handled = true; 
                                }
                            } 
                        } 
                        break;
                } 
            }

            return result;
        } 

        ///  
        /// Critical: Because it uses _hwndTarget 
        /// 
        [SecurityCritical] 
        private void Process_WM_WINDOWPOSCHANGING(UIElement rootUIElement, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            // Only if SizeToContent overrides Win32 sizing change calls.
            // If it's coming from OnResize (_myOwnUpdate != true), it means we are adjusting 
            // to the right size; don't need to do anything here.
            if ((_myOwnUpdate != true) && (SizeToContent != SizeToContent.Manual)) 
            { 
                // Get the current style and calculate the size to be with the new style.
                // If WM_WINDOWPOSCHANGING is sent because of style changes, WM_STYLECHANGED is sent 
                // before this. The style bits we get here are updated ones, but haven't been applied
                // to Window yet. For example, when the window is changing to borderless, without updating the window size,
                // the window size will remain the same but the client area will be bigger. So when SizeToContent is on, we calculate
                // the window size to be with the new style using AdustWindowRectEx and adjust it to make sure client area is not affected. 
                NativeMethods.RECT rect = AdjustWindowSize(rootUIElement.RenderSize);
 
                int newCX = rect.right - rect.left; 
                int newCY = rect.bottom - rect.top;
 
                // Get WINDOWPOS structure data from lParam; it contains information about the window's
                // new size and position.
                NativeMethods.WINDOWPOS windowPos = (NativeMethods.WINDOWPOS)UnsafeNativeMethods.PtrToStructure(lParam, typeof(NativeMethods.WINDOWPOS));
 
                bool sizeChanged = false;
 
                // If SWP_NOSIZE is set to ignore cx, cy. It could be a style or position change. 
                if ((windowPos.flags & NativeMethods.SWP_NOSIZE) == NativeMethods.SWP_NOSIZE)
                { 
                    NativeMethods.RECT windowRect = new NativeMethods.RECT(0, 0, 0, 0);

                    // Get the current Window rect
                    SafeNativeMethods.GetWindowRect(new HandleRef(this, _hwndWrapper.Handle), ref windowRect); 

                    // If there is no size change with the new style we don't need to do anything. 
                    if ((newCX != (windowRect.right - windowRect.left)) || 
                        (newCY != (windowRect.bottom - windowRect.top)))
                    { 
                        // Otherwise unmark the flag to make our changes effective.
                        windowPos.flags &= ~NativeMethods.SWP_NOSIZE;

                        // When SWP_NOSIZE is on, the size info in cx and cy is bogus. They are ignored. 
                        // When we turn it off, we need to provide valid value for both of them.
                        windowPos.cx = newCX; 
                        windowPos.cy = newCY; 
                        sizeChanged = true;
                    } 
                }
                else
                {
                    // We have excluded SizeToContent == SizeToContent.Manual before entering this. 
                    bool sizeToWidth = (SizeToContent == SizeToContent.Height) ? false : true;
                    bool sizeToHeight = (SizeToContent == SizeToContent.Width) ? false : true; 
 
                    // Update WindowPos with the size we want.
                    if ((sizeToWidth) && (windowPos.cx != newCX)) 
                    {
                        windowPos.cx = newCX;
                        sizeChanged = true;
                    } 

                    if ((sizeToHeight) && (windowPos.cy != newCY)) 
                    { 
                        windowPos.cy = newCY;
                        sizeChanged = true; 
                    }
                }

                // Marshal the structure back only when changed 
                if (sizeChanged)
                { 
                    Marshal.StructureToPtr(windowPos, lParam, true); 
                }
            } 
        }

        /// 
        /// Critical: Because it uses _hwndTarget 
        /// 
        [SecurityCritical] 
        private void Process_WM_SIZE(UIElement rootUIElement, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) 
        {
            int x = NativeMethods.SignedLOWORD(lParam); 
            int y = NativeMethods.SignedHIWORD(lParam);
            Point pt = new Point(x, y);
            bool etwEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal);
            int  ctxHashCode = 0; 

            // 1. If it's coming from Layout (_myOwnUpdate), it means we are adjusting 
            // to the right size; don't need to do anything here. 
            // 2. If SizeToContent is set to WidthAndHeight, then we maintain the current hwnd size
            // in WM_WINDOWPOSCHANGING, so we don't need to re-layout here.  If SizeToContent 
            // is set to Width or Height and developer calls SetWindowPos to set a new
            // Width/Height, we need to do a layout.
            // 3. We also don't need to do anything if it's minimized.
 
            // Keeps the status of whether the Window is in Minimized state or not.
            _isWindowInMinimizeState = (NativeMethods.IntPtrToInt32(wParam) == NativeMethods.SIZE_MINIMIZED) ? true : false; 
 
            if ((!_myOwnUpdate) && (_sizeToContent != SizeToContent.WidthAndHeight) && !_isWindowInMinimizeState)
            { 
                Point relevantPt = new Point(pt.X, pt.Y);

                // WM_SIZE has the client size of the window.
                // for appmodel window case, get the outside size of the hwnd. 
                if (_adjustSizingForNonClientArea == true)
                { 
                    NativeMethods.RECT rect = new NativeMethods.RECT(0, 0, (int)pt.X, (int)pt.Y); 
                    GetSizeForWindowObject(ref rect);
                    relevantPt.X = rect.right - rect.left; 
                    relevantPt.Y = rect.bottom - rect.top;
                }

                // The lParam/wParam size and the GetSizeForWindowObject size are 
                // both in device co-ods, thus we convert to Measure co-ods here.
                relevantPt = _hwndTarget.TransformFromDevice.Transform(relevantPt); 
 
                Size sz = new Size(
                    (_sizeToContent == SizeToContent.Width ? double.PositiveInfinity : relevantPt.X), 
                    (_sizeToContent == SizeToContent.Height ? double.PositiveInfinity : relevantPt.Y));

                // NOTE: hamidm -- 6/03/04
                // 962884 Avalon content does not resize when the favorites 
                // (or other side pane) is closed
                // 
                // The issue is that when the browser shows favorites window, avalon 
                // window is resized and we get WM_SIZE.  Here, we pass the IE window's
                // size to Measure so that Computed[Width/Height] gets the correct 
                // IE window dimensions.  Since, IE window's size may not change, the
                // call to Measure is optimized out and no layout happens.  Invalidating
                // layout here ensures that we do layout.
                // This can happen only in the Window case 
                if (_adjustSizingForNonClientArea == true)
                { 
                    rootUIElement.InvalidateMeasure(); 
                }
 
                if (etwEnabled)
                {
                    ctxHashCode = this.Dispatcher.GetHashCode();
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.StartEvent, ctxHashCode); 

                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.StartEvent, ctxHashCode); 
                } 

                rootUIElement.Measure(sz); 

                if (_sizeToContent == SizeToContent.Width) sz = new Size(rootUIElement.DesiredSize.Width, relevantPt.Y);
                else if (_sizeToContent == SizeToContent.Height) sz = new Size(relevantPt.X, rootUIElement.DesiredSize.Height);
                else sz = new Size(relevantPt.X, relevantPt.Y); 

                if (etwEnabled) 
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.MEASUREGUID), MS.Utility.EventType.EndEvent);
 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.StartEvent, ctxHashCode);
                }

                rootUIElement.Arrange(new Rect(new Point(), sz)); 

                if (etwEnabled) 
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.ARRANGEGUID), MS.Utility.EventType.EndEvent);
 
                    EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.LAYOUTPASSGUID), MS.Utility.EventType.EndEvent);
                }
                rootUIElement.UpdateLayout(); //finalizes layout
 
            }
        } 
 
        /// 
        /// Critical: Because it uses _hwndTarget 
        /// 
        [SecurityCritical]
        private void DisableSizeToContent(UIElement rootUIElement, IntPtr hwnd)
        { 
            if (_sizeToContent != SizeToContent.Manual)
            { 
                _sizeToContent = SizeToContent.Manual; 

                // hamidm - 10/27/2005 
                // 1348020 Window expereience layout issue when SizeToContent is being turned
                // off by user interaction
                // This bug was caused b/c we were giving rootUIElement.DesiredSize as input
                // to Measure/Arrange below.  That is incorrect since rootUIElement.DesiredSize may not 
                // cover the entire hwnd client area.
 
                // GetSizeFromHwnd returns either the outside size or the client size of the hwnd based on 
                // _adjustSizeingForNonClientArea flag in logical units.
                Size sizeLogicalUnits = GetSizeFromHwnd(); 
                rootUIElement.Measure(sizeLogicalUnits);
                rootUIElement.Arrange(new Rect(new Point(), sizeLogicalUnits));

                rootUIElement.UpdateLayout(); //finalizes layout 

 
                if (SizeToContentChanged != null) 
                {
                    SizeToContentChanged(this, EventArgs.Empty); 
                }
            }
        }
 
        // This method makes sure that we get the size from the correct
        // hwnd for the browser case. 
        ///  
        /// Critical - calls critical methods (HwndSourceHelper.GetHandle and GetAncestor)
        /// TreatAsSafe - it's ok to return size of window. it doesn't return info gotten through critical calls. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void GetSizeForWindowObject(ref NativeMethods.RECT rc)
        { 
            IntPtr hwndRoot = UnsafeNativeMethods.GetAncestor(new HandleRef(this, CriticalHandle), NativeMethods.GA_ROOT);
            SafeNativeMethods.GetWindowRect(new HandleRef(this, hwndRoot), ref rc); 
        } 

        ///  
        ///     Critical: This is a hook that gets called back with information about messages related to input
        ///     Calling this from outside or causing this to be invoked could yield risky situations
        /// 
        [SecurityCritical] 
        private IntPtr InputFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        { 
            IntPtr result = IntPtr.Zero ; 

            // NOTE (alexz): invoke _stylus.FilterMessage before _mouse.FilterMessage 
            // to give _stylus a chance to eat mouse message generated by stylus
            if (!_isDisposed && _stylus != null && !handled)
            {
                result = _stylus.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled); 
            }
 
            if (!_isDisposed && _mouse != null && !handled) 
            {
                result = _mouse.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled); 
            }

            if (!_isDisposed && _keyboard != null && !handled)
            { 
                result = _keyboard.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled);
            } 
 
            if (!_isDisposed && _appCommand != null && !handled)
            { 
                result = _appCommand.Value.FilterMessage(hwnd, msg, wParam, lParam, ref handled);
            }

            return result; 
        }
 
        ///  
        ///    Called from HwndWrapper on all window messages.
        ///  
        // assumes Context.Access() is held.
        private IntPtr PublicHooksFilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            // The default result for messages we handle is 0. 
            IntPtr result = IntPtr.Zero ;
 
            // Call all of the public hooks 
            // We do this even if we are disposed because otherwise the hooks
            // would never see the WM_DESTROY etc. message. 
            if (_hooks != null)
            {
                for (int i = 0, nCount = _hooks.Count; i < nCount; i++)
                { 
                    result = ((HwndSourceHook)_hooks[i])(hwnd, msg, wParam, lParam, ref handled);
                    if(handled) 
                    { 
                        break;
                    } 
                }
            }
            if (NativeMethods.WM_NCDESTROY == msg)
            { 
                // We delivered the message to the hooks and the message
                // is WM_NCDESTROY, so our commitments should be finished 
                // we can do final teardown. (like disposing the _hooks) 
                OnNoMoreWindowMessages();
            } 

            return result;
        }
 
#region IKeyboardInputSink
        private class MSGDATA 
        { 
            public MSG msg;
            public bool handled; 
        }

        /// 
        /// HwndSource keyboard input is sent through this delegate to check for 
        /// Child Hwnd interop requirments.  If there are no child hwnds or focus
        /// is on this non-child hwnd then normal Avalon processing is done. 
        ///  
        ///
        /// Critical - This can be used to spoof input 
        /// 
        [SecurityCritical]
        private void OnPreprocessMessageThunk(ref MSG msg, ref bool handled)
        { 
//             VerifyAccess();
 
            if (handled) 
            {
                return; 
            }

            // We only do these message.
            switch (msg.message) 
            {
            case NativeMethods.WM_KEYUP: 
            case NativeMethods.WM_KEYDOWN: 
            case NativeMethods.WM_SYSKEYUP:
            case NativeMethods.WM_SYSKEYDOWN: 
            case NativeMethods.WM_CHAR:
            case NativeMethods.WM_SYSCHAR:
            case NativeMethods.WM_DEADCHAR:
            case NativeMethods.WM_SYSDEADCHAR: 
                MSGDATA msgdata = new MSGDATA();
                msgdata.msg = msg; 
                msgdata.handled = handled; 

                // Do this under the exception filter/handlers of the 
                // dispatcher for this thread.
                //
                // NOTE: we lose the "perf optimization" of passing everything
                // around by-ref since we have to call through a delegate. 
                object result = Dispatcher.CurrentDispatcher.Invoke(
                    DispatcherPriority.Send, 
                    new DispatcherOperationCallback(OnPreprocessMessage), 
                    msgdata);
 
                if (result != null)
                {
                    handled = (bool)result;
                } 

                // the semantics dictate that the callers could change this data. 
                msg = msgdata.msg; 
                break;
            } 
        }


        ///  
        /// Critical - Can be used to spoof input
        ///     Asserts UnmanagedCode permission to call IKeyboardInputSink methods. 
        ///  
        [SecurityCritical]
        private object OnPreprocessMessage(object param) 
        {
            MSGDATA msgdata = (MSGDATA) param;

            // At the top level check if someone below us has Focus. 
            // Mnemonics are broadcast to all branches of the window tree; even
            // those that don't have focus.  BUT! at least someone under this 
            // TopLevel window must have focus. 
            if (!((IKeyboardInputSink)this).HasFocusWithin())
            { 
                return msgdata.handled;
            }

            ModifierKeys modifierKeys = HwndKeyboardInputProvider.GetSystemModifierKeys(); 

            // Interop with the Interop layer 
            // 
            switch (msgdata.msg.message)
            { 
            case NativeMethods.WM_SYSKEYDOWN:
            case NativeMethods.WM_KEYDOWN:
                // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS
                // In case a nested message pump is used before we return 
                // from processing this message, we disable processing the
                // next WM_CHAR message because if the code pumps messages 
                // it should really mark the message as handled. 
                _eatCharMessages = true;
                DispatcherOperation restoreCharMessages = Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(RestoreCharMessages), null); 

                msgdata.handled = CriticalTranslateAccelerator(ref msgdata.msg, modifierKeys);
                if(!msgdata.handled)
                { 
                    // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS
                    // We did not handle the WM_KEYDOWN, so it is OK to process WM_CHAR messages. 
                    // We can also abort the pending restore operation since we don't need it. 
                    _eatCharMessages = false;
                    restoreCharMessages.Abort(); 
                }
                break;

            case NativeMethods.WM_SYSKEYUP: 
            case NativeMethods.WM_KEYUP:
                msgdata.handled = CriticalTranslateAccelerator(ref msgdata.msg, modifierKeys); 
                break; 

            case NativeMethods.WM_CHAR: 
            case NativeMethods.WM_SYSCHAR:
            case NativeMethods.WM_DEADCHAR:
            case NativeMethods.WM_SYSDEADCHAR:
                // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
                if(!_eatCharMessages)
                { 
                    // IKIS implementation does a demand. 
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
                    try 
                    {
                        msgdata.handled = ((IKeyboardInputSink)this).TranslateChar(ref msgdata.msg, modifierKeys);

                        if (!msgdata.handled) 
                        {
                            msgdata.handled = ((IKeyboardInputSink)this).OnMnemonic(ref msgdata.msg, modifierKeys); 
                        } 
                    }
                    finally 
                    {
                        SecurityPermission.RevertAssert();
                    }
 
                    if (!msgdata.handled)
                    { 
                        _keyboard.Value.ProcessTextInputAction(msgdata.msg.hwnd, msgdata.msg.message, 
                                                               msgdata.msg.wParam, msgdata.msg.lParam, ref msgdata.handled);
                    } 
                }
                break;
            }
            return msgdata.handled; 
        }
 
        ///  
        ///     Registers a child KeyboardInputSink with this sink.  A site
        ///     is returned. 
        /// 
        ///
        /// This API requires unrestricted UI Window permission.
        /// 
        /// 
        ///     Critical: This API can be used for input spoofing 
        ///     PublicOK: This method has a demand on it. 
        /// 
        [SecurityCritical, UIPermissionAttribute(SecurityAction.Demand, Unrestricted=true)] 
        IKeyboardInputSite IKeyboardInputSink.RegisterKeyboardInputSink(IKeyboardInputSink sink)
        {
            CheckDisposed(true);
 
            if (sink == null)
            { 
                throw new ArgumentNullException("sink"); 
            }
 
            if (sink.KeyboardInputSite != null)
            {
                throw new ArgumentException(SR.Get(SRID.KeyboardSinkAlreadyOwned));
            } 

            HwndSourceKeyboardInputSite site = new HwndSourceKeyboardInputSite(this, sink); 
 
            if (_keyboardInputSinkChildren == null)
                _keyboardInputSinkChildren = new List(); 
            _keyboardInputSinkChildren.Add(site);

            return site;
        } 

        ///  
        ///     Gives the component a chance to process keyboard input. 
        ///     Return value is true if handled, false if not.  Components
        ///     will generally call a child component's TranslateAccelerator 
        ///     if they can't handle the input themselves.  The message must
        ///     either be WM_KEYDOWN or WM_SYSKEYDOWN.  It is illegal to
        ///     modify the MSG structure, it's passed by reference only as
        ///     a performance optimization. 
        /// 
        /// 
        /// This API is not available in Internet Zone. 
        ///
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     TreatAsSafe: This method has a demand on it.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        bool IKeyboardInputSink.TranslateAccelerator(ref MSG msg, ModifierKeys modifiers)
        { 
            SecurityHelper.DemandUnmanagedCode(); 
//             VerifyAccess();
 
            return CriticalTranslateAccelerator(ref msg, modifiers);
        }

        ///  
        ///     Set focus to the first or last tab stop (according to the
        ///     TraversalRequest).  If it can't, because it has no tab stops, 
        ///     the return value is false. 
        /// 
        bool IKeyboardInputSink.TabInto(TraversalRequest request) 
        {
            bool traversed = false;

            if(request == null) 
            {
                throw new ArgumentNullException("request"); 
            } 

            UIElement root =_rootVisual.Value as UIElement; 
            if(root != null)
            {
                // atanask:
                // request.Mode == FocusNavigationDirection.First will navigate to the fist tabstop including root 
                // request.Mode == FocusNavigationDirection.Last will navigate to the last tabstop including root
                traversed = root.MoveFocus(request); 
            } 

            return traversed; 
        }

        /// 
        ///     The property should start with a null value.  The component's 
        ///     container will set this property to a non-null value before
        ///     any other methods are called.  It may be set multiple times, 
        ///     and should be set to null before disposal. 
        /// 
        /// 
        /// Setting KeyboardInputSite is not available in Internet Zone.
        ///
        /// 
        ///     Critical: This API can be used for input spoofing 
        ///     PublicOK: This method has a demand on it.
        ///  
        IKeyboardInputSite IKeyboardInputSink.KeyboardInputSite 
        {
            [SecurityCritical] 
            get
            {
                SecurityHelper.DemandUnmanagedCode();
                return _keyboardInputSite; 
            }
 
            [SecurityCritical] 
            set
            { 
                SecurityHelper.DemandUnmanagedCode();

                _keyboardInputSite = value;
            } 
        }
 
        ///  
        ///     This method is called whenever one of the component's
        ///     mnemonics is invoked.  The message must either be WM_KEYDOWN 
        ///     or WM_SYSKEYDOWN.  It's illegal to modify the MSG structrure,
        ///     it's passed by reference only as a performance optimization.
        ///     If this component contains child components, the container
        ///     OnMnemonic will need to call the child's OnMnemonic method. 
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing 
        ///     TreatAsSafe: This method has a demand on it.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        bool IKeyboardInputSink.OnMnemonic(ref MSG msg, ModifierKeys modifiers)
        {
//             VerifyAccess(); 
            SecurityHelper.DemandUnmanagedCode();
            switch(msg.message) 
            { 
                case NativeMethods.WM_SYSCHAR:
                case NativeMethods.WM_SYSDEADCHAR: 
                    string text = new string((char)msg.wParam, 1);
                    if ((text != null) && (text.Length > 0))
                    {
                        if (AccessKeyManager.IsKeyRegistered(this, text)) 
                        {
                            AccessKeyManager.ProcessKey(this, text, false); 
 
                            //
                            return true; 
                        }
                    }
                    // these are OK
                    break; 

                case NativeMethods.WM_CHAR: 
                case NativeMethods.WM_DEADCHAR: 
                    // these are OK
                    break; 

                default:
                    throw new ArgumentException(SR.Get(SRID.OnlyAcceptsKeyMessages));
            } 

            // We record the last message that was processed by us. 
            // This is also checked in WndProc processing to prevent double processing. 
            _lastKeyboardMessage = msg;
 
            // The Avalon bubble will take care of access key processing for this HWND
            // So now we just call the children.
            if (null == _keyboardInputSinkChildren)
                return false; 

            foreach ( HwndSourceKeyboardInputSite childSite in _keyboardInputSinkChildren ) 
            { 
                if (((IKeyboardInputSite)childSite).Sink.OnMnemonic(ref msg, modifiers))
                    return true; 
            }
            return false;
        }
 
        /// 
        ///     Gives the component a chance to process keyboard input messages 
        ///     WM_CHAR, WM_SYSCHAR, WM_DEADCHAR or WM_SYSDEADCHAR before calling OnMnemonic. 
        ///     Will return true if "handled" meaning don't pass it to OnMnemonic.
        ///     The message must be WM_CHAR, WM_SYSCHAR, WM_DEADCHAR or WM_SYSDEADCHAR. 
        ///     It is illegal to modify the MSG structure, it's passed by reference
        ///     only as a performance optimization.
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     TreatAsSafe: This method has a demand on it. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        bool IKeyboardInputSink.TranslateChar(ref MSG msg, ModifierKeys modifiers) 
        {
            SecurityHelper.DemandUnmanagedCode();
            if(HasFocus)
                return false; 

            IKeyboardInputSink focusSink = this.ChildSinkWithFocus; 
            if(null != focusSink) 
            {
                return focusSink.TranslateChar(ref msg, modifiers); 
            }
            return false;
        }
 
        /// 
        /// 
        ///  
        bool IKeyboardInputSink.HasFocusWithin()
        { 
            if(HasFocus)
            {
                return true;
            } 
            else
            { 
                if (null == _keyboardInputSinkChildren) 
                    return false;
 
                foreach (HwndSourceKeyboardInputSite site in _keyboardInputSinkChildren)
                {
                    if (((IKeyboardInputSite)site).Sink.HasFocusWithin())
                    { 
                        return true;
                    } 
                } 
                return false;
            } 
        }

        /// 
        ///   The method is not part of the interface (IKeyboardInputSink). 
        /// 
        /// The Site that containes the sink to unregister 
        ///  
        ///     Critical - calls critical methods.
        ///  
        [ SecurityCritical ]
        internal void CriticalUnregisterKeyboardInputSink(HwndSourceKeyboardInputSite site)
        {
            if(_isDisposed) 
                return;
 
            if (null != _keyboardInputSinkChildren) 
            {
                if (!_keyboardInputSinkChildren.Remove(site)) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.KeyboardSinkNotAChild));
                }
            } 
        }
 
        IKeyboardInputSink ChildSinkWithFocus 
        {
            get 
            {
                IKeyboardInputSink ikis=null;

                if(null == _keyboardInputSinkChildren) 
                    return null;
 
                foreach (HwndSourceKeyboardInputSite site in _keyboardInputSinkChildren) 
                {
                    IKeyboardInputSite isite = (IKeyboardInputSite)site; 

                    if (isite.Sink.HasFocusWithin())
                    {
                        ikis = isite.Sink; 
                        break;
                    } 
                } 
                // This private property should only be called correctly.
                Debug.Assert(null!=ikis, "ChildSinkWithFocus called when none had focus"); 
                return ikis;
            }
        }
 
        /// 
        ///     Critical: This API could be vulnerable to input spoofing. 
        ///  
        [SecurityCritical, FriendAccessAllowed]
        internal bool CriticalTranslateAccelerator(ref MSG msg, ModifierKeys modifiers) 
        {
            switch (msg.message)
            {
                case NativeMethods.WM_KEYUP: 
                case NativeMethods.WM_KEYDOWN:
                case NativeMethods.WM_SYSKEYUP: 
                case NativeMethods.WM_SYSKEYDOWN: 
                    // these are OK
                    break; 

                default:
                    throw new ArgumentException(SR.Get(SRID.OnlyAcceptsKeyMessages));
            } 

            if (_keyboard == null) 
                return false; 

            bool handled = false; 

            // TranslateAccelerator is called recursively on child Hwnds (Source & Host)
            // If this is the first Avalon TranslateAccelerator processing then we send the
            // key to be processed to the standard Avalon Input Filters and stuff. 
            if (PerThreadData.TranslateAcceleratorCallDepth == 0)
            { 
                // We record the last message that was processed by us. 
                // This is also checked in WndProc processing to prevent double processing.
                // TranslateAcclerator is called from the pump before DispatchMessage 
                // and the WndProc is called from DispatchMessage.   We have processing
                // in both places.  If we run the pump we process keyboard message here.
                // If we don't own the pump we process them in HwndKeyboardInputProvider.WndProc.
                _lastKeyboardMessage = msg; 

                //  NORMAL AVALON KEYBOARD INPUT CASE 
                // If this is the top most Avalon window (it might be a child Hwnd 
                // but no Avalon windows above it).  And focus is on this window then
                // do the Normal Avalon Keyboard input Processing. 
                if (HasFocus)
                {
                    _keyboard.Value.ProcessKeyAction(ref msg, ref handled);
                } 
                // ELSE the focus is in but not on this HwndSource.
                // Do the once only message input filters etc and Tunnel/Bubble down 
                // to the element that contains the child window with focus. 
                // The Child HwndHost object will hook OnPreviewKeyDown() etc
                // to make the transition to its TranslateAccelerator() between the 
                // tunnel and the bubble.
                else
                {
                    IKeyboardInputSink focusSink = ChildSinkWithFocus; 
                    IInputElement focusElement = (IInputElement)focusSink;
 
                    try { 
                        PerThreadData.TranslateAcceleratorCallDepth += 1;
                        Keyboard.PrimaryDevice.ForceTarget = focusElement; 
                       _keyboard.Value.ProcessKeyAction(ref msg, ref handled);
                    }
                    finally
                    { 
                        Keyboard.PrimaryDevice.ForceTarget = null;
                        PerThreadData.TranslateAcceleratorCallDepth -= 1; 
                    } 
                }
 
            }
            // ELSE we have seen this MSG before, we are HwndSource decendant of an
            // HwndSource (that ancestor presumably did the processing above).
            // Here we raise the tunnel/bubble events without the once only keyboard 
            // input filtering.
            else 
            { 
                int virtualKey = HwndKeyboardInputProvider.GetVirtualKey(msg.wParam, msg.lParam);
                int scanCode = HwndKeyboardInputProvider.GetScanCode(msg.wParam, msg.lParam); 
                bool isExtendedKey = HwndKeyboardInputProvider.IsExtendedKey(msg.lParam);
                Key key = KeyInterop.KeyFromVirtualKey(virtualKey);

                RoutedEvent keyPreviewEvent=null; 
                RoutedEvent keyEvent=null;
                switch (msg.message) 
                { 
                case NativeMethods.WM_KEYUP:
                case NativeMethods.WM_SYSKEYUP: 
                    keyPreviewEvent = Keyboard.PreviewKeyUpEvent;
                    keyEvent = Keyboard.KeyUpEvent;
                    break;
                case NativeMethods.WM_KEYDOWN: 
                case NativeMethods.WM_SYSKEYDOWN:
                    keyPreviewEvent = Keyboard.PreviewKeyDownEvent; 
                    keyEvent = Keyboard.KeyDownEvent; 
                    break;
                } 

                IKeyboardInputSink focusSink = HasFocus ? null : ChildSinkWithFocus;
                IInputElement focusElement = focusSink as IInputElement;
 
                // focusElement may be null, in which case Target is just "focus"
                try { 
                    Keyboard.PrimaryDevice.ForceTarget = focusElement; 
                    focusElement = Keyboard.PrimaryDevice.Target;
 
                    KeyEventArgs tunnelArgs = new KeyEventArgs(Keyboard.PrimaryDevice, this, msg.time, key);
                    tunnelArgs.ScanCode = scanCode;
                    tunnelArgs.IsExtendedKey = isExtendedKey;
                    tunnelArgs.RoutedEvent = keyPreviewEvent; 
                    focusElement.RaiseEvent(tunnelArgs);
 
                    handled = tunnelArgs.Handled; 
                    if (!handled)
                    { 
                        KeyEventArgs bubbleArgs = new KeyEventArgs(Keyboard.PrimaryDevice, this, msg.time, key);
                        bubbleArgs.ScanCode = scanCode;
                        bubbleArgs.IsExtendedKey = isExtendedKey;
                        bubbleArgs.RoutedEvent=keyEvent; 
                        focusElement.RaiseEvent(bubbleArgs);
 
                        handled = bubbleArgs.Handled; 
                        if (!handled)
                        { 
                            // Raise the TranslateAccelerator event on the
                            // InputManager to allow keyboard navigation to
                            // happen on a descendent HwndSource
                            InputManager.UnsecureCurrent.RaiseTranslateAccelerator(bubbleArgs); 
                            handled = bubbleArgs.Handled;
                        } 
                    } 
                }
                finally 
                {
                    Keyboard.PrimaryDevice.ForceTarget = null;
                }
            } 

            return handled; 
        } 

        // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
        // Go back to accepting character messages.  This method is posted
        // to the dispatcher when char messages are disable.
        internal static object RestoreCharMessages(object unused)
        { 
            _eatCharMessages = false;
            return null; 
        } 

#endregion IKeyboardInputSink 


        internal bool IsRepeatedKeyboardMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
        { 
            if (msg != _lastKeyboardMessage.message)
                return false; 
            if (hwnd != _lastKeyboardMessage.hwnd) 
                return false;
            if (wParam != _lastKeyboardMessage.wParam) 
                return false;
            if (lParam != _lastKeyboardMessage.lParam)
                return false;
            return true; 
        }
 
        ///  
        ///    This event handler is called from HwndWrapper when it is Disposing.
        ///  
        // This could happen if someone calls his Dispose before (or instead
        // of) our dispose.  Or, more likely, the real window was killed by
        // something like the user clicking the close box.
        private void OnHwndDisposed(object sender, EventArgs args) 
        {
            // This method is called from the HwndWrapper.Dispose(). 
            // So make sure we don't call HwndWrapper.Dispose(). 
            _inRealHwndDispose = true;
            Dispose(); 
        }

        /// 
        ///    Called after the last window message is processed. 
        /// 
 
        // HwndSource is required to continue certain operations while, 
        // and even after, Dispose runs.  HwndSource is resposible for
        // calling WndProcHooks with every message the window sees. 
        // Including: WM_CLOSE, WM_DESTROY, WM_NCDESTROY.  The doc says
        // WM_NCDESTROY is the very last message, so we can release the
        // Hooks after that.
        // This assumes the Context.Access() is held. 
        private void OnNoMoreWindowMessages()
        { 
            _hooks.Clear(); 
            _hooks = null;
        } 

        private void OnShutdownFinished(object sender, EventArgs args)
        {
            // Note: We are already in the context being disposed. 
            Dispose();
        } 
 
        //
        // NOTE: shutdown order is very important.  Review any changes 
        // carefully.
        //
        /// 
        ///     Critical: This accesses the various sites and providers 
        ///     Safe: Disposing the object is a safe operation.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private void Dispose(bool disposing)
        { 
            if(disposing)
            {
                // Make sure all access is synchronized.
//                 this.VerifyAccess(); 

                if (!_isDisposing) 
                { 
                    // _isDisposing is a guard against re-entery into this
                    // routine.  We fire Dispose and SourceChanged (RootVisual 
                    // change) events which could cause re-entery.
                    _isDisposing = true;

                    // Notify listeners that we are being disposed.  We do this 
                    // before we dispose our internal stuff, in case the event
                    // listener needs to access something. 
                    if(Disposed != null) 
                    {
                        try 
                        {
                            Disposed(this, EventArgs.Empty);
                        }
#pragma warning disable 56500 
                        // We can't tolerate an exception thrown by third-party code to
                        // abort our Dispose half-way through.  So we just eat it. 
                        catch 
                        {
                        } 
#pragma warning restore 56500
                        Disposed = null;
                    }
 
                    // Remove any listeners of the ContentRendered event
                    ClearContentRenderedListeners(); 
 
                    // Clear the root visual.  This will raise a SourceChanged
                    // event to registered listeners. 
                    RootVisualInternal = null;
                    RemoveSource();

                    // Unregister ourselves if we are a registered KeyboardInputSink. 
                    if(_keyboardInputSite != null)
                    { 
                        _keyboardInputSite.Unregister(); 
                        _keyboardInputSite = null;
                    } 
                    _keyboardInputSinkChildren = null;

                    // Dispose the HwndStylusInputProvider BEFORE we destroy the HWND.
                    // This us because the stylus provider has an async channel and 
                    // they don't want to process data after the HWND is destroyed.
                    if (_stylus != null) 
                    { 
                        _stylus.Value.Dispose();
                        _stylus = null; 
                    }

                    // Our general shut-down principle is to destroy the window
                    // and let the individual HwndXXX components respons to WM_DESTROY. 
                    //
                    // (see comment above about disposing the HwndStylusInputProvider) 
                    // 
                    {
                        if (_hwndTarget != null) 
                        {
                            _hwndTarget.Dispose();
                            _hwndTarget = null;
                        } 

                        if (_hwndWrapper != null) 
                        { 
                            // Revoke the drop target.
                            if (_hwndWrapper.Handle != IntPtr.Zero && _registeredDropTargetCount > 0) 
                            {
                                // This call is safe since DragDrop.RevokeDropTarget is checking the unmanged
                                // code permission.
                                DragDrop.RevokeDropTarget(_hwndWrapper.Handle); 
                                _registeredDropTargetCount--;
                            } 
 
                            // Remove our HwndWrapper.Dispose() hander.
                            _hwndWrapper.Disposed -= new EventHandler(OnHwndDisposed); 

                            if (!_inRealHwndDispose)
                                _hwndWrapper.Dispose();
 
                            // Don't null out _hwndWrapper after the Dispose().
                            // Dispose() will start destroying the Window but we 
                            // still need to talk to it during that process while 
                            // the WM_ msgs arrive.
                        } 
                    }

                    if(_mouse != null)
                    { 
                        _mouse.Value.Dispose();
                        _mouse = null; 
                    } 

                    if(_keyboard != null) 
                    {
                        _keyboard.Value.Dispose();
                        _keyboard = null;
                    } 

                    if (_appCommand != null) 
                    { 
                        _appCommand.Value.Dispose();
                        _appCommand = null; 
                    }

                    if(null != _weakShutdownHandler)
                    { 
                        _weakShutdownHandler.Dispose();
                        _weakShutdownHandler = null; 
                    } 

                    if(null != _weakPreprocessMessageHandler) 
                    {
                        _weakPreprocessMessageHandler.Dispose();
                        _weakPreprocessMessageHandler = null;
                    } 

                    // We wait to set the "_isDisposed" flag until after the 
                    // Disposed, SourceChange (RootVisual=null), etc. events 
                    // have fired.  We want to remain functional should their
                    // handlers call methods on us. 
                    //
                    // Note: as the HwndWrapper shuts down, the final few messages
                    // will continue to pass through our WndProc hook.
                    _isDisposed = true; 
                }
            } 
        } 

        private void CheckDisposed(bool verifyAccess) 
        {
            if(verifyAccess)
            {
//                 this.VerifyAccess(); 
            }
 
            if(_isDisposed) 
            {
                throw new ObjectDisposedException(null, SR.Get(SRID.HwndSourceDisposed)); 
            }
        }

        ///  
        ///     Critical: This code accesses hwndtarget
        ///     TreatAsSafe: Information is ok to expose 
        ///  
        private bool IsUsable
        { 
            [SecurityCritical,SecurityTreatAsSafe]
            get
            {
                return _isDisposed == false && 
                       _hwndTarget != null &&
                       _hwndTarget.IsDisposed == false; 
            } 
        }
 
        /// 
        ///     Critical - calls a method with an elevation ( GetFocus )
        ///     TreatAsSafe - determining whether you have focus within the window is considered safe.
        ///                   Worst case you can know whether keyboard/keypress events will go to the current window. 
        /// 
        private bool HasFocus 
        { 
            [SecurityCritical, SecurityTreatAsSafe]
            get 
            {
                return UnsafeNativeMethods.GetFocus() == CriticalHandle;
            }
        } 

        private static bool IsValidSizeToContent(SizeToContent value) 
        { 
            return value == SizeToContent.Manual ||
                   value == SizeToContent.Width  || 
                   value == SizeToContent.Height ||
                   value == SizeToContent.WidthAndHeight;
        }
 
        class ThreadDataBlob
        { 
            public int TranslateAcceleratorCallDepth; 
        }
 
        private static ThreadDataBlob PerThreadData
        {
            get
            { 
                ThreadDataBlob data;
                object obj = Thread.GetData(_threadSlot); 
                if(null == obj) 
                {
                    data = new ThreadDataBlob(); 
                    Thread.SetData(_threadSlot, data);
                }
                else
                { 
                    data = (ThreadDataBlob) obj;
                } 
                return data; 
            }
        } 

#region WeakEventHandlers

        private class WeakEventDispatcherShutdown: WeakReference 
        {
            public WeakEventDispatcherShutdown(HwndSource source, Dispatcher that): base(source) 
            { 
                _that = that;
                _that.ShutdownFinished += new EventHandler(this.OnShutdownFinished); 
            }

            public void OnShutdownFinished(object sender, EventArgs e)
            { 
                HwndSource source = this.Target as HwndSource;
                if(null != source) 
                { 
                    source.OnShutdownFinished(sender, e);
                } 
                else
                {
                    Dispose();
                } 
            }
 
            public void Dispose() 
            {
                if(null != _that) 
                {
                    _that.ShutdownFinished-= new EventHandler(this.OnShutdownFinished);
                }
            } 

            private Dispatcher _that; 
        } 

        private class WeakEventPreprocessMessage: WeakReference 
        {
            /// 
            ///     Critical: This code calls attaches an arbitrary window
            ///     to the call path for the component dispatcher call back 
            /// 
            [SecurityCritical] 
            public WeakEventPreprocessMessage(HwndSource source): base(source) 
            {
                ComponentDispatcher.ThreadPreprocessMessage += 
                                new ThreadMessageEventHandler(this.OnPreprocessMessage);
            }

            ///  
            ///     Critical: This can be used to spoof and change input
            ///  
            [SecurityCritical] 
            public void OnPreprocessMessage(ref MSG msg, ref bool handled)
            { 
                HwndSource source = this.Target as HwndSource;
                if(null != source)
                {
                    source.OnPreprocessMessageThunk(ref msg, ref handled); 
                }
                else 
                { 
                    Dispose();
                } 
            }


            ///  
            ///     Critical:This code calls into ComponentDispatcher
            ///     to disconnect a listener 
            ///     TreatAsSafe: This code is ok to call 
            /// 
            [SecurityCritical,SecurityTreatAsSafe] 
            public void Dispose()
            {
                ComponentDispatcher.ThreadPreprocessMessage -=
                                new ThreadMessageEventHandler(this.OnPreprocessMessage); 
            }
        } 
 
#endregion WeakEventHandlers
 
        private object                      _constructionParameters; // boxed HwndSourceParameters

        private bool                        _isDisposed = false;
        private bool                        _isDisposing = false; 
        private bool                        _inRealHwndDispose = false;
        private bool                        _adjustSizingForNonClientArea; 
        private bool                        _myOwnUpdate; 
        private bool                        _isWindowInMinimizeState = false;
 
        private int                         _registeredDropTargetCount;

        private SizeToContent               _sizeToContent = SizeToContent.Manual;
        private Size?                       _previousSize; 

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical.
        ///  
        [SecurityCritical]
        private HwndWrapper                 _hwndWrapper;

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data is considered critical. 
        ///  
        [SecurityCritical]
        private HwndTarget                  _hwndTarget; 

        private SecurityCriticalDataForSet                      _rootVisual;

        private ArrayList                   _hooks; 
        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical. 
        /// 
        private SecurityCriticalDataClass      _mouse; 
        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data is considered critical.
        ///  
        private SecurityCriticalDataClass   _keyboard;
        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical.
        ///  
        private SecurityCriticalDataClass     _stylus;

        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data is considered critical.
        ///  
        private SecurityCriticalDataClass _appCommand; 

        WeakEventDispatcherShutdown _weakShutdownHandler; 
        WeakEventPreprocessMessage _weakPreprocessMessageHandler;

        private static System.LocalDataStoreSlot _threadSlot;
 
        private MSG                         _lastKeyboardMessage;
        private List _keyboardInputSinkChildren; 
 
        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data can be used to spoof input
        /// 
        [SecurityCritical]
        private IKeyboardInputSite          _keyboardInputSite = null; 

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified 
        ///     elevation. This data can be used to spoof input
        ///  
        [SecurityCritical]
        private HwndWrapperHook             _layoutHook;

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data can be used to spoof input 
        ///  
        [SecurityCritical]
        private HwndWrapperHook             _inputHook; 

        /// 
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data can be used to spoof input 
        /// 
        [SecurityCritical] 
        private HwndWrapperHook             _hwndTargetHook; 

        ///  
        ///     Critical:This reference cannot be given out or assigned to outside of a verified
        ///     elevation. This data can be used to spoof input
        /// 
        [SecurityCritical] 
        private HwndWrapperHook             _publicHook;
 
        // MITIGATION: HANDLED_KEYDOWN_STILL_GENERATES_CHARS 
        //
        // Avalon relies on the policy that if you handle the KeyDown 
        // event, you will not get the TextInput events caused by
        // pressing the key.  This is generally implemented because the
        // message pump calls ComponentDispatcher.RaiseThreadMessage and
        // we return whether or not the WM_KEYDOWN message was handled, 
        // and the message pump will only call TranslateMessage() if the
        // WM_KEYDOWN was not handled.  However, naive message pumps don't 
        // call ComponentDispatcher.RaiseThreadMessage, and always call 
        // TranslateMessage, so the WM_CHAR is generated no matter what.
        // The best work around we could think of was to eat the WM_CHAR 
        // messages and not report them to Avalon.
        //
        [ThreadStatic]
        internal static bool _eatCharMessages; // used from HwndKeyboardInputProvider 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

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