RootBrowserWindow.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / AppModel / RootBrowserWindow.cs / 3 / RootBrowserWindow.cs

                            //---------------------------------------------------------------------------- 
//
// File: RootBrowserWindow.cs
//
// Description: This class will implement the hosting and bridging logic 
//              between the browser and Avalon.  This will be the top
//              level "frame" that hosts all content in IE.  This class 
//              will not be public. 
//
// Created: 04/28/03 
//
// Copyright (C) 2001 by Microsoft Corporation.  All rights reserved.
//
//  History: 
//      hamidm  06/11/03    moved over to wcp tree
//--------------------------------------------------------------------------- 
using System; 
using System.Collections.Generic;
using System.ComponentModel; 
using System.Diagnostics;
using System.Printing;
using System.Runtime.InteropServices;
using System.Security; 
using System.Security.Permissions;
using System.Text; 
using System.Windows; 
using System.Windows.Automation.Peers;
using System.Windows.Controls; 
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media; 
using System.Windows.Navigation;
using MS.Internal.Commands; 
using MS.Internal.Controls; 
using MS.Win32;
using System.Drawing.Printing; 

//In order to avoid generating warnings about unknown message numbers and
//unknown pragmas when compiling your C# source code with the actual C# compiler,
//you need to disable warnings 1634 and 1691. (Presharp Documentation) 
#pragma warning disable 1634, 1691
 
 
namespace MS.Internal.AppModel
{ 

    /// 
    ///
    ///  
    internal sealed class RootBrowserWindow : NavigationWindow, IWindowService, IJournalNavigationScopeHost
    { 
        //---------------------------------------------- 
        //
        // Constructors 
        //
        //----------------------------------------------
        #region Constructors
 

        static RootBrowserWindow() 
        { 
            CommandHelpers.RegisterCommandHandler(typeof(RootBrowserWindow), ApplicationCommands.Print,
                    new ExecutedRoutedEventHandler(OnCommandPrint), new CanExecuteRoutedEventHandler(OnQueryEnabledCommandPrint)); 
        }

        /// 
        /// 
        /// 
        ///  
        ///     Critical:Calls base class constructor that is only present for RBW scenario 
        /// 
        [SecurityCritical] 
        private RootBrowserWindow():base(true)
        {
            // Allow tabbing out to the browser - see KeyInputSite and OnKeyDown().
            // IE 6 doesn't provide the necessary support. 
            // By checking for the negative top-level case, we allow to tab out of XBAPs hosted in an iframe;
            // this support is enabled regardless of the browser we're on (to avoid browser-specifics here). 
            if (!IsDownlevelPlatform || !BrowserInteropHelper.IsAvalonTopLevel) 
            {
                SetValue(KeyboardNavigation.TabNavigationProperty, KeyboardNavigationMode.Continue); 
                SetValue(KeyboardNavigation.ControlTabNavigationProperty, KeyboardNavigationMode.Continue);
            }
        }
        #endregion Constructors 

        //---------------------------------------------- 
        // 
        // Protected Methods
        // 
        //----------------------------------------------
        #region Protected Methods

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

        /// 
        ///     Critical - Hooks up the event handler that sets the status bar text (OnRequestSetStatusBar_Hyperlink). 
        ///     TreatAsSafe - Safe to set up the handler over here; OnRequestSetStatusBar_Hyperlink is connected to
        ///                   RequestSetStatusBarEvent which is supposed to be raised only by Hyperlink which has the 
        ///                   anti-spoofing mitigations in place. The RequestSetStatusBarEventArgs used in the event 
        ///                   is protected as well.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnInitialized(EventArgs args)
        {
            AddHandler(Hyperlink.RequestSetStatusBarEvent, new RoutedEventHandler(OnRequestSetStatusBar_Hyperlink)); 
            base.OnInitialized(args);
        } 
 
        protected override Size MeasureOverride(Size constraint)
        { 
            return base.MeasureOverride(GetSizeInLogicalUnits());
        }

        protected override Size ArrangeOverride(Size arrangeBounds) 
        {
            // Get the size of the avalon window and pass it to 
            // the base implementation. The return value tells the Size 
            // that we are occupying.  Since, we are RBW we will occupy the
            // entire available size and thus we don't care what our child wants. 
            base.ArrangeOverride(GetSizeInLogicalUnits());
            return arrangeBounds;
        }
 
        protected override void OnActivated(EventArgs e)
        { 
        } 

        protected override void OnDeactivated(EventArgs e) 
        {
        }

        protected override void OnStateChanged(EventArgs e) 
        {
        } 
 
        protected override void OnLocationChanged(EventArgs e)
        { 
        }

        protected override void OnClosing(CancelEventArgs e)
        { 
        }
 
        protected override void OnClosed(EventArgs e) 
        {
        } 

        ///
        /// Critical - calls the SUC'd IBCS.PostReadyStateChange().
        /// TreatAsSafe - Only READYSTATE_COMPLETE is posted, once, at the end of the activation sequence, 
        ///     when the browser expects it.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        protected override void OnContentRendered(EventArgs e)
        { 
            base.OnContentRendered(e);

            // Posting READYSTATE_COMPLETE triggers the WebOC's DocumentComplete event.
            // Media Center, in particular, uses this to make the WebOC it hosts visible. 
            if (!_loadingCompletePosted)
            { 
                Browser.PostReadyStateChange(READYSTATE_COMPLETE); 
                _loadingCompletePosted = true;
            } 
        }

        protected override void OnKeyDown(KeyEventArgs e)
        { 
            // In browser apps, Ctrl+Tab switches tabs. F6 simulates it here.
            if (e.Key == Key.F6 && (e.KeyboardDevice.Modifiers & ~ModifierKeys.Shift) == 0) 
            { 
                if (KeyboardNavigation.Navigate(
                        e.KeyboardDevice.FocusedElement as DependencyObject ?? this, 
                        Key.Tab, e.KeyboardDevice.Modifiers | ModifierKeys.Control))
                {
                    e.Handled = true;
                } 
            }
 
            if (!e.Handled) 
            {
                base.OnKeyDown(e); 
            }
        }

        #endregion Protected methods 

        //---------------------------------------------- 
        // 
        // Internal Methods
        // 
        //----------------------------------------------
        #region Internal Methods

        ///  
        ///     Creates the RBW object and sets the Style property on it
        ///     to the correct value 
        ///  
        /// 
        ///     Critical: Calls RBW class constructor 
        /// 
        [SecurityCritical]
        internal static RootBrowserWindow CreateAndInitialize()
        { 
            RootBrowserWindow rbw = new RootBrowserWindow();
            rbw.InitializeRBWStyle(); 
            return rbw; 
        }
 
        /// 
        /// Critical: This code elevates to all window permission
        /// 
        [SecurityCritical] 
        internal override void CreateAllStyle()
        { 
            Invariant.Assert(App != null, "RootBrowserWindow must be created in an Application"); 

            IHostService ihs = (IHostService)App.GetService(typeof(IHostService)); 

            Invariant.Assert(ihs!=null, "IHostService in RootBrowserWindow cannot be null");
            Invariant.Assert(ihs.HostWindowHandle != IntPtr.Zero, "IHostService.HostWindowHandle in RootBrowserWindow cannot be null");
 
            //This sets the _ownerHandle correctly and will be used to create the _sourceWindow
            //with the correct parent 
            UIPermission uip = new UIPermission(UIPermissionWindow.AllWindows); 
            uip.Assert();//Blessed Assert to set owner handle and to set styles
            try 
            {
                this.OwnerHandle = ihs.HostWindowHandle;
                this.Win32Style = NativeMethods.WS_CHILD | NativeMethods.WS_CLIPCHILDREN | NativeMethods.WS_CLIPSIBLINGS;
            } 
            finally
            { 
                CodeAccessPermission.RevertAssert(); 
            }
 
        }

        ///
        /// Critical: Exposes a window handle (ParentWindow). Base class implementation is also Critical. 
        ///
        [SecurityCritical] 
        internal override HwndSourceParameters CreateHwndSourceParameters() 
        {
            HwndSourceParameters parameters = base.CreateHwndSourceParameters(); 
            parameters.TreatAsInputRoot = true;
            return parameters;
        }
 
        /// 
        ///     Override for SourceWindow creation. 
        ///     Virtual only so that we may assert. 
        /// 
        ///  
        ///     Critical - Calls critical base-class function.
        ///                Calls critical functions GetAncestor and GetForegroundWindow.
        /// 
        [SecurityCritical] 
        internal override void CreateSourceWindowImpl()
        { 
            Browser.OnBeforeShowNavigationWindow(); 

            base.CreateSourceWindowImpl(); 
            Invariant.Assert(IsSourceWindowNull == false, "Failed to create HwndSourceWindow for browser hosting");

            // _sourceWindowCreationCompleted specifies that HwndSource creation has completed.  This is used
            // to minimize the SetWindowPos calls from ResizeMove when Height/Width is set prior to calling 
            // show on RBW (this also occurs when Height/Width is set in the style of RBW)
            _sourceWindowCreationCompleted = true; 
 
            if (_rectSet)
            { 
                _rectSet = false;
                ResizeMove(_xDeviceUnits, _yDeviceUnits, _widthDeviceUnits, _heightDeviceUnits);
            }
 
            SetUpInputHooks();
 
            // 
            // While the RBW is created and shown, the Top Browser window should have already been created and shown,
            // Browser doesn't notify this RBW of the activation status again unless user activates/deactivates the main 
            // window. It is time to transfer the Top Browser Window's activation status to this RBW so that user's
            // code can get correct status through property IsActivate.
            //
            IntPtr topWindow = UnsafeNativeMethods.GetAncestor(new HandleRef(this, CriticalHandle), 2/*GA_ROOT*/); 
            Debug.Assert(topWindow != IntPtr.Zero);
            IntPtr activeWindow = UnsafeNativeMethods.GetForegroundWindow(); 
            HandleActivate(activeWindow == topWindow); 
        }
 
        // No need to clear App.MainWindow for RBW case.  It throws an exception if attempted
        internal override void TryClearingMainWindow()
        {
        } 

        internal override void CorrectStyleForBorderlessWindowCase() 
        { 
        }
 
        internal override void GetRequestedDimensions(ref double requestedLeft, ref double requestedTop, ref double requestedWidth, ref double requestedHeight)
        {
            requestedTop = 0;
            requestedLeft = 0; 
            requestedWidth = this.Width;
            requestedHeight = this.Height; 
        } 

        /// 
        ///     Critical - It also calls critical method (SetRootVisual)
        ///
        [SecurityCritical]
        internal override void SetupInitialState(double requestedTop, double requestedLeft, double requestedWidth, double requestedHeight) 
        {
            // If RBW Height/Width was set before calling show in RBW, we need 
            // to update the browser with that size now 
            SetBrowserSize();
            SetRootVisual(); 
        }

        internal override int nCmdForShow()
        { 
            return NativeMethods.SW_SHOW;
        } 
 
        internal override bool HandleWmNcHitTestMsg(IntPtr lParam, ref IntPtr refInt)
        { 
            return false;
        }

        internal override WindowMinMax GetWindowMinMax() 
        {
            return new WindowMinMax(0, double.PositiveInfinity); 
        } 

        // RBW overrides WmMoveChangedHelper default behavior where it calls 
        // either SetValue/CoerceValue on Top/Left DPs since that will
        // throw an exception for RBW.  Furthermore, in RBW, we don't want
        // to fire LocationChanged event.
        internal override void WmMoveChangedHelper() 
        {
        } 
 
        /// 
        ///     Resizes and moves the RBW (which is a WS_CHILD window).  This is called by 
        ///     AppProxyInternal when the host callsbacks into it with the new size/location.
        ///     We need this internal since Height/Width/Top/Left on RBW govern the host'ss
        ///     properties.
        ///  
        /// 
        ///     The location of WS_CHILD window is relative to it parent window thus when the 
        ///     browser moves it does not call this method since the relative position of this window 
        ///     wrt the browser hasn't changed.
        ///  
        /// New left of the RBW
        /// New top of the RBW
        /// New width of the RBW
        /// New height of the RBW 
        ///
        ///     Critical as this method handles critical data. 
        ///     TreatAsSafe - as the RBW is always contained within the browser's window. 
        ///                          you can move the internal window all you want - but given that you're really
        ///                          contained within the BrowserWindow - the worse you could do is make some of your content not visible. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        internal void ResizeMove(int xDeviceUnits, int yDeviceUnits, int widthDeviceUnits, int heightDeviceUnits)
        { 
            // _sourceWindowCreationCompleted specifies that HwndSource creation has completed.  This is used
            // to minimize the SetWindowPos calls from ResizeMove when Height/Width is set prior to calling 
            // show on RBW (this also occurs when Height/Width is set in the style of RBW).  Thus, we want to 
            // resize the underlying avalon hwnd only after its creation is completed
            if (_sourceWindowCreationCompleted == false) 
            {
                _xDeviceUnits = xDeviceUnits;
                _yDeviceUnits = yDeviceUnits;
                _widthDeviceUnits = widthDeviceUnits; 
                _heightDeviceUnits = heightDeviceUnits;
 
                _rectSet = true; 

                return; 
            }

            Invariant.Assert(IsSourceWindowNull == false, "sourceWindow cannot be null if _sourceWindowCreationCompleted is true");
 
            HandleRef handleRef;
            handleRef = new HandleRef( this, CriticalHandle ) ; 
 
            UnsafeNativeMethods.SetWindowPos( handleRef ,
                           NativeMethods.NullHandleRef, 
                           xDeviceUnits,
                           yDeviceUnits,
                           widthDeviceUnits,
                           heightDeviceUnits, 
                           NativeMethods.SWP_NOZORDER
                           | NativeMethods.SWP_NOACTIVATE 
                           | NativeMethods.SWP_SHOWWINDOW); 
        }
 
        /// 
        ///     This is called when the Title dependency property changes in the Window.
        /// 
        /// 
        /// Critical - calls SUC'd IBCS.SetTitle
        /// TreatAsSafe - setting the text on the browser's window is considered safe. 
        ///                 - spoofing is not possible as the browser prepends it's own string to the string 
        ///                      e.g. Microsoft Internet Explorer
        ///                 - it can be done in partial trust in HTML via the TITLE tag. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void UpdateTitle(string titleStr)
        { 
            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null) // null on shutdown 
            { 
                string title = PruneTitleString(titleStr);
 
                // SHOULD NOT CALL BASE; BASE IMPLEMENTS TEXT PROPERTY ON WINDOW
                ibcs.SetTitle(title);

            } 
        }
 
        ///  
        ///     This is called by NavigationService to set the status bar content
        ///     for the browser 
        /// 
        /// 
        ///     We propagate object.ToString() to the browser's status bar.
        ///  
        ///
        ///     Critical - calls SetStatusText which is SUC'ed. 
        /// 
        ///     No longer considered TreatAsSafe in order to protect against hyperlink spoofing.
        ///     Browsers implement access restriction to the status bar from script nowadays. 
        ///
        [SecurityCritical]
        internal void SetStatusBarText(string statusString)
        { 
            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null) // could be null if shutting down 
            { 
                ibcs.SetStatusText(statusString);
            } 
        }

        /// 
        ///     Called to update Height of the browser.  Currently, this method is called from 
        ///     two places:
        /// 
        ///     1) OnHeightInvalidated from window.cs 
        ///     2) SetBrowserSize in RBW
        ///  
        ///
        ///     Critical - Can be used to change the size of the browser
        ///     TreatAsSafe - clamps values so that window cannot be sized greater than desktop bounds.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void UpdateHeight(double newHeightLogicalUnits) 
        { 
            Point sizeDeviceUnits = LogicalToDeviceUnits(new Point(0, newHeightLogicalUnits));
            int heightDeviceUnits = (int)Math.Round(sizeDeviceUnits.Y); 

            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null)
            { 
                //
                // Note: right now IE is clipping browser height to desktop size. 
                // However it should be clipped to available desktop size. See Windows OS Bug #1045038 
                // The code below is to fix this for now.
                // Even if IE's code is changed - likely we keep this as defense in-depth. 
                //

                int maxHeightDeviceUnits = GetMaxWindowHeight();
                heightDeviceUnits = heightDeviceUnits > maxHeightDeviceUnits ? maxHeightDeviceUnits : heightDeviceUnits; 
                heightDeviceUnits = heightDeviceUnits < MIN_BROWSER_HEIGHT_DEVICE_UNITS ? MIN_BROWSER_HEIGHT_DEVICE_UNITS : heightDeviceUnits;
                ibcs.SetHeight(heightDeviceUnits); 
            } 
        }
 
        ///
        ///     Critical - Can be used to change the size of the browser
        ///     TreatAsSafe - clamps values so that window cannot be sized greater than desktop bounds.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void UpdateWidth(double newWidthLogicalUnits) 
        { 
            Point sizeDeviceUnits = LogicalToDeviceUnits(new Point(newWidthLogicalUnits, 0));
            int widthDeviceUnits  = (int)Math.Round(sizeDeviceUnits.X); 

            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null)
            { 
                //
                // Note: right now IE is clipping browser width to desktop size. 
                // However it should be clipped to available desktop size. See Windows OS Bug #1045038 
                // The code below is to fix this for now.
                // Even if IE's code is changed - likely we keep this as defense in-depth. 
                //
                int maxWidthDeviceUnits = GetMaxWindowWidth();
                widthDeviceUnits = widthDeviceUnits > maxWidthDeviceUnits ? maxWidthDeviceUnits : widthDeviceUnits;
 
                widthDeviceUnits = widthDeviceUnits < MIN_BROWSER_WIDTH_DEVICE_UNITS ? MIN_BROWSER_WIDTH_DEVICE_UNITS : widthDeviceUnits;
                ibcs.SetWidth(widthDeviceUnits); 
            } 
        }
 
        /// 
        /// When being reloaded from history in the browser, we need to
        /// set up the journal again
        ///  
        /// 
        internal void SetJournalForBrowserInterop(Journal journal) 
        { 
            Invariant.Assert(journal != null, "Failed to get Journal for browser integration");
            base.JournalNavigationScope.Journal = journal; 
        }

        void IJournalNavigationScopeHost.OnJournalAvailable()
        { 
            base.Journal.BackForwardStateChange += new EventHandler(HandleBackForwardStateChange);
        } 
 
        // For downlevel platforms, we don't have integration with the journal, so we have to
        // use our own Journal. 
        ///
        ///     Critical - calls IBCS.GoBack
        ///
        [SecurityCritical] 
        bool IJournalNavigationScopeHost.GoBackOverride()
        { 
            if (HasTravelLogIntegration) 
            {
                IBrowserCallbackServices ibcs = Browser; 
                if (ibcs != null)
                {
                    try
                    { 
                        ibcs.GoBack();
                    } 
#pragma warning disable 6502 // PRESharp - Catch statements should not have empty bodies 
                    catch (OperationCanceledException)
                    { 
                        // Catch the OperationCanceledException when the navigation is canceled.
                        // See comments in applicationproxyinternal._LoadHistoryStreamDelegate.
                    }
#pragma warning restore 6502 
                }
                return true; 
            } 
            return false; // Proceed with internal GoBack.
        } 

        // For downlevel platforms, we don't have integration with the journal, so we have to
        // use our own Journal.
        /// 
        ///     Critical - calls IBCS.GoForward
        /// 
        [SecurityCritical] 
        bool IJournalNavigationScopeHost.GoForwardOverride()
        { 
            if (HasTravelLogIntegration)
            {
                IBrowserCallbackServices ibcs = Browser;
                if (ibcs != null) 
                {
                    try 
                    { 
                        ibcs.GoForward();
                    } 
#pragma warning disable 6502 // PRESharp - Catch statements should not have empty bodies
                    catch (OperationCanceledException)
                    {
                        // Catch the OperationCanceledException when the navigation is canceled. 
                        // See comments in applicationproxyinternal._LoadHistoryStreamDelegate.
                    } 
#pragma warning restore 6502 
                }
                return true; 
            }
            return false; // Proceed with internal GoForward.
        }
 
        internal override void VerifyApiSupported()
        { 
            throw new InvalidOperationException(SR.Get(SRID.NotSupportedInBrowser)); 
        }
 
        internal override void ClearResizeGripControl(Control oldCtrl)
        {
            // don't do anything here since we do not support
            // ResizeGrip for RBW 
        }
 
        internal override void SetResizeGripControl(Control ctrl) 
        {
            // don't do anything here since we do not support 
            // ResizeGrip for RBW
        }

        // This is called in weboc's static constructor. 
        internal void AddLayoutUpdatedHandler()
        { 
            LayoutUpdated += new EventHandler(OnLayoutUpdated); 
        }
 
        internal void TabInto(bool forward)
        {
            TraversalRequest tr = new TraversalRequest(
                forward ? FocusNavigationDirection.First : FocusNavigationDirection.Last); 
            MoveFocus(tr);
        } 
 
        #endregion Internal Methods
 
        //----------------------------------------------
        //
        // Private Methods
        // 
        //----------------------------------------------
        #region Private methods 
        ///  
        ///     Sets the correct style property on the RBW object based on the
        ///     browser version 
        /// 
        private void InitializeRBWStyle()
        {
            // If we are on a downlevel platform, then we don't integrate with the browser's 
            // travellog, so we have to use our own Journal and supply our own navigation chrome.
            if (!HasTravelLogIntegration) 
            { 
                SetResourceReference(StyleProperty, SystemParameters.NavigationChromeDownLevelStyleKey);
 
                // if the Template property is not defined in a custom style, the property system gets
                // the Template property value for the NavigationWindow from the theme file.  Since,
                // we want to get the Template property value from the browser styles, we need to
                // set the DefaultStyleKeyProperty here. 
                SetValue(DefaultStyleKeyProperty, SystemParameters.NavigationChromeDownLevelStyleKey);
            } 
            else 
            {
                SetResourceReference(StyleProperty, SystemParameters.NavigationChromeStyleKey); 

                // if the Template property is not defined in a custom style, the property system gets
                // the Template property value for the NavigationWindow from the theme file.  Since,
                // we want to get the Template property value from the browser styles, we need to 
                // set the DefaultStyleKeyProperty here.
                SetValue(DefaultStyleKeyProperty, SystemParameters.NavigationChromeStyleKey); 
            } 
        }
 
        /// 
        ///     Critical - Elevates to get access to the HwndSource and installs hooks.
        ///     TreatAsSafe - The HwndSoure is not exposed. The message hooks installed are internal ones, and they are for the RBW specifically.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void SetUpInputHooks() 
        { 
            IKeyboardInputSink sink;
            new UIPermission(PermissionState.Unrestricted).Assert(); //BlessedAssert 
            try
            {
                _inputPostFilter = new HwndWrapperHook(BrowserInteropHelper.PostFilterInput);
                HwndSource hwndSource = base.HwndSourceWindow; 
                hwndSource.HwndWrapper.AddHookLast(_inputPostFilter);
 
                sink = (IKeyboardInputSink)hwndSource; 
            }
            finally 
            {
                UIPermission.RevertAll();
            }
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); //BlessedAssert 
            try
            { 
                Debug.Assert(sink.KeyboardInputSite == null); 
                sink.KeyboardInputSite = new KeyInputSite(new SecurityCriticalData(sink));
            } 
            finally
            {
                SecurityPermission.RevertAll();
            } 
        }
 
        ///  
        ///     Updates browser size if Height/Width is not set to default value (NaN).  This
        ///     means that Height/Width was set prior to calling Show on RBW and we need to 
        ///     propagate that to the browser.  This method is called from SetupInitialize which
        ///     is called from CreateSourceWindowImpl
        /// 
        private void SetBrowserSize() 
        {
            Point requestedSizeDeviceUnits = LogicalToDeviceUnits(new Point(this.Width, this.Height)); 
 
            // if Width was specified
            if (!DoubleUtil.IsNaN(this.Width)) 
            {
                // at this stage, ActualWidth/Height is not set since
                // layout has not happened (it happens when we set the
                // RootVisual of the HwndSource) 
                UpdateWidth(requestedSizeDeviceUnits.X);
            } 
 
            // if Height was specified
            if (!DoubleUtil.IsNaN(this.Height)) 
            {
                // at this stage, ActualWidth/Height is not set since
                // layout has not happened (it happens when we set the
                // RootVisual of the HwndSource) 
                UpdateHeight(requestedSizeDeviceUnits.Y);
            } 
        } 

        private string PruneTitleString(string rawString) 
        {
            StringBuilder sb = new StringBuilder();
            bool inMiddleOfWord = false;
 
            for (int i=0; i < rawString.Length; i++)
            { 
                if (Char.IsWhiteSpace(rawString[i]) == false) 
                {
                    sb.Append(rawString[i]); 
                    inMiddleOfWord = true;
                }
                else
                { 
                    if (inMiddleOfWord == true)
                    { 
                        sb.Append(' '); 
                        inMiddleOfWord = false;
                    } 
                }
            }

            // remove the last space if it exists 
            return sb.ToString().TrimEnd(' ');
        } 
 
        private void OnLayoutUpdated(object obj, EventArgs args)
        { 
            try
            {
                VerifyWebOCOverlap(NavigationService);
            } 
            finally
            { 
                _webBrowserList.Clear(); 
            }
        } 

        private void VerifyWebOCOverlap(NavigationService navigationService)
        {
            for (int i = 0; i < navigationService.ChildNavigationServices.Count; i++) 
            {
                NavigationService childNavService = (NavigationService)(navigationService.ChildNavigationServices[i]); 
                WebBrowser webBrowser = childNavService.WebBrowser; 
                if (webBrowser != null)
                { 
                    for (int j = 0; j < _webBrowserList.Count; j++)
                    {
                        // Note: We are using WebBrowser.BoundRect, which is relative to parent window.
                        // Since WebBrowsers are all siblings child windows right now, e.g., we don't allow WebOC inside 
                        // Popup window, this is a better performed way. If we change that, we should make sure the rects
                        // to compare are relative to desktop. 
                        Rect rect = Rect.Intersect(webBrowser.BoundRect, _webBrowserList[j].BoundRect); 
                        // Only when the intersect rect's Width and Height are both bigger than 0, we consider them overlapping.
                        // Even when 2 edges are next to each other, it is considered as intersect by the Rect class. 
                        if ((rect.Width > 0) && (rect.Height > 0))
                        {
                            throw new InvalidOperationException(SR.Get(SRID.WebBrowserOverlap));
                        } 
                    }
                    _webBrowserList.Add(webBrowser); 
                } 
                else
                { 
                    VerifyWebOCOverlap(childNavService);
                }
            }
        } 

        ///  
        /// We are not using the CanGoBack/CanGoForward property change since that is fired only 
        /// if the value changes eg. if we had 3 entries in the backstack, then a back navigation
        /// won't fire this since the value is still 'true' and has not changed. 
        /// What we need is the UpdateView() notification or the BackForwardState change
        /// notification which is fired from UpdateView() of the Journal.
        /// Trying to hook the event will create the journal even if there was no navigation
        /// so just using an virtual override to do the work. 
        /// 
        /// 
        ///     Critical - as this method calls into Browser call back method for back and forward. 
        ///                This is a pinoke call.
        ///     TreatAsSafe - as this is a safe operation. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        private void HandleBackForwardStateChange(object sender, EventArgs args)
        { 
            //Nothing to do for downlevel platform
            if (!HasTravelLogIntegration) 
                return; 

            IBrowserCallbackServices ibcs = Browser; 
            if (ibcs != null)
            {
                ibcs.UpdateBackForwardState();
            } 
        }
 
 
        ///
        /// Given a proposed width - and curWidth - return the MaxWidth the window can be opened to. 
        /// Used to prevent sizing of window > desktop bounds in browser.
        ///
        ///
        /// Critical - calls back to browser to get the current left. 
        /// TreatAsSafe - this value isn't returned or stored.
        ///               value returned is the current maximum width allowed considered safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe ]
        private int GetMaxWindowWidth() 
        {
            NativeMethods.RECT desktopArea = WorkAreaBoundsForNearestMonitor;
            int browserLeft = 0;
            int curBrowserWidth = 0; 
            IBrowserCallbackServices ibcs = Browser;
 
            bool successful = false ; 

            successful = (ibcs != null) && ibcs.GetLeft(ref browserLeft ); 

            if ( ! successful )
            {
                browserLeft = 0; 
            }
 
            successful = (ibcs != null) && ibcs.GetWidth(ref curBrowserWidth); 

            if (! successful) 
            {
                curBrowserWidth = 0;
            }
 
            int availableWidth = desktopArea.right - browserLeft;
            int maxWidth = availableWidth > curBrowserWidth ? availableWidth : curBrowserWidth; 
 
            return maxWidth;
        } 

        ///
        /// Given a proposed height - and curHeight - return the MaxHeight the window can be opened to.
        /// Used to prevent sizing of window > desktop bounds in browser. 
        ///
        /// 
        /// Critical - calls back to browser to get the current top. 
        /// TreatAsSafe - this value isn't returned or stored.
        ///               value returned is the current maximum height allowed considered safe. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ]
        private int GetMaxWindowHeight()
        { 
            NativeMethods.RECT desktopArea = WorkAreaBoundsForNearestMonitor;
            int browserTop = 0; 
            int curBrowserHeight = 0; 
            IBrowserCallbackServices ibcs = Browser;
            bool successful = false ; 

            successful = (ibcs != null) && ibcs.GetTop(ref browserTop );

            if ( ! successful ) 
            {
                browserTop = 0; 
            } 

            successful = (ibcs != null) && ibcs.GetHeight(ref curBrowserHeight); 

            if ( ! successful )
            {
                curBrowserHeight = 0; 
            }
 
            int availableHeight =  desktopArea.bottom - browserTop ; 
            int maxHeight = availableHeight > curBrowserHeight ? availableHeight : curBrowserHeight;
 
            return maxHeight;
        }

 
        ///
        ///For browser hosting cases, we get the rects through OLE activation before we create the 
        ///RootBrowserWindow. Even if SourceWindow or Handle are null, we can return the cached rects 
        ///
        private Size GetSizeInLogicalUnits() 
        {
            Size size;

            // Adding check for IsCompositionTargetInvalid as part of the fix for WOSB 1453012 
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            { 
                // return _widthDeviceUnits & _heightDeviceUnits if hwndsource is not yet available. 
                // We will resize when hwnd becomes available, because the DeviceToLogicalUnits calculation
                // depends on hwnd being available. If it's not high dpi, the second resize will be optimized 
                // by layout system.
                size = new Size(_widthDeviceUnits, _heightDeviceUnits);
            }
            else 
            {
                // It's better to get WindowSize instead of doing WindowSize.Width & WindowSize.Height 
                // because WindowSize queries HwndSource. 
                size = WindowSize;
                Point ptLogicalUnits = DeviceToLogicalUnits(new Point(size.Width, size.Height)); 
                size = new Size(ptLogicalUnits.X, ptLogicalUnits.Y);
            }

            return size; 
        }
 
        ///  
        ///     Critical - Sets the status bar text. Can be used to do URL spoofing.
        ///  
        [SecurityCritical]
        private void OnRequestSetStatusBar_Hyperlink(object sender, RoutedEventArgs e)
        {
            RequestSetStatusBarEventArgs statusEvent = e as RequestSetStatusBarEventArgs; 

            if ( statusEvent != null ) 
            { 
                SetStatusBarText(statusEvent.Text);
            } 
        }

        ///
        /// Prints the content of the App's MainWindow.  The logic is that if the content is not visual but IInputElement 
        /// we will try to let it handle the command first. If it does not handle the print command we will get the corresponding
        /// visual in the visual tree and use that to print. 
        /// 
        private static void OnCommandPrint(object sender, ExecutedRoutedEventArgs e)
        { 
#if !DONOTREFPRINTINGASMMETA
            RootBrowserWindow rbw = sender as RootBrowserWindow;
            Invariant.Assert(rbw != null);
 
            if (! rbw._isPrintingFromRBW)
            { 
                Visual vis = rbw.Content as Visual; 

                if (vis == null) 
                {
                    // If the content is not Visual but IInputElement, try to let it handle the command first.
                    // This is for the document scenario. Printing a document is different from printing a visual.
                    // Printing a visual is to print how it is rendered on screen. Printing a doc prints the full 
                    // doc inculding the part that is not visible. There might be other functionalities that are
                    // specific for document. FlowDocument's viewer knows how to print the doc. 
                    IInputElement target = rbw.Content as IInputElement; 

                    if (target != null) 
                    {
                        // CanExecute will bubble up. If nobody between the content and rbw can handle it,
                        // It would call back on RBW again. Use _isPrintingFromRBW to prevent the loop.
                        rbw._isPrintingFromRBW = true; 
                        try
                        { 
                            if (ApplicationCommands.Print.CanExecute(null, target)) 
                            {
                                ApplicationCommands.Print.Execute(null, target); 
                                return;
                            }
                        }
                        finally 
                        {
                            rbw._isPrintingFromRBW = false; 
                        } 
                    }
                } 

                // Let the user choose a printer and set print options.
                PrintDialog printDlg = new PrintDialog();
 
                // If the user pressed the OK button on the print dialog, we proceed
                if (printDlg.ShowDialog() == true) 
                { 
                    string printJobDescription = GetPrintJobDescription(App.MainWindow);
 
                    // If the root is not visual and does not know how to print itself, we find the
                    // corresponding visual and use that to print.
                    if (vis == null)
                    { 
                        INavigatorImpl navigator = rbw as INavigatorImpl;
                        Invariant.Assert(navigator != null); 
 
                        vis = navigator.FindRootViewer();
                        Invariant.Assert(vis != null); 
                    }

                    // Area we can print to for the chosen printer
                    Rect imageableRect = GetImageableRect(printDlg); 

                    // We print Visuals aligned with the top/left corner of the printable area. 
                    // We do not attempt to print very large Visuals across multiple pages. 
                    // Any portion that doesn't fit on a single page will get cropped by the
                    // print system. 

                    // Used to draw our visual into another visual for printing purposes
                    VisualBrush visualBrush = new VisualBrush(vis);
                    visualBrush.Stretch = Stretch.None; 

                    // Visual we will print - containing a rectangle the size of our 
                    // original Visual but offset into the printable area 
                    DrawingVisual drawingVisual = new DrawingVisual();
                    DrawingContext context = drawingVisual.RenderOpen(); 
                    context.DrawRectangle(visualBrush,
                                          null,
                                          new Rect(imageableRect.X,
                                                   imageableRect.Y, 
                                                   vis.VisualDescendantBounds.Width,
                                                   vis.VisualDescendantBounds.Height)); 
                    context.Close(); 

                    printDlg.PrintVisual(drawingVisual, printJobDescription); 
                }
            }
#endif // DONOTREFPRINTINGASMMETA
        } 

        private static void OnQueryEnabledCommandPrint(object sender, CanExecuteRoutedEventArgs  e) 
        { 
            RootBrowserWindow rbw = sender as RootBrowserWindow;
            Invariant.Assert(rbw != null); 

            if ((!e.Handled) && (!rbw._isPrintingFromRBW))
            {
                // While we could print null it doesn't really make sense to do so 
                e.CanExecute = rbw.Content != null;
            } 
        } 

        /// 
        /// Critical - calls out to PrintDialog to get the PrintQueue and its PrintCapabilities
        /// TreatAsSafe - these values aren't returned or stored
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        private static Rect GetImageableRect(PrintDialog dialog)
        { 
            Invariant.Assert(dialog != null, "Dialog should not be null."); 

            PrintQueue queue = null; 
            PrintCapabilities capabilities = null;
            PageImageableArea imageableArea = null;
            Rect imageableRect = Rect.Empty;
 
            // This gets the PringDocumentImageableArea.OriginWidth/OriginHeight
            // of the PrintQueue the user chose in the dialog. 
            CodeAccessPermission printp = new System.Drawing.Printing.PrintingPermission(PrintingPermissionLevel.DefaultPrinting); 
            printp.Assert();//Blessed Assert to get PrintQueue and call GetPrintCapabilities
            try 
            {
                queue = dialog.PrintQueue;
                if (queue != null)
                { 
                    capabilities = queue.GetPrintCapabilities();
                } 
            } 
            finally
            { 
                CodeAccessPermission.RevertAssert();
            }

            if (capabilities != null) 
            {
                imageableArea = capabilities.PageImageableArea; 
                if (imageableArea != null) 
                {
                    imageableRect = new Rect(imageableArea.OriginWidth, 
                                             imageableArea.OriginHeight,
                                             imageableArea.ExtentWidth,
                                             imageableArea.ExtentHeight);
                } 
            }
 
            // If for any reason we couldn't get the actual printer's values 
            // we fallback to a constant and the values available from the
            // PrintDialog. 
            if (imageableRect == Rect.Empty)
            {
                imageableRect = new Rect(NON_PRINTABLE_MARGIN,
                    NON_PRINTABLE_MARGIN, 
                    dialog.PrintableAreaWidth,
                    dialog.PrintableAreaHeight); 
            } 

            return imageableRect; 
        }

        /// 
        ///    Generate the title of the print job for a given Window. 
        /// 
        private static string GetPrintJobDescription(Window window) 
        { 
            Invariant.Assert(window != null, "Window should not be null.");
 
            string description = null;
            string pageTitle = null;

            // Get the window title 
            string windowTitle = window.Title;
            if (windowTitle != null) 
            { 
                windowTitle = windowTitle.Trim();
            } 

            // Get the page title, if available
            Page page = window.Content as Page;
            if (page != null) 
            {
                pageTitle = page.Title; 
                if (pageTitle != null) 
                {
                    pageTitle = pageTitle.Trim(); 
                }
            }

            // If window and page title are available, use them together, 
            // otherwise use which ever is available
            if (!String.IsNullOrEmpty(windowTitle)) 
            { 
                if (!String.IsNullOrEmpty(pageTitle))
                { 
                    description = SR.Get(SRID.PrintJobDescription, windowTitle, pageTitle);
                }
                else
                { 
                    description = windowTitle;
                } 
            } 

            // No window title so use the page title on its own 
            if (description == null && !String.IsNullOrEmpty(pageTitle))
            {
                description = pageTitle;
            } 

            // If neither window or page titles are available, try and use 
            // the source URI for the content 
            if (description == null && BrowserInteropHelper.Source != null)
            { 
                Uri source = BrowserInteropHelper.Source;
                if (source.IsFile)
                {
                    description = source.LocalPath; 
                }
                else 
                { 
                    description = source.ToString();
                } 
            }

            // If no other option, use a localized constant
            if (description == null) 
            {
                description = SR.Get(SRID.UntitledPrintJobDescription); 
            } 

            return description; 
        }


        #endregion Private methods 

        //---------------------------------------------- 
        // 
        // Private Properties
        // 
        //----------------------------------------------
        #region Private properties
        private static Application App
        { 
            get { return Application.Current; }
        } 
 

        private static IBrowserCallbackServices Browser 
        {
            get
            {
                // There will be no IBrowserCallbackServices available in some situations, e.g., during shutdown 
                IBrowserCallbackServices ibcs = (App == null ? null : App.BrowserCallbackServices);
                return ibcs; 
            } 
        }
 
        ///
        /// Critical - calls the SUC'd IBCS.IsDownlevelPlatform.
        /// TreatAsSafe - this information is okay to give out.
        /// 
        private bool IsDownlevelPlatform
        { 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (!_isDownlevelPlatformValid)
                {
                    IBrowserCallbackServices ibcs = Browser;
                    _isDownlevelPlatform = (ibcs != null) ? ibcs.IsDownlevelPlatform() : false; 

                    _isDownlevelPlatformValid = true; 
                } 
                return _isDownlevelPlatform;
            } 
        }

        internal bool HasTravelLogIntegration
        { 
            get
            { 
                return !IsDownlevelPlatform && BrowserInteropHelper.IsAvalonTopLevel; 
            }
        } 

        #endregion Private properties

        //---------------------------------------------- 
        //
        // Private Classes 
        // 
        //----------------------------------------------
        #region Private Classes 

        /// 
        /// This class is used to print objects which are not directly supported by XpsDocumentWriter.
        /// It's sole purpose is to make a non-abstract version of Visual. 
        /// 
        private class PrintVisual : ContainerVisual { } 
 

        private class KeyInputSite : IKeyboardInputSite 
        {
            internal KeyInputSite(SecurityCriticalData sink)
            {
                _sink = sink; 
            }
 
            ///  
            /// Critical: sets critical data.
            /// Safe: setting to null is okay. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            void IKeyboardInputSite.Unregister()
            { 
                _sink = new SecurityCriticalData(null);
            } 
 
            /// 
            /// Critical: IKeyboardInputSink could be used to spoof input. 
            /// 
            IKeyboardInputSink IKeyboardInputSite.Sink
            {
                [SecurityCritical] 
                get { return _sink.Value; }
            } 
 
            /// 
            /// Critical: calls the SUC'd IBCS.TabOut(). 
            /// Safe: tabbing out of the application is safe.
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            bool IKeyboardInputSite.OnNoMoreTabStops(TraversalRequest request) 
            {
                return Browser.TabOut(request.FocusNavigationDirection == FocusNavigationDirection.Next); 
                // i. Tabbing-in is handled by ApplicationProxyInternal. 
            }
 
            /// 
            /// Critical: The encapsulated interface could be used to spoof input.
            /// 
            SecurityCriticalData _sink; 
        };
 
        #endregion Private Classes 

 
        //----------------------------------------------
        //
        // Private Members
        // 
        //----------------------------------------------
        #region private members 
 
        //Cache the values until the HwndSourceWindow is created
        private int  _xDeviceUnits, _yDeviceUnits, _widthDeviceUnits, _heightDeviceUnits; 
        private bool _rectSet;

        private bool _isPrintingFromRBW;
        private bool _isDownlevelPlatformValid; 
        private bool _isDownlevelPlatform;
        private bool _sourceWindowCreationCompleted; 
 
        private List _webBrowserList = new List();
 
        /// 
        /// The event delegate has to be stored because HwndWrapper keeps only a weak reference to it.
        /// 
        ///  
        /// Critical: could be used to spoof input
        ///  
        [SecurityCritical] 
        private HwndWrapperHook _inputPostFilter;
 
        private bool _loadingCompletePosted;
        const int READYSTATE_COMPLETE = 4;

        // Fallback constant for the size of non-printable margin.  This is used if 
        // we cant retrieve the actual size from the PrintQueue.
        private const int NON_PRINTABLE_MARGIN = 15; 
 
        //
        // Setting these as the min-browser width & height. 
        // Note that we can't use User's min window-width & height - these are specifically about browser window.
        //
        private const int MIN_BROWSER_WIDTH_DEVICE_UNITS = 200;
 
        private const int MIN_BROWSER_HEIGHT_DEVICE_UNITS = 200;
        #endregion private members 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// File: RootBrowserWindow.cs
//
// Description: This class will implement the hosting and bridging logic 
//              between the browser and Avalon.  This will be the top
//              level "frame" that hosts all content in IE.  This class 
//              will not be public. 
//
// Created: 04/28/03 
//
// Copyright (C) 2001 by Microsoft Corporation.  All rights reserved.
//
//  History: 
//      hamidm  06/11/03    moved over to wcp tree
//--------------------------------------------------------------------------- 
using System; 
using System.Collections.Generic;
using System.ComponentModel; 
using System.Diagnostics;
using System.Printing;
using System.Runtime.InteropServices;
using System.Security; 
using System.Security.Permissions;
using System.Text; 
using System.Windows; 
using System.Windows.Automation.Peers;
using System.Windows.Controls; 
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media; 
using System.Windows.Navigation;
using MS.Internal.Commands; 
using MS.Internal.Controls; 
using MS.Win32;
using System.Drawing.Printing; 

//In order to avoid generating warnings about unknown message numbers and
//unknown pragmas when compiling your C# source code with the actual C# compiler,
//you need to disable warnings 1634 and 1691. (Presharp Documentation) 
#pragma warning disable 1634, 1691
 
 
namespace MS.Internal.AppModel
{ 

    /// 
    ///
    ///  
    internal sealed class RootBrowserWindow : NavigationWindow, IWindowService, IJournalNavigationScopeHost
    { 
        //---------------------------------------------- 
        //
        // Constructors 
        //
        //----------------------------------------------
        #region Constructors
 

        static RootBrowserWindow() 
        { 
            CommandHelpers.RegisterCommandHandler(typeof(RootBrowserWindow), ApplicationCommands.Print,
                    new ExecutedRoutedEventHandler(OnCommandPrint), new CanExecuteRoutedEventHandler(OnQueryEnabledCommandPrint)); 
        }

        /// 
        /// 
        /// 
        ///  
        ///     Critical:Calls base class constructor that is only present for RBW scenario 
        /// 
        [SecurityCritical] 
        private RootBrowserWindow():base(true)
        {
            // Allow tabbing out to the browser - see KeyInputSite and OnKeyDown().
            // IE 6 doesn't provide the necessary support. 
            // By checking for the negative top-level case, we allow to tab out of XBAPs hosted in an iframe;
            // this support is enabled regardless of the browser we're on (to avoid browser-specifics here). 
            if (!IsDownlevelPlatform || !BrowserInteropHelper.IsAvalonTopLevel) 
            {
                SetValue(KeyboardNavigation.TabNavigationProperty, KeyboardNavigationMode.Continue); 
                SetValue(KeyboardNavigation.ControlTabNavigationProperty, KeyboardNavigationMode.Continue);
            }
        }
        #endregion Constructors 

        //---------------------------------------------- 
        // 
        // Protected Methods
        // 
        //----------------------------------------------
        #region Protected Methods

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

        /// 
        ///     Critical - Hooks up the event handler that sets the status bar text (OnRequestSetStatusBar_Hyperlink). 
        ///     TreatAsSafe - Safe to set up the handler over here; OnRequestSetStatusBar_Hyperlink is connected to
        ///                   RequestSetStatusBarEvent which is supposed to be raised only by Hyperlink which has the 
        ///                   anti-spoofing mitigations in place. The RequestSetStatusBarEventArgs used in the event 
        ///                   is protected as well.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        protected override void OnInitialized(EventArgs args)
        {
            AddHandler(Hyperlink.RequestSetStatusBarEvent, new RoutedEventHandler(OnRequestSetStatusBar_Hyperlink)); 
            base.OnInitialized(args);
        } 
 
        protected override Size MeasureOverride(Size constraint)
        { 
            return base.MeasureOverride(GetSizeInLogicalUnits());
        }

        protected override Size ArrangeOverride(Size arrangeBounds) 
        {
            // Get the size of the avalon window and pass it to 
            // the base implementation. The return value tells the Size 
            // that we are occupying.  Since, we are RBW we will occupy the
            // entire available size and thus we don't care what our child wants. 
            base.ArrangeOverride(GetSizeInLogicalUnits());
            return arrangeBounds;
        }
 
        protected override void OnActivated(EventArgs e)
        { 
        } 

        protected override void OnDeactivated(EventArgs e) 
        {
        }

        protected override void OnStateChanged(EventArgs e) 
        {
        } 
 
        protected override void OnLocationChanged(EventArgs e)
        { 
        }

        protected override void OnClosing(CancelEventArgs e)
        { 
        }
 
        protected override void OnClosed(EventArgs e) 
        {
        } 

        ///
        /// Critical - calls the SUC'd IBCS.PostReadyStateChange().
        /// TreatAsSafe - Only READYSTATE_COMPLETE is posted, once, at the end of the activation sequence, 
        ///     when the browser expects it.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        protected override void OnContentRendered(EventArgs e)
        { 
            base.OnContentRendered(e);

            // Posting READYSTATE_COMPLETE triggers the WebOC's DocumentComplete event.
            // Media Center, in particular, uses this to make the WebOC it hosts visible. 
            if (!_loadingCompletePosted)
            { 
                Browser.PostReadyStateChange(READYSTATE_COMPLETE); 
                _loadingCompletePosted = true;
            } 
        }

        protected override void OnKeyDown(KeyEventArgs e)
        { 
            // In browser apps, Ctrl+Tab switches tabs. F6 simulates it here.
            if (e.Key == Key.F6 && (e.KeyboardDevice.Modifiers & ~ModifierKeys.Shift) == 0) 
            { 
                if (KeyboardNavigation.Navigate(
                        e.KeyboardDevice.FocusedElement as DependencyObject ?? this, 
                        Key.Tab, e.KeyboardDevice.Modifiers | ModifierKeys.Control))
                {
                    e.Handled = true;
                } 
            }
 
            if (!e.Handled) 
            {
                base.OnKeyDown(e); 
            }
        }

        #endregion Protected methods 

        //---------------------------------------------- 
        // 
        // Internal Methods
        // 
        //----------------------------------------------
        #region Internal Methods

        ///  
        ///     Creates the RBW object and sets the Style property on it
        ///     to the correct value 
        ///  
        /// 
        ///     Critical: Calls RBW class constructor 
        /// 
        [SecurityCritical]
        internal static RootBrowserWindow CreateAndInitialize()
        { 
            RootBrowserWindow rbw = new RootBrowserWindow();
            rbw.InitializeRBWStyle(); 
            return rbw; 
        }
 
        /// 
        /// Critical: This code elevates to all window permission
        /// 
        [SecurityCritical] 
        internal override void CreateAllStyle()
        { 
            Invariant.Assert(App != null, "RootBrowserWindow must be created in an Application"); 

            IHostService ihs = (IHostService)App.GetService(typeof(IHostService)); 

            Invariant.Assert(ihs!=null, "IHostService in RootBrowserWindow cannot be null");
            Invariant.Assert(ihs.HostWindowHandle != IntPtr.Zero, "IHostService.HostWindowHandle in RootBrowserWindow cannot be null");
 
            //This sets the _ownerHandle correctly and will be used to create the _sourceWindow
            //with the correct parent 
            UIPermission uip = new UIPermission(UIPermissionWindow.AllWindows); 
            uip.Assert();//Blessed Assert to set owner handle and to set styles
            try 
            {
                this.OwnerHandle = ihs.HostWindowHandle;
                this.Win32Style = NativeMethods.WS_CHILD | NativeMethods.WS_CLIPCHILDREN | NativeMethods.WS_CLIPSIBLINGS;
            } 
            finally
            { 
                CodeAccessPermission.RevertAssert(); 
            }
 
        }

        ///
        /// Critical: Exposes a window handle (ParentWindow). Base class implementation is also Critical. 
        ///
        [SecurityCritical] 
        internal override HwndSourceParameters CreateHwndSourceParameters() 
        {
            HwndSourceParameters parameters = base.CreateHwndSourceParameters(); 
            parameters.TreatAsInputRoot = true;
            return parameters;
        }
 
        /// 
        ///     Override for SourceWindow creation. 
        ///     Virtual only so that we may assert. 
        /// 
        ///  
        ///     Critical - Calls critical base-class function.
        ///                Calls critical functions GetAncestor and GetForegroundWindow.
        /// 
        [SecurityCritical] 
        internal override void CreateSourceWindowImpl()
        { 
            Browser.OnBeforeShowNavigationWindow(); 

            base.CreateSourceWindowImpl(); 
            Invariant.Assert(IsSourceWindowNull == false, "Failed to create HwndSourceWindow for browser hosting");

            // _sourceWindowCreationCompleted specifies that HwndSource creation has completed.  This is used
            // to minimize the SetWindowPos calls from ResizeMove when Height/Width is set prior to calling 
            // show on RBW (this also occurs when Height/Width is set in the style of RBW)
            _sourceWindowCreationCompleted = true; 
 
            if (_rectSet)
            { 
                _rectSet = false;
                ResizeMove(_xDeviceUnits, _yDeviceUnits, _widthDeviceUnits, _heightDeviceUnits);
            }
 
            SetUpInputHooks();
 
            // 
            // While the RBW is created and shown, the Top Browser window should have already been created and shown,
            // Browser doesn't notify this RBW of the activation status again unless user activates/deactivates the main 
            // window. It is time to transfer the Top Browser Window's activation status to this RBW so that user's
            // code can get correct status through property IsActivate.
            //
            IntPtr topWindow = UnsafeNativeMethods.GetAncestor(new HandleRef(this, CriticalHandle), 2/*GA_ROOT*/); 
            Debug.Assert(topWindow != IntPtr.Zero);
            IntPtr activeWindow = UnsafeNativeMethods.GetForegroundWindow(); 
            HandleActivate(activeWindow == topWindow); 
        }
 
        // No need to clear App.MainWindow for RBW case.  It throws an exception if attempted
        internal override void TryClearingMainWindow()
        {
        } 

        internal override void CorrectStyleForBorderlessWindowCase() 
        { 
        }
 
        internal override void GetRequestedDimensions(ref double requestedLeft, ref double requestedTop, ref double requestedWidth, ref double requestedHeight)
        {
            requestedTop = 0;
            requestedLeft = 0; 
            requestedWidth = this.Width;
            requestedHeight = this.Height; 
        } 

        /// 
        ///     Critical - It also calls critical method (SetRootVisual)
        ///
        [SecurityCritical]
        internal override void SetupInitialState(double requestedTop, double requestedLeft, double requestedWidth, double requestedHeight) 
        {
            // If RBW Height/Width was set before calling show in RBW, we need 
            // to update the browser with that size now 
            SetBrowserSize();
            SetRootVisual(); 
        }

        internal override int nCmdForShow()
        { 
            return NativeMethods.SW_SHOW;
        } 
 
        internal override bool HandleWmNcHitTestMsg(IntPtr lParam, ref IntPtr refInt)
        { 
            return false;
        }

        internal override WindowMinMax GetWindowMinMax() 
        {
            return new WindowMinMax(0, double.PositiveInfinity); 
        } 

        // RBW overrides WmMoveChangedHelper default behavior where it calls 
        // either SetValue/CoerceValue on Top/Left DPs since that will
        // throw an exception for RBW.  Furthermore, in RBW, we don't want
        // to fire LocationChanged event.
        internal override void WmMoveChangedHelper() 
        {
        } 
 
        /// 
        ///     Resizes and moves the RBW (which is a WS_CHILD window).  This is called by 
        ///     AppProxyInternal when the host callsbacks into it with the new size/location.
        ///     We need this internal since Height/Width/Top/Left on RBW govern the host'ss
        ///     properties.
        ///  
        /// 
        ///     The location of WS_CHILD window is relative to it parent window thus when the 
        ///     browser moves it does not call this method since the relative position of this window 
        ///     wrt the browser hasn't changed.
        ///  
        /// New left of the RBW
        /// New top of the RBW
        /// New width of the RBW
        /// New height of the RBW 
        ///
        ///     Critical as this method handles critical data. 
        ///     TreatAsSafe - as the RBW is always contained within the browser's window. 
        ///                          you can move the internal window all you want - but given that you're really
        ///                          contained within the BrowserWindow - the worse you could do is make some of your content not visible. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        internal void ResizeMove(int xDeviceUnits, int yDeviceUnits, int widthDeviceUnits, int heightDeviceUnits)
        { 
            // _sourceWindowCreationCompleted specifies that HwndSource creation has completed.  This is used
            // to minimize the SetWindowPos calls from ResizeMove when Height/Width is set prior to calling 
            // show on RBW (this also occurs when Height/Width is set in the style of RBW).  Thus, we want to 
            // resize the underlying avalon hwnd only after its creation is completed
            if (_sourceWindowCreationCompleted == false) 
            {
                _xDeviceUnits = xDeviceUnits;
                _yDeviceUnits = yDeviceUnits;
                _widthDeviceUnits = widthDeviceUnits; 
                _heightDeviceUnits = heightDeviceUnits;
 
                _rectSet = true; 

                return; 
            }

            Invariant.Assert(IsSourceWindowNull == false, "sourceWindow cannot be null if _sourceWindowCreationCompleted is true");
 
            HandleRef handleRef;
            handleRef = new HandleRef( this, CriticalHandle ) ; 
 
            UnsafeNativeMethods.SetWindowPos( handleRef ,
                           NativeMethods.NullHandleRef, 
                           xDeviceUnits,
                           yDeviceUnits,
                           widthDeviceUnits,
                           heightDeviceUnits, 
                           NativeMethods.SWP_NOZORDER
                           | NativeMethods.SWP_NOACTIVATE 
                           | NativeMethods.SWP_SHOWWINDOW); 
        }
 
        /// 
        ///     This is called when the Title dependency property changes in the Window.
        /// 
        /// 
        /// Critical - calls SUC'd IBCS.SetTitle
        /// TreatAsSafe - setting the text on the browser's window is considered safe. 
        ///                 - spoofing is not possible as the browser prepends it's own string to the string 
        ///                      e.g. Microsoft Internet Explorer
        ///                 - it can be done in partial trust in HTML via the TITLE tag. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void UpdateTitle(string titleStr)
        { 
            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null) // null on shutdown 
            { 
                string title = PruneTitleString(titleStr);
 
                // SHOULD NOT CALL BASE; BASE IMPLEMENTS TEXT PROPERTY ON WINDOW
                ibcs.SetTitle(title);

            } 
        }
 
        ///  
        ///     This is called by NavigationService to set the status bar content
        ///     for the browser 
        /// 
        /// 
        ///     We propagate object.ToString() to the browser's status bar.
        ///  
        ///
        ///     Critical - calls SetStatusText which is SUC'ed. 
        /// 
        ///     No longer considered TreatAsSafe in order to protect against hyperlink spoofing.
        ///     Browsers implement access restriction to the status bar from script nowadays. 
        ///
        [SecurityCritical]
        internal void SetStatusBarText(string statusString)
        { 
            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null) // could be null if shutting down 
            { 
                ibcs.SetStatusText(statusString);
            } 
        }

        /// 
        ///     Called to update Height of the browser.  Currently, this method is called from 
        ///     two places:
        /// 
        ///     1) OnHeightInvalidated from window.cs 
        ///     2) SetBrowserSize in RBW
        ///  
        ///
        ///     Critical - Can be used to change the size of the browser
        ///     TreatAsSafe - clamps values so that window cannot be sized greater than desktop bounds.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void UpdateHeight(double newHeightLogicalUnits) 
        { 
            Point sizeDeviceUnits = LogicalToDeviceUnits(new Point(0, newHeightLogicalUnits));
            int heightDeviceUnits = (int)Math.Round(sizeDeviceUnits.Y); 

            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null)
            { 
                //
                // Note: right now IE is clipping browser height to desktop size. 
                // However it should be clipped to available desktop size. See Windows OS Bug #1045038 
                // The code below is to fix this for now.
                // Even if IE's code is changed - likely we keep this as defense in-depth. 
                //

                int maxHeightDeviceUnits = GetMaxWindowHeight();
                heightDeviceUnits = heightDeviceUnits > maxHeightDeviceUnits ? maxHeightDeviceUnits : heightDeviceUnits; 
                heightDeviceUnits = heightDeviceUnits < MIN_BROWSER_HEIGHT_DEVICE_UNITS ? MIN_BROWSER_HEIGHT_DEVICE_UNITS : heightDeviceUnits;
                ibcs.SetHeight(heightDeviceUnits); 
            } 
        }
 
        ///
        ///     Critical - Can be used to change the size of the browser
        ///     TreatAsSafe - clamps values so that window cannot be sized greater than desktop bounds.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal override void UpdateWidth(double newWidthLogicalUnits) 
        { 
            Point sizeDeviceUnits = LogicalToDeviceUnits(new Point(newWidthLogicalUnits, 0));
            int widthDeviceUnits  = (int)Math.Round(sizeDeviceUnits.X); 

            IBrowserCallbackServices ibcs = Browser;
            if (ibcs != null)
            { 
                //
                // Note: right now IE is clipping browser width to desktop size. 
                // However it should be clipped to available desktop size. See Windows OS Bug #1045038 
                // The code below is to fix this for now.
                // Even if IE's code is changed - likely we keep this as defense in-depth. 
                //
                int maxWidthDeviceUnits = GetMaxWindowWidth();
                widthDeviceUnits = widthDeviceUnits > maxWidthDeviceUnits ? maxWidthDeviceUnits : widthDeviceUnits;
 
                widthDeviceUnits = widthDeviceUnits < MIN_BROWSER_WIDTH_DEVICE_UNITS ? MIN_BROWSER_WIDTH_DEVICE_UNITS : widthDeviceUnits;
                ibcs.SetWidth(widthDeviceUnits); 
            } 
        }
 
        /// 
        /// When being reloaded from history in the browser, we need to
        /// set up the journal again
        ///  
        /// 
        internal void SetJournalForBrowserInterop(Journal journal) 
        { 
            Invariant.Assert(journal != null, "Failed to get Journal for browser integration");
            base.JournalNavigationScope.Journal = journal; 
        }

        void IJournalNavigationScopeHost.OnJournalAvailable()
        { 
            base.Journal.BackForwardStateChange += new EventHandler(HandleBackForwardStateChange);
        } 
 
        // For downlevel platforms, we don't have integration with the journal, so we have to
        // use our own Journal. 
        ///
        ///     Critical - calls IBCS.GoBack
        ///
        [SecurityCritical] 
        bool IJournalNavigationScopeHost.GoBackOverride()
        { 
            if (HasTravelLogIntegration) 
            {
                IBrowserCallbackServices ibcs = Browser; 
                if (ibcs != null)
                {
                    try
                    { 
                        ibcs.GoBack();
                    } 
#pragma warning disable 6502 // PRESharp - Catch statements should not have empty bodies 
                    catch (OperationCanceledException)
                    { 
                        // Catch the OperationCanceledException when the navigation is canceled.
                        // See comments in applicationproxyinternal._LoadHistoryStreamDelegate.
                    }
#pragma warning restore 6502 
                }
                return true; 
            } 
            return false; // Proceed with internal GoBack.
        } 

        // For downlevel platforms, we don't have integration with the journal, so we have to
        // use our own Journal.
        /// 
        ///     Critical - calls IBCS.GoForward
        /// 
        [SecurityCritical] 
        bool IJournalNavigationScopeHost.GoForwardOverride()
        { 
            if (HasTravelLogIntegration)
            {
                IBrowserCallbackServices ibcs = Browser;
                if (ibcs != null) 
                {
                    try 
                    { 
                        ibcs.GoForward();
                    } 
#pragma warning disable 6502 // PRESharp - Catch statements should not have empty bodies
                    catch (OperationCanceledException)
                    {
                        // Catch the OperationCanceledException when the navigation is canceled. 
                        // See comments in applicationproxyinternal._LoadHistoryStreamDelegate.
                    } 
#pragma warning restore 6502 
                }
                return true; 
            }
            return false; // Proceed with internal GoForward.
        }
 
        internal override void VerifyApiSupported()
        { 
            throw new InvalidOperationException(SR.Get(SRID.NotSupportedInBrowser)); 
        }
 
        internal override void ClearResizeGripControl(Control oldCtrl)
        {
            // don't do anything here since we do not support
            // ResizeGrip for RBW 
        }
 
        internal override void SetResizeGripControl(Control ctrl) 
        {
            // don't do anything here since we do not support 
            // ResizeGrip for RBW
        }

        // This is called in weboc's static constructor. 
        internal void AddLayoutUpdatedHandler()
        { 
            LayoutUpdated += new EventHandler(OnLayoutUpdated); 
        }
 
        internal void TabInto(bool forward)
        {
            TraversalRequest tr = new TraversalRequest(
                forward ? FocusNavigationDirection.First : FocusNavigationDirection.Last); 
            MoveFocus(tr);
        } 
 
        #endregion Internal Methods
 
        //----------------------------------------------
        //
        // Private Methods
        // 
        //----------------------------------------------
        #region Private methods 
        ///  
        ///     Sets the correct style property on the RBW object based on the
        ///     browser version 
        /// 
        private void InitializeRBWStyle()
        {
            // If we are on a downlevel platform, then we don't integrate with the browser's 
            // travellog, so we have to use our own Journal and supply our own navigation chrome.
            if (!HasTravelLogIntegration) 
            { 
                SetResourceReference(StyleProperty, SystemParameters.NavigationChromeDownLevelStyleKey);
 
                // if the Template property is not defined in a custom style, the property system gets
                // the Template property value for the NavigationWindow from the theme file.  Since,
                // we want to get the Template property value from the browser styles, we need to
                // set the DefaultStyleKeyProperty here. 
                SetValue(DefaultStyleKeyProperty, SystemParameters.NavigationChromeDownLevelStyleKey);
            } 
            else 
            {
                SetResourceReference(StyleProperty, SystemParameters.NavigationChromeStyleKey); 

                // if the Template property is not defined in a custom style, the property system gets
                // the Template property value for the NavigationWindow from the theme file.  Since,
                // we want to get the Template property value from the browser styles, we need to 
                // set the DefaultStyleKeyProperty here.
                SetValue(DefaultStyleKeyProperty, SystemParameters.NavigationChromeStyleKey); 
            } 
        }
 
        /// 
        ///     Critical - Elevates to get access to the HwndSource and installs hooks.
        ///     TreatAsSafe - The HwndSoure is not exposed. The message hooks installed are internal ones, and they are for the RBW specifically.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void SetUpInputHooks() 
        { 
            IKeyboardInputSink sink;
            new UIPermission(PermissionState.Unrestricted).Assert(); //BlessedAssert 
            try
            {
                _inputPostFilter = new HwndWrapperHook(BrowserInteropHelper.PostFilterInput);
                HwndSource hwndSource = base.HwndSourceWindow; 
                hwndSource.HwndWrapper.AddHookLast(_inputPostFilter);
 
                sink = (IKeyboardInputSink)hwndSource; 
            }
            finally 
            {
                UIPermission.RevertAll();
            }
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); //BlessedAssert 
            try
            { 
                Debug.Assert(sink.KeyboardInputSite == null); 
                sink.KeyboardInputSite = new KeyInputSite(new SecurityCriticalData(sink));
            } 
            finally
            {
                SecurityPermission.RevertAll();
            } 
        }
 
        ///  
        ///     Updates browser size if Height/Width is not set to default value (NaN).  This
        ///     means that Height/Width was set prior to calling Show on RBW and we need to 
        ///     propagate that to the browser.  This method is called from SetupInitialize which
        ///     is called from CreateSourceWindowImpl
        /// 
        private void SetBrowserSize() 
        {
            Point requestedSizeDeviceUnits = LogicalToDeviceUnits(new Point(this.Width, this.Height)); 
 
            // if Width was specified
            if (!DoubleUtil.IsNaN(this.Width)) 
            {
                // at this stage, ActualWidth/Height is not set since
                // layout has not happened (it happens when we set the
                // RootVisual of the HwndSource) 
                UpdateWidth(requestedSizeDeviceUnits.X);
            } 
 
            // if Height was specified
            if (!DoubleUtil.IsNaN(this.Height)) 
            {
                // at this stage, ActualWidth/Height is not set since
                // layout has not happened (it happens when we set the
                // RootVisual of the HwndSource) 
                UpdateHeight(requestedSizeDeviceUnits.Y);
            } 
        } 

        private string PruneTitleString(string rawString) 
        {
            StringBuilder sb = new StringBuilder();
            bool inMiddleOfWord = false;
 
            for (int i=0; i < rawString.Length; i++)
            { 
                if (Char.IsWhiteSpace(rawString[i]) == false) 
                {
                    sb.Append(rawString[i]); 
                    inMiddleOfWord = true;
                }
                else
                { 
                    if (inMiddleOfWord == true)
                    { 
                        sb.Append(' '); 
                        inMiddleOfWord = false;
                    } 
                }
            }

            // remove the last space if it exists 
            return sb.ToString().TrimEnd(' ');
        } 
 
        private void OnLayoutUpdated(object obj, EventArgs args)
        { 
            try
            {
                VerifyWebOCOverlap(NavigationService);
            } 
            finally
            { 
                _webBrowserList.Clear(); 
            }
        } 

        private void VerifyWebOCOverlap(NavigationService navigationService)
        {
            for (int i = 0; i < navigationService.ChildNavigationServices.Count; i++) 
            {
                NavigationService childNavService = (NavigationService)(navigationService.ChildNavigationServices[i]); 
                WebBrowser webBrowser = childNavService.WebBrowser; 
                if (webBrowser != null)
                { 
                    for (int j = 0; j < _webBrowserList.Count; j++)
                    {
                        // Note: We are using WebBrowser.BoundRect, which is relative to parent window.
                        // Since WebBrowsers are all siblings child windows right now, e.g., we don't allow WebOC inside 
                        // Popup window, this is a better performed way. If we change that, we should make sure the rects
                        // to compare are relative to desktop. 
                        Rect rect = Rect.Intersect(webBrowser.BoundRect, _webBrowserList[j].BoundRect); 
                        // Only when the intersect rect's Width and Height are both bigger than 0, we consider them overlapping.
                        // Even when 2 edges are next to each other, it is considered as intersect by the Rect class. 
                        if ((rect.Width > 0) && (rect.Height > 0))
                        {
                            throw new InvalidOperationException(SR.Get(SRID.WebBrowserOverlap));
                        } 
                    }
                    _webBrowserList.Add(webBrowser); 
                } 
                else
                { 
                    VerifyWebOCOverlap(childNavService);
                }
            }
        } 

        ///  
        /// We are not using the CanGoBack/CanGoForward property change since that is fired only 
        /// if the value changes eg. if we had 3 entries in the backstack, then a back navigation
        /// won't fire this since the value is still 'true' and has not changed. 
        /// What we need is the UpdateView() notification or the BackForwardState change
        /// notification which is fired from UpdateView() of the Journal.
        /// Trying to hook the event will create the journal even if there was no navigation
        /// so just using an virtual override to do the work. 
        /// 
        /// 
        ///     Critical - as this method calls into Browser call back method for back and forward. 
        ///                This is a pinoke call.
        ///     TreatAsSafe - as this is a safe operation. 
        ///
        [SecurityCritical, SecurityTreatAsSafe]
        private void HandleBackForwardStateChange(object sender, EventArgs args)
        { 
            //Nothing to do for downlevel platform
            if (!HasTravelLogIntegration) 
                return; 

            IBrowserCallbackServices ibcs = Browser; 
            if (ibcs != null)
            {
                ibcs.UpdateBackForwardState();
            } 
        }
 
 
        ///
        /// Given a proposed width - and curWidth - return the MaxWidth the window can be opened to. 
        /// Used to prevent sizing of window > desktop bounds in browser.
        ///
        ///
        /// Critical - calls back to browser to get the current left. 
        /// TreatAsSafe - this value isn't returned or stored.
        ///               value returned is the current maximum width allowed considered safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe ]
        private int GetMaxWindowWidth() 
        {
            NativeMethods.RECT desktopArea = WorkAreaBoundsForNearestMonitor;
            int browserLeft = 0;
            int curBrowserWidth = 0; 
            IBrowserCallbackServices ibcs = Browser;
 
            bool successful = false ; 

            successful = (ibcs != null) && ibcs.GetLeft(ref browserLeft ); 

            if ( ! successful )
            {
                browserLeft = 0; 
            }
 
            successful = (ibcs != null) && ibcs.GetWidth(ref curBrowserWidth); 

            if (! successful) 
            {
                curBrowserWidth = 0;
            }
 
            int availableWidth = desktopArea.right - browserLeft;
            int maxWidth = availableWidth > curBrowserWidth ? availableWidth : curBrowserWidth; 
 
            return maxWidth;
        } 

        ///
        /// Given a proposed height - and curHeight - return the MaxHeight the window can be opened to.
        /// Used to prevent sizing of window > desktop bounds in browser. 
        ///
        /// 
        /// Critical - calls back to browser to get the current top. 
        /// TreatAsSafe - this value isn't returned or stored.
        ///               value returned is the current maximum height allowed considered safe. 
        ///
        [SecurityCritical, SecurityTreatAsSafe ]
        private int GetMaxWindowHeight()
        { 
            NativeMethods.RECT desktopArea = WorkAreaBoundsForNearestMonitor;
            int browserTop = 0; 
            int curBrowserHeight = 0; 
            IBrowserCallbackServices ibcs = Browser;
            bool successful = false ; 

            successful = (ibcs != null) && ibcs.GetTop(ref browserTop );

            if ( ! successful ) 
            {
                browserTop = 0; 
            } 

            successful = (ibcs != null) && ibcs.GetHeight(ref curBrowserHeight); 

            if ( ! successful )
            {
                curBrowserHeight = 0; 
            }
 
            int availableHeight =  desktopArea.bottom - browserTop ; 
            int maxHeight = availableHeight > curBrowserHeight ? availableHeight : curBrowserHeight;
 
            return maxHeight;
        }

 
        ///
        ///For browser hosting cases, we get the rects through OLE activation before we create the 
        ///RootBrowserWindow. Even if SourceWindow or Handle are null, we can return the cached rects 
        ///
        private Size GetSizeInLogicalUnits() 
        {
            Size size;

            // Adding check for IsCompositionTargetInvalid as part of the fix for WOSB 1453012 
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            { 
                // return _widthDeviceUnits & _heightDeviceUnits if hwndsource is not yet available. 
                // We will resize when hwnd becomes available, because the DeviceToLogicalUnits calculation
                // depends on hwnd being available. If it's not high dpi, the second resize will be optimized 
                // by layout system.
                size = new Size(_widthDeviceUnits, _heightDeviceUnits);
            }
            else 
            {
                // It's better to get WindowSize instead of doing WindowSize.Width & WindowSize.Height 
                // because WindowSize queries HwndSource. 
                size = WindowSize;
                Point ptLogicalUnits = DeviceToLogicalUnits(new Point(size.Width, size.Height)); 
                size = new Size(ptLogicalUnits.X, ptLogicalUnits.Y);
            }

            return size; 
        }
 
        ///  
        ///     Critical - Sets the status bar text. Can be used to do URL spoofing.
        ///  
        [SecurityCritical]
        private void OnRequestSetStatusBar_Hyperlink(object sender, RoutedEventArgs e)
        {
            RequestSetStatusBarEventArgs statusEvent = e as RequestSetStatusBarEventArgs; 

            if ( statusEvent != null ) 
            { 
                SetStatusBarText(statusEvent.Text);
            } 
        }

        ///
        /// Prints the content of the App's MainWindow.  The logic is that if the content is not visual but IInputElement 
        /// we will try to let it handle the command first. If it does not handle the print command we will get the corresponding
        /// visual in the visual tree and use that to print. 
        /// 
        private static void OnCommandPrint(object sender, ExecutedRoutedEventArgs e)
        { 
#if !DONOTREFPRINTINGASMMETA
            RootBrowserWindow rbw = sender as RootBrowserWindow;
            Invariant.Assert(rbw != null);
 
            if (! rbw._isPrintingFromRBW)
            { 
                Visual vis = rbw.Content as Visual; 

                if (vis == null) 
                {
                    // If the content is not Visual but IInputElement, try to let it handle the command first.
                    // This is for the document scenario. Printing a document is different from printing a visual.
                    // Printing a visual is to print how it is rendered on screen. Printing a doc prints the full 
                    // doc inculding the part that is not visible. There might be other functionalities that are
                    // specific for document. FlowDocument's viewer knows how to print the doc. 
                    IInputElement target = rbw.Content as IInputElement; 

                    if (target != null) 
                    {
                        // CanExecute will bubble up. If nobody between the content and rbw can handle it,
                        // It would call back on RBW again. Use _isPrintingFromRBW to prevent the loop.
                        rbw._isPrintingFromRBW = true; 
                        try
                        { 
                            if (ApplicationCommands.Print.CanExecute(null, target)) 
                            {
                                ApplicationCommands.Print.Execute(null, target); 
                                return;
                            }
                        }
                        finally 
                        {
                            rbw._isPrintingFromRBW = false; 
                        } 
                    }
                } 

                // Let the user choose a printer and set print options.
                PrintDialog printDlg = new PrintDialog();
 
                // If the user pressed the OK button on the print dialog, we proceed
                if (printDlg.ShowDialog() == true) 
                { 
                    string printJobDescription = GetPrintJobDescription(App.MainWindow);
 
                    // If the root is not visual and does not know how to print itself, we find the
                    // corresponding visual and use that to print.
                    if (vis == null)
                    { 
                        INavigatorImpl navigator = rbw as INavigatorImpl;
                        Invariant.Assert(navigator != null); 
 
                        vis = navigator.FindRootViewer();
                        Invariant.Assert(vis != null); 
                    }

                    // Area we can print to for the chosen printer
                    Rect imageableRect = GetImageableRect(printDlg); 

                    // We print Visuals aligned with the top/left corner of the printable area. 
                    // We do not attempt to print very large Visuals across multiple pages. 
                    // Any portion that doesn't fit on a single page will get cropped by the
                    // print system. 

                    // Used to draw our visual into another visual for printing purposes
                    VisualBrush visualBrush = new VisualBrush(vis);
                    visualBrush.Stretch = Stretch.None; 

                    // Visual we will print - containing a rectangle the size of our 
                    // original Visual but offset into the printable area 
                    DrawingVisual drawingVisual = new DrawingVisual();
                    DrawingContext context = drawingVisual.RenderOpen(); 
                    context.DrawRectangle(visualBrush,
                                          null,
                                          new Rect(imageableRect.X,
                                                   imageableRect.Y, 
                                                   vis.VisualDescendantBounds.Width,
                                                   vis.VisualDescendantBounds.Height)); 
                    context.Close(); 

                    printDlg.PrintVisual(drawingVisual, printJobDescription); 
                }
            }
#endif // DONOTREFPRINTINGASMMETA
        } 

        private static void OnQueryEnabledCommandPrint(object sender, CanExecuteRoutedEventArgs  e) 
        { 
            RootBrowserWindow rbw = sender as RootBrowserWindow;
            Invariant.Assert(rbw != null); 

            if ((!e.Handled) && (!rbw._isPrintingFromRBW))
            {
                // While we could print null it doesn't really make sense to do so 
                e.CanExecute = rbw.Content != null;
            } 
        } 

        /// 
        /// Critical - calls out to PrintDialog to get the PrintQueue and its PrintCapabilities
        /// TreatAsSafe - these values aren't returned or stored
        ///
        [SecurityCritical, SecurityTreatAsSafe] 
        private static Rect GetImageableRect(PrintDialog dialog)
        { 
            Invariant.Assert(dialog != null, "Dialog should not be null."); 

            PrintQueue queue = null; 
            PrintCapabilities capabilities = null;
            PageImageableArea imageableArea = null;
            Rect imageableRect = Rect.Empty;
 
            // This gets the PringDocumentImageableArea.OriginWidth/OriginHeight
            // of the PrintQueue the user chose in the dialog. 
            CodeAccessPermission printp = new System.Drawing.Printing.PrintingPermission(PrintingPermissionLevel.DefaultPrinting); 
            printp.Assert();//Blessed Assert to get PrintQueue and call GetPrintCapabilities
            try 
            {
                queue = dialog.PrintQueue;
                if (queue != null)
                { 
                    capabilities = queue.GetPrintCapabilities();
                } 
            } 
            finally
            { 
                CodeAccessPermission.RevertAssert();
            }

            if (capabilities != null) 
            {
                imageableArea = capabilities.PageImageableArea; 
                if (imageableArea != null) 
                {
                    imageableRect = new Rect(imageableArea.OriginWidth, 
                                             imageableArea.OriginHeight,
                                             imageableArea.ExtentWidth,
                                             imageableArea.ExtentHeight);
                } 
            }
 
            // If for any reason we couldn't get the actual printer's values 
            // we fallback to a constant and the values available from the
            // PrintDialog. 
            if (imageableRect == Rect.Empty)
            {
                imageableRect = new Rect(NON_PRINTABLE_MARGIN,
                    NON_PRINTABLE_MARGIN, 
                    dialog.PrintableAreaWidth,
                    dialog.PrintableAreaHeight); 
            } 

            return imageableRect; 
        }

        /// 
        ///    Generate the title of the print job for a given Window. 
        /// 
        private static string GetPrintJobDescription(Window window) 
        { 
            Invariant.Assert(window != null, "Window should not be null.");
 
            string description = null;
            string pageTitle = null;

            // Get the window title 
            string windowTitle = window.Title;
            if (windowTitle != null) 
            { 
                windowTitle = windowTitle.Trim();
            } 

            // Get the page title, if available
            Page page = window.Content as Page;
            if (page != null) 
            {
                pageTitle = page.Title; 
                if (pageTitle != null) 
                {
                    pageTitle = pageTitle.Trim(); 
                }
            }

            // If window and page title are available, use them together, 
            // otherwise use which ever is available
            if (!String.IsNullOrEmpty(windowTitle)) 
            { 
                if (!String.IsNullOrEmpty(pageTitle))
                { 
                    description = SR.Get(SRID.PrintJobDescription, windowTitle, pageTitle);
                }
                else
                { 
                    description = windowTitle;
                } 
            } 

            // No window title so use the page title on its own 
            if (description == null && !String.IsNullOrEmpty(pageTitle))
            {
                description = pageTitle;
            } 

            // If neither window or page titles are available, try and use 
            // the source URI for the content 
            if (description == null && BrowserInteropHelper.Source != null)
            { 
                Uri source = BrowserInteropHelper.Source;
                if (source.IsFile)
                {
                    description = source.LocalPath; 
                }
                else 
                { 
                    description = source.ToString();
                } 
            }

            // If no other option, use a localized constant
            if (description == null) 
            {
                description = SR.Get(SRID.UntitledPrintJobDescription); 
            } 

            return description; 
        }


        #endregion Private methods 

        //---------------------------------------------- 
        // 
        // Private Properties
        // 
        //----------------------------------------------
        #region Private properties
        private static Application App
        { 
            get { return Application.Current; }
        } 
 

        private static IBrowserCallbackServices Browser 
        {
            get
            {
                // There will be no IBrowserCallbackServices available in some situations, e.g., during shutdown 
                IBrowserCallbackServices ibcs = (App == null ? null : App.BrowserCallbackServices);
                return ibcs; 
            } 
        }
 
        ///
        /// Critical - calls the SUC'd IBCS.IsDownlevelPlatform.
        /// TreatAsSafe - this information is okay to give out.
        /// 
        private bool IsDownlevelPlatform
        { 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (!_isDownlevelPlatformValid)
                {
                    IBrowserCallbackServices ibcs = Browser;
                    _isDownlevelPlatform = (ibcs != null) ? ibcs.IsDownlevelPlatform() : false; 

                    _isDownlevelPlatformValid = true; 
                } 
                return _isDownlevelPlatform;
            } 
        }

        internal bool HasTravelLogIntegration
        { 
            get
            { 
                return !IsDownlevelPlatform && BrowserInteropHelper.IsAvalonTopLevel; 
            }
        } 

        #endregion Private properties

        //---------------------------------------------- 
        //
        // Private Classes 
        // 
        //----------------------------------------------
        #region Private Classes 

        /// 
        /// This class is used to print objects which are not directly supported by XpsDocumentWriter.
        /// It's sole purpose is to make a non-abstract version of Visual. 
        /// 
        private class PrintVisual : ContainerVisual { } 
 

        private class KeyInputSite : IKeyboardInputSite 
        {
            internal KeyInputSite(SecurityCriticalData sink)
            {
                _sink = sink; 
            }
 
            ///  
            /// Critical: sets critical data.
            /// Safe: setting to null is okay. 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            void IKeyboardInputSite.Unregister()
            { 
                _sink = new SecurityCriticalData(null);
            } 
 
            /// 
            /// Critical: IKeyboardInputSink could be used to spoof input. 
            /// 
            IKeyboardInputSink IKeyboardInputSite.Sink
            {
                [SecurityCritical] 
                get { return _sink.Value; }
            } 
 
            /// 
            /// Critical: calls the SUC'd IBCS.TabOut(). 
            /// Safe: tabbing out of the application is safe.
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            bool IKeyboardInputSite.OnNoMoreTabStops(TraversalRequest request) 
            {
                return Browser.TabOut(request.FocusNavigationDirection == FocusNavigationDirection.Next); 
                // i. Tabbing-in is handled by ApplicationProxyInternal. 
            }
 
            /// 
            /// Critical: The encapsulated interface could be used to spoof input.
            /// 
            SecurityCriticalData _sink; 
        };
 
        #endregion Private Classes 

 
        //----------------------------------------------
        //
        // Private Members
        // 
        //----------------------------------------------
        #region private members 
 
        //Cache the values until the HwndSourceWindow is created
        private int  _xDeviceUnits, _yDeviceUnits, _widthDeviceUnits, _heightDeviceUnits; 
        private bool _rectSet;

        private bool _isPrintingFromRBW;
        private bool _isDownlevelPlatformValid; 
        private bool _isDownlevelPlatform;
        private bool _sourceWindowCreationCompleted; 
 
        private List _webBrowserList = new List();
 
        /// 
        /// The event delegate has to be stored because HwndWrapper keeps only a weak reference to it.
        /// 
        ///  
        /// Critical: could be used to spoof input
        ///  
        [SecurityCritical] 
        private HwndWrapperHook _inputPostFilter;
 
        private bool _loadingCompletePosted;
        const int READYSTATE_COMPLETE = 4;

        // Fallback constant for the size of non-printable margin.  This is used if 
        // we cant retrieve the actual size from the PrintQueue.
        private const int NON_PRINTABLE_MARGIN = 15; 
 
        //
        // Setting these as the min-browser width & height. 
        // Note that we can't use User's min window-width & height - these are specifically about browser window.
        //
        private const int MIN_BROWSER_WIDTH_DEVICE_UNITS = 200;
 
        private const int MIN_BROWSER_HEIGHT_DEVICE_UNITS = 200;
        #endregion private members 
    } 
}

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