HwndHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / Interop / HwndHost.cs / 2 / HwndHost.cs

                            using System; 
using System.Diagnostics;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Input; 
using System.Collections;
using MS.Win32; 
using MS.Internal; 
using MS.Internal.PresentationFramework;                   // SecurityHelper
using System.Security; 
using System.Security.Permissions;
using Microsoft.Win32;
using System.Windows.Media;
using System.Windows.Interop; 
using System.Runtime.InteropServices;
using System.Windows.Threading; 
 
// Disable pragma warnings to enable PREsharp pragmas
#pragma warning disable 1634, 1691 

namespace System.Windows.Interop
{
    ///  
    ///     The HwndHost class hosts an HWND inside of an Avalon tree.
    ///  
    /// Subclassing requires unmanaged code permission 
    ///
    /// 
    ///     Inheritance demand put in place - as to host activeX controls you should have Unmanaged code permission.
    ///
    ///
 
    [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
    public abstract class HwndHost : FrameworkElement, IDisposable, IWin32Window, IKeyboardInputSink 
    { 
        static HwndHost()
        { 
            FocusableProperty.OverrideMetadata(typeof(HwndHost), new FrameworkPropertyMetadata(true));
        }

        ///  
        ///     Constructs an instance of the HwndHost class.
        ///  
        /// Not available in Internet zone 
        ///
        ///     Critical - calls critical code, sets critical _fTrusted flag. 
        ///     PublicOk - trusted flag is set to false.
        ///
        [ SecurityCritical ]
        protected HwndHost() 
        {
            Initialize( false ) ; 
        } 

        /// 
        ///     Critical sets fTrustedBit.
        ///
        [ SecurityCritical, FriendAccessAllowed ]
        internal HwndHost(bool fTrusted ) 
        {
            Initialize( fTrusted ) ; 
        } 

        ///  
        ///    Because we own an HWND, we implement a finalizer to make sure that we destroy it.
        /// 
        ~HwndHost()
        { 
            Dispose(false);
        } 
 
        /// 
        ///     Disposes this object. 
        /// 
        public void Dispose()
        {
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 
 
        /// 
        ///     The Win32 handle of the hosted window. 
        /// 
        /// 
        ///     Callers must have UnmanagedCode permission to call this API.
        ///  
        /// 
        ///     Critical: This code accesses IsWindow, returns hwndHandle. 
        ///     PublicOk: There is a demand 
        /// 
        public IntPtr Handle 
        {
            [SecurityCritical]
            get
            { 
                SecurityHelper.DemandUnmanagedCode();
 
                return CriticalHandle; 
            }
        } 

        /// 
        ///     An event that is notified of all unhandled messages received
        ///     by the hosted window. 
        /// 
        ///  
        ///     Callers must have UnmanagedCode permission to call this API. 
        /// 
        /// 
        ///     Demand put in place as a defense in depth measure.
        ///
        public event HwndSourceHook MessageHook
        { 
            add
            { 
//                 VerifyAccess(); 

                SecurityHelper.DemandUnmanagedCode(); 

                if(_hooks == null)
                {
                    _hooks = new ArrayList(8); 
                }
 
                _hooks.Add(value); 
            }
 
            remove
            {
//                 VerifyAccess();
                SecurityHelper.DemandUnmanagedCode(); 

                if(_hooks != null) 
                { 
                    _hooks.Remove(value);
 
                    if(_hooks.Count == 0)
                    {
                        _hooks = null;
                    } 
                }
            } 
        } 

        ///  
        /// 
        /// 
        ///
        /// Critical - Calls ComponentDispatcher.UnsecureCurrentKeyboardMessage. 
        /// TreatAsSafe - Only calls for trusted controls
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        protected override void OnKeyUp(KeyEventArgs e)
        { 
            MSG msg;
            if (_fTrusted.Value)
            {
                msg = ComponentDispatcher.UnsecureCurrentKeyboardMessage; 
            }
            else 
            { 
                msg = ComponentDispatcher.CurrentKeyboardMessage;
            } 

            ModifierKeys modifiers = HwndKeyboardInputProvider.GetSystemModifierKeys();

            bool handled = ((IKeyboardInputSink)this).TranslateAccelerator(ref msg, modifiers); 

            if(handled) 
                e.Handled = handled; 

            base.OnKeyUp(e); 
        }

        /// 
        ///  
        /// 
        /// 
        /// Critical - Calls ComponentDispatcher.UnsecureCurrentKeyboardMessage. 
        /// TreatAsSafe - Only calls for trusted controls
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnKeyDown(KeyEventArgs e)
        {
            MSG msg; 
            if (_fTrusted.Value)
            { 
                msg = ComponentDispatcher.UnsecureCurrentKeyboardMessage; 
            }
            else 
            {
                msg = ComponentDispatcher.CurrentKeyboardMessage;
            }
 

            ModifierKeys modifiers = HwndKeyboardInputProvider.GetSystemModifierKeys(); 
 
            bool handled = ((IKeyboardInputSink)this).TranslateAccelerator(ref msg, modifiers);
 
            if(handled)
                e.Handled = handled;

            base.OnKeyDown(e); 
        }
 
 
#region IKeyboardInputSink
        ///  
        ///     Registers a IKeyboardInputSink with the HwndSource in order
        ///     to retreive a unique IKeyboardInputSite for it.
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     PublicOk: The interface declaration for this method has a demand on it. 
        ///  
        [SecurityCritical]
        IKeyboardInputSite IKeyboardInputSink.RegisterKeyboardInputSink(IKeyboardInputSink sink) 
        {
            throw new InvalidOperationException(SR.Get(SRID.HwndHostDoesNotSupportChildKeyboardSinks));
        }
 
        /// 
        ///     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.
        ///  
        /// 
        ///     Critical: This API can be used for input spoofing 
        ///     PublicOk: The interface declaration for this method has a demand on it. 
        /// 
        [SecurityCritical] 
        bool IKeyboardInputSink.TranslateAccelerator(ref MSG msg, ModifierKeys modifiers)
        {
            return false;
        } 

        ///  
        ///     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)
        {
            return false; 
        }
 
        ///  
        ///     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.
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     PublicOk: The interface declaration for this method has a demand on it. 
        ///  
        IKeyboardInputSite IKeyboardInputSink.KeyboardInputSite
        { 
            get
            {
                return _keyboardInputSite;
            } 

            [SecurityCritical] 
            set 
            {
                _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 
        ///     PublicOk: The interface declaration for this method has a demand on it.
        ///  
        [SecurityCritical] 
        bool IKeyboardInputSink.OnMnemonic(ref MSG msg, ModifierKeys modifiers)
        { 
            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 
        ///     PublicOk: The interface declaration for this method has a demand on it.
        ///  
        [SecurityCritical] 
        bool IKeyboardInputSink.TranslateChar(ref MSG msg, ModifierKeys modifiers)
        { 
            return false;
        }

        ///  
        ///     This returns true if the sink, or a child of it, has focus. And false otherwise.
        ///  
        /// 
        ///     Critical - calls a method with a SUC - GetFocus.
        ///     PublicOk: - no critical information exposed. 
        ///                   It's ok to return whether hwndHost has focus within itself in PT.
        ///
        ///     Demand put in place as a defense-in-depth measure.
        /// 
        [SecurityCritical]
        bool IKeyboardInputSink.HasFocusWithin() 
        { 
            DemandIfUntrusted();
 
            HandleRef hwndFocus = new HandleRef(this, UnsafeNativeMethods.GetFocus());
            if (_hwnd.Handle != IntPtr.Zero && (hwndFocus.Handle == _hwnd.Handle || UnsafeNativeMethods.IsChild(_hwnd, hwndFocus)))
            {
                return true; 
            }
            return false; 
        } 

        private IKeyboardInputSite _keyboardInputSite = null; 
#endregion IKeyboardInputSink

        /// 
        ///     Updates the child window to reflect the state of this element. 
        /// 
        ///  
        ///     This includes the size of the window, the position of the 
        ///     window, and the visibility of the window.
        ///  
        /// Not available in Internet zone
        ///
        ///     Critical: This code accesses critical code and also calls into PresentationSource
        ///     PublicOk : Repositioning the activeX control is ok. 
        ///                Net effect is to make window location consistent with what layout calculated.
        /// 
        [SecurityCritical] 
        public void UpdateWindowPos()
        { 
            // Verify the thread has access to the context.
            // VerifyAccess();

            if (_isDisposed) 
            {
                return; 
            } 

            // Position the child HWND where layout put it.  To do this we 
            // have to get coordinates relative to the parent window.

            PresentationSource source = null;
            CompositionTarget vt = null; 
            if (( CriticalHandle != IntPtr.Zero) && IsVisible)
            { 
                source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); 
                if(source != null)
                { 
                    vt = source.CompositionTarget;
                }
            }
 
            if(vt != null && vt.RootVisual != null)
            { 
                // Translate the layout information assigned to us from the co-ordinate 
                // space of this element, through the root visual, to the Win32 client
                // co-ordinate space 
                NativeMethods.RECT rcClientRTLAdjusted = CalculateAssignedRC(source);

                // Set the Win32 position for the child window.
                // 
                // Note, we can't check the existing position because we use
                // SWP_ASYNCWINDOWPOS, which means we could have pending position 
                // change requests that haven't been applied yet.  If we need 
                // this functionality (to avoid the extra SetWindowPos calls),
                // we'll have to track the last RECT we sent Win32 ourselves. 
                //
                Rect rectClientRTLAdjusted = PointUtil.ToRect(rcClientRTLAdjusted);
                OnWindowPositionChanged(rectClientRTLAdjusted);
 
                // Show the window
                // Based on Dwayne, the reason we also show/hide window in UpdateWindowPos is for the 
                // following kind of scenario: When applying RenderTransform to HwndHost, the hwnd 
                // will be left behind. Developer can workaround by hide the hwnd first using pinvoke.
                // After the RenderTransform is applied to the HwndHost, call UpdateWindowPos to [....] up 
                // the hwnd's location, size and visibility with WPF.
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_SHOW);
            }
            else 
            {
                // For some reason we shouldn't be displayed: either we don't 
                // have a parent, or the parent no longer has a root visual, 
                // or we are marked as not being visible.
                // 
                // Just hide the window to get it out of the way.
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE);
            }
        } 

        // Translate the layout information assigned to us from the co-ordinate 
        // space of this element, through the root visual, to the Win32 client 
        // co-ordinate space
        /// 
        ///     Critical: This code accesses critical code and also calls into PresentationSource
        ///     TAS : Calculate the new position of the activeX control is ok.
        ///                Net effect is to make window location consistent with what layout calculated.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private NativeMethods.RECT CalculateAssignedRC(PresentationSource source) 
        { 
            Rect rectElement = new Rect(RenderSize);
            Rect rectRoot = PointUtil.ElementToRoot(rectElement, this, source); 
            Rect rectClient = PointUtil.RootToClient(rectRoot, source);

            // Adjust for Right-To-Left oriented windows
            IntPtr hwndParent = UnsafeNativeMethods.GetParent(_hwnd); 
            NativeMethods.RECT rcClient = PointUtil.FromRect(rectClient);
            NativeMethods.RECT rcClientRTLAdjusted = PointUtil.AdjustForRightToLeft(rcClient, new HandleRef(null, hwndParent)); 
 
            return rcClientRTLAdjusted;
        } 

        /// 
        ///     Disposes this object.
        ///  
        /// 
        ///     true if called from explisit Dispose; and we free all objects managed and un-managed. 
        ///     false if called from the finalizer; and we free only un-managed objects. 
        /// 
        ///  
        ///     Derived classes should override this if they have additional
        ///     cleanup to do.  The base class implementation should be called.
        ///     Note that the calling thread must be the dispatcher thread.
        ///     If a window is being hosted, that window is destroyed. 
        /// 
        /// 
        ///     Critical - call to RemoveSourceChangeHandler invokes critical delegate. 
        ///     SecurityTreatAsSafe : - disposing the HwndHost is considered ok.
        /// 
        [ SecurityCritical, SecurityTreatAsSafe ]
        protected virtual void Dispose(bool disposing)
        {
            if (_isDisposed == true) 
            {
                return; 
            } 

 
            if(disposing)
            {
                // Verify the thread has access to the context.
#pragma warning suppress 6519 
                 VerifyAccess();
 
 
                // Remove our subclass.  Even if this fails, it will be forcably removed
                // when the window is destroyed. 
                if (_hwndSubclass != null)
                {
                    // Check if it is trusted (WebOC and AddInHost), call CriticalDetach to avoid the Demand.
                    if (_fTrusted.Value == true) 
                    {
                        _hwndSubclass.CriticalDetach(false); 
                    } 
                    else
                    { 
                        _hwndSubclass.RequestDetach(false);
                    }

                    _hwndSubclass = null; 
                }
 
                // Drop the hooks so that they can be garbage-collected. 
                _hooks = null;
 
                // We no longer need to know about the source changing.
                PresentationSource.RemoveSourceChangedHandler(this, new SourceChangedEventHandler(OnSourceChanged));
            }
 
            _weakEventDispatcherShutdown.Dispose();
            _weakEventDispatcherShutdown = null; 
 
            DestroyWindow();
 
            _isDisposed = true;
        }

        private void OnDispatcherShutdown(object sender, EventArgs e) 
        {
            Dispose(); 
        } 

        ///  
        ///     Derived classes override this method to actually build the
        ///     window being hosted.
        /// 
        ///  
        ///     The parent HWND for the child window.
        ///  
        ///  
        ///     The HWND handle to the child window that was created.
        ///  
        /// 
        ///     The window that is returned must be a child window of the
        ///     specified parent window.
        ///      
        ///     In addition, the child window will only be subclassed if
        ///     the window is owned by the calling thread. 
        ///  
        protected abstract HandleRef BuildWindowCore(HandleRef hwndParent);
 
        /// 
        ///     Derived classes override this method to actually build the
        ///     window being hosted.
        ///  
        protected abstract void DestroyWindowCore(HandleRef hwnd);
 
        ///  
        ///     A protected override for accessing the window proc of the
        ///     hosted child window. 
        /// 
        /// Not available in Internet zone
        ///
        ///     Critical - accesses _hwnd Critical member. 
        ///     PublicOk - Inheritance Demand for unmanaged codepermission to buslclass.
        ///                any caller of the protected must have Unmanaged code permission. 
        ///     DemandIfUntrusted is there as a defense in depth measure. 
        /// 
        [ SecurityCritical ] 
        protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            DemandIfUntrusted();
 
            switch (msg)
            { 
                case NativeMethods.WM_NCDESTROY: 
                    _hwnd = new HandleRef(null, IntPtr.Zero);
                    break; 

                // When layout happens, we first calculate the right size/location then call SetWindowPos.
                // We only allow the changes that are coming from Avalon layout. The hwnd is not allowed to change by itself.
                // So the size of the hwnd should always be RenderSize and the position be where layout puts it. 
                case NativeMethods.WM_WINDOWPOSCHANGING:
                    PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); 
 
                    if (source != null)
                    { 
                        // 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));

                        // Get the rect assigned by layout to us. 
                        NativeMethods.RECT assignedRC = CalculateAssignedRC(source);
 
                        windowPos.cx = assignedRC.right - assignedRC.left; 
                        windowPos.cy = assignedRC.bottom - assignedRC.top;
 
                        windowPos.x = assignedRC.left;
                        windowPos.y = assignedRC.top;

                        // marshal size/location back 
                        Marshal.StructureToPtr(windowPos, lParam, true);
                    } 
 
                    break;
 

                case NativeMethods.WM_GETOBJECT:
                    handled = true;
                    return OnWmGetObject(wParam, lParam); 
            }
 
            return IntPtr.Zero ; 
        }
 
        #region Automation

        /// 
        /// Creates AutomationPeer () 
        /// 
        protected override AutomationPeer OnCreateAutomationPeer() 
        { 
            return new HwndHostAutomationPeer(this);
        } 

        /// 
        ///     Critical    - Calls critical HwndHost.CriticalHandle.
        ///  
        [SecurityCritical]
        private IntPtr OnWmGetObject(IntPtr wparam, IntPtr lparam) 
        { 
            IntPtr result = IntPtr.Zero;
 
            AutomationPeer containerPeer = UIElementAutomationPeer.CreatePeerForElement(this);
            if (containerPeer != null)
            {
                // get the element proxy 
                IRawElementProviderSimple el = containerPeer.GetInteropChild();
                result = AutomationInteropProvider.ReturnRawElementProvider(CriticalHandle, wparam, lparam, el); 
            } 
            return result;
        } 

        #endregion Automation

        // 

 
 

 



 

 
        [ SecurityCritical ] 
        protected virtual void OnWindowPositionChanged(Rect rcBoundingBox)
        { 
            if (_isDisposed)
            {
                return;
            } 

            UnsafeNativeMethods.SetWindowPos(_hwnd, 
                                           new HandleRef(null, IntPtr.Zero), 
                                           (int)rcBoundingBox.X,
                                           (int)rcBoundingBox.Y, 
                                           (int)rcBoundingBox.Width,
                                           (int)rcBoundingBox.Height,
                                           NativeMethods.SWP_ASYNCWINDOWPOS
                                           | NativeMethods.SWP_NOZORDER 
                                           | NativeMethods.SWP_NOCOPYBITS
                                           | NativeMethods.SWP_NOACTIVATE); 
        } 

        ///  
        ///     Return the desired size of the HWND.
        /// 
        /// 
        ///     HWNDs usually expect a very simplisitic layout model where 
        ///     a window gets to be whatever size it wants to be.  To respect
        ///     this we request the initial size that the window was created 
        ///     at.  A window created with a 0 dimension will adopt whatever 
        ///     size the containing layout wants it to be.  Layouts are free
        ///     to actually size the window to whatever they want, and the 
        ///     child window will always be sized accordingly.
        ///     
        ///     Derived classes should only override this method if they
        ///     have special knowlege about the size the window wants to be. 
        ///     Examples of such may be special HWND types like combo boxes.
        ///     In such cases, the base class must still be called, but the 
        ///     return value can be changed appropriately. 
        /// 
        /// Not available in Internet zone 
        ///
        ///     Critical - calls CriticalHandle
        ///     TreatAsSafe - CriticalHandle used for a null check, not leaked out.
        ///                   Ok to Override MeasureOverride and return a size in PT. 
        /// Demand put in place as a defense in depth measure.
        /// 
        /// 
        [ SecurityCritical, SecurityTreatAsSafe ]
        protected override Size MeasureOverride(Size constraint) 
        {
            DemandIfUntrusted();

            Size desiredSize = new Size(0,0); 

            // Measure to our desired size.  If we have a 0-length dimension, 
            // the system will assume we don't care about that dimension. 
            if(CriticalHandle != IntPtr.Zero)
            { 
                desiredSize.Width = Math.Min(_desiredSize.Width, constraint.Width);
                desiredSize.Height = Math.Min(_desiredSize.Height, constraint.Height);
            }
 
            return desiredSize;
        } 
 
        /// 
        ///     GetDrawing - Returns the drawing content of this Visual. 
        /// 
        /// 
        ///     This returns a bitmap obtained by calling the PrintWindow Win32 API.
        ///  
        internal override DrawingGroup GetDrawing()
        { 
            return GetDrawingHelper(); 
        }
 
        /// 
        /// Returns the bounding box of the content.
        /// 
        internal override Rect GetContentBounds() 
        {
            return new Rect(RenderSize); 
        } 

        /// 
        ///     Critical - calls many native methods, accesses critical data
        ///     TreatAsSafe - Demands UIWindow permission before giving out a bitmap of this window.
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        private DrawingGroup GetDrawingHelper()
        { 
            // Printing an HWND requires UIPermissionWindow.AllWindows to give out its pixels. 
            SecurityHelper.DemandUIWindowPermission();
 
            DrawingGroup drawingGroup = null;

            if(_hwnd.Handle != IntPtr.Zero && UnsafeNativeMethods.IsWindow(_hwnd))
            { 
                NativeMethods.RECT rc = new NativeMethods.RECT();
                SafeNativeMethods.GetWindowRect(_hwnd, ref rc); 
                int width = rc.right - rc.left; 
                int height = rc.bottom - rc.top;
 
                HandleRef hdcScreen = new HandleRef(this, UnsafeNativeMethods.GetDC(new HandleRef(this, IntPtr.Zero)));
                if(hdcScreen.Handle != IntPtr.Zero)
                {
                    HandleRef hdcBitmap = new HandleRef(this, IntPtr.Zero); 
                    HandleRef hBitmap = new HandleRef(this, IntPtr.Zero);
 
                    try 
                    {
                        hdcBitmap = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleDC(hdcScreen)); 
                        if(hdcBitmap.Handle != IntPtr.Zero)
                        {
                            hBitmap = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleBitmap(hdcScreen, width, height));
 
                            if(hBitmap.Handle != IntPtr.Zero)
                            { 
                                // Select the bitmap into the DC so that we draw to it. 
                                IntPtr hOldBitmap = UnsafeNativeMethods.CriticalSelectObject(hdcBitmap, hBitmap.Handle);
                                try 
                                {
                                    // Clear the bitmap to white (so we don't waste toner printing a black bitmap something fails).
                                    NativeMethods.RECT rcPaint = new NativeMethods.RECT(0,0,width, height);
                                    IntPtr hbrWhite = UnsafeNativeMethods.CriticalGetStockObject(NativeMethods.WHITE_BRUSH); 
                                    UnsafeNativeMethods.CriticalFillRect(hdcBitmap.Handle, ref rcPaint, hbrWhite);
 
                                    // First try to use the PrintWindow API. 
                                    bool result = UnsafeNativeMethods.CriticalPrintWindow(_hwnd, hdcBitmap, 0);
                                    if(result == false) 
                                    {
                                        // Fall back to sending a WM_PRINT message to the window.
                                        //
                                        // Note: there are known cases where WM_PRINT is not implemented 
                                        // to provide visual parity with WM_PAINT.  However, since the
                                        // GetDrawing method is virtual, the derived class can override 
                                        // this default implementation and provide a better implementation. 
                                        UnsafeNativeMethods.SendMessage(_hwnd.Handle, NativeMethods.WM_PRINT, hdcBitmap.Handle, (IntPtr) (NativeMethods.PRF_CHILDREN | NativeMethods.PRF_CLIENT | NativeMethods.PRF_ERASEBKGND | NativeMethods.PRF_NONCLIENT));
                                    } 
                                    else
                                    {
                                        // There is a know issue where calling PrintWindow on a window will
                                        // clear all dirty regions (but since it is redirected, the screen 
                                        // won't be updated).  As a result we can leave unpainted pixels on
                                        // the screen if PrintWindow is called when the window was dirty. 
                                        // 
                                        // To fix this, we just force the child window to repaint.
                                        // 
                                        UnsafeNativeMethods.CriticalRedrawWindow(_hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RDW_INVALIDATE | NativeMethods.RDW_ALLCHILDREN);
                                    }

                                    // Create a DrawingGroup that only contains an ImageDrawing that wraps the bitmap. 
                                    drawingGroup = new DrawingGroup();
                                    System.Windows.Media.Imaging.BitmapSource bitmapSource = Imaging.CriticalCreateBitmapSourceFromHBitmap(hBitmap.Handle, IntPtr.Zero, Int32Rect.Empty, null, WICBitmapAlphaChannelOption.WICBitmapIgnoreAlpha); 
                                    Rect rectElement    = new Rect(RenderSize); 
                                    drawingGroup.Children.Add(new ImageDrawing(bitmapSource, rectElement));
                                    drawingGroup.Freeze(); 
                                }
                                finally
                                {
                                    // Put the old bitmap back into the DC. 
                                    UnsafeNativeMethods.CriticalSelectObject(hdcBitmap, hOldBitmap);
                                } 
                            } 
                        }
                    } 
                    finally
                    {
                        UnsafeNativeMethods.ReleaseDC(new HandleRef(this, IntPtr.Zero), hdcScreen);
                        hdcScreen = new HandleRef(null, IntPtr.Zero); 

                        if(hBitmap.Handle != IntPtr.Zero) 
                        { 
                            UnsafeNativeMethods.DeleteObject(hBitmap);
                            hBitmap = new HandleRef(this, IntPtr.Zero); 
                        }

                        if(hdcBitmap.Handle != IntPtr.Zero)
                        { 
                            UnsafeNativeMethods.CriticalDeleteDC(hdcBitmap);
                            hdcBitmap = new HandleRef(this, IntPtr.Zero); 
                        } 
                    }
                } 
            }

            return drawingGroup;
        } 

        /// 
        ///     Critical - calls a method that linkdemands. 
        ///                creates critical for set data.
        /// 
        [ SecurityCritical ]
        private void Initialize( bool fTrusted )
        {
            _fTrusted = new SecurityCriticalDataForSet ( fTrusted ) ; 

            _hwndSubclassHook = new HwndWrapperHook(SubclassWndProc); 
            _handlerLayoutUpdated = new EventHandler(OnLayoutUpdated); 
            _handlerEnabledChanged = new DependencyPropertyChangedEventHandler(OnEnabledChanged);
            _handlerVisibleChanged = new DependencyPropertyChangedEventHandler(OnVisibleChanged); 
            PresentationSource.AddSourceChangedHandler(this, new SourceChangedEventHandler(OnSourceChanged));

            _weakEventDispatcherShutdown = new WeakEventDispatcherShutdown(this, this.Dispatcher);
        } 

        /// 
        ///     Use this method as a defense-in-depth measure only. 
        ///
        /// 
        ///     Not critical - demands are ok.
        ///
        private void DemandIfUntrusted()
        { 
            if ( ! _fTrusted.Value )
                SecurityHelper.DemandUnmanagedCode(); 
        } 

        /// 
        /// Critical - calls CriticalFromVisual.
        /// TreatAsSafe - does not expose the HwndSource obtained.
        ///
        [SecurityCritical , SecurityTreatAsSafe ] 
        private void OnSourceChanged(object sender, SourceChangedEventArgs e)
        { 
            // Remove ourselves as an IKeyboardInputSinks child of our previous 
            // containing window.
            if(_keyboardInputSite != null) 
            {
                if (_fTrusted.Value == true)
                {
                    new UIPermission(PermissionState.Unrestricted).Assert(); //BlessedAssert: 
                }
 
                try 
                {
                    _keyboardInputSite.Unregister(); 
                }
                finally
                {
                    if (_fTrusted.Value == true) 
                        CodeAccessPermission.RevertAssert();
                } 
 
                _keyboardInputSite = null;
            } 

            // Add ourselves as an IKeyboardInputSinks child of our containing window.
            IKeyboardInputSink source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */) as IKeyboardInputSink;
            if(source != null) 
            {
                if (_fTrusted.Value == true) 
                { 
                    new UIPermission(PermissionState.Unrestricted).Assert(); //BlessedAssert:
                } 

                try
                {
                    ((IKeyboardInputSink)this).KeyboardInputSite = source.RegisterKeyboardInputSink(this); 
                }
                finally 
                { 
                    if (_fTrusted.Value == true)
                        CodeAccessPermission.RevertAssert(); 
                }
            }

            BuildOrReparentWindow(); 
        }
 
        private void OnLayoutUpdated(object sender, EventArgs e) 
        {
            UpdateWindowPos(); 
        }

        /// 
        ///     Critical: This code calls into critical method EnableWindow 
        ///     TreatAsSafe: Changing window to being enabled is safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private void OnEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        { 
            if (_isDisposed)
            {
                return;
            } 

            bool boolNewValue = (bool)e.NewValue; 
            UnsafeNativeMethods.EnableWindow(_hwnd, boolNewValue); 
        }
 
        /// 
        ///     Critical: This code calls into critical method show window
        ///     TreatAsSafe: Changing window visibility is safe.
        ///                  Window is always a child window. 
        /// 
        [SecurityCritical,SecurityTreatAsSafe] 
        private void OnVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
        {
            if (_isDisposed) 
            {
                return;
            }
 
            bool vis = (bool)e.NewValue;
 
            // 

 



            if(vis) 
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_SHOWNA);
            else 
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE); 
        }
 
        // This routine handles the following cases:
        // 1) a parent window is present, build the child window
        // 2) a parent is present, reparent the child window to it
        // 3) a parent window is not present, hide the child window by parenting it to a message-only window. 
        /// 
        /// Critical - calls Critical GetParent 
        /// TreatAsSafe - it doesn't disclose GetParent returned information. also 
        ///               as a defense in depth measure - we demand if not trusted. Setting trusted is critical
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void BuildOrReparentWindow()
        {
            DemandIfUntrusted(); 

            // Verify the thread has access to the context. 
            // VerifyAccess(); 

            // Prevent reentry while building a child window, 
            // also prevent the reconstruction of Disposed objects.
            if(_isBuildingWindow || _isDisposed)
            {
                return; 
            }
 
            _isBuildingWindow = true; 

            // Find the source window, this must be the parent window of 
            // the child window.
            IntPtr hwndParent = IntPtr.Zero;
            PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */);
            if(source != null) 
            {
                HwndSource hwndSource = source as HwndSource ; 
                if(hwndSource != null) 
                {
                    hwndParent = hwndSource.CriticalHandle; 
                }
            }
            else
            { 
                // attempt to also walk through 3D - if we get a non-null result then we know we are inside of
                // a 3D scene which is not supported 
                PresentationSource goingThrough3DSource = PresentationSource.CriticalFromVisual(this, true /* enable2DTo3DTransition */); 
                if (goingThrough3DSource != null)
                { 
                    if (TraceHwndHost.IsEnabled)
                    {
                        TraceHwndHost.Trace(TraceEventType.Warning, TraceHwndHost.HwndHostIn3D);
                    } 
                }
            } 
 
            try
            { 
                if(hwndParent != IntPtr.Zero)
                {
                    if(_hwnd.Handle == IntPtr.Zero)
                    { 
                        // We now have a parent window, so we can create the child
                        // window. 
                        BuildWindow(new HandleRef(null, hwndParent)); 
                        this.LayoutUpdated += _handlerLayoutUpdated;
                        this.IsEnabledChanged += _handlerEnabledChanged; 
                        this.IsVisibleChanged += _handlerVisibleChanged;
                    }
                    else if(hwndParent != UnsafeNativeMethods.GetParent(_hwnd))
                    { 
                        // We have a different parent window.  Just reparent the
                        // child window under the new parent window. 
                        UnsafeNativeMethods.SetParent(_hwnd, new HandleRef(null,hwndParent)); 
                    }
                } 
                else
                {
                    // Reparent control window to a message-only window.  This
                    // keeps the child window around, but it is not visible and 
                    // will not receive any normal messages.  We can reparent
                    // the window later when a new parent is available. 
                    UnsafeNativeMethods.SetParent(_hwnd, new HandleRef(null,NativeMethods.HWND_MESSAGE)); 
                }
            } 
            finally
            {
                // Be careful to clear our guard bit.
                _isBuildingWindow = false; 
            }
        } 
 

        ///  
        /// Critical: Calls critical methods - eg. GetWindowLong, IsParent, GetParent etc.
        /// TreatAsSafe: We demand if the trusted bit is not set.
        ///                      Setting the trusted bit is criical.
        ///  
        [ SecurityCritical, SecurityTreatAsSafe ]
        private void BuildWindow(HandleRef hwndParent) 
        { 
            // Demand unmanaged code to the caller. IT'S RISKY TO REMOVE THIS
            DemandIfUntrusted(); 

            // Allow the derived class to build our HWND.
            _hwnd = BuildWindowCore(hwndParent);
 
            if(_hwnd.Handle == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(_hwnd))
            { 
                throw new InvalidOperationException(SR.Get(SRID.ChildWindowNotCreated)); 
            }
 
            // Make sure that the window that was created is indeed a child window.
            int windowStyle = UnsafeNativeMethods.GetWindowLong(new HandleRef(this,_hwnd.Handle), NativeMethods.GWL_STYLE);
            if((windowStyle & NativeMethods.WS_CHILD) == 0)
            { 
                throw new InvalidOperationException(SR.Get(SRID.HostedWindowMustBeAChildWindow));
            } 
 
            // Make sure the child window is the child of the expected parent window.
            if(hwndParent.Handle != UnsafeNativeMethods.GetParent(_hwnd)) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ChildWindowMustHaveCorrectParent));
            }
 
            // Only subclass the child HWND if it is owned by our thread.
            int idWindowProcess; 
            int idWindowThread = UnsafeNativeMethods.GetWindowThreadProcessId(_hwnd, out idWindowProcess); 

#if WCP_SERVER2003_OR_LATER_ENABLED 
            IntPtr hCurrentThread = UnsafeNativeMethods.GetCurrentThread();
            if ((idWindowThread == SafeNativeMethods.GetThreadId(hCurrentThread)) &&
                (idWindowProcess == UnsafeNativeMethods.GetProcessIdOfThread(hCurrentThread)))
#else 
            if ((idWindowThread == SafeNativeMethods.GetCurrentThreadId()) &&
                (idWindowProcess == SafeNativeMethods.GetCurrentProcessId())) 
#endif 
            {
                _hwndSubclass = new HwndSubclass(_hwndSubclassHook); 
                _hwndSubclass.CriticalAttach(_hwnd.Handle);
            }

            // Initially make sure the window is hidden.  We will show it later during rendering. 
            UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE);
 
            // Assume the desired size is the initial size.  If the window was 
            // created with a 0-length dimension, we assume this means we
            // should fill all available space. 
            NativeMethods.RECT rc = new NativeMethods.RECT();
            SafeNativeMethods.GetWindowRect(_hwnd, ref rc);

            // Convert from pixels to measure units. 
            // PresentationSource can't be null if we get here.
            PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); 
            Point ptUpperLeft = new Point(rc.left, rc.top); 
            Point ptLowerRight = new Point(rc.right, rc.bottom);
            ptUpperLeft = source.CompositionTarget.TransformFromDevice.Transform(ptUpperLeft); 
            ptLowerRight = source.CompositionTarget.TransformFromDevice.Transform(ptLowerRight);
            _desiredSize = new Size(ptLowerRight.X - ptUpperLeft.X, ptLowerRight.Y - ptUpperLeft.Y);

            // We have a new desired size, so invalidate measure. 
            InvalidateMeasure();
        } 
 
        /// 
        ///     Critical - calls CriticalHandle. 
        ///     TreatAsSafe - destroying a window previously created considered safe.
        /// 
        [ SecurityCritical, SecurityTreatAsSafe  ]
        private void DestroyWindow() 
        {
            // Destroy the window if we are hosting one. 
            if( CriticalHandle == IntPtr.Zero) 
                return;
 
            if(!CheckAccess())
            {
                // I understand we can get in here on the finalizer thread.  And
                // touching other GC'ed objects in the finalizer is typically bad. 
                // But a Context object can be accessed after finalization.
                // We need to touch the Context to switch to the right thread. 
                // If the Context has been finalized then we won't get switched 
                // and that is OK.
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(AsyncDestroyWindow), null); 
                return;
            }

            HandleRef hwnd = _hwnd; 
            _hwnd = new HandleRef(null, IntPtr.Zero);
 
            DestroyWindowCore(hwnd); 
        }
 
        private object AsyncDestroyWindow(object arg)
        {
            DestroyWindow();
            return null; 
        }
 
        /// 
        ///     Critical - returns Handle
        /// 
        internal IntPtr CriticalHandle
        {
            [SecurityCritical]
            get 
            {
                if(_hwnd.Handle != IntPtr.Zero) 
                { 
                    if(!UnsafeNativeMethods.IsWindow(_hwnd))
                    { 
                        _hwnd = new HandleRef(null, IntPtr.Zero);
                    }
                }
 
                return _hwnd.Handle;
            } 
        } 

        /// 
        ///     Critical - can be used to spoof messages.
        ///
        [ SecurityCritical ]
        private IntPtr SubclassWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
        {
            IntPtr result = IntPtr.Zero ; 
 
            // Call the virtual first.
            result = WndProc(hwnd, msg, wParam, lParam, ref handled); 

            // Call the handlers for the MessageHook event.
            if(!handled && _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;
                    }
                }
            } 

            return result; 
        } 

        private DependencyPropertyChangedEventHandler _handlerEnabledChanged; 
        private DependencyPropertyChangedEventHandler _handlerVisibleChanged;
        private EventHandler _handlerLayoutUpdated;

        /// 
        ///     Critical - ctor was critical. Manipulating/Handing this out to PT would be unsafe.
        /// 
        [ SecurityCritical ] 
        private HwndSubclass _hwndSubclass;
 
        ///
        ///     Critical - ctor was critical. Manipulating/Handing this out to PT would be unsafe.
        ///
        [ SecurityCritical ] 
        private HwndWrapperHook _hwndSubclassHook;
 
        /// 
        ///     Critical - ctor was critical. Manipulating/Handing this out to PT would be unsafe.
        /// 
        [ SecurityCritical ]
        private HandleRef _hwnd;

        private ArrayList _hooks; 
        private Size _desiredSize;
 
        private SecurityCriticalDataForSet _fTrusted ; 

        private bool _isBuildingWindow = false; 

        private bool _isDisposed = false;

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

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

            private Dispatcher _that; 
        } 
        WeakEventDispatcherShutdown _weakEventDispatcherShutdown;
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Diagnostics;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Input; 
using System.Collections;
using MS.Win32; 
using MS.Internal; 
using MS.Internal.PresentationFramework;                   // SecurityHelper
using System.Security; 
using System.Security.Permissions;
using Microsoft.Win32;
using System.Windows.Media;
using System.Windows.Interop; 
using System.Runtime.InteropServices;
using System.Windows.Threading; 
 
// Disable pragma warnings to enable PREsharp pragmas
#pragma warning disable 1634, 1691 

namespace System.Windows.Interop
{
    ///  
    ///     The HwndHost class hosts an HWND inside of an Avalon tree.
    ///  
    /// Subclassing requires unmanaged code permission 
    ///
    /// 
    ///     Inheritance demand put in place - as to host activeX controls you should have Unmanaged code permission.
    ///
    ///
 
    [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
    public abstract class HwndHost : FrameworkElement, IDisposable, IWin32Window, IKeyboardInputSink 
    { 
        static HwndHost()
        { 
            FocusableProperty.OverrideMetadata(typeof(HwndHost), new FrameworkPropertyMetadata(true));
        }

        ///  
        ///     Constructs an instance of the HwndHost class.
        ///  
        /// Not available in Internet zone 
        ///
        ///     Critical - calls critical code, sets critical _fTrusted flag. 
        ///     PublicOk - trusted flag is set to false.
        ///
        [ SecurityCritical ]
        protected HwndHost() 
        {
            Initialize( false ) ; 
        } 

        /// 
        ///     Critical sets fTrustedBit.
        ///
        [ SecurityCritical, FriendAccessAllowed ]
        internal HwndHost(bool fTrusted ) 
        {
            Initialize( fTrusted ) ; 
        } 

        ///  
        ///    Because we own an HWND, we implement a finalizer to make sure that we destroy it.
        /// 
        ~HwndHost()
        { 
            Dispose(false);
        } 
 
        /// 
        ///     Disposes this object. 
        /// 
        public void Dispose()
        {
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 
 
        /// 
        ///     The Win32 handle of the hosted window. 
        /// 
        /// 
        ///     Callers must have UnmanagedCode permission to call this API.
        ///  
        /// 
        ///     Critical: This code accesses IsWindow, returns hwndHandle. 
        ///     PublicOk: There is a demand 
        /// 
        public IntPtr Handle 
        {
            [SecurityCritical]
            get
            { 
                SecurityHelper.DemandUnmanagedCode();
 
                return CriticalHandle; 
            }
        } 

        /// 
        ///     An event that is notified of all unhandled messages received
        ///     by the hosted window. 
        /// 
        ///  
        ///     Callers must have UnmanagedCode permission to call this API. 
        /// 
        /// 
        ///     Demand put in place as a defense in depth measure.
        ///
        public event HwndSourceHook MessageHook
        { 
            add
            { 
//                 VerifyAccess(); 

                SecurityHelper.DemandUnmanagedCode(); 

                if(_hooks == null)
                {
                    _hooks = new ArrayList(8); 
                }
 
                _hooks.Add(value); 
            }
 
            remove
            {
//                 VerifyAccess();
                SecurityHelper.DemandUnmanagedCode(); 

                if(_hooks != null) 
                { 
                    _hooks.Remove(value);
 
                    if(_hooks.Count == 0)
                    {
                        _hooks = null;
                    } 
                }
            } 
        } 

        ///  
        /// 
        /// 
        ///
        /// Critical - Calls ComponentDispatcher.UnsecureCurrentKeyboardMessage. 
        /// TreatAsSafe - Only calls for trusted controls
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        protected override void OnKeyUp(KeyEventArgs e)
        { 
            MSG msg;
            if (_fTrusted.Value)
            {
                msg = ComponentDispatcher.UnsecureCurrentKeyboardMessage; 
            }
            else 
            { 
                msg = ComponentDispatcher.CurrentKeyboardMessage;
            } 

            ModifierKeys modifiers = HwndKeyboardInputProvider.GetSystemModifierKeys();

            bool handled = ((IKeyboardInputSink)this).TranslateAccelerator(ref msg, modifiers); 

            if(handled) 
                e.Handled = handled; 

            base.OnKeyUp(e); 
        }

        /// 
        ///  
        /// 
        /// 
        /// Critical - Calls ComponentDispatcher.UnsecureCurrentKeyboardMessage. 
        /// TreatAsSafe - Only calls for trusted controls
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnKeyDown(KeyEventArgs e)
        {
            MSG msg; 
            if (_fTrusted.Value)
            { 
                msg = ComponentDispatcher.UnsecureCurrentKeyboardMessage; 
            }
            else 
            {
                msg = ComponentDispatcher.CurrentKeyboardMessage;
            }
 

            ModifierKeys modifiers = HwndKeyboardInputProvider.GetSystemModifierKeys(); 
 
            bool handled = ((IKeyboardInputSink)this).TranslateAccelerator(ref msg, modifiers);
 
            if(handled)
                e.Handled = handled;

            base.OnKeyDown(e); 
        }
 
 
#region IKeyboardInputSink
        ///  
        ///     Registers a IKeyboardInputSink with the HwndSource in order
        ///     to retreive a unique IKeyboardInputSite for it.
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     PublicOk: The interface declaration for this method has a demand on it. 
        ///  
        [SecurityCritical]
        IKeyboardInputSite IKeyboardInputSink.RegisterKeyboardInputSink(IKeyboardInputSink sink) 
        {
            throw new InvalidOperationException(SR.Get(SRID.HwndHostDoesNotSupportChildKeyboardSinks));
        }
 
        /// 
        ///     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.
        ///  
        /// 
        ///     Critical: This API can be used for input spoofing 
        ///     PublicOk: The interface declaration for this method has a demand on it. 
        /// 
        [SecurityCritical] 
        bool IKeyboardInputSink.TranslateAccelerator(ref MSG msg, ModifierKeys modifiers)
        {
            return false;
        } 

        ///  
        ///     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)
        {
            return false; 
        }
 
        ///  
        ///     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.
        /// 
        ///  
        ///     Critical: This API can be used for input spoofing
        ///     PublicOk: The interface declaration for this method has a demand on it. 
        ///  
        IKeyboardInputSite IKeyboardInputSink.KeyboardInputSite
        { 
            get
            {
                return _keyboardInputSite;
            } 

            [SecurityCritical] 
            set 
            {
                _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 
        ///     PublicOk: The interface declaration for this method has a demand on it.
        ///  
        [SecurityCritical] 
        bool IKeyboardInputSink.OnMnemonic(ref MSG msg, ModifierKeys modifiers)
        { 
            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 
        ///     PublicOk: The interface declaration for this method has a demand on it.
        ///  
        [SecurityCritical] 
        bool IKeyboardInputSink.TranslateChar(ref MSG msg, ModifierKeys modifiers)
        { 
            return false;
        }

        ///  
        ///     This returns true if the sink, or a child of it, has focus. And false otherwise.
        ///  
        /// 
        ///     Critical - calls a method with a SUC - GetFocus.
        ///     PublicOk: - no critical information exposed. 
        ///                   It's ok to return whether hwndHost has focus within itself in PT.
        ///
        ///     Demand put in place as a defense-in-depth measure.
        /// 
        [SecurityCritical]
        bool IKeyboardInputSink.HasFocusWithin() 
        { 
            DemandIfUntrusted();
 
            HandleRef hwndFocus = new HandleRef(this, UnsafeNativeMethods.GetFocus());
            if (_hwnd.Handle != IntPtr.Zero && (hwndFocus.Handle == _hwnd.Handle || UnsafeNativeMethods.IsChild(_hwnd, hwndFocus)))
            {
                return true; 
            }
            return false; 
        } 

        private IKeyboardInputSite _keyboardInputSite = null; 
#endregion IKeyboardInputSink

        /// 
        ///     Updates the child window to reflect the state of this element. 
        /// 
        ///  
        ///     This includes the size of the window, the position of the 
        ///     window, and the visibility of the window.
        ///  
        /// Not available in Internet zone
        ///
        ///     Critical: This code accesses critical code and also calls into PresentationSource
        ///     PublicOk : Repositioning the activeX control is ok. 
        ///                Net effect is to make window location consistent with what layout calculated.
        /// 
        [SecurityCritical] 
        public void UpdateWindowPos()
        { 
            // Verify the thread has access to the context.
            // VerifyAccess();

            if (_isDisposed) 
            {
                return; 
            } 

            // Position the child HWND where layout put it.  To do this we 
            // have to get coordinates relative to the parent window.

            PresentationSource source = null;
            CompositionTarget vt = null; 
            if (( CriticalHandle != IntPtr.Zero) && IsVisible)
            { 
                source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); 
                if(source != null)
                { 
                    vt = source.CompositionTarget;
                }
            }
 
            if(vt != null && vt.RootVisual != null)
            { 
                // Translate the layout information assigned to us from the co-ordinate 
                // space of this element, through the root visual, to the Win32 client
                // co-ordinate space 
                NativeMethods.RECT rcClientRTLAdjusted = CalculateAssignedRC(source);

                // Set the Win32 position for the child window.
                // 
                // Note, we can't check the existing position because we use
                // SWP_ASYNCWINDOWPOS, which means we could have pending position 
                // change requests that haven't been applied yet.  If we need 
                // this functionality (to avoid the extra SetWindowPos calls),
                // we'll have to track the last RECT we sent Win32 ourselves. 
                //
                Rect rectClientRTLAdjusted = PointUtil.ToRect(rcClientRTLAdjusted);
                OnWindowPositionChanged(rectClientRTLAdjusted);
 
                // Show the window
                // Based on Dwayne, the reason we also show/hide window in UpdateWindowPos is for the 
                // following kind of scenario: When applying RenderTransform to HwndHost, the hwnd 
                // will be left behind. Developer can workaround by hide the hwnd first using pinvoke.
                // After the RenderTransform is applied to the HwndHost, call UpdateWindowPos to [....] up 
                // the hwnd's location, size and visibility with WPF.
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_SHOW);
            }
            else 
            {
                // For some reason we shouldn't be displayed: either we don't 
                // have a parent, or the parent no longer has a root visual, 
                // or we are marked as not being visible.
                // 
                // Just hide the window to get it out of the way.
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE);
            }
        } 

        // Translate the layout information assigned to us from the co-ordinate 
        // space of this element, through the root visual, to the Win32 client 
        // co-ordinate space
        /// 
        ///     Critical: This code accesses critical code and also calls into PresentationSource
        ///     TAS : Calculate the new position of the activeX control is ok.
        ///                Net effect is to make window location consistent with what layout calculated.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private NativeMethods.RECT CalculateAssignedRC(PresentationSource source) 
        { 
            Rect rectElement = new Rect(RenderSize);
            Rect rectRoot = PointUtil.ElementToRoot(rectElement, this, source); 
            Rect rectClient = PointUtil.RootToClient(rectRoot, source);

            // Adjust for Right-To-Left oriented windows
            IntPtr hwndParent = UnsafeNativeMethods.GetParent(_hwnd); 
            NativeMethods.RECT rcClient = PointUtil.FromRect(rectClient);
            NativeMethods.RECT rcClientRTLAdjusted = PointUtil.AdjustForRightToLeft(rcClient, new HandleRef(null, hwndParent)); 
 
            return rcClientRTLAdjusted;
        } 

        /// 
        ///     Disposes this object.
        ///  
        /// 
        ///     true if called from explisit Dispose; and we free all objects managed and un-managed. 
        ///     false if called from the finalizer; and we free only un-managed objects. 
        /// 
        ///  
        ///     Derived classes should override this if they have additional
        ///     cleanup to do.  The base class implementation should be called.
        ///     Note that the calling thread must be the dispatcher thread.
        ///     If a window is being hosted, that window is destroyed. 
        /// 
        /// 
        ///     Critical - call to RemoveSourceChangeHandler invokes critical delegate. 
        ///     SecurityTreatAsSafe : - disposing the HwndHost is considered ok.
        /// 
        [ SecurityCritical, SecurityTreatAsSafe ]
        protected virtual void Dispose(bool disposing)
        {
            if (_isDisposed == true) 
            {
                return; 
            } 

 
            if(disposing)
            {
                // Verify the thread has access to the context.
#pragma warning suppress 6519 
                 VerifyAccess();
 
 
                // Remove our subclass.  Even if this fails, it will be forcably removed
                // when the window is destroyed. 
                if (_hwndSubclass != null)
                {
                    // Check if it is trusted (WebOC and AddInHost), call CriticalDetach to avoid the Demand.
                    if (_fTrusted.Value == true) 
                    {
                        _hwndSubclass.CriticalDetach(false); 
                    } 
                    else
                    { 
                        _hwndSubclass.RequestDetach(false);
                    }

                    _hwndSubclass = null; 
                }
 
                // Drop the hooks so that they can be garbage-collected. 
                _hooks = null;
 
                // We no longer need to know about the source changing.
                PresentationSource.RemoveSourceChangedHandler(this, new SourceChangedEventHandler(OnSourceChanged));
            }
 
            _weakEventDispatcherShutdown.Dispose();
            _weakEventDispatcherShutdown = null; 
 
            DestroyWindow();
 
            _isDisposed = true;
        }

        private void OnDispatcherShutdown(object sender, EventArgs e) 
        {
            Dispose(); 
        } 

        ///  
        ///     Derived classes override this method to actually build the
        ///     window being hosted.
        /// 
        ///  
        ///     The parent HWND for the child window.
        ///  
        ///  
        ///     The HWND handle to the child window that was created.
        ///  
        /// 
        ///     The window that is returned must be a child window of the
        ///     specified parent window.
        ///      
        ///     In addition, the child window will only be subclassed if
        ///     the window is owned by the calling thread. 
        ///  
        protected abstract HandleRef BuildWindowCore(HandleRef hwndParent);
 
        /// 
        ///     Derived classes override this method to actually build the
        ///     window being hosted.
        ///  
        protected abstract void DestroyWindowCore(HandleRef hwnd);
 
        ///  
        ///     A protected override for accessing the window proc of the
        ///     hosted child window. 
        /// 
        /// Not available in Internet zone
        ///
        ///     Critical - accesses _hwnd Critical member. 
        ///     PublicOk - Inheritance Demand for unmanaged codepermission to buslclass.
        ///                any caller of the protected must have Unmanaged code permission. 
        ///     DemandIfUntrusted is there as a defense in depth measure. 
        /// 
        [ SecurityCritical ] 
        protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            DemandIfUntrusted();
 
            switch (msg)
            { 
                case NativeMethods.WM_NCDESTROY: 
                    _hwnd = new HandleRef(null, IntPtr.Zero);
                    break; 

                // When layout happens, we first calculate the right size/location then call SetWindowPos.
                // We only allow the changes that are coming from Avalon layout. The hwnd is not allowed to change by itself.
                // So the size of the hwnd should always be RenderSize and the position be where layout puts it. 
                case NativeMethods.WM_WINDOWPOSCHANGING:
                    PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); 
 
                    if (source != null)
                    { 
                        // 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));

                        // Get the rect assigned by layout to us. 
                        NativeMethods.RECT assignedRC = CalculateAssignedRC(source);
 
                        windowPos.cx = assignedRC.right - assignedRC.left; 
                        windowPos.cy = assignedRC.bottom - assignedRC.top;
 
                        windowPos.x = assignedRC.left;
                        windowPos.y = assignedRC.top;

                        // marshal size/location back 
                        Marshal.StructureToPtr(windowPos, lParam, true);
                    } 
 
                    break;
 

                case NativeMethods.WM_GETOBJECT:
                    handled = true;
                    return OnWmGetObject(wParam, lParam); 
            }
 
            return IntPtr.Zero ; 
        }
 
        #region Automation

        /// 
        /// Creates AutomationPeer () 
        /// 
        protected override AutomationPeer OnCreateAutomationPeer() 
        { 
            return new HwndHostAutomationPeer(this);
        } 

        /// 
        ///     Critical    - Calls critical HwndHost.CriticalHandle.
        ///  
        [SecurityCritical]
        private IntPtr OnWmGetObject(IntPtr wparam, IntPtr lparam) 
        { 
            IntPtr result = IntPtr.Zero;
 
            AutomationPeer containerPeer = UIElementAutomationPeer.CreatePeerForElement(this);
            if (containerPeer != null)
            {
                // get the element proxy 
                IRawElementProviderSimple el = containerPeer.GetInteropChild();
                result = AutomationInteropProvider.ReturnRawElementProvider(CriticalHandle, wparam, lparam, el); 
            } 
            return result;
        } 

        #endregion Automation

        // 

 
 

 



 

 
        [ SecurityCritical ] 
        protected virtual void OnWindowPositionChanged(Rect rcBoundingBox)
        { 
            if (_isDisposed)
            {
                return;
            } 

            UnsafeNativeMethods.SetWindowPos(_hwnd, 
                                           new HandleRef(null, IntPtr.Zero), 
                                           (int)rcBoundingBox.X,
                                           (int)rcBoundingBox.Y, 
                                           (int)rcBoundingBox.Width,
                                           (int)rcBoundingBox.Height,
                                           NativeMethods.SWP_ASYNCWINDOWPOS
                                           | NativeMethods.SWP_NOZORDER 
                                           | NativeMethods.SWP_NOCOPYBITS
                                           | NativeMethods.SWP_NOACTIVATE); 
        } 

        ///  
        ///     Return the desired size of the HWND.
        /// 
        /// 
        ///     HWNDs usually expect a very simplisitic layout model where 
        ///     a window gets to be whatever size it wants to be.  To respect
        ///     this we request the initial size that the window was created 
        ///     at.  A window created with a 0 dimension will adopt whatever 
        ///     size the containing layout wants it to be.  Layouts are free
        ///     to actually size the window to whatever they want, and the 
        ///     child window will always be sized accordingly.
        ///     
        ///     Derived classes should only override this method if they
        ///     have special knowlege about the size the window wants to be. 
        ///     Examples of such may be special HWND types like combo boxes.
        ///     In such cases, the base class must still be called, but the 
        ///     return value can be changed appropriately. 
        /// 
        /// Not available in Internet zone 
        ///
        ///     Critical - calls CriticalHandle
        ///     TreatAsSafe - CriticalHandle used for a null check, not leaked out.
        ///                   Ok to Override MeasureOverride and return a size in PT. 
        /// Demand put in place as a defense in depth measure.
        /// 
        /// 
        [ SecurityCritical, SecurityTreatAsSafe ]
        protected override Size MeasureOverride(Size constraint) 
        {
            DemandIfUntrusted();

            Size desiredSize = new Size(0,0); 

            // Measure to our desired size.  If we have a 0-length dimension, 
            // the system will assume we don't care about that dimension. 
            if(CriticalHandle != IntPtr.Zero)
            { 
                desiredSize.Width = Math.Min(_desiredSize.Width, constraint.Width);
                desiredSize.Height = Math.Min(_desiredSize.Height, constraint.Height);
            }
 
            return desiredSize;
        } 
 
        /// 
        ///     GetDrawing - Returns the drawing content of this Visual. 
        /// 
        /// 
        ///     This returns a bitmap obtained by calling the PrintWindow Win32 API.
        ///  
        internal override DrawingGroup GetDrawing()
        { 
            return GetDrawingHelper(); 
        }
 
        /// 
        /// Returns the bounding box of the content.
        /// 
        internal override Rect GetContentBounds() 
        {
            return new Rect(RenderSize); 
        } 

        /// 
        ///     Critical - calls many native methods, accesses critical data
        ///     TreatAsSafe - Demands UIWindow permission before giving out a bitmap of this window.
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        private DrawingGroup GetDrawingHelper()
        { 
            // Printing an HWND requires UIPermissionWindow.AllWindows to give out its pixels. 
            SecurityHelper.DemandUIWindowPermission();
 
            DrawingGroup drawingGroup = null;

            if(_hwnd.Handle != IntPtr.Zero && UnsafeNativeMethods.IsWindow(_hwnd))
            { 
                NativeMethods.RECT rc = new NativeMethods.RECT();
                SafeNativeMethods.GetWindowRect(_hwnd, ref rc); 
                int width = rc.right - rc.left; 
                int height = rc.bottom - rc.top;
 
                HandleRef hdcScreen = new HandleRef(this, UnsafeNativeMethods.GetDC(new HandleRef(this, IntPtr.Zero)));
                if(hdcScreen.Handle != IntPtr.Zero)
                {
                    HandleRef hdcBitmap = new HandleRef(this, IntPtr.Zero); 
                    HandleRef hBitmap = new HandleRef(this, IntPtr.Zero);
 
                    try 
                    {
                        hdcBitmap = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleDC(hdcScreen)); 
                        if(hdcBitmap.Handle != IntPtr.Zero)
                        {
                            hBitmap = new HandleRef(this, UnsafeNativeMethods.CriticalCreateCompatibleBitmap(hdcScreen, width, height));
 
                            if(hBitmap.Handle != IntPtr.Zero)
                            { 
                                // Select the bitmap into the DC so that we draw to it. 
                                IntPtr hOldBitmap = UnsafeNativeMethods.CriticalSelectObject(hdcBitmap, hBitmap.Handle);
                                try 
                                {
                                    // Clear the bitmap to white (so we don't waste toner printing a black bitmap something fails).
                                    NativeMethods.RECT rcPaint = new NativeMethods.RECT(0,0,width, height);
                                    IntPtr hbrWhite = UnsafeNativeMethods.CriticalGetStockObject(NativeMethods.WHITE_BRUSH); 
                                    UnsafeNativeMethods.CriticalFillRect(hdcBitmap.Handle, ref rcPaint, hbrWhite);
 
                                    // First try to use the PrintWindow API. 
                                    bool result = UnsafeNativeMethods.CriticalPrintWindow(_hwnd, hdcBitmap, 0);
                                    if(result == false) 
                                    {
                                        // Fall back to sending a WM_PRINT message to the window.
                                        //
                                        // Note: there are known cases where WM_PRINT is not implemented 
                                        // to provide visual parity with WM_PAINT.  However, since the
                                        // GetDrawing method is virtual, the derived class can override 
                                        // this default implementation and provide a better implementation. 
                                        UnsafeNativeMethods.SendMessage(_hwnd.Handle, NativeMethods.WM_PRINT, hdcBitmap.Handle, (IntPtr) (NativeMethods.PRF_CHILDREN | NativeMethods.PRF_CLIENT | NativeMethods.PRF_ERASEBKGND | NativeMethods.PRF_NONCLIENT));
                                    } 
                                    else
                                    {
                                        // There is a know issue where calling PrintWindow on a window will
                                        // clear all dirty regions (but since it is redirected, the screen 
                                        // won't be updated).  As a result we can leave unpainted pixels on
                                        // the screen if PrintWindow is called when the window was dirty. 
                                        // 
                                        // To fix this, we just force the child window to repaint.
                                        // 
                                        UnsafeNativeMethods.CriticalRedrawWindow(_hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RDW_INVALIDATE | NativeMethods.RDW_ALLCHILDREN);
                                    }

                                    // Create a DrawingGroup that only contains an ImageDrawing that wraps the bitmap. 
                                    drawingGroup = new DrawingGroup();
                                    System.Windows.Media.Imaging.BitmapSource bitmapSource = Imaging.CriticalCreateBitmapSourceFromHBitmap(hBitmap.Handle, IntPtr.Zero, Int32Rect.Empty, null, WICBitmapAlphaChannelOption.WICBitmapIgnoreAlpha); 
                                    Rect rectElement    = new Rect(RenderSize); 
                                    drawingGroup.Children.Add(new ImageDrawing(bitmapSource, rectElement));
                                    drawingGroup.Freeze(); 
                                }
                                finally
                                {
                                    // Put the old bitmap back into the DC. 
                                    UnsafeNativeMethods.CriticalSelectObject(hdcBitmap, hOldBitmap);
                                } 
                            } 
                        }
                    } 
                    finally
                    {
                        UnsafeNativeMethods.ReleaseDC(new HandleRef(this, IntPtr.Zero), hdcScreen);
                        hdcScreen = new HandleRef(null, IntPtr.Zero); 

                        if(hBitmap.Handle != IntPtr.Zero) 
                        { 
                            UnsafeNativeMethods.DeleteObject(hBitmap);
                            hBitmap = new HandleRef(this, IntPtr.Zero); 
                        }

                        if(hdcBitmap.Handle != IntPtr.Zero)
                        { 
                            UnsafeNativeMethods.CriticalDeleteDC(hdcBitmap);
                            hdcBitmap = new HandleRef(this, IntPtr.Zero); 
                        } 
                    }
                } 
            }

            return drawingGroup;
        } 

        /// 
        ///     Critical - calls a method that linkdemands. 
        ///                creates critical for set data.
        /// 
        [ SecurityCritical ]
        private void Initialize( bool fTrusted )
        {
            _fTrusted = new SecurityCriticalDataForSet ( fTrusted ) ; 

            _hwndSubclassHook = new HwndWrapperHook(SubclassWndProc); 
            _handlerLayoutUpdated = new EventHandler(OnLayoutUpdated); 
            _handlerEnabledChanged = new DependencyPropertyChangedEventHandler(OnEnabledChanged);
            _handlerVisibleChanged = new DependencyPropertyChangedEventHandler(OnVisibleChanged); 
            PresentationSource.AddSourceChangedHandler(this, new SourceChangedEventHandler(OnSourceChanged));

            _weakEventDispatcherShutdown = new WeakEventDispatcherShutdown(this, this.Dispatcher);
        } 

        /// 
        ///     Use this method as a defense-in-depth measure only. 
        ///
        /// 
        ///     Not critical - demands are ok.
        ///
        private void DemandIfUntrusted()
        { 
            if ( ! _fTrusted.Value )
                SecurityHelper.DemandUnmanagedCode(); 
        } 

        /// 
        /// Critical - calls CriticalFromVisual.
        /// TreatAsSafe - does not expose the HwndSource obtained.
        ///
        [SecurityCritical , SecurityTreatAsSafe ] 
        private void OnSourceChanged(object sender, SourceChangedEventArgs e)
        { 
            // Remove ourselves as an IKeyboardInputSinks child of our previous 
            // containing window.
            if(_keyboardInputSite != null) 
            {
                if (_fTrusted.Value == true)
                {
                    new UIPermission(PermissionState.Unrestricted).Assert(); //BlessedAssert: 
                }
 
                try 
                {
                    _keyboardInputSite.Unregister(); 
                }
                finally
                {
                    if (_fTrusted.Value == true) 
                        CodeAccessPermission.RevertAssert();
                } 
 
                _keyboardInputSite = null;
            } 

            // Add ourselves as an IKeyboardInputSinks child of our containing window.
            IKeyboardInputSink source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */) as IKeyboardInputSink;
            if(source != null) 
            {
                if (_fTrusted.Value == true) 
                { 
                    new UIPermission(PermissionState.Unrestricted).Assert(); //BlessedAssert:
                } 

                try
                {
                    ((IKeyboardInputSink)this).KeyboardInputSite = source.RegisterKeyboardInputSink(this); 
                }
                finally 
                { 
                    if (_fTrusted.Value == true)
                        CodeAccessPermission.RevertAssert(); 
                }
            }

            BuildOrReparentWindow(); 
        }
 
        private void OnLayoutUpdated(object sender, EventArgs e) 
        {
            UpdateWindowPos(); 
        }

        /// 
        ///     Critical: This code calls into critical method EnableWindow 
        ///     TreatAsSafe: Changing window to being enabled is safe.
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private void OnEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        { 
            if (_isDisposed)
            {
                return;
            } 

            bool boolNewValue = (bool)e.NewValue; 
            UnsafeNativeMethods.EnableWindow(_hwnd, boolNewValue); 
        }
 
        /// 
        ///     Critical: This code calls into critical method show window
        ///     TreatAsSafe: Changing window visibility is safe.
        ///                  Window is always a child window. 
        /// 
        [SecurityCritical,SecurityTreatAsSafe] 
        private void OnVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
        {
            if (_isDisposed) 
            {
                return;
            }
 
            bool vis = (bool)e.NewValue;
 
            // 

 



            if(vis) 
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_SHOWNA);
            else 
                UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE); 
        }
 
        // This routine handles the following cases:
        // 1) a parent window is present, build the child window
        // 2) a parent is present, reparent the child window to it
        // 3) a parent window is not present, hide the child window by parenting it to a message-only window. 
        /// 
        /// Critical - calls Critical GetParent 
        /// TreatAsSafe - it doesn't disclose GetParent returned information. also 
        ///               as a defense in depth measure - we demand if not trusted. Setting trusted is critical
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void BuildOrReparentWindow()
        {
            DemandIfUntrusted(); 

            // Verify the thread has access to the context. 
            // VerifyAccess(); 

            // Prevent reentry while building a child window, 
            // also prevent the reconstruction of Disposed objects.
            if(_isBuildingWindow || _isDisposed)
            {
                return; 
            }
 
            _isBuildingWindow = true; 

            // Find the source window, this must be the parent window of 
            // the child window.
            IntPtr hwndParent = IntPtr.Zero;
            PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */);
            if(source != null) 
            {
                HwndSource hwndSource = source as HwndSource ; 
                if(hwndSource != null) 
                {
                    hwndParent = hwndSource.CriticalHandle; 
                }
            }
            else
            { 
                // attempt to also walk through 3D - if we get a non-null result then we know we are inside of
                // a 3D scene which is not supported 
                PresentationSource goingThrough3DSource = PresentationSource.CriticalFromVisual(this, true /* enable2DTo3DTransition */); 
                if (goingThrough3DSource != null)
                { 
                    if (TraceHwndHost.IsEnabled)
                    {
                        TraceHwndHost.Trace(TraceEventType.Warning, TraceHwndHost.HwndHostIn3D);
                    } 
                }
            } 
 
            try
            { 
                if(hwndParent != IntPtr.Zero)
                {
                    if(_hwnd.Handle == IntPtr.Zero)
                    { 
                        // We now have a parent window, so we can create the child
                        // window. 
                        BuildWindow(new HandleRef(null, hwndParent)); 
                        this.LayoutUpdated += _handlerLayoutUpdated;
                        this.IsEnabledChanged += _handlerEnabledChanged; 
                        this.IsVisibleChanged += _handlerVisibleChanged;
                    }
                    else if(hwndParent != UnsafeNativeMethods.GetParent(_hwnd))
                    { 
                        // We have a different parent window.  Just reparent the
                        // child window under the new parent window. 
                        UnsafeNativeMethods.SetParent(_hwnd, new HandleRef(null,hwndParent)); 
                    }
                } 
                else
                {
                    // Reparent control window to a message-only window.  This
                    // keeps the child window around, but it is not visible and 
                    // will not receive any normal messages.  We can reparent
                    // the window later when a new parent is available. 
                    UnsafeNativeMethods.SetParent(_hwnd, new HandleRef(null,NativeMethods.HWND_MESSAGE)); 
                }
            } 
            finally
            {
                // Be careful to clear our guard bit.
                _isBuildingWindow = false; 
            }
        } 
 

        ///  
        /// Critical: Calls critical methods - eg. GetWindowLong, IsParent, GetParent etc.
        /// TreatAsSafe: We demand if the trusted bit is not set.
        ///                      Setting the trusted bit is criical.
        ///  
        [ SecurityCritical, SecurityTreatAsSafe ]
        private void BuildWindow(HandleRef hwndParent) 
        { 
            // Demand unmanaged code to the caller. IT'S RISKY TO REMOVE THIS
            DemandIfUntrusted(); 

            // Allow the derived class to build our HWND.
            _hwnd = BuildWindowCore(hwndParent);
 
            if(_hwnd.Handle == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(_hwnd))
            { 
                throw new InvalidOperationException(SR.Get(SRID.ChildWindowNotCreated)); 
            }
 
            // Make sure that the window that was created is indeed a child window.
            int windowStyle = UnsafeNativeMethods.GetWindowLong(new HandleRef(this,_hwnd.Handle), NativeMethods.GWL_STYLE);
            if((windowStyle & NativeMethods.WS_CHILD) == 0)
            { 
                throw new InvalidOperationException(SR.Get(SRID.HostedWindowMustBeAChildWindow));
            } 
 
            // Make sure the child window is the child of the expected parent window.
            if(hwndParent.Handle != UnsafeNativeMethods.GetParent(_hwnd)) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ChildWindowMustHaveCorrectParent));
            }
 
            // Only subclass the child HWND if it is owned by our thread.
            int idWindowProcess; 
            int idWindowThread = UnsafeNativeMethods.GetWindowThreadProcessId(_hwnd, out idWindowProcess); 

#if WCP_SERVER2003_OR_LATER_ENABLED 
            IntPtr hCurrentThread = UnsafeNativeMethods.GetCurrentThread();
            if ((idWindowThread == SafeNativeMethods.GetThreadId(hCurrentThread)) &&
                (idWindowProcess == UnsafeNativeMethods.GetProcessIdOfThread(hCurrentThread)))
#else 
            if ((idWindowThread == SafeNativeMethods.GetCurrentThreadId()) &&
                (idWindowProcess == SafeNativeMethods.GetCurrentProcessId())) 
#endif 
            {
                _hwndSubclass = new HwndSubclass(_hwndSubclassHook); 
                _hwndSubclass.CriticalAttach(_hwnd.Handle);
            }

            // Initially make sure the window is hidden.  We will show it later during rendering. 
            UnsafeNativeMethods.ShowWindowAsync(_hwnd, NativeMethods.SW_HIDE);
 
            // Assume the desired size is the initial size.  If the window was 
            // created with a 0-length dimension, we assume this means we
            // should fill all available space. 
            NativeMethods.RECT rc = new NativeMethods.RECT();
            SafeNativeMethods.GetWindowRect(_hwnd, ref rc);

            // Convert from pixels to measure units. 
            // PresentationSource can't be null if we get here.
            PresentationSource source = PresentationSource.CriticalFromVisual(this, false /* enable2DTo3DTransition */); 
            Point ptUpperLeft = new Point(rc.left, rc.top); 
            Point ptLowerRight = new Point(rc.right, rc.bottom);
            ptUpperLeft = source.CompositionTarget.TransformFromDevice.Transform(ptUpperLeft); 
            ptLowerRight = source.CompositionTarget.TransformFromDevice.Transform(ptLowerRight);
            _desiredSize = new Size(ptLowerRight.X - ptUpperLeft.X, ptLowerRight.Y - ptUpperLeft.Y);

            // We have a new desired size, so invalidate measure. 
            InvalidateMeasure();
        } 
 
        /// 
        ///     Critical - calls CriticalHandle. 
        ///     TreatAsSafe - destroying a window previously created considered safe.
        /// 
        [ SecurityCritical, SecurityTreatAsSafe  ]
        private void DestroyWindow() 
        {
            // Destroy the window if we are hosting one. 
            if( CriticalHandle == IntPtr.Zero) 
                return;
 
            if(!CheckAccess())
            {
                // I understand we can get in here on the finalizer thread.  And
                // touching other GC'ed objects in the finalizer is typically bad. 
                // But a Context object can be accessed after finalization.
                // We need to touch the Context to switch to the right thread. 
                // If the Context has been finalized then we won't get switched 
                // and that is OK.
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(AsyncDestroyWindow), null); 
                return;
            }

            HandleRef hwnd = _hwnd; 
            _hwnd = new HandleRef(null, IntPtr.Zero);
 
            DestroyWindowCore(hwnd); 
        }
 
        private object AsyncDestroyWindow(object arg)
        {
            DestroyWindow();
            return null; 
        }
 
        /// 
        ///     Critical - returns Handle
        /// 
        internal IntPtr CriticalHandle
        {
            [SecurityCritical]
            get 
            {
                if(_hwnd.Handle != IntPtr.Zero) 
                { 
                    if(!UnsafeNativeMethods.IsWindow(_hwnd))
                    { 
                        _hwnd = new HandleRef(null, IntPtr.Zero);
                    }
                }
 
                return _hwnd.Handle;
            } 
        } 

        /// 
        ///     Critical - can be used to spoof messages.
        ///
        [ SecurityCritical ]
        private IntPtr SubclassWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
        {
            IntPtr result = IntPtr.Zero ; 
 
            // Call the virtual first.
            result = WndProc(hwnd, msg, wParam, lParam, ref handled); 

            // Call the handlers for the MessageHook event.
            if(!handled && _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;
                    }
                }
            } 

            return result; 
        } 

        private DependencyPropertyChangedEventHandler _handlerEnabledChanged; 
        private DependencyPropertyChangedEventHandler _handlerVisibleChanged;
        private EventHandler _handlerLayoutUpdated;

        /// 
        ///     Critical - ctor was critical. Manipulating/Handing this out to PT would be unsafe.
        /// 
        [ SecurityCritical ] 
        private HwndSubclass _hwndSubclass;
 
        ///
        ///     Critical - ctor was critical. Manipulating/Handing this out to PT would be unsafe.
        ///
        [ SecurityCritical ] 
        private HwndWrapperHook _hwndSubclassHook;
 
        /// 
        ///     Critical - ctor was critical. Manipulating/Handing this out to PT would be unsafe.
        /// 
        [ SecurityCritical ]
        private HandleRef _hwnd;

        private ArrayList _hooks; 
        private Size _desiredSize;
 
        private SecurityCriticalDataForSet _fTrusted ; 

        private bool _isBuildingWindow = false; 

        private bool _isDisposed = false;

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

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

            private Dispatcher _that; 
        } 
        WeakEventDispatcherShutdown _weakEventDispatcherShutdown;
    } 
}

// 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