File: System\Windows\Window.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows.Appearance;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Shell;
using System.Windows.Threading;
using MS.Internal;
using MS.Internal.AppModel;
using MS.Internal.Interop;
using MS.Internal.KnownBoxes;
using MS.Win32;
using System.Diagnostics.CodeAnalysis;
 
using BuildInfo = MS.Internal.PresentationFramework.BuildInfo;
using SNM = Standard.NativeMethods;
using HRESULT = MS.Internal.Interop.HRESULT;
using Win32Error = MS.Internal.Interop.Win32Error;
 
//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 System.Windows
{
    [Localizability(LocalizationCategory.Ignore)]
    public class Window : ContentControl, IWindowService
    {
        //---------------------------------------------------
        //
        // Constructors
        //
        //---------------------------------------------------
        #region Constructors
 
        /// <summary>
        ///     Initializes the dependency ids of this class
        /// </summary>
        static Window()
        {
            HeightProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnHeightChanged)));
            MinHeightProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnMinHeightChanged)));
            MaxHeightProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnMaxHeightChanged)));
            WidthProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnWidthChanged)));
            MinWidthProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnMinWidthChanged)));
            MaxWidthProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnMaxWidthChanged)));
 
            // override VisibilityProperty Metadata. For Window, Visibility.Visible means the Window is visible.
            // Visibility.Hidden and Visibility.Collapsed mean the Window is not visible.
            // Visibility.Hidden and Visibility.Collapsed are treated the same.
            // We default to Visibility.Collapsed since RenderSize returns (0,0) only for
            // collapsed elements and not for hidden. We want to return (0,0) when window is
            // never shown.
            VisibilityProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(Visibility.Collapsed, new PropertyChangedCallback(_OnVisibilityChanged), new CoerceValueCallback(CoerceVisibility)));
 
            IsTabStopProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
            KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle));
            KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle));
            KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle));
            FocusManager.IsFocusScopeProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(BooleanBoxes.TrueBox));
 
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(typeof(Window)));
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(Window));
 
            FlowDirectionProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(new PropertyChangedCallback(_OnFlowDirectionChanged)));
            // ideally this would just use a ValidateValueCallback
            // We don't support setting RenderTransform and ClipToBounds on Window. Exception will be thrown in Coerce callbacks
            RenderTransformProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(Transform.Identity, new PropertyChangedCallback(_OnRenderTransformChanged), new CoerceValueCallback(CoerceRenderTransform)));
            ClipToBoundsProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox, new PropertyChangedCallback(_OnClipToBoundsChanged), new CoerceValueCallback(CoerceClipToBounds)));
 
            // Note that this event only gets raised in Windows 7 and later.
            WM_TASKBARBUTTONCREATED = UnsafeNativeMethods.RegisterWindowMessage("TaskbarButtonCreated");
 
            WM_APPLYTASKBARITEMINFO = UnsafeNativeMethods.RegisterWindowMessage("WPF_ApplyTaskbarItemInfo");
 
            EventManager.RegisterClassHandler(typeof(Window),
                UIElement.ManipulationCompletedEvent,
                new EventHandler<ManipulationCompletedEventArgs>(OnStaticManipulationCompleted),
                /*handledEventsToo*/ true);
            EventManager.RegisterClassHandler(typeof(Window),
                UIElement.ManipulationInertiaStartingEvent,
                new EventHandler<ManipulationInertiaStartingEventArgs>(OnStaticManipulationInertiaStarting),
                /*handledEventsToo*/ true);
 
            Window.DpiChangedEvent = EventManager.RegisterRoutedEvent("DpiChanged", RoutingStrategy.Bubble,
                typeof (System.Windows.DpiChangedEventHandler), typeof (Window));
        }
 
        /// <summary>
        ///     Constructs a window object
        /// </summary>
        /// <remarks>
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance.
        ///
        ///     Initializes the Width/Height, Top/Left properties to use windows
        ///     default. Updates Application object properties if inside app.
        ///
        ///     Also, window style is set to WS_CHILD inside CreateSourceWindow
        ///     for browser hosted case
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        public Window()
        {
            _inTrustedSubWindow = false;
            Initialize();
        }
 
        /// <summary>
        ///     Constructs a window object
        /// </summary>
        /// <remarks>
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance.
        ///
        ///     Initializes the Width/Height, Top/Left properties to use windows
        ///     default. Updates Application object properties if inside app.
        ///
        ///     Also, window style is set to WS_CHILD inside CreateSourceWindow
        ///     for browser hosted case
        ///
        ///     This method currently requires full trust to run.
        /// </remarks>
        internal Window(bool inRbw):base()
        {
            if (inRbw)
            {
                _inTrustedSubWindow = true;
            }
            else
            {
                _inTrustedSubWindow = false;
            }
            Initialize();
}
        #endregion Constructors
 
        //---------------------------------------------------
        //
        // Public Methods
        //
        //---------------------------------------------------
        #region Public Methods
 
        /// <summary>
        ///     Show the window
        /// </summary>
        /// <remarks>
        ///     Calling Show on window is the same as setting the
        ///     Visibility property to Visibility.Visible.
        /// </remarks>
        public void Show()
        {
            VerifyContextAndObjectState();
            VerifyCanShow();
            VerifyNotClosing();
            VerifyConsistencyWithAllowsTransparency();
 
            // Update the property value only.  Do not do anything further in
            // _OnVisibilityInvalidate since we will synchronously call ShowHelper
            // from here.
            UpdateVisibilityProperty(Visibility.Visible);
 
            ShowHelper(BooleanBoxes.TrueBox);
        }
 
        /// <summary>
        ///     Hide the window
        /// </summary>
        /// <remarks>
        ///     Calling Hide on window is the same as setting the
        ///     Visibility property to Visibility.Hidden
        ///     </remarks>
        public void Hide()
        {
            VerifyContextAndObjectState();
 
            if (_disposed == true)
            {
                return;
            }
 
            // set Visibility to Hidden even if _isVisible is false since
            // _isVisible can be false b/c of Visibility = Collapsed and Hide()
            // should change Visibility to Hidden.
            //
            // Update the property value only.  Do not do anything further in
            // _OnVisibilityInvalidate since we will synchronously call ShowHelper
            // from here.
            UpdateVisibilityProperty(Visibility.Hidden);
 
            ShowHelper(BooleanBoxes.FalseBox);
        }
 
        /// <summary>
        ///     Closes the Window
        /// </summary>
        /// <remarks>
        ///     Window fires the Closing event before it closes. If the
        ///     user cancels the closing event, the window is not closed.
        ///     Otherwise, the window is closed and the Closed event is
        ///     fired.
        ///
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        public void Close()
        {
            // this call ends up throwing an exception if Close
            // is not allowed
            VerifyApiSupported();
            VerifyContextAndObjectState();
            InternalClose(false, false);
        }
 
        /// <summary>
        ///     Kick off the Window's MoveWindow loop
        /// </summary>
        /// <remarks>
        ///     To enable custom chrome on Windows. First check if this is the Left MouseButton.
        ///     Will throw exception if it's not, otherwise, will kick off the Windows's MoveWindow loop.
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        public void DragMove()
        {
            // this call ends up throwing an exception if dragmove
            // is not allowed
            VerifyApiSupported();
            VerifyContextAndObjectState();
            VerifyHwndCreateShowState();
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return;
            }
 
            // Mouse.LeftButton actually reflects the primary button user is using.
            // So we don't need to check whether the button has been swapped here.
            if (Mouse.LeftButton == MouseButtonState.Pressed)
            {
                if (WindowState == WindowState.Normal)
                {
                    // SendMessage's return value is dependent on the message send.  WM_SYSCOMMAND
                    // and WM_LBUTTONUP return value just signify whether the WndProc handled the
                    // message or not, so they are not interesting
#pragma warning disable 6523
                    UnsafeNativeMethods.SendMessage( Handle, WindowMessage.WM_SYSCOMMAND, (IntPtr)NativeMethods.SC_MOUSEMOVE, IntPtr.Zero);
                    UnsafeNativeMethods.SendMessage( Handle, WindowMessage.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
#pragma warning restore 6523
                }
            }
            else
            {
                throw new InvalidOperationException(SR.DragMoveFail);
            }
}
 
        /// <summary>
        ///     Shows the window as a modal window
        /// </summary>
        /// <returns>bool?</returns>
        /// <remarks>
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        public Nullable<bool> ShowDialog()
        {
            // this call ends up throwing an exception if ShowDialog
            // is not allowed
            VerifyApiSupported();
            VerifyContextAndObjectState();
            VerifyCanShow();
            VerifyNotClosing();
            VerifyConsistencyWithAllowsTransparency();
 
            if ( _isVisible == true )
            {
                throw new InvalidOperationException(SR.ShowDialogOnVisible);
            }
            else if ( _showingAsDialog == true )
            {
                throw new InvalidOperationException(SR.ShowDialogOnModal);
            }
 
            _dialogOwnerHandle = _ownerHandle;
 
            // verify owner handle is window
            if (UnsafeNativeMethods.IsWindow( new HandleRef( null, _dialogOwnerHandle ) ) != true)
            {
                _dialogOwnerHandle = IntPtr.Zero;
            }
 
 
            // remember the current active window;
            // this is used when dialog creation fails or dialog closes, we set the active window back to this one.
            _dialogPreviousActiveHandle = UnsafeNativeMethods.GetActiveWindow();
 
            // if owner window is not specified, we get the current active window on this thread's
            // message queue as the owner.
            if (_dialogOwnerHandle == IntPtr.Zero)
            {
                _dialogOwnerHandle = _dialogPreviousActiveHandle;
            }
 
            // If hwndOwner == HWNDESKTOP, change it to NULL.  This way the desktop
            // (and all its children) won't be disabled if the dialog is modal.
            if ((_dialogOwnerHandle != IntPtr.Zero) &&
                (_dialogOwnerHandle == UnsafeNativeMethods.GetDesktopWindow()))
            {
                _dialogOwnerHandle = IntPtr.Zero;
            }
 
            // if dialog owner is not null, get the top level window (case where dialog owner is a
            // child window), and save it's state regarding enabled and active window
            if (_dialogOwnerHandle != IntPtr.Zero)
            {
                // get the top level window from the dialog owner handle
                int style = 0;
 
                while (_dialogOwnerHandle != IntPtr.Zero)
                {
                    style = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, _dialogOwnerHandle), NativeMethods.GWL_STYLE);
                    if ((style & NativeMethods.WS_CHILD) == NativeMethods.WS_CHILD)
                    {
                        _dialogOwnerHandle = UnsafeNativeMethods.GetParent(new HandleRef(null, _dialogOwnerHandle));
                    }
                    else
                    {
                        break;
                    }
                }
            }
 
            Debug.Assert(_threadWindowHandles == null, "_threadWindowHandles must be null before enumerating the thread windows");
 
            // NOTE:
            // _threadWindowHandles is created here. This reference is nulled out in EnableThreadWindows
            // when it is called with a true parameter. Please do not null it out anywhere else.
            // EnableThreadWindow(true) is called when dialog is going away. Once dialog is closed and
            // thread windows have been enabled, then there no need to keep the list around.
            // Please see BUG 929740 before making any changes to how _threadWindowHandles works.
            _threadWindowHandles = new List<IntPtr>();
            //Get visible and enabled windows in the thread
            // If the callback function returns true for all windows in the thread, the return value is true.
            // If the callback function returns false on any enumerated window, or if there are no windows
            // found in the thread, the return value is false.
            // No need for use to actually check the return value.
#pragma warning disable 6523
            UnsafeNativeMethods.EnumThreadWindows(SafeNativeMethods.GetCurrentThreadId(),
                                                  new NativeMethods.EnumThreadWindowsCallback(ThreadWindowsCallback),
                                                  NativeMethods.NullHandleRef);
#pragma warning enable 6523
            //disable those windows
            EnableThreadWindows(false);
 
            IntPtr hWndCapture = SafeNativeMethods.GetCapture();
            if (hWndCapture != IntPtr.Zero)
            {
                //
                // NOTE:
                // EnableWindow(false) (called from EnableThreadWindows(false)
                // sends WM_CANCELMODE to the window, so we don't need
                // to send it again.  However, if we change our impl
                // of dialog such that we don't disable all windows on the
                // thread, then we would need this call. Keeping this code here
                // until we finish the Dialog task # 18498
 
                // UnsafeNativeMethods.SendMessage(hWndCapture,
                //                                WindowMessage.WM_CANCELMODE,
                //                                IntPtr.Zero,
                //                                IntPtr.Zero);
 
                // hWndCapture = UnsafeNativeMethods.GetCapture();
                // if (hWndCapture != IntPtr.Zero)
                // {
                    // PS # 862892
                    // WCP: Investigate whether ReleaseCapture is needed in ShowDialog
                    SafeNativeMethods.ReleaseCapture();
                // }
            }
 
            // Ensure Dialog RoutedCommand is registered with CommandManager
            EnsureDialogCommand();
 
            try
            {
                _showingAsDialog = true;
                Show();
            }
            catch
            {
                // NOTE:
                // See BUG 929740.
                // _threadWindowHandles is created before calling ShowDialog and is deleted in
                // EnableThreadWindows (when it's called with true).
                //
                // Window dlg = new Window();
                // Button b = new button();
                // b.OnClick += new ClickHandler(OnClick);
                // dlg.ShowDialog();
                //
                //
                // void OnClick(...)
                // {
                //      dlg.Close();
                //      throw new Exception();
                // }
                //
                //
                // If above code is written, then we get inside this exception handler only after the dialog
                // is closed.  In that case all the windows that we disabled before showing the dialog have already
                // been enabled and _threadWindowHandles set to null in EnableThreadWindows.  Thus, we don't
                // need to do it again.
                //
                // In any other exception cases, we get in this handler before Dialog is closed and thus we do
                // need to enable all the disable windows.
                if (_threadWindowHandles != null)
                {
                    // Some exception case. Re-enable the windows that were disabled
                    EnableThreadWindows(true);
                }
 
                // Activate the previously active window.
                // This code/logic came from User.
                if ( (_dialogPreviousActiveHandle != IntPtr.Zero) &&
                    (UnsafeNativeMethods.IsWindow(new HandleRef(null, _dialogPreviousActiveHandle)) == true))
                {
                    // SetFocus fails if the input hwnd is not a Window or if the Window is not on the
                    // calling thread.
                    //
                    // Furthermore, this code path is executed when an exception occurs when we try to
                    // show the window.  Here we are doing the minimum possible to restore state of
                    // the avalon window object.  Hence, if for some reason, we are not able to
                    // SetFocus to the window that previously had focus, we don't care as that failure
                    // is not important enought to warrant throwing an exception.
                    UnsafeNativeMethods.TrySetFocus(new HandleRef(null, _dialogPreviousActiveHandle), ref _dialogPreviousActiveHandle);
                }
 
                // clears _showingAsDialog and accelerators related fields
                ClearShowKeyboardCueState();
                _showingAsDialog = false;
 
                // using catch and throw instead of catch(Exception e) throw e;  since the former
                // gives the complete call stack upto the offending method where the exception is thrown
                throw;
            }
            finally
            {
                // If the owner window belongs to another thread, the reactivation
                // of the owner may have failed within DestroyWindow().  Therefore,
                // if the current thread is in the foreground and the owner is not
                // in the foreground we can safely set the foreground back
                // to the owner.
#if FIGURE_OUT

                // WCP Dialog: Figure out what to do when reactivating the owner window
                // which is in another thread.
                if (_dialogOwnerHandle != IntPtr.Zero)
                {
                    if (IsCurrentThreadForeground() &&
                        !IsInForegroundQueue(hwndOwner))
                    {
                        NtUserSetForegroundWindow(hwndOwner);
                    }
                }
#endif //FIGURE_OUT
                _showingAsDialog = false;
            }
            return _dialogResult;
        }
 
 
        /// <summary>
        ///     This method tries to activate the Window.
        /// </summary>
        /// <remarks>
        ///     This method calls SetForegroundWindow on the hWnd, thus the rules for SetForegroundWindow
        ///     apply to this method.
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        /// <returns>bool -- indicating whether the window was activated or not</returns>
        public bool Activate()
        {
            // this call ends up throwing an exception if Activate
            // is not allowed
            VerifyApiSupported();
            VerifyContextAndObjectState();
            VerifyHwndCreateShowState();
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            return UnsafeNativeMethods.SetForegroundWindow(new HandleRef(null, Handle));
        }
        #region LogicalTree
        /// <summary>
        ///     Returns enumerator to logical children
        /// </summary>
        protected internal override IEnumerator LogicalChildren
        {
            get
            {
                // Don't use UIElementCollection because we don't have a reference to content's visual parent;
                // window has style and user can change it.
                return new SingleChildEnumerator(this.Content);
            }
        }
 
        #endregion LogicalTree
 
        #region static public method
 
        /// <summary>
        /// Gets Window in which the given DependecyObject is hosted in.
        /// </summary>
        /// <param name="dependencyObject">Returns the Window the given dependencyObject is hosted in.</param>
        /// <returns>Window</returns>
        public static Window GetWindow(DependencyObject dependencyObject)
        {
            ArgumentNullException.ThrowIfNull(dependencyObject);
 
            // Window.IWindowServiceProperty is an internal inheritable dependency property
            // Normally this value is set to the root Window element, all the element
            // inside the window view will get this value through property inheritance mechanism.
 
            return dependencyObject.GetValue(Window.IWindowServiceProperty) as Window;
        }
 
        #endregion static public method
 
        #endregion Public Methods
        //---------------------------------------------------
        //
        // Public Properties
        //
        //---------------------------------------------------
        #region Public Properties
 
        /// <summary>
        /// Gets or sets the Fluent theme mode of the window.
        /// </summary>
        /// <remarks>
        /// Setting this property controls if Fluent theme is loaded in Light, Dark or System mode.
        /// It also controls the application of backdrop and darkmode on window.
        /// The four values for the ThemeMode enum are :
        ///     <see cref="ThemeMode.None"/> - No Fluent theme is loaded. However, if <see cref="Application.ThemeMode"/> is not None,
        ///         then the window will appear as defined in <see cref="Application.ThemeMode"/>.
        ///     <see cref="ThemeMode.System"/> - Fluent theme is loaded based on the system theme.
        ///     <see cref="ThemeMode.Light"/> - Fluent theme is loaded in Light mode.
        ///     <see cref="ThemeMode.Dark"/> - Fluent theme is loaded in Dark mode.
        ///
        /// These values are predefined in <see cref="ThemeMode"/> struct.
        ///
        /// The default value is <see cref="ThemeMode.None"/>.
        ///
        /// <see cref="ThemeMode"/> and <see cref="Resources"/> are designed to be in sync with each other.
        ///     Syncing is done in order to avoid UI inconsistencies, for example, if the application is in dark mode
        ///     but the windows are in light mode or vice versa.
        ///
        ///     Setting this property loads the Fluent theme dictionaries in the window resources.
        ///     So, if you set this property, it is preferrable to not include Fluent theme dictionaries
        ///     in the window resources manually. If you do, the Fluent theme dictionaries added in the window
        ///     resources will take precedence over the ones added by setting this property.
        ///
        ///     This property is experimental and may be removed in future versions.
        /// </remarks>
        [Experimental("WPF0001")]
        [TypeConverter(typeof(ThemeModeConverter))]
        public ThemeMode ThemeMode
        {
            get
            {
                VerifyContextAndObjectState();
                return _themeMode;
            }
            set
            {
                VerifyContextAndObjectState();
 
                if(!ThemeManager.IsValidThemeMode(value))
                {
                    throw new ArgumentException(string.Format("ThemeMode value {0} is invalid. Use None, System, Light or Dark", value));
                }
 
                ThemeMode oldTheme = _themeMode;
                _themeMode = value;
 
                if(!AreResourcesInitialized)
                {
                    ThemeManager.OnWindowThemeChanged(this, oldTheme, value);
                    AreResourcesInitialized = false;
 
                    _reloadFluentDictionary = true;
                }
 
                if(IsSourceWindowNull)
                {
                    _deferThemeLoading = true;
                }
                else
                {
                    ThemeManager.OnWindowThemeChanged(this, oldTheme, value);
                }
            }
        }
 
        /// <summary>
        /// DependencyProperty for TaskbarItemInfo
        /// </summary>
        public static readonly DependencyProperty TaskbarItemInfoProperty = DependencyProperty.Register(
            "TaskbarItemInfo",
            typeof(TaskbarItemInfo),
            typeof(Window),
            new PropertyMetadata(
                null,
                (d, e) => ((Window)d).OnTaskbarItemInfoChanged(e),
                VerifyAccessCoercion));
 
        /// <summary>
        /// RoutedEvent for when DPI of the screen the Window is on, changes.
        /// </summary>
        public static readonly RoutedEvent DpiChangedEvent;
 
        /// <summary>
        /// Get or set the TaskbarItemInfo associated with this Window.
        /// </summary>
        public TaskbarItemInfo TaskbarItemInfo
        {
            get
            {
                VerifyContextAndObjectState();
                return (TaskbarItemInfo)GetValue(TaskbarItemInfoProperty);
            }
            set
            {
                VerifyContextAndObjectState();
                SetValue(TaskbarItemInfoProperty, value);
            }
        }
 
        private void OnTaskbarItemInfoChanged(DependencyPropertyChangedEventArgs e)
        {
            var oldBar = (TaskbarItemInfo)e.OldValue;
            var newBar = (TaskbarItemInfo)e.NewValue;
 
            // We don't propagate changes to this on anything earlier than Windows 7.
            if (!Utilities.IsOSWindows7OrNewer)
            {
                return;
            }
 
            if (!e.IsASubPropertyChange)
            {
                if (oldBar != null)
                {
                    oldBar.PropertyChanged -= OnTaskbarItemInfoSubPropertyChanged;
                }
                if (newBar != null)
                {
                    newBar.PropertyChanged += OnTaskbarItemInfoSubPropertyChanged;
                }
                ApplyTaskbarItemInfo();
            }
        }
 
        private void HandleTaskbarListError(HRESULT hr)
        {
            if (hr.Failed)
            {
                // Even if some of the taskbar methods get this error it doesn't mean that all of them will.
                // They aren't all implemented with SendMessageTimeout, and unfortunately the ITaskbarList3 API inconsistently
                // exposes that implementation detail.
                if (hr == (HRESULT)Win32Error.ERROR_TIMEOUT)
                {
                    // Explorer appears to be busy.  Post back to the Window to try again.
                    if (TraceShell.IsEnabled)
                    {
                        TraceShell.Trace(TraceEventType.Error, TraceShell.ExplorerTaskbarTimeout);
                        TraceShell.Trace(TraceEventType.Warning, TraceShell.ExplorerTaskbarRetrying);
                    }
 
                    // Explorer being non-responsive should be a transient issue.  Post back to apply the full TaskbarItemInfo.
                    _taskbarRetryTimer.Start();
                }
                else if (hr == (HRESULT)Win32Error.ERROR_INVALID_WINDOW_HANDLE || hr == HRESULT.E_NOTIMPL)
                {
                    // We'll get this when Explorer's not running.  This means there's no Shell to integrate with.
                    if (TraceShell.IsEnabled)
                    {
                        TraceShell.Trace(TraceEventType.Warning, TraceShell.ExplorerTaskbarNotRunning);
                    }
                    // If this is a transient condition then we'll get a WM_TASKBARBUTTONCREATED when Explorer comes
                    // back and the taskbar button gets created again, at which point we'll rehook.
                    // In the meantime, just stop trying since there's no reasonable expectation of recovery.
                    Utilities.SafeRelease(ref _taskbarList);
                }
                else
                {
                    // That covers the troublesome errors that we know how to handle.
                    // For anything else we'll ignore the error and count on a subsequent update to correct the state.
                    if (TraceShell.IsEnabled)
                    {
                        TraceShell.Trace(TraceEventType.Error, TraceShell.NativeTaskbarError(hr.ToString()));
                    }
                }
            }
        }
 
        private void OnTaskbarItemInfoSubPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            // Don't propagate changes from other TaskbarItemInfos.
            if (sender != this.TaskbarItemInfo)
            {
                // Since this and the TaskbarItemInfo should share affinity for the same thread
                // this really shouldn't happen...
                Debug.Assert(false);
                return;
            }
 
            // Defer any sub-property changes until the native ITaskbarList3 has been set up.
            if (_taskbarList == null)
            {
                return;
            }
 
            // If the taskbar has timed out in the last minute, don't try to do this again.
            if (_taskbarRetryTimer != null && _taskbarRetryTimer.IsEnabled)
            {
                return;
            }
 
            DependencyProperty dp = e.Property;
 
            HRESULT hr = HRESULT.S_OK;
 
            if (dp == TaskbarItemInfo.ProgressStateProperty)
            {
                hr = UpdateTaskbarProgressState();
            }
            else if (dp == TaskbarItemInfo.ProgressValueProperty)
            {
                hr = UpdateTaskbarProgressValue();
            }
            else if (dp == TaskbarItemInfo.OverlayProperty)
            {
                hr = UpdateTaskbarOverlay();
            }
            else if (dp == TaskbarItemInfo.DescriptionProperty)
            {
                hr = UpdateTaskbarDescription();
            }
            else if (dp == TaskbarItemInfo.ThumbnailClipMarginProperty)
            {
                hr = UpdateTaskbarThumbnailClipping();
            }
            else if (dp == TaskbarItemInfo.ThumbButtonInfosProperty)
            {
                hr = UpdateTaskbarThumbButtons();
            }
 
            HandleTaskbarListError(hr);
        }
 
        /// <summary>
        /// DependencyProperty for AllowsTransparency
        /// </summary>
        public static readonly DependencyProperty AllowsTransparencyProperty =
                DependencyProperty.Register(
                        "AllowsTransparency",
                        typeof(bool),
                        typeof(Window),
                        new FrameworkPropertyMetadata(
                                BooleanBoxes.FalseBox,
                                new PropertyChangedCallback(OnAllowsTransparencyChanged),
                                new CoerceValueCallback(CoerceAllowsTransparency)));
 
        /// <summary>
        /// Whether or not the Window uses per-pixel opacity
        /// </summary>
        public bool AllowsTransparency
        {
            get { return (bool)GetValue(AllowsTransparencyProperty); }
            set { SetValue(AllowsTransparencyProperty, BooleanBoxes.Box(value)); }
        }
 
        private static void OnAllowsTransparencyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }
 
        private static object CoerceAllowsTransparency(DependencyObject d, object value)
        {
            value = VerifyAccessCoercion(d, value);
 
            if (!((Window) d).IsSourceWindowNull)
            {
                throw new InvalidOperationException(SR.ChangeNotAllowedAfterShow);
            }
 
            return value;
        }
 
        /// <summary>
        ///     The DependencyProperty for TitleProperty.
        ///     Flags:              None
        ///     Default Value:      String.Empty
        /// </summary>
        public static readonly DependencyProperty TitleProperty =
                DependencyProperty.Register("Title", typeof(String), typeof(Window),
                        new FrameworkPropertyMetadata(String.Empty,
                                new PropertyChangedCallback(_OnTitleChanged)),
                        new ValidateValueCallback(_ValidateText));
        /// <summary>
        ///     The data that will be displayed as the title of the window.
        ///     Hosts are free to display the title in any manner that they
        ///     want.  For example, the browser may display the title set via
        ///     the Title property somewhere besides the caption bar
        /// </summary>
        [Localizability(LocalizationCategory.Title)]
        public string Title
        {
            get
            {
                VerifyContextAndObjectState();
 
                return (String)GetValue(TitleProperty);
            }
            set
            {
                VerifyContextAndObjectState();
 
                SetValue(TitleProperty, value);
            }
        }
 
        /// <summary>
        ///     The DependencyProperty for Icon
        ///     Flags:              None
        ///     Default Value:      None
        /// </summary>
        public static readonly DependencyProperty IconProperty =
                DependencyProperty.Register(
                        "Icon",
                        typeof(ImageSource),
                        typeof(Window),
                        new FrameworkPropertyMetadata(
                                new PropertyChangedCallback(_OnIconChanged),
                                new CoerceValueCallback(VerifyAccessCoercion)));
 
        /// <summary>
        ///     Sets the Icon of the Window
        /// </summary>
        /// <remarks>
        ///     Following is the precedence for displaying the icon:
        ///
        ///     1) Use ImageSource provided by the Icon property.  If Icon property is
        ///     null, see 2 below.
        ///     2) If Icon Property is not set, then use the Application icon
        ///     embedded in the exe.  Querying Icon property returns null.
        ///     3) If no icon is embedded in the exe, then we set IntPtr.Zero
        ///     as the icon and Win32 displays its default icon.  Querying Icon
        ///     property returns null.
        ///
        ///     If Icon property is set, Window does not dispose that object when it
        ///     is closed.
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        public ImageSource Icon
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // Icon is not allowed
                VerifyApiSupported();
 
                return (ImageSource) GetValue(IconProperty);
            }
 
            set
            {
                // this call ends up throwing an exception if accessing
                // Icon is not allowed
                VerifyApiSupported();
                VerifyContextAndObjectState();
 
                SetValue(IconProperty, value);
            }
        }
 
        /// <summary>
        ///     The DependencyProperty for SizeToContentProperty.
        ///     Flags:              None
        ///     Default Value:      "SizeToContent.Manual"
        /// </summary>
        public static readonly DependencyProperty SizeToContentProperty =
                DependencyProperty.Register("SizeToContent",
                        typeof(SizeToContent),
                        typeof(Window),
                        new FrameworkPropertyMetadata(
                                SizeToContent.Manual,
                                new PropertyChangedCallback(_OnSizeToContentChanged)),
                        new ValidateValueCallback(_ValidateSizeToContentCallback));
 
        /// <summary>
        /// Auto size Window to its content's size
        /// </summary>
        /// <remarks>
        /// 1. SizeToContent can be applied to Width Height independently
        /// 2. After SizeToContent is set, setting Width/Height does not take affect if that
        ///    dimension is sizing to content.
        /// 3. SizeToContent is turned off (restored to SizeToContent.Manual) if user starts to
        ///    interact with window in terms of size
        /// </remarks>
        /// <value>
        /// Default value is SizeToContent.Manual
        /// </value>
        public SizeToContent SizeToContent
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // SizeToContent is not allowed
                VerifyApiSupported();
 
                return (SizeToContent) GetValue(SizeToContentProperty);
            }
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // SizeToContent is not allowed
                VerifyApiSupported();
 
                SetValue(SizeToContentProperty, value);
            }
        }
 
        /// <summary>
        /// DependencyProperty for <see cref="Top" /> property.
        /// </summary>
 
        public static readonly DependencyProperty TopProperty =
                Canvas.TopProperty.AddOwner(typeof(Window),
                        new FrameworkPropertyMetadata(
                                Double.NaN,
                                new PropertyChangedCallback(_OnTopChanged),
                                new CoerceValueCallback(CoerceTop)));
 
        /// <summary>
        ///     Position for Top of the host window
        /// </summary>
        /// <remarks>
        ///     The following values are valid:
        ///     Positive Doubles: sets the top location to the specified value
        ///     NaN: indicates to use the system default value. This
        ///     is the default for Top property
        ///     PositiveInfinity, NegativeInfinity: These are invalid inputs.
        /// </remarks>
        /// <value></value>
        [TypeConverter($"System.Windows.LengthConverter, PresentationFramework, Version={BuildInfo.WCP_VERSION}, Culture=neutral, PublicKeyToken={BuildInfo.WCP_PUBLIC_KEY_TOKEN}, Custom=null")]
        public double Top
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing Top
                // is not allowed
                VerifyApiSupported();
                return (double)GetValue(TopProperty);
            }
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing Top
                // is not allowed
                VerifyApiSupported();
 
                // we don't do an if check here to see if the new value is the same
                // as the current Top value b/c the current value maybe as a result
                // of user resizing which means the the local value of Top has not
                // been written to.  So, if window.Top is explicitly set now we want
                // to write to the local value.  We do make this if check in Top
                // property invalidation callback for optimization
                SetValue(TopProperty, value);
            }
        }
 
        /// <summary>
        /// DependencyProperty for <see cref="Left" /> property.
        /// </summary>
        public static readonly DependencyProperty LeftProperty =
                Canvas.LeftProperty.AddOwner(typeof(Window),
                        new FrameworkPropertyMetadata(
                                Double.NaN,
                                new PropertyChangedCallback(_OnLeftChanged),
                                new CoerceValueCallback(CoerceLeft)));
 
        /// <summary>
        ///     Position for Left edge of  coordinate of the host window
        /// </summary>
        /// <remarks>
        ///     The following values are valid:
        ///     Positive Doubles: sets the top location to the specified value
        ///     NaN: indicates to use the system default value. This
        ///     is the default for Top property
        ///     PositiveInfinity, NegativeInfinity: These are invalid inputs.
        /// </remarks>
        /// <value></value>
        [TypeConverter($"System.Windows.LengthConverter, PresentationFramework, Version={BuildInfo.WCP_VERSION}, Culture=neutral, PublicKeyToken={BuildInfo.WCP_PUBLIC_KEY_TOKEN}, Custom=null")]
        public double Left
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing left
                // is not allowed
                VerifyApiSupported();
                return (double)GetValue(LeftProperty);
            }
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing left
                // is not allowed
                VerifyApiSupported();
 
                // we don't do an if check here to see if the new value is the same
                // as the current Left value b/c the current value maybe as a result
                // of user resizing which means the the local value of Left has not
                // been written to.  So, if window.Left is explicitly set now we want
                // to write to the local value.  We do make this if check in Left
                // property invalidation callback for optimization
                SetValue(LeftProperty, value);
            }
        }
 
        /// <summary>
        ///     This property returns the restoring rectangle of the window.  This information
        ///     can be used to track a users size and position preferences when the
        ///     Window is maximized or minimized.
        ///
        ///     If RestoreBounds is queried before the Window has been shown or after it has
        ///     been closed, it will return Rect.Empty.
        /// </summary>
        /// <remarks>
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
 
        public Rect RestoreBounds
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing RestoreBounds
                // is not allowed
                VerifyApiSupported();
 
                // either before calling show or after closing AND
                // Adding check for IsCompositionTargetInvalid
                if (IsSourceWindowNull || IsCompositionTargetInvalid)
                {
                    return Rect.Empty;
                }
 
                return GetNormalRectLogicalUnits(Handle);
            }
        }
 
        /// <summary>
        ///     This enum can have following values
        ///         Manual (default)
        ///         CenterScreen
        ///         CenterOwner
        ///
        ///     If the WindowStartupLocation is WindowStartupLocation.Manual then
        ///     Top and Left properites are used to position the window.
        ///     This property is used only before window creation. Once the window is
        ///     created hiding it and showing it will not take this property into account.
        /// </summary>
        /// <remarks>
        ///     WindowStartupLocation is used to position the window only it it is set to
        ///     WindowStartupLocation.CenterScreen or WindowStartupLocation.CenterOwner,
        ///     otherwise Top/Left is used.  Furthermore, if determining the location
        ///     of the window is not possible when WindowStartupLocation is set to
        ///     WindowStartupLocation.CenterScreen or WindowStartupLocation.Owner, then
        ///     Top/Left is used instead.
        /// </remarks>
        [DefaultValue(WindowStartupLocation.Manual)]
        public WindowStartupLocation WindowStartupLocation
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // WindowStartupLocation is not allowed
                VerifyApiSupported();
 
                return _windowStartupLocation;
            }
 
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // WindowStartupLocation is not allowed
                VerifyApiSupported();
 
                //validate WindowStartupLocation enum
                if (!IsValidWindowStartupLocation(value))
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof( WindowStartupLocation ));
                }
                _windowStartupLocation = value;
            }
        }
 
        /// <summary>
        ///     The DependencyProperty for ShowInTaskbarProperty.
        ///     Flags:              None
        ///     Default Value:      true
        /// </summary>
        public static readonly DependencyProperty ShowInTaskbarProperty =
                DependencyProperty.Register("ShowInTaskbar",
                        typeof(bool),
                        typeof(Window),
                        new FrameworkPropertyMetadata(BooleanBoxes.TrueBox,
                                new PropertyChangedCallback(_OnShowInTaskbarChanged),
                                new CoerceValueCallback(VerifyAccessCoercion)));
 
        ///<summary>
        ///     Determines if the window should show up in the system taskbar.
        ///     This also determines if the window appears in the Alt-Tab list.
        ///</summary>
        public bool ShowInTaskbar
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // ShowInTaskbar is not allowed
                VerifyApiSupported();
 
                return (bool) GetValue(ShowInTaskbarProperty);
            }
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // ShowInTaskbar is not allowed
                VerifyApiSupported();
 
                SetValue(ShowInTaskbarProperty, BooleanBoxes.Box(value));
            }
        }
 
        /// <summary>
        ///     The key needed set a read-only property.
        /// </summary>
        private static readonly DependencyPropertyKey IsActivePropertyKey
            = DependencyProperty.RegisterReadOnly("IsActive", typeof(bool), typeof(Window),
                                          new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
 
        /// <summary>
        ///     The DependencyProperty for IsActive.
        ///     Flags:              None
        ///     Default Value:      True
        ///     Read-Only:          true
        /// </summary>
        public static readonly DependencyProperty IsActiveProperty
            = IsActivePropertyKey.DependencyProperty;
 
        /// <summary>
        /// IsActive property. It indicates whether the Window is active.
        /// The title bar will have the active theme. The active window will be
        /// the topmost of all top-level windows that don't explicitly set the TopMost property or style.
        /// If a window is active, focus is within the window.
        /// </summary>
        public bool IsActive
        {
            get
            {
                VerifyContextAndObjectState();
                return (bool)GetValue(IsActiveProperty);
            }
        }
 
        /// <summary>
        ///     This set the owner for the property of the current window.
        ///     If the window has owner and the owner is minimized then
        ///     owned window is also minimized. Owner window can never be
        ///     over owned window. Owned window is NOT modal. So user can
        ///     still interact with owner window. This property can not be
        ///     set of the top level window.
        /// </summary>
        ///<remarks>
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        ///</remarks>
        [DefaultValue(null)]
        public Window Owner
        {
            get
            {
                // this call ends up throwing an exception if accessing Owner
                // is not allowed
                VerifyApiSupported();
                VerifyContextAndObjectState();
                return _ownerWindow;
            }
            set
            {
                // this call ends up throwing an exception if accessing Owner
                // is not allowed
                VerifyApiSupported();
                VerifyContextAndObjectState();
                if (value == this)
                {
                    throw new ArgumentException(SR.CannotSetOwnerToItself);
                }
 
                if ( _showingAsDialog == true )
                {
                    throw new InvalidOperationException(SR.CantSetOwnerAfterDialogIsShown);
                }
 
                if (value != null && value.IsSourceWindowNull == true)
                {
                    // Try to be specific in the error message.
                    if (value._disposed)
                    {
                        throw new InvalidOperationException(SR.CantSetOwnerToClosedWindow);
                    }
                    throw new InvalidOperationException(SR.CantSetOwnerWhosHwndIsNotCreated);
                }
 
                if ( _ownerWindow == value )
                {
                    return;
                }
 
                if (!_disposed)
                {
                    // Check to see if value is already a child of this window.
                    // If yes, throw Exception
                    if (value != null)
                    {
                        WindowCollection ownedWindows = OwnedWindows;
                        for (int i = 0; i < ownedWindows.Count; i++)
                        {
                            if (ownedWindows[i] == value)
                            {
                                throw new ArgumentException(SR.Format(SR.CircularOwnerChild, value, this));
                            }
                        }
                    }
 
                    // Update OwnerWindows of the previous owner
                    if (_ownerWindow != null)
                    {
                        // using OwnedWindowsInternl b/c we want to modifying the
                        // underlying collection
                        _ownerWindow.OwnedWindowsInternal.Remove(this);
                    }
                }
 
                // Update parent handle. If value is null, then make parent
                // handle IntPtr.Zero
                _ownerWindow = value;
 
                // We should not do anything if the window is already closed and maybe throw exception.
                // In Dev10, it is unknown whether we can begin to throw exceptions, because it is a BC.
                // In Dev10, we still update _ownerWindow after window is closed just so that the Owner getter
                // returns the right value.
                if (_disposed)
                {
                    return;
                }
 
                SetOwnerHandle(_ownerWindow != null ? _ownerWindow.Handle: IntPtr.Zero);
 
                // Update OwnerWindows of the new owner
                if (_ownerWindow != null)
                {
                    // using OwnedWindowsInternl b/c we want to modifying the
                    // underlying collection
                    _ownerWindow.OwnedWindowsInternal.Add(this);
                }
            }
        }
 
        /// This code checks to see if the owner property is null
        /// True if the window is null , false other wise
        private bool IsOwnerNull
        {
            get
            {
                return (_ownerWindow == null);
            }
}
        /// <summary>
        ///     This is a collection of windows that are owned by current window.
        /// </summary>
        // This collection is a copy of the original one to avoid synchronizing issues.
        // DO-NOT USE THIS PROPERY IF YOU MEAN TO MODIFY THE UNDERLYING COLLECTION.  USE
        // OwnedWindowsInternal PROPERTY FOR MODIFYING THE UNDERLYING DATASTRUCTURE.
        public WindowCollection OwnedWindows
        {
            get
            {
                VerifyContextAndObjectState();
                return OwnedWindowsInternal.Clone();
            }
        }
 
        /// <summary>
        /// Gets Showing as dialog
        /// </summary>
        internal bool IsShowingAsDialog
        {
            get
            {
                return _showingAsDialog;
            }
        }
 
        /// <summary>
        /// Sets/gets DialogResult
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), TypeConverter(typeof(DialogResultConverter))]
        public Nullable<bool> DialogResult
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // DialogResult is not allowed
                VerifyApiSupported();
 
                return _dialogResult;
            }
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // DialogResult is not allowed
                VerifyApiSupported();
 
                if (_showingAsDialog == true)
                {
                    // This value should be set only after the window is created and shown as dialog.
 
                    // When _showingAsDialog is set, _sourceWindow must be set too.
                    Debug.Assert( IsSourceWindowNull == false , "IsSourceWindowNull cannot be true when _showingAsDialog is true");
 
 
                    // According to the new design, setting DialogResult to its current value will not have any effect.
                    if (_dialogResult != value)
                    {
                        _dialogResult = value;
 
                        // if DialogResult is set from within a Closing event then
                        // the window is in the closing state.  Thus, if we call
                        // Close() again from here we go into an infinite loop.
                        //
                        // Note: Windows OS bug # 934500 Setting DialogResult
                        // on the Closing EventHandler of a Dialog causes StackOverFlowException
 
                        if(_isClosing == false)
                        {
                            Close();
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException(SR.DialogResultMustBeSetAfterShowDialog);
}
            }
        }
 
        /// <summary>
        ///     The DependencyProperty for WindowStyleProperty.
        ///     Flags:              None
        ///     Default Value:      WindowStyle.SingleBorderWindow
        /// </summary>
        public static readonly DependencyProperty WindowStyleProperty =
                DependencyProperty.Register("WindowStyle", typeof(WindowStyle), typeof(Window),
                        new FrameworkPropertyMetadata(
                                WindowStyle.SingleBorderWindow,
                                new PropertyChangedCallback(_OnWindowStyleChanged),
                                new CoerceValueCallback(CoerceWindowStyle)),
                        new ValidateValueCallback(_ValidateWindowStyleCallback));
 
        /// <summary>
        ///     Defines the visual style of the window (3DBorderWindow,
        ///     SingleBorderWindow, ToolWindow, none).
        /// </summary>
        /// <remarks>
        ///     Default will be SingleBorderWindow.
        /// </remarks>
        public WindowStyle WindowStyle
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // WindowStyle is not allowed
                VerifyApiSupported();
 
                return (WindowStyle) GetValue(WindowStyleProperty);
            }
            set
            {
                VerifyContextAndObjectState();
                // this call ends up throwing an exception if accessing
                // WindowStyle is not allowed
                VerifyApiSupported();
 
                SetValue(WindowStyleProperty, value);
            }
        }
 
        private static object CoerceWindowStyle(DependencyObject d, object value)
        {
            value = VerifyAccessCoercion(d, value);
 
            if (!((Window)d).IsSourceWindowNull)
            {
                // Since the new style hasn't actually been set yet, verify against the new value.
                ((Window)d).VerifyConsistencyWithAllowsTransparency((WindowStyle)value);
            }
 
            return value;
        }
 
        /// <summary>
        ///     The DependencyProperty for WindowStateProperty.
        ///     Flags:              None
        ///     Default Value:      WindowState.Normal
        /// </summary>
        public static readonly DependencyProperty WindowStateProperty =
                DependencyProperty.Register("WindowState", typeof(WindowState), typeof(Window),
                        new FrameworkPropertyMetadata(
                                WindowState.Normal,
                                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                new PropertyChangedCallback(_OnWindowStateChanged),
                                new CoerceValueCallback(VerifyAccessCoercion)),
                        new ValidateValueCallback(_ValidateWindowStateCallback));
 
        /// <summary>
        ///     Current state of the window.  Valid options are Maximized, Minimized,
        ///     or Normal.  The host window may choose to ignore a request to change
        ///     the current window state.
        /// </summary>
        public WindowState WindowState
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // WindowState is not allowed
                VerifyApiSupported();
 
                return (WindowState) GetValue(WindowStateProperty);
            }
            set
            {
                VerifyContextAndObjectState();
                // this call ends up throwing an exception if accessing
                // WindowState is not allowed
                VerifyApiSupported();
 
                SetValue(WindowStateProperty, value);
            }
        }
 
        /// <summary>
        ///     The DependencyProperty for the ResizeMode property.
        ///     Flags:                  AffectsMeasure
        ///     Default Value:      false
        /// </summary>
        public static readonly DependencyProperty ResizeModeProperty =
                DependencyProperty.Register("ResizeMode", typeof(ResizeMode), typeof(Window),
                        new FrameworkPropertyMetadata(ResizeMode.CanResize,
                                FrameworkPropertyMetadataOptions.AffectsMeasure,
                                new PropertyChangedCallback(_OnResizeModeChanged),
                                new CoerceValueCallback(VerifyAccessCoercion)),
                        new ValidateValueCallback(_ValidateResizeModeCallback));
 
        /// <summary>
        ///     Current state of the window.  Valid options are Maximized, Minimized,
        ///     or Normal.  The host window may choose to ignore a request to change
        ///     the current window state.
        /// </summary>
        public ResizeMode ResizeMode
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // ResizeMode is not allowed
                VerifyApiSupported();
 
                return ((ResizeMode) GetValue(ResizeModeProperty));
            }
            set
            {
                VerifyContextAndObjectState();
                // this call ends up throwing an exception if accessing
                // ResizeMode is not allowed
                VerifyApiSupported();
 
                SetValue(ResizeModeProperty, value);
            }
        }
 
        /// <summary>
        ///     The DependencyProperty for TopmostProperty.
        ///     Flags:              None
        ///     Default Value:      false
        /// </summary>
        public static readonly DependencyProperty TopmostProperty =
                DependencyProperty.Register("Topmost",
                        typeof(bool),
                        typeof(Window),
                        new FrameworkPropertyMetadata(BooleanBoxes.FalseBox,
                                new PropertyChangedCallback(_OnTopmostChanged),
                                new CoerceValueCallback(VerifyAccessCoercion)));
 
        /// <summary>
        ///     Determines if this window is always on the top.
        /// </summary>
        public bool Topmost
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // Topmost is not allowed
                VerifyApiSupported();
 
                return (bool) GetValue(TopmostProperty);
            }
            set
            {
                VerifyContextAndObjectState();
                // this call ends up throwing an exception if accessing
                // Topmost is not allowed
                VerifyApiSupported();
 
                SetValue(TopmostProperty, BooleanBoxes.Box(value));
            }
        }
 
        public static readonly DependencyProperty ShowActivatedProperty =
                DependencyProperty.Register("ShowActivated",
                        typeof(bool),
                        typeof(Window),
                        new FrameworkPropertyMetadata(BooleanBoxes.TrueBox,
                                null,
                                new CoerceValueCallback(VerifyAccessCoercion)));
 
        /// <summary>
        ///     Determines if this window is activated when shown (default = true).
        /// </summary>
        /// <remarks>
        ///     Not supported for RBW.
        /// </remarks>
        public bool ShowActivated
        {
            get
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // ShowActivated is not allowed
                VerifyApiSupported();
 
                return (bool)GetValue(ShowActivatedProperty);
            }
            set
            {
                VerifyContextAndObjectState();
 
                // this call ends up throwing an exception if accessing
                // ShowActivated is not allowed
                VerifyApiSupported();
 
                SetValue(ShowActivatedProperty, BooleanBoxes.Box(value));
            }
        }
 
        #endregion Public Properties
 
        //---------------------------------------------------
        //
        // Public Events
        //
        //---------------------------------------------------
        #region Public Events
 
        /// <summary>
        ///     This event is raised after the window source is created before it is shown
        /// </summary>
        public event EventHandler SourceInitialized
        {
            add { Events.AddHandler(EVENT_SOURCEINITIALIZED, value); }
            remove { Events.RemoveHandler(EVENT_SOURCEINITIALIZED, value); }
        }
 
        /// <summary>
        ///     This event is raised after the DPI of the screen on which the Window is displayed, changes.
        /// </summary>
        public event DpiChangedEventHandler DpiChanged
        {
            add { AddHandler(Window.DpiChangedEvent, value); }
            remove { RemoveHandler(Window.DpiChangedEvent, value); }
        }
 
        /// <summary>
        ///     This event is raised when the window is activated
        /// </summary>
        public event EventHandler Activated
        {
            add { Events.AddHandler(EVENT_ACTIVATED, value); }
            remove { Events.RemoveHandler(EVENT_ACTIVATED, value); }
        }
 
        /// <summary>
        ///     This event is raised when the window is deactivated
        /// </summary>
        public event EventHandler Deactivated
        {
            add { Events.AddHandler(EVENT_DEACTIVATED, value); }
            remove { Events.RemoveHandler(EVENT_DEACTIVATED, value); }
        }
 
        /// <summary>
        ///     This event is raised when the window state is changed
        /// </summary>
        public event EventHandler StateChanged
        {
            add { Events.AddHandler(EVENT_STATECHANGED, value); }
            remove { Events.RemoveHandler(EVENT_STATECHANGED, value); }
        }
 
        /// <summary>
        ///     This event is raised when the window location is changed
        /// </summary>
        public event EventHandler LocationChanged
        {
            add { Events.AddHandler(EVENT_LOCATIONCHANGED, value); }
            remove { Events.RemoveHandler(EVENT_LOCATIONCHANGED, value); }
        }
 
        /// <summary>
        ///     This event is raised before the window is closed
        /// </summary>
        /// <remarks>
        ///     The user can set the CancelEventArg.Cancel property to true to prevent
        ///     the window from closing. However, if the Applicaiton is shutting down
        ///     the window closing cannot be cancelled
        /// </remarks>
        public event CancelEventHandler Closing
        {
            add { Events.AddHandler(EVENT_CLOSING, value); }
            remove { Events.RemoveHandler(EVENT_CLOSING, value); }
        }
 
        /// <summary>
        ///     This event is raised when the window is closed.
        /// </summary>
        public event EventHandler Closed
        {
            add { Events.AddHandler(EVENT_CLOSED, value); }
            remove { Events.RemoveHandler(EVENT_CLOSED, value); }
        }
 
        /// <summary>
        ///     This event is raised when the window and its content is rendered.
        /// </summary>
        public event EventHandler ContentRendered
        {
            add { Events.AddHandler(EVENT_CONTENTRENDERED, value); }
            remove { Events.RemoveHandler(EVENT_CONTENTRENDERED, value); }
        }
 
        #endregion Public Events
 
        //---------------------------------------------------
        //
        // Internal Events
        //
        //---------------------------------------------------
        #region Internal Events
 
        /// <summary>
        ///     This event is raised when the <see cref="System.Windows.Media.VisualCollection"/> of
        ///     this <see cref="Window"/> object is modified
        /// </summary>
        /// <remarks>
        ///     This corresponds to <see cref="OnVisualChildrenChanged(DependencyObject, DependencyObject)"/>.
        ///     The primary consumer of this event is <see cref="System.Windows.Shell.WindowChromeWorker"/>,
        ///     which only needs to be aware of the fact that Visual children have changed, but doesn't
        ///     need to know which children have changed. Therefore the <see cref="DependencyObject"/>
        ///     parameters of <see cref="OnVisualChildrenChanged(DependencyObject, DependencyObject)"/> are
        ///     not passed along to the <see cref="Shell.WindowChromeWorker"/> via this event.
        /// </remarks>
        internal event EventHandler<EventArgs> VisualChildrenChanged
        {
            add { Events.AddHandler(EVENT_VISUALCHILDRENCHANGED, value); }
            remove { Events.RemoveHandler(EVENT_VISUALCHILDRENCHANGED, value); }
        }
 
        #endregion
 
        //---------------------------------------------------
        //
        // Protected Methods
        //
        //---------------------------------------------------
        #region Protected Methods
 
        /// <summary>
        /// Creates AutomationPeer (<see cref="UIElement.OnCreateAutomationPeer"/>)
        /// </summary>
        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new WindowAutomationPeer(this);
        }
 
        /// <summary>
        /// OnDpiChanged is called when the DPI at which this Window is rendered, changes.
        /// </summary>
        protected override void OnDpiChanged(DpiScale oldDpi, DpiScale newDpi)
        {
            RaiseEvent(new DpiChangedEventArgs(oldDpi, newDpi, Window.DpiChangedEvent, this));
        }
 
        /// <summary>
        /// OnVisualParentChanged is called when the parent of the Visual is changed.
        /// </summary>
        /// <param name="oldParent">Old parent or null if the Visual did not have a parent before.</param>
        protected internal sealed override void OnVisualParentChanged(DependencyObject oldParent)
        {
            VerifyContextAndObjectState();
            base.OnVisualParentChanged(oldParent);
 
            // Checking for Visual parent here covers all the scenarios
            // including the following:
 
            // Window w1 = new Window();
            // Window w2 = new WIndow();
            // w1.Show();
            // w2.Show();
            // w1.VisualChildren.Add(w2);
 
 
            // Window w1 = new Window();
            // Window w2 = new WIndow();
            // w1.Show();
            // w1.VisualChildren.Add(w2);
            //  w2.Show();
 
            if ( VisualTreeHelper.GetParent(this) != null )
            {
                throw new InvalidOperationException(SR.WindowMustBeRoot);
            }
        }
 
        /// <summary>
        ///     Measurement override. Implements content sizing logic.
        /// </summary>
        /// <remarks>
        ///     Deducts the frame size from the constraint and then passes it on
        ///     to its child.  Only supports one Visual child (just like control)
        /// </remarks>
        protected override Size MeasureOverride(Size availableSize)
        {
            VerifyContextAndObjectState();
 
            // Window content should respect Window's Max/Min size
            // setting in a SizeToContent Window.
            //
            // Take Min/Max[Width/Height] into consideration.  The logic here is similar to
            // that used in FE.MeasureCore but is limited to Min/Max restriction.  Furthermore,
            // we have our own version of MinMax struct called WindowMinMax that takes
            // SizeToContent into account when calculating the min/max values for height/width.
            //
            // We don't do anything special in ArrangeOverride the Arrange size is guaranteed
            // to be the available hwnd size which should be atleast as big as the desired size.
 
            Size frameworkAvailableSize = new Size(availableSize.Width, availableSize.Height);
 
            WindowMinMax mm = GetWindowMinMax();
 
            frameworkAvailableSize.Width  = Math.Max(mm.minWidth,  Math.Min(frameworkAvailableSize.Width, mm.maxWidth));
            frameworkAvailableSize.Height = Math.Max(mm.minHeight, Math.Min(frameworkAvailableSize.Height, mm.maxHeight));
 
            //  call to specific layout to measure
            Size desiredSize = MeasureOverrideHelper(frameworkAvailableSize);
 
            //  maximize desiredSize with user provided min size
            desiredSize = new Size(
                Math.Max(desiredSize.Width, mm.minWidth),
                Math.Max(desiredSize.Height, mm.minHeight));
 
            return desiredSize;
        }
 
        /// <summary>
        ///     ArrangeOverride allows for the customization of the positioning of children.
        /// </summary>
        /// <remarks>
        ///     Deducts the frame size of the window from the constraint and then
        ///     arranges its child.  Supports only one child.
        /// </remarks>
        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            VerifyContextAndObjectState();
 
            // Window content should respect Window's Max/Min size
            // setting in a SizeToContent Window.
 
            WindowMinMax mm = GetWindowMinMax();
 
            arrangeBounds.Width  = Math.Max(mm.minWidth,  Math.Min(arrangeBounds.Width, mm.maxWidth));
            arrangeBounds.Height = Math.Max(mm.minHeight, Math.Min(arrangeBounds.Height, mm.maxHeight));
 
            // Three primary cases
            //      1) hwnd does not exist  -- don't do anything
            //      1a) CompositionTarget is invalid -- don't do anything
            //      2) Child visual exists  -- arrange child at arrangeBounds - window frame size
            //      3) No Child visual      -- don't do anything
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return arrangeBounds;
            }
 
            if (this.VisualChildrenCount > 0)
            {
                UIElement child = this.GetVisualChild(0) as UIElement;
                if (child != null)
                {
                    // Find out the size of the window frame x.
                    // (constraint - x) is the size we pass onto
                    // our child
                    Size frameSize = GetHwndNonClientAreaSizeInMeasureUnits();
 
                    // In some instances (constraint size - frame size) can be negative. One instance
                    // is when window is set to minimized before layout has happened.  Apparently, Win32
                    // gives a rect(-32000, -32000, -31840, -31975) for GetWindowRect when hwnd is
                    // minimized.  However, when we calculate the frame size we get width = 8 and
                    // height = 28!!!  Here, we will take the max of zero and the difference b/w the
                    // hwnd size and the frame size
                    //
                    // PS Windows OS Bug: 955861
 
                    Size childArrangeBounds = new Size();
                    childArrangeBounds.Width = Math.Max(0.0, arrangeBounds.Width - frameSize.Width);
                    childArrangeBounds.Height = Math.Max(0.0, arrangeBounds.Height - frameSize.Height);
 
                    child.Arrange(new Rect(childArrangeBounds));
 
                    // Windows OS bug # 928719, 953458
                    // The default impl of FlowDirection is that it adds a transform on the element
                    // on whom the FlowDirection property is RlTb.  However, transforms work only if
                    // there is a parent visual.  In the window case, we are the root and thus this
                    // does not work.  Thus, we add the same transform to our child, if our
                    // FlowDireciton = Rltb.
                    if (FlowDirection == FlowDirection.RightToLeft)
                    {
                        InternalSetLayoutTransform(child, new MatrixTransform(-1.0, 0.0, 0.0, 1.0, childArrangeBounds.Width, 0.0));
                    }
}
            }
            return arrangeBounds;
        }
 
        /// <summary>
        ///     This method is invoked when the Content property changes.
        /// </summary>
        /// <param name="oldContent">The old value of the Content property.</param>
        /// <param name="newContent">The new value of the Content property.</param>
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);
 
            // FxCop: ConstructorsShouldNotCallBaseClassVirtualMethods::
            // System.Windows (presentationframework.dll 2 violation)
            //
            // We can't set IWS property in the cctor since it results
            // in calling some virtual.  So, as an alternative we set it
            // when content is changed and when we set the root visual.
            // We set it here, b/c once window has logical children, they
            // can query for inherited IWS property.
            SetIWindowService();
 
            // We post a dispatcher work item to fire ContentRendered
            // only if this is Loaded in the tree.  If not, we will
            // post it from the LoadedHandler.  This guarantees that
            // we don't fire ContentRendered on a subtree that is not
            // connected to a PresentationSource
            if (IsLoaded == true)
            {
                PostContentRendered();
            }
            else
            {
                // _postContentRenderedFromLoadedHandler == true means
                // that we deferred to the Loaded event to PostConetentRendered
                // for the previous content change and Loaded has not fired yet.
                // Thus we don't want to hook up another event handler
                if (_postContentRenderedFromLoadedHandler == false)
                {
                    this.Loaded += new RoutedEventHandler(LoadedHandler);
                    _postContentRenderedFromLoadedHandler = true;
                }
            }
        }
 
        /// <summary>
        ///     This even fires after the window source is created before it is shown. This event is non cancelable and is
        ///     for user infromational purposes
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers that subclass
        ///     the event. If you override this method - you need to call base.OnSourceInitialized(...) for
        ///     the corresponding event to be raised.
        /// </remarks>
        /// <param name="e"></param>
        protected virtual void OnSourceInitialized(EventArgs e)
        {
            VerifyContextAndObjectState();
 
            // Setting WindowBackdrop
            WindowBackdropManager.SetBackdrop(this, WindowBackdropType);
 
            EventHandler handler = (EventHandler)Events[EVENT_SOURCEINITIALIZED];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This event fires when window is activated. This event is non cancelable and is
        ///     for user infromational purposes
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers that subclass
        ///     the event. If you override this method - you need to call base.OnActivated(...) for
        ///     the corresponding event to be raised.
        /// </remarks>
        /// <param name="e"></param>
        protected virtual void OnActivated(EventArgs e)
        {
            VerifyContextAndObjectState();
            EventHandler handler = (EventHandler)Events[EVENT_ACTIVATED];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This even fires when window is deactivated. This event is non cancelable and is
        ///     for user infromational purposes
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers that subclass
        ///     the event. If you override this method - you need to call base.OnDeactivated(...) for
        ///     the corresponding event to be raised.
        /// </remarks>
        protected virtual void OnDeactivated(EventArgs e)
        {
            VerifyContextAndObjectState();
            EventHandler handler = (EventHandler)Events[EVENT_DEACTIVATED];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This even fires when window state is changed. This event is non
        ///     cancelable and is for user infromational purposes
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers
        ///     that subclass the event. If you override this method - you need to call
        ///     base.OnStateChanged(...) for the corresponding event to be raised.
        /// </remarks>
        protected virtual void OnStateChanged(EventArgs e)
        {
            VerifyContextAndObjectState();
            EventHandler handler = (EventHandler)Events[EVENT_STATECHANGED];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This event fires when window location changes. This event is not
        ///     cancelable and is for user infromational purposes
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers that subclass
        ///     the event. If you override this method - you need to call base.OnLocationChanged(...) for
        ///     the corresponding event to be raised.
        /// </remarks>
        protected virtual void OnLocationChanged(EventArgs e)
        {
            VerifyContextAndObjectState();
            EventHandler handler = (EventHandler)Events[EVENT_LOCATIONCHANGED];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This event fires when window is Closing. This event is cancelable and thus the
        ///     user can set the CancelEventArgs.Cancel property to true to dismiss window
        ///     closing
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers that subclass
        ///     the event. If you override this method - you need to call base.OnClosing(...) for
        ///     the corresponding event to be raised.
        /// </remarks>
        protected virtual void OnClosing(CancelEventArgs e)
        {
            VerifyContextAndObjectState();
            CancelEventHandler handler = (CancelEventHandler)Events[EVENT_CLOSING];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This event fires when window is closed. This event is non cancelable and is
        ///     for user infromational purposes
        /// </summary>
        /// <remarks>
        ///     This method follows the .Net programming guideline of having a protected virtual
        ///     method that raises an event, to provide a convenience for developers that subclass
        ///     the event. If you override this method - you need to call base.OnClosed(...) for
        ///     the corresponding event to be raised.
        /// </remarks>
        protected virtual void OnClosed(EventArgs e)
        {
            VerifyContextAndObjectState();
            EventHandler handler = (EventHandler)Events[EVENT_CLOSED];
            if (handler != null) handler(this, e);
        }
 
        /// <summary>
        ///     This override fires the ContentRendered event.
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnContentRendered(EventArgs e)
        {
            VerifyContextAndObjectState();
 
            // After the content is rendered we want to check if there is an element that needs to be focused
            // If there is - set focus to it
            DependencyObject doContent = Content as DependencyObject;
            if (doContent != null)
            {
                IInputElement focusedElement = FocusManager.GetFocusedElement(doContent) as IInputElement;
                if (focusedElement != null)
                    focusedElement.Focus();
            }
 
            EventHandler handler = (EventHandler)Events[EVENT_CONTENTRENDERED];
            if (handler != null) handler(this, e);
        }
        #endregion Protected Methods
 
        //---------------------------------------------------
        //
        // Protected Internal Methods
        //
        //---------------------------------------------------
        #region Protected Internal Methods
 
        /// <summary>
        /// Called when the <see cref="System.Windows.Media.VisualCollection"/> of the visual object is modified
        /// </summary>
        /// <param name="visualAdded">The <see cref="Visual"/> that was added to the collection</param>
        /// <param name="visualRemoved">The <see cref="Visual"/> that was removed from the collection</param>
        protected internal override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
        {
            VerifyContextAndObjectState();
 
            var handler = Events[EVENT_VISUALCHILDRENCHANGED] as EventHandler<EventArgs>;
            handler?.Invoke(this, new EventArgs());
        }
 
        #endregion
 
        //---------------------------------------------------
        //
        // Internal Methods
        //
        //---------------------------------------------------
        #region Internal Methods
        internal Point DeviceToLogicalUnits(Point ptDeviceUnits)
        {
            Invariant.Assert(IsCompositionTargetInvalid == false, "IsCompositionTargetInvalid is supposed to be false here");
            Point ptLogicalUnits = _swh.CompositionTarget.TransformFromDevice.Transform(ptDeviceUnits);
            return ptLogicalUnits;
        }
 
        internal Point LogicalToDeviceUnits(Point ptLogicalUnits)
        {
            Invariant.Assert(IsCompositionTargetInvalid == false, "IsCompositionTargetInvalid is supposed to be false here");
            Point ptDeviceUnits = _swh.CompositionTarget.TransformToDevice.Transform(ptLogicalUnits);
            return ptDeviceUnits;
        }
 
        internal void AddFluentDictionary(ResourceDictionary value, out bool invalidateResources)
        {
            invalidateResources = false;
 
            if(_reloadFluentDictionary && !AreResourcesInitialized)
            {
                if(value != null && ThemeMode != ThemeMode.None)
                {
                    value.MergedDictionaries.Insert(0, ThemeManager.GetThemeDictionary(ThemeMode));
                    invalidateResources = true;
                }
 
                _reloadFluentDictionary = false;
            }
        }
 
        internal static bool VisibilityToBool(Visibility v)
        {
            switch (v)
            {
                case Visibility.Visible:
                    return true;
                case Visibility.Hidden:
                case Visibility.Collapsed:
                    return false;
                default:
                    return false;
            }
        }
 
        /// <summary>
        ///     Called by ResizeGrip control to set its reference in the Window object
        /// </summary>
        /// <remarks>
        ///     RBW doesn't need ResizeGrip and hence it doesn't do
        ///     anything in this virtual
        /// </remarks>
        internal virtual void SetResizeGripControl(Control ctrl)
        {
            _resizeGripControl = ctrl;
        }
 
        internal virtual void ClearResizeGripControl(Control oldCtrl)
        {
            if (oldCtrl == _resizeGripControl)
            {
                _resizeGripControl = null;
            }
        }
 
        internal virtual void TryClearingMainWindow()
        {
            if (IsInsideApp && this == App.MainWindow)
            {
                App.MainWindow = null;
            }
        }
 
        /// <summary>
        ///     Send a WM_CLOSE message to close the window. When the WM_CLOSE message is
        ///     processed by the WindowFilterMessage function, the Closing event is fired.
        ///     Closing event is cancelable and thus can dismiss window closing.
        /// </summary>
        /// <param name="shutdown">Specifies whether the app should shutdown or not</param>
        /// <param name="ignoreCancel">Specifies whether cancelling closing should be ignored </param>
        internal void InternalClose(bool shutdown, bool ignoreCancel)
        {
            VerifyNotClosing();
 
            if (_disposed == true)
            {
                return;
            }
 
            _appShuttingDown = shutdown;
            _ignoreCancel = ignoreCancel;
 
            if ( IsSourceWindowNull )
            {
                _isClosing = true;
 
                // Event handler exception continuality: if exception occurs in Closing event handler, the
                // cleanup action is to finish closing.
                CancelEventArgs e = new CancelEventArgs(false);
                try
                {
                    OnClosing(e);
                }
                catch
                {
                    CloseWindowBeforeShow();
                    throw;
                }
 
                if (ShouldCloseWindow(e.Cancel))
                {
                    CloseWindowBeforeShow();
                }
                else
                {
                    _isClosing = false;
                    // Dialog does not close with ESC key after it has been cancelled
                    //
                    // No need to reset DialogResult to null here since source window is null.  That means
                    // that ShowDialog has not been called and thus no need to worry about DialogResult.
                }
            }
            else
            {
                // close window synchronously
 
                // We demand for UIPermission AllWindows at the public API, Window.Close(), level.
                // It can be called when shutting down the app.
                // The public entry to that code path Application.Shutdown is
                // also protected with a demand for UIPermission with AllWindow access
 
                // SendMessage's return value is dependent on the message send.  WM_CLOSE
                // return value just signify whether the WndProc handled the
                // message or not, so it is not interesting
#pragma warning disable 6523
                UnsafeNativeMethods.UnsafeSendMessage(Handle, WindowMessage.WM_CLOSE, new IntPtr(), new IntPtr());
#pragma warning enable 6523
            }
        }
 
        // NOTE:
        // We fire Closing and Closed envent even if the hwnd is not
        // created yet i.e. window is not shown.
        private void CloseWindowBeforeShow()
        {
            InternalDispose();
 
            // raise Closed event
            OnClosed(EventArgs.Empty);
        }
 
        internal bool IsSourceWindowNull
        {
            get
            {
                if ( _swh != null )
                {
                    return _swh.IsSourceWindowNull;
                }
                return true;
            }
        }
 
        internal bool IsCompositionTargetInvalid
        {
            get
            {
                if (_swh != null)
                {
                    return _swh.IsCompositionTargetInvalid;
                }
                return true;
            }
        }
 
        internal NativeMethods.RECT WorkAreaBoundsForNearestMonitor
        {
            get
            {
                Debug.Assert( _swh != null );
                return _swh.WorkAreaBoundsForNearestMonitor;
            }
        }
 
        internal Size WindowSize
        {
            get
            {
                Debug.Assert( _swh != null );
                return _swh.WindowSize;
            }
        }
 
        // This is currently exposed just for DRTs.
        // PLEASE NOTE THAT IF YOU ARE CALLING THIS WITHIN AVALON CODE - YOU ARE CALLING A SECURITY CRITICAL METHOD
        // YOU WILL HAVE TO WORK WITH THE SECURITY TEAM TO REVIEW YOUR USAGE
        internal HwndSource HwndSourceWindow
        {
            get
            {
 
                if ( _swh != null )
                    return _swh.HwndSourceWindow;
                else
                    return null;
            }
        }
 
        // WCP Window:  Define the dispose behavior for Window
        // We need to define the Dispose behavior for the Window class.  We used to
        // dispose off the object when the Window was closed; however, this does not
        // work for EmbeddedDialogs since we need to get the DialogResult after the
        // EmbeddedDialog is closed.  So, we changed this functionality for M6.
        // We need to define if and when we should dispose the Window object.
 
        // NOTE: added on 10/03/02
        // We should set our _hwndSource reference to null here.
        // Else, if the hwndSource is not null, users can call
        // public APIs that use hwndSource and it will fail
 
        /// <summary>
        ///     can be used by internal derived class
        /// </summary>
        private void InternalDispose()
        {
            _disposed = true;
 
            // UpdateWindowLists here instead of in WM_CLOSE for 2 reasons.
            // 1. WM_CLOSE is not fired for child window. An example would be RootBrowserWindow (bug 1754467).
            // 2. It is not fired as a result of calling Dispose directly on HwndSource (HwndSource distroy the window).
            UpdateWindowListsOnClose();
 
#if DISPOSE
            // detach all events
            Utilities.SafeDispose(ref _events);
#endif
            // NOTE:
            // This InternalDispose method is called while
            // processing WM_DESTROY msg. Once we're done
            // processing this msg, HwndWrapper does its processing.
            // We don't need to dispose _swh here b/c
            // HwndWrapper fires the hwndDisposed event while
            // processing WM_DESTROY msg. HwndSource listens to
            // this event and disposes itself i.e. the CompositionTarget etc.
            // If we call dispose here, HwndWrapper.Dispose sends
            // a WM_DESTROY msg and it is a duplicate msg.
 
            // When the window is closing, stop any deferred operations.
            if (_taskbarRetryTimer != null)
            {
                _taskbarRetryTimer.Stop();
                _taskbarRetryTimer = null;
            }
 
            try
            {
                ClearSourceWindow();
 
                Utilities.SafeDispose(ref _hiddenWindow);
                Utilities.SafeDispose(ref _defaultLargeIconHandle);
                Utilities.SafeDispose(ref _defaultSmallIconHandle);
                Utilities.SafeDispose(ref _currentLargeIconHandle);
                Utilities.SafeDispose(ref _currentSmallIconHandle);
                Utilities.SafeRelease(ref _taskbarList);
 
                if(ThemeMode != ThemeMode.None)
                {
                    ThemeManager.FluentEnabledWindows.Remove(this);
                }
            }
            finally
            {
                _isClosing = false;
            }
        }
 
        /// <summary>
        ///     This is a callback called to set the window Visual. It is called after
        ///     the source window has been created.
        /// </summary>
        internal override void OnAncestorChanged()
        {
            base.OnAncestorChanged();
            if (Parent != null)
            {
                throw new InvalidOperationException(SR.WindowMustBeRoot);
            }
        }
 
        /// <summary>
        ///     Initializes the _style and _styleEx bits.
        /// </summary>
        internal virtual void CreateAllStyle()
        {
            // we don't need to set to WS_OVERLAPPEDWINDOW since all the styles are set
            // manually depending on window properties.
            //
            // We always have the sysmenu
            // If the Window has a Caption, then this also
            // shows the icon and the close box
 
            _Style = NativeMethods.WS_CLIPCHILDREN | NativeMethods.WS_SYSMENU;
            _StyleEx = 0;
 
            CreateWindowStyle();
            CreateWindowState();
 
            // do all the other checks and update style bits
 
            // Visibility bits
            if ( _isVisible )
            {
                _Style |= NativeMethods.WS_VISIBLE;
            }
 
            SetTaskbarStatus();
            CreateTopmost();
            CreateResizibility();
            CreateRtl();
        }
 
        /// <summary>
        ///     Create the window
        ///     Virtual so that subclasses ( currently only RootBrowserWindow) - may assert for HwndSource creation.
        /// </summary>
        internal virtual void CreateSourceWindowDuringShow()
        {
            CreateSourceWindow(true);
        }
 
        /// <remarks>
        ///     This method is called in the following two cases:
        ///     1. As a result of calling Show on Window, Window.Show (Visibility = Visible).
        ///     2. WindowInteropHelper.EnsureHandle is called. Hwnd is created but not shown.
        ///        We only create hwnd. RootVisual is not set until Show.
        ///
        ///     This method does the following:
        ///     CalculateLocation of the window:
        ///         Calculates location of window. If either Top/Left is CW_USEDEFAULT,
        ///         we have to make sure that window displays on the screen. Details in
        ///         the methods.
        ///
        ///     Calculate size:
        ///         Calculates size. If either one of Width/Height is set, then we
        ///         create a window with both set to default and then resizing it
        ///         to the set value
        ///
        ///     Update Properties:
        ///         After the hwnd is created, we updated our property values for various
        ///         properties
        ///
        ///     Modify the message filter:
        ///         Elevated processes don't normally receive messages from unelevated processes.
        ///         For taskbar integration in Windows 7 we need to explicitly allow explorer to post
        ///         messages to this window..
        /// </remarks>
        /// <param name="duringShow">Specifies whether this method is called from Window.Show
        /// or WindowInteropHelper.EnsureHandle</param>
        internal void CreateSourceWindow(bool duringShow)
        {
            VerifyContextAndObjectState();
            VerifyCanShow();
            VerifyNotClosing();
            VerifyConsistencyWithAllowsTransparency();
 
            // We do not support create hwnd before shown for RBW.
            if (duringShow == false)
            {
                VerifyApiSupported();
            }
 
            // we need to cache initial requested top and left as the very first thing
            // since updating the styles etc (as for borderless case below) fires
            // WM_MOVE and update Top/Left.  Also, for RBW case, Top/Left is returned
            // as 0,0 since they are inconsequential.
 
            double requestedTop = 0;
            double requestedLeft = 0;
            double requestedWidth = 0;
            double requestedHeight = 0;
 
            GetRequestedDimensions(ref requestedLeft, ref requestedTop, ref requestedWidth, ref requestedHeight);
 
            // Initially, an HWND created in a Per-Monitor Aware process may not
            // have a reliable DPI. Instead, it would be associated with the monitor in which the screen point (0,0)
            // happens to be, but the screen point corresponding to a WPF Window's (requestedLeft, requestedTop) may
            // not map into that monitor. Our initial DeviceToLogicalUnits and LogicalToDeviceUnits transforms
            // would normally have to rely on the DPI obtained from this HWND, which may lead us to
            // an incorrect result when calculating screen points. To avoid this, we use a special heuristic here
            // to identify the (screenLeft, screenTop) initially without relying on the HWND, and then
            // supply it to HwndSourceParameters at the time of HWND creation. This would in turn set up the HWND
            // with the correct DPI from the start, and all our transformations would also follow suit.
            var topLeftPointHelper = new WindowStartupTopLeftPointHelper(new Point(requestedLeft, requestedTop));
 
            using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd))
            {
                // set window style and styleEx bits
                // CreateAllStyle is internal virtual. RBW overrides it to set style to WS_CHILD and
                // set parent handle
                CreateAllStyle();
 
                // create the Win32 Window
                HwndSourceParameters param = CreateHwndSourceParameters();
                if (topLeftPointHelper.ScreenTopLeft.HasValue)
                {
                    var screenTopLeft = topLeftPointHelper.ScreenTopLeft.Value;
                    param.SetPosition((int)screenTopLeft.X, (int)screenTopLeft.Y);
                }
 
                // HwndSource disposes itself when HwndWrapper process the WM_DESTROY message.
                // Window sends WM_CLOSE (which in turn sends WM_DESTROY) to the hwnd when
                // Window.Close() is called.  Thus, this HwndSource created by window is always
                // disposed by HwndSource itself
#pragma warning disable 56518
                HwndSource source = new HwndSource(param);
#pragma warning enable 56518
                _swh = new SourceWindowHelper(source);
                source.SizeToContentChanged += new EventHandler(OnSourceSizeToContentChanged);
 
                // since we created the window with the style, mark
                // sm as not dirty so that we don't unneccessarialy update
                // the Win32 style bits.
                sm.Dirty = false;
 
                // NOTE:
                // HwndSource COULD ADD STYLE/STYLEEX BITS TO THE ONES SUPPLIED. TODAY,
                // HwndSource ADDS WS_CLIPCHILDREN TO THE STYLE WHICH MAY NOT
                // BE REFLECTED IN OUR CACHED STYLE BITS.  IF WE WERE
                // TO UPDATE THE WIN32 SYTLE, THE STYLES ADDED BY HWNDSOURCE
                // WOULD BE LOST.  IF IN THE FUTURE, WE UPDATE STYLE
                // BITS IN THIS METHOD, WE WOULD NEED TO FIRST GET THE
                // CURRENT STYLE FROM THE HWND USING:
                //
                // _Style = StyleFromHwnd;
                //
 
                // Since RBW cannot access WindowStyle, hence it overrides
                // this virtual and does nothing it it.
                CorrectStyleForBorderlessWindowCase();
} // end using StyleManager
 
            // We don't do anything that uses the Window styles below so we might as
            // well close the using so that we update the new style to the hwnd.
            // This change was made to solve a problem where SizeToContent.WidthAndHeight borderless
            // windows where actually bigger than the content size.  This was b/c of
            // the fact that we didn't update the style of the hwnd before setting
            // the RootVisual which inturn calls MeasureOverride on Window from
            // where we calculating the non-client area size using the stale
            // style bits from the hwnd.
 
            // Add Disposed event handler
            _swh.AddDisposedHandler ( new EventHandler(OnSourceWindowDisposed) );
 
            _hwndCreatedButNotShown = !duringShow;
 
            // Since this is only for Win7 taskbar integration, don't bother with this call unless we're on an appropriate OS.
            if (Utilities.IsOSWindows7OrNewer)
            {
                // In case the application is run elevated, explicitly allow WM_TASKBARBUTTONCREATED and WM_COMMAND
                // through the message filter.  This method call will fail if the application was started with
                // SECURITY_MANDATORY_LOW_RID, so don't propagate failed error codes.
                // It's not the end of the world if this fails: Shell integration simply won't work.
                MSGFLTINFO info;
                UnsafeNativeMethods.ChangeWindowMessageFilterEx(_swh.Handle, WM_TASKBARBUTTONCREATED, MSGFLT.ALLOW, out info);
                UnsafeNativeMethods.ChangeWindowMessageFilterEx(_swh.Handle, WindowMessage.WM_COMMAND, MSGFLT.ALLOW, out info);
            }
 
            if (Standard.Utility.IsOSWindows10OrNewer)
            {
                if (ThemeManager.IsFluentThemeEnabled)
                {
                    ThemeManager.ApplyStyleOnWindow(this);
                }
 
                if (_deferThemeLoading)
                {
                    _deferThemeLoading = false;
                    ThemeManager.OnWindowThemeChanged(this, ThemeMode.None, ThemeMode);
                }
            }
 
            // Sub classes can have different intialization. RBW does very minimalistic
            // stuff in its override
            SetupInitialState(requestedTop, requestedLeft, requestedWidth, requestedHeight);
 
            // Fire SourceInitialized event
            OnSourceInitialized(EventArgs.Empty);
        }
 
        internal void SetImmersiveDarkMode(bool useDarkMode)
        {
            if(!Standard.Utility.IsOSWindows11OrNewer) return;
 
            if(_useDarkMode == useDarkMode) return;
 
            IntPtr handle = Handle;
            if (handle != IntPtr.Zero)
            {
                bool succeeded = SNM.DwmSetWindowAttributeUseImmersiveDarkMode(handle, useDarkMode);
                if(succeeded)
                {
                    _useDarkMode = useDarkMode;
                }
            }
        }
 
        internal virtual HwndSourceParameters CreateHwndSourceParameters()
        {
            HwndSourceParameters param = new HwndSourceParameters(Title, NativeMethods.CW_USEDEFAULT, NativeMethods.CW_USEDEFAULT);
            param.UsesPerPixelOpacity = AllowsTransparency;
            param.WindowStyle = _Style;
            param.ExtendedWindowStyle = _StyleEx;
            param.ParentWindow = _ownerHandle;
            param.AdjustSizingForNonClientArea = true;
            param.HwndSourceHook = new HwndSourceHook(WindowFilterMessage); // hook to process window messages
            return param;
        }
 
        private void OnSourceSizeToContentChanged(object sender, EventArgs args)
        {
            SizeToContent = HwndSourceSizeToContent;
        }
 
        internal virtual void CorrectStyleForBorderlessWindowCase()
        {
            // We create an OverLapped window for which user adds WS_CAPTION
            // to the passed in style.  If we were creating a borderless window,
            // remove WS_CAPTION from the hwnd.
            //
            // We should really be using WS_POPUP for borderless windows, but
            // there's a bug with default sizing where user creates the popup
            // window with 0,0 size.
            //
 
            using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd))
            {
                if (WindowStyle == WindowStyle.None)
                {
                    _Style = _swh.StyleFromHwnd;
                    _Style &= ~NativeMethods.WS_CAPTION;
                }
            }
        }
 
        internal virtual void GetRequestedDimensions(ref double requestedLeft, ref double requestedTop, ref double requestedWidth, ref double requestedHeight)
        {
            requestedTop = this.Top;
            requestedLeft = this.Left;
            requestedWidth = this.Width;
            requestedHeight = this.Height;
        }
 
        internal virtual void SetupInitialState(double requestedTop, double requestedLeft, double requestedWidth, double requestedHeight)
        {
            // Push the current SizeToContent value to HwndSource after it's created. Initial sync up.
            HwndSourceSizeToContent = (SizeToContent) GetValue(SizeToContentProperty);
            UpdateIcon();
 
            NativeMethods.RECT rc = WindowBounds;
            Size sizeDeviceUnits = new Size(rc.right - rc.left, rc.bottom - rc.top);
            double xDeviceUnits = rc.left;
            double yDeviceUnits = rc.top;
 
            bool updateHwndPlacement = false;
 
            // This code is absolutely necessary here.  This is the initial sync up
            // for Left/Top.  We don't do this in WM_MOVE if sourceWindow is
            // null (it is null b/c the call to create HwndSource has not returned at the point)
            // and we are not listening to WM_CREATE either.  The reasons for not
            // doing so is b/c if sourceWindow is null, we can't get to the CompositionTarget
            // to convert b/w device and logical pixels
            Point currentLocationLogicalUnits = DeviceToLogicalUnits(new Point(xDeviceUnits, yDeviceUnits));
 
            // Update our current hwnd ActualTop/ActualLeft values
            // The _actualLeft and _actualTop need to be updated before we coerce Top and Left.
            // See CoerceTop for more info.
            _actualLeft = currentLocationLogicalUnits.X;
            _actualTop = currentLocationLogicalUnits.Y;
            // Coerce Top and Left value to be the intial value used in CreateWindowEx.
            try
            {
                _updateHwndLocation = false;
                CoerceValue(TopProperty);
                CoerceValue(LeftProperty);
            }
            finally
            {
                _updateHwndLocation = true;
            }
 
            Point requestedSizeDeviceUnits = LogicalToDeviceUnits(new Point(requestedWidth, requestedHeight));
            Point requestedLocationDeviceUnits = LogicalToDeviceUnits(new Point(requestedLeft, requestedTop));
 
            // if Width was specified and is not the same as the current width, then update it
            if ((!double.IsNaN(requestedWidth)) && (!DoubleUtil.AreClose(sizeDeviceUnits.Width, requestedSizeDeviceUnits.X)))
            {
                // at this stage, ActualWidth/Height is not set since
                // layout has not happened (it happens when we set the
                // RootVisual of the HwndSource)
 
                updateHwndPlacement = true;
                sizeDeviceUnits.Width = requestedSizeDeviceUnits.X;
 
                // SetWindowPlacement for Width/Height when Width/Height is set and WindowState is maximized/minimized.
                if (WindowState != WindowState.Normal)
                {
                    UpdateHwndRestoreBounds(requestedWidth, BoundsSpecified.Width);
                }
            }
 
            // if Height was specified and is not the same as the current height, then update it
            if (!double.IsNaN(requestedHeight) && (!DoubleUtil.AreClose(sizeDeviceUnits.Height, requestedSizeDeviceUnits.Y)))
            {
                // at this stage, ActualWidth/Height is not set since
                // layout has not happened (it happens when we set the
                // RootVisual of the HwndSource)
 
                updateHwndPlacement = true;
                sizeDeviceUnits.Height = requestedSizeDeviceUnits.Y;
 
                // SetWindowPlacement for Width/Height when Width/Height is set and WindowState is maximized/minimized.
                if (WindowState != WindowState.Normal)
                {
                    UpdateHwndRestoreBounds(requestedHeight, BoundsSpecified.Height);
                }
            }
 
            // if left was specified and is not the same as the current left, then update it
            if (!double.IsNaN(requestedLeft) && (!DoubleUtil.AreClose(xDeviceUnits, requestedLocationDeviceUnits.X)))
            {
                updateHwndPlacement = true;
                xDeviceUnits = requestedLocationDeviceUnits.X;
 
                // SetWindowPlacement for Top/Left when Top/Left is set and WindowState is maximized/minimized.
                if (WindowState != WindowState.Normal)
                {
                    UpdateHwndRestoreBounds(requestedLeft, BoundsSpecified.Left);
                }
            }
 
            // if top was specified and is not the same as the current top, then update it
            if (!double.IsNaN(requestedTop) && (!DoubleUtil.AreClose(yDeviceUnits, requestedLocationDeviceUnits.Y)))
            {
                updateHwndPlacement = true;
                yDeviceUnits = requestedLocationDeviceUnits.Y;
 
                // SetWindowPlacement for Top/Left when Top/Left is set and WindowState is maximized/minimized.
                if (WindowState != WindowState.Normal)
                {
                    UpdateHwndRestoreBounds(requestedTop, BoundsSpecified.Top);
                }
            }
 
            Point minSizeDeviceUnits = LogicalToDeviceUnits(new Point(MinWidth, MinHeight));
            Point maxSizeDeviceUnits = LogicalToDeviceUnits(new Point(MaxWidth, MaxHeight));
 
            // We need this here b/c when WM_GETMINMAXINFO is handled as a result of
            // creating the hwnd, _swh is null and thus we cannot get to the CompositionTarget
            // to convert b/w device and logical units.  Thus, once the hwnd is created, we
            // need to check to make sure that the hwnd is within the min/max boundaries.
            //
            // Here is idea it to detect if we are outside the min/max range and if yes, cause
            // a resize.  This resize will call WM_GETMINMAXINFO and that will further take
            // care of the bounds
 
            if (!Double.IsPositiveInfinity(maxSizeDeviceUnits.X) && (sizeDeviceUnits.Width > maxSizeDeviceUnits.X))
            {
                updateHwndPlacement = true;
                sizeDeviceUnits.Width = maxSizeDeviceUnits.X;
            }
 
            if (!Double.IsPositiveInfinity(minSizeDeviceUnits.Y) && (sizeDeviceUnits.Height > maxSizeDeviceUnits.Y))
            {
                updateHwndPlacement = true;
                sizeDeviceUnits.Height = maxSizeDeviceUnits.Y;
            }
 
            if (sizeDeviceUnits.Width < minSizeDeviceUnits.X)
            {
                updateHwndPlacement = true;
                sizeDeviceUnits.Width = minSizeDeviceUnits.X;
            }
 
            if (sizeDeviceUnits.Height < minSizeDeviceUnits.Y)
            {
                updateHwndPlacement = true;
                sizeDeviceUnits.Height = minSizeDeviceUnits.Y;
            }
 
            // Now that we know the window Width/Height/Left/Top, we want to calculate
            // the location based on WindowStartupLocation enum.  All inputs to
            // CalculateWindowLocation must be in DEVICE units.  It will return true,
            // if it updated theinput values of left, top.
            //
            updateHwndPlacement = (CalculateWindowLocation(ref xDeviceUnits, ref yDeviceUnits, sizeDeviceUnits)? true: updateHwndPlacement);
 
            // We need to update the hwnd size before we set RootVisual b/c setting RootVisual
            // results in a Measure/Arrange/Layout and we want to set the correct hwnd size
            // now so that layout happens at the correct size.
            //
 
            //
            // We are intentionally not merging this SetWindowPos with the one in SetRootVisualAndUpdateSTC. The reason is
            // that if Width or Height is set we initially create the hwnd with both as default win32 size
            // and later (above call to SetWindowPos) resizes it to reflect the specified Width or Height.
            // After this is done, we set RootVisual which results in a layout with the correct size of
            // the hwnd.
            //
            // If we merge the two SetWindowPos calls, then for the scenario where
            // Width or Height is set initially, we create the hwnd with win32 default size.  Setting RootVisual
            // would cause layout to happen at that default size.  Now, we resize the window to reflect the
            // specified size which will result in another layout.
            //
            // The third option is to set RootVisual after doing all resizes.  This is not possible to do for
            // the SizeToContent case since we don't know the size of hwnd until RootVisual is set and layout
            // has happened.
            //
 
            if (updateHwndPlacement == true)
            {
                if (WindowState == WindowState.Normal)
                {
                    UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle),
                        new HandleRef(null, IntPtr.Zero),
                        DoubleUtil.DoubleToInt(xDeviceUnits),
                        DoubleUtil.DoubleToInt(yDeviceUnits),
                        DoubleUtil.DoubleToInt(sizeDeviceUnits.Width),
                        DoubleUtil.DoubleToInt(sizeDeviceUnits.Height),
                        NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE
                        );
 
                    // The value of Top and Left is affected by WindowState and WindowStartupLocation.
                    // we need to coerce Top and Left whenever these deciding factors change.
                    // More info in CoerceTop.
                    try
                    {
                        _updateHwndLocation = false;
                        _updateStartupLocation = true;
                        CoerceValue(TopProperty);
                        CoerceValue(LeftProperty);
                    }
                    finally
                    {
                        _updateHwndLocation = true;
                        _updateStartupLocation = false;
                    }
                }
            }
 
            // RootVisual is not set until Show.
            // Only set RootVisual when we are going to show the window.
            if (!HwndCreatedButNotShown)
            {
                SetRootVisualAndUpdateSTC();
            }
        }
 
        internal void SetRootVisual()
        {
            //FxCop: ConstructorsShouldNotCallBaseClassVirtualMethods::
            // System.Windows (presentationframework.dll 2 violation)
            //
            // We can't set IWS property in the cctor since it results
            // in calling some virtual.  So, as an alternative we set it
            // when content is changed and when we set the root visual.
            // We set it here, b/c once RootVisual is set, the visual tree
            // can/is created and visual children can query for inherited
            // IWS property.
            SetIWindowService();
 
            // set root visual  synchronously, shell request
            if ( IsSourceWindowNull == false )
            {
                _swh.RootVisual = this;
            }
        }
 
        internal void SetRootVisualAndUpdateSTC()
        {
            SetRootVisual();
 
            // We update size/location based on the value of SizeToContent after the RootVisual is set.
            // The world (size/location) could have changed after SetRootVisual.  Verify assumptions before moving on.
            // Specifically SetRootVisual may have initialized a Layout, and if an event handler Closed the Window
            // as a result then _swh (used by LogicalToDeviceUnits) is already disposed.
            if (!IsSourceWindowNull)
            {
                // if SizeToContent, we would need to set the location again if
                // WSL is CenterOwner or CenterScreen b/c size may have changed
                // after we set the RootVisual on HwndSource.
                // And if the hwnd is created but is not shown yet, we need to re-calculate the location again because
                // the value of the WindowStartupLocation can change after EnsureHandle is called.
                // We only update location if there is any change needed.
                if ((SizeToContent != SizeToContent.Manual) || (HwndCreatedButNotShown == true))
                {
                    NativeMethods.RECT rc = WindowBounds;
                    double xDeviceUnits = rc.left;
                    double yDeviceUnits = rc.top;
 
                    // inputs to CalculateWindowLocation must be in DEVICE units
                    Point newSizeDeviceUnits = LogicalToDeviceUnits(new Point(this.ActualWidth, this.ActualHeight));
                    if (CalculateWindowLocation(ref xDeviceUnits, ref yDeviceUnits, new Size(newSizeDeviceUnits.X, newSizeDeviceUnits.Y)))
                    {
                        if (WindowState == WindowState.Normal)
                        {
                            UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle),
                                new HandleRef(null, IntPtr.Zero),
                                DoubleUtil.DoubleToInt(xDeviceUnits),
                                DoubleUtil.DoubleToInt(yDeviceUnits),
                                0,
                                0,
                                NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE
                                );
 
                            // The value of Top and Left is affected by WindowState and WindowStartupLocation.
                            // we need to coerce Top and Left whenever these deciding factors change.
                            // More info in CoerceTop.
                            try
                            {
                                _updateHwndLocation = false;
                                _updateStartupLocation = true;
                                CoerceValue(TopProperty);
                                CoerceValue(LeftProperty);
                            }
                            finally
                            {
                                _updateHwndLocation = true;
                                _updateStartupLocation = false;
                            }
                        }
                    }
                }
            }
        }
 
        /// <summary>
        ///     Create the style bits depending on the WindowStyle property
        /// </summary>
        /// <remarks>
        ///     This method does not clear the bits, so the style bits should be cleared
        ///     before calling this method
        /// </remarks>
        private void CreateWindowStyle()
        {
            // Clear the style bits related to WindowStyle
            _Style &= ~NativeMethods.WS_CAPTION;
            _StyleEx &= ~(NativeMethods.WS_EX_CLIENTEDGE | NativeMethods.WS_EX_TOOLWINDOW);
 
            // WS_CAPTION == WS_BORDER | WS_DLGFRAME (0x00C00000L)
            // Thus no need to set/clear WS_BORDER when we are
            // already seting/clearing WS_CAPTION
            switch (WindowStyle)
            {
                case WindowStyle.None:
                    _Style &= (~NativeMethods.WS_CAPTION);
                    break;
 
                case WindowStyle.SingleBorderWindow:
                    _Style |= NativeMethods.WS_CAPTION;
                    break;
 
                case WindowStyle.ThreeDBorderWindow:
                    _Style |= NativeMethods.WS_CAPTION;
                    _StyleEx |= NativeMethods.WS_EX_CLIENTEDGE;
                    break;
 
                case WindowStyle.ToolWindow:
                    _Style |= NativeMethods.WS_CAPTION;
                    _StyleEx |= NativeMethods.WS_EX_TOOLWINDOW;
                    break;
#if Never
                case WindowBorderStyle.Sizable:
                    _startSettings.Style |= NativeMethods.WS_BORDER | NativeMethods.WS_THICKFRAME;
                    break;
 
                case WindowBorderStyle.FixedDialog:
                    _startSettings.Style |= NativeMethods.WS_BORDER;
                    _startSettings.StyleEx |= NativeMethods.WS_EX_DLGMODALFRAME;
                    break;
                case WindowBorderStyle.SizableToolWindow:
                    _startSettings.Style |= NativeMethods.WS_BORDER | NativeMethods.WS_THICKFRAME;
                    _startSettings.StyleEx |= NativeMethods.WS_EX_TOOLWINDOW;
                    break;
#endif
            }
        }
 
        // called as a result of title property changing to propagate it to the hwnd
        internal virtual void UpdateTitle(string title)
        {
            // Adding check for IsCompositionTargetInvalid
            if ( IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                UnsafeNativeMethods.SetWindowText(new HandleRef(this, Handle), title);
            }
        }
 
        // called as a result of Height/MinHeight/MaxHeight and Width/MinWidth/MaxWidth property changing to update the hwnd size
        private void UpdateHwndSizeOnWidthHeightChange(double widthLogicalUnits, double heightLogicalUnits)
        {
            if (!_inTrustedSubWindow)
            {
            }
            Debug.Assert( IsSourceWindowNull == false , "IsSourceWindowNull cannot be true when calling this function");
 
            Point ptDeviceUnits = LogicalToDeviceUnits(new Point(widthLogicalUnits, heightLogicalUnits));
            UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle),
                        new HandleRef(null, IntPtr.Zero),
                        0,
                        0,
                        DoubleUtil.DoubleToInt(ptDeviceUnits.X),
                        DoubleUtil.DoubleToInt(ptDeviceUnits.Y),
                        NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE
                        );
        }
 
        // Activate or Deactivate window
        internal void HandleActivate(bool windowActivated)
        {
            //
            // This method is called by WM_ACTIVATE msg hander for the stand alone
            // window case.  WM_ACTIVATE is sent twice when activating a minimized
            // window by mouse click; once with window state minimized and then again
            // with window state normal.  Thus, we have the following if conditions
            // to fire Activated/Deactivated events only if we're activating/deactivating
            // the window and the window was previously deactivated/activated.
            //
            // Please look at (Activated event fires twice on window when
            // you minimize and restore a window) on this issue.
            //
 
            // Event handler exception continuality: if exception occurs in Activated/Deactivated event handlers, our state will not be
            // corrupted because the state related to Activated/Deactivated, IsActive is set before the event is fired.
            // Please check Event handler exception continuality if the logic changes.
            if ((windowActivated == true) && (IsActive == false))
            {
                SetValue(IsActivePropertyKey, BooleanBoxes.TrueBox);
                OnActivated(EventArgs.Empty);
            }
            else if ((windowActivated == false) && (IsActive == true))
            {
                SetValue(IsActivePropertyKey, BooleanBoxes.FalseBox);
                OnDeactivated(EventArgs.Empty);
            }
        }
 
        internal virtual void UpdateHeight(double newHeight)
        {
            if (WindowState == WindowState.Normal)
            {
                // We cannot save the current hwnd height in logical units in WmSizeChanged b/c the HwndSource
                // might not be completely created at that time (when we call new HwndSource from CreateSourceWindow)
                // and DeviceToLogicalUnits fails.  Thus we convert to logical units here before we call
                // UpdateHwndSizeonWidthHeightChange since that expects logical units.
 
                NativeMethods.RECT rc = WindowBounds;
                Point sizeLogicalUnits = DeviceToLogicalUnits(new Point(rc.Width, 0));
                UpdateHwndSizeOnWidthHeightChange(sizeLogicalUnits.X, newHeight);
            }
            else
            {
                UpdateHwndRestoreBounds(newHeight, BoundsSpecified.Height);
            }
        }
 
        internal virtual void UpdateWidth(double newWidth)
        {
            if (WindowState == WindowState.Normal)
            {
                // We cannot save the current hwnd width in logical units in WmSizeChanged b/c the HwndSource
                // might not be completely created at that time (when we call new HwndSource from CreateSourceWindow)
                // and DeviceToLogicalUnits fails.  Thus we convert to logical units here before we call
                // UpdateHwndSizeonWidthHeightChange since that expects logical units.
 
                NativeMethods.RECT rc = WindowBounds;
                Point sizeLogicalUnits = DeviceToLogicalUnits(new Point(0, rc.Height));
                UpdateHwndSizeOnWidthHeightChange(newWidth, sizeLogicalUnits.Y);
            }
            else
            {
                // set restore width
                UpdateHwndRestoreBounds(newWidth, BoundsSpecified.Width);
            }
        }
 
        internal virtual void VerifyApiSupported()
        {
            // don't do anything here since we allow this API in Window.
            // Subclasses can throw exception in their override if
            // they don't allow the api.
        }
        #endregion Internal Methods
 
 
        //----------------------------------------------
        //
        // Internal Properties
        //
        //----------------------------------------------
        #region Internal Properties
 
        /// <summary>
        /// Gets or sets a value determining preferred backdrop type for current <see cref="Window"/>.
        /// </summary>
        internal WindowBackdropType WindowBackdropType
        {
            get => (WindowBackdropType)GetValue(WindowBackdropTypeProperty);
            set => SetValue(WindowBackdropTypeProperty, value);
        }
 
        /// <summary>
        /// Property for <see cref="WindowBackdropType"/>.
        /// </summary>
        internal static readonly DependencyProperty WindowBackdropTypeProperty = DependencyProperty.Register(
            nameof(WindowBackdropType),
            typeof(WindowBackdropType),
            typeof(Window),
            new PropertyMetadata(
                WindowBackdropType.MainWindow,
                new PropertyChangedCallback(OnBackdropTypeChanged)));
 
        private static void OnBackdropTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is not Window window)
            {
                return;
            }
 
            if (e.OldValue == e.NewValue)
            {
                return;
            }
 
            WindowBackdropManager.SetBackdrop(window, (WindowBackdropType)e.NewValue);
        }
 
 
        internal bool HwndCreatedButNotShown
        {
            get
            {
                return _hwndCreatedButNotShown;
            }
        }
 
        internal bool IsDisposed
        {
            get
            {
                return _disposed;
            }
        }
 
        /// <summary>
        /// This tells whether user has set Visible or not. It's currently used in Application
        /// where if Visibility has not been set when the Window is navigated to, we set it to
        /// Visible
        /// </summary>
        internal bool IsVisibilitySet
        {
            get
            {
                VerifyContextAndObjectState();
                return _isVisibilitySet;
            }
        }
 
        /// <summary>
        ///     Exposes the hwnd of the window. This property is used by the WindowInteropHandler
        ///     class
        /// </summary>
        internal IntPtr Handle
        {
            get
            {
                VerifyContextAndObjectState();
                if (_swh != null)
                {
                    return _swh.Handle;
                }
                else
                return IntPtr.Zero;
            }
        }
 
        /// <summary>
        ///     Enables to get/set the owner handle for this window. This property is used by
        ///     the WindowInteropHelper class
        /// </summary>
        ///<remarks>
        ///     This API is currently not available for use in Internet Zone.
        ///</remarks>
        internal IntPtr OwnerHandle
        {
            get
            {
 
                VerifyContextAndObjectState();
                return _ownerHandle;
            }
            set
            {
 
                VerifyContextAndObjectState();
 
                if ( _showingAsDialog == true )
                {
                    throw new InvalidOperationException(SR.CantSetOwnerAfterDialogIsShown);
                }
 
                SetOwnerHandle(value);
            }
        }
 
        /// <summary>
        ///     This is used by RBW to set the correct win32 style
        /// </summary>
        internal int Win32Style
        {
            get
            {
                VerifyContextAndObjectState();
                return _Style;
            }
            set
            {
                VerifyContextAndObjectState();
 
                // The reason this is not wrapped by a manager is that it should never
                // be invoked outside the scope on an already established manager.
                Debug.Assert(Manager != null, "HwndStyleManager must have a valid value here");
                _Style = value;
            }
        }
 
        internal int _Style
        {
            get
            {
                if (Manager != null)
                {
                    return _styleDoNotUse;
}
                else if ( IsSourceWindowNull )
                {
                    return _styleDoNotUse;
}
                else
                {
                    return _swh.StyleFromHwnd;
                }
            }
            set
            {
                _styleDoNotUse = value;
                Manager.Dirty = true;
            }
        }
 
        internal int _StyleEx
        {
            get
            {
                if (Manager != null)
                {
                    return _styleExDoNotUse;
}
                else if (IsSourceWindowNull == true  )
                {
                    return _styleExDoNotUse;
}
                else
                {
                    return _swh.StyleExFromHwnd;
                }
                }
            set
            {
                _styleExDoNotUse = value;
                Manager.Dirty = true;
            }
        }
 
        internal HwndStyleManager Manager
        {
            get { return _manager; }
            set { _manager = value; }
        }
 
        bool IWindowService.UserResized
        {
            get { return false; }
        }
 
        internal bool AreResourcesInitialized
        {
            get
            {
                return _resourcesInitialized;
            }
            set
            {
                _resourcesInitialized = value;
            }
        }
 
        #endregion Internal Properties
 
        //----------------------------------------------
        //
        // Internal Fields
        //
        //----------------------------------------------
        #region Internal Fields
 
        /// <summary>
        /// DialogCancel Command. It closes window if it's dialog and return false as the dialog value.
        /// </summary>
        /// <remarks>
        /// Right now this is only used by Cancel Button to close the dialog.
        /// </remarks>
        internal static readonly RoutedCommand DialogCancelCommand = new RoutedCommand("DialogCancel", typeof(Window));
 
        #endregion Internal Fields
 
 
        //----------------------------------------------
        //
        // Internal Types
        //
        //----------------------------------------------
        #region Internal Types
        // similar to the one in FE except that it takes care of SizeToContent
        // while determining the min/max values for height and width.
        internal struct WindowMinMax
        {
            internal double minWidth;
            internal double maxWidth;
            internal double minHeight;
            internal double maxHeight;
 
            internal WindowMinMax(double minSize, double maxSize)
            {
                minWidth = minSize;
                maxWidth = maxSize;
                minHeight = minSize;
                maxHeight = maxSize;
            }
        }
        #endregion Internal Types
 
        //----------------------------------------------
        //
        // Private Methods
        //
        //----------------------------------------------
        #region Private Methods
        private Size MeasureOverrideHelper(Size constraint)
        {
            // need to handle infinity
            // return the entire client area of the window
            // Measure children properly.
 
            // Three primary cases
            //      1)  hwnd does not exist  -- return 0,0
            //      1a) CompositionTarget is invalid -- return 0,0
            //      2)  Child visual exists  -- we return child.DesiredSize + frame size
            //      3)  No Child visual      -- return the hwnd size (this should be the same
            //                                  as the one passed into MeasureOverride for our framework)
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                // No need to use CompositionTarget.TransformFromDevice
                // since size is 0,0
                return new Size(0,0);
            }
 
            if (this.VisualChildrenCount > 0)
            {
                UIElement child = this.GetVisualChild(0) as UIElement;
                if (child != null) // UIElement children
                {
                    // Find out the size of the window frame x.
                    // (constraint - x) is the size we pass onto
                    // our child
 
                    Size frameSize = GetHwndNonClientAreaSizeInMeasureUnits();
 
                    // In some instances (constraint size - frame size) can be negative. One instance
                    // is when window is set to minimized before layout has happened.  Apparently, Win32
                    // gives a rect(-32000, -32000, -31840, -31975) for GetWindowRect when hwnd is
                    // minimized.  However, when we calculate the frame size we get width = 8 and
                    // height = 28!!!  Here, we will take the max of zero and the difference b/w the
                    // hwnd size and the frame size
                    //
                    // PS Windows OS Bug: 955861
                    Size childConstraint = new Size();
                    childConstraint.Width = ((constraint.Width == Double.PositiveInfinity) ? Double.PositiveInfinity : Math.Max(0.0, (constraint.Width - frameSize.Width)));
                    childConstraint.Height = ((constraint.Height == Double.PositiveInfinity) ? Double.PositiveInfinity : Math.Max(0.0, (constraint.Height - frameSize.Height)));
 
                    child.Measure(childConstraint);
                    Size childDesiredSize = child.DesiredSize;
                    return new Size(childDesiredSize.Width + frameSize.Width, childDesiredSize.Height + frameSize.Height);
                }
            }
 
            // if we reach here, we return the input size
            return _swh.GetSizeFromHwndInMeasureUnits();
        }
 
        // Similar logic as in FE.MinMax and takes care of max/min size allowed by win32 for the hwnd.  However, we
        // don't take Height/Width into consideration.  This is because of the following reasons:
        //
        // 1) Window Height/Width info doesn't matter here since we just need to ensure that the child element is
        //    layed out within the Max/Min restrictions of the window.  Window is layed out at the size sent into MO/AO
        //    and Height and Width of the window does not play a part MO/AO stage.
        //
        // 2) We had (FlowDocumentReader: When the maximise button is clicked on the window with FDR the
        //    content don't reflow to fill in the entire window) and the fix for that is to simply not use H/W here.
        //    GetWindowMinMax fixes the following bugs:
        //
        //    (Window content should respect Window's Max/Min size)
        //    (Wrong window actual size returned if Autosize window content is smaller than the actual
        //    window (seems to return content size as opposed to window size))
        //
        //  This method is called by both MeasureOverride( ) and WmGetMinMaxInfo( ).
        //  It will calculate a final Min/Max size in logic units for this HWND based on Win32 restricted value and
        //  current Min/Max setting in this instance.
        //
        internal virtual WindowMinMax GetWindowMinMax()
        {
            WindowMinMax mm = new WindowMinMax( );
 
            Invariant.Assert(IsCompositionTargetInvalid == false, "IsCompositionTargetInvalid is supposed to be false here");
 
            // convert the max/min size (taken in to account the hwnd size restrictions by win32) into logical units
            double maxWidthDeviceUnits = _trackMaxWidthDeviceUnits;
            double maxHeightDeviceUnits = _trackMaxHeightDeviceUnits;
            if (WindowState == WindowState.Maximized)
            {
                // On some systems, the trackMax size is a few pixels smaller than
                // the windowMax size.   Use the larger size for maximized windows.
                maxWidthDeviceUnits = Math.Max(_trackMaxWidthDeviceUnits, _windowMaxWidthDeviceUnits);
                maxHeightDeviceUnits = Math.Max(_trackMaxHeightDeviceUnits, _windowMaxHeightDeviceUnits);
            }
 
            Point maxSizeLogicalUnits = DeviceToLogicalUnits(new Point(maxWidthDeviceUnits, maxHeightDeviceUnits));
            Point minSizeLogicalUnits = DeviceToLogicalUnits(new Point(_trackMinWidthDeviceUnits, _trackMinHeightDeviceUnits));
 
            //
            // Get the final Min/Max Width
            //
            mm.minWidth = Math.Max(this.MinWidth, minSizeLogicalUnits.X);
 
            // Min's precedence is higher than Max; If Min is greater than Max, use Min.
            if (MinWidth > MaxWidth)
            {
                mm.maxWidth = Math.Min(MinWidth, maxSizeLogicalUnits.X);
            }
            else
            {
                if (!Double.IsPositiveInfinity(MaxWidth))
                {
                    mm.maxWidth = Math.Min(MaxWidth, maxSizeLogicalUnits.X);
                }
                else
                {
                    mm.maxWidth = maxSizeLogicalUnits.X;
                }
            }
 
            //
            // Get the final Min/Max Height
            //
            mm.minHeight = Math.Max(this.MinHeight, minSizeLogicalUnits.Y);
 
            // Min's precedence is higher than Max; If Min is greater than Max, use Min.
            if (MinHeight > MaxHeight)
            {
                mm.maxHeight = Math.Min(this.MinHeight, maxSizeLogicalUnits.Y);
            }
            else
            {
                if (!Double.IsPositiveInfinity(MaxHeight))
                {
                    mm.maxHeight = Math.Min(MaxHeight, maxSizeLogicalUnits.Y);
                }
                else
                {
                    mm.maxHeight = maxSizeLogicalUnits.Y;
                }
            }
 
            return mm;
        }
 
        private void LoadedHandler(object sender, RoutedEventArgs e)
        {
            if (_postContentRenderedFromLoadedHandler == true)
            {
                PostContentRendered();
                _postContentRenderedFromLoadedHandler = false;
                this.Loaded -= new RoutedEventHandler(LoadedHandler);
            }
        }
 
        /// <remarks> Keep this method in sync with Frame.PostContentRendered(). </remarks>
        private void PostContentRendered()
        {
            // Post the firing of ContentRendered as Input priority work item so
            // that ContentRendered will be fired after render query empties.
            if (_contentRenderedCallback != null)
            {
                // Content was changed again before the previous rendering completed (or at least
                // before the Dispatcher got to Input priority callbacks).
                _contentRenderedCallback.Abort();
            }
            _contentRenderedCallback = Dispatcher.BeginInvoke(DispatcherPriority.Input,
                                   (DispatcherOperationCallback) delegate (object arg)
                                   {
                                       // Event handler exception continuality: there are no state related/depending on ContentRendered event.
                                       // If an exception occurs in event handler, our state will not be corrupted.
                                       // Please check event handler exception continuality if the logic changes.
                                       Window thisRef = (Window)arg;
                                       thisRef._contentRenderedCallback = null;
                                       thisRef.OnContentRendered(EventArgs.Empty);
                                       return null;
                                   },
                                   this);
        }
 
        /// <summary>
        /// Ensure Dialog command is registered with the CommandManager
        /// </summary>
        private void EnsureDialogCommand()
        {
            // _dialogCommandAdded is a static variable, however, we're not synchronizing
            // access to it.  The reason is that, CommandManager is thread safe and according
            // to KiranKu we don't want to take the overhead of locking here.  For multiple
            // threaded cases, we could end up calling the CommandManager more than once but
            // KiranKu is okay with that perf hit in the corner case.
            if (!_dialogCommandAdded)
            {
                // Right now we only have DialogCancel Command, which closes window if it's dialog and return false as the dialog's result.
                CommandBinding binding = new CommandBinding(DialogCancelCommand);
                binding.Executed += new ExecutedRoutedEventHandler(OnDialogCommand);
                CommandManager.RegisterClassCommandBinding(typeof(Window), binding);
 
                _dialogCommandAdded = true;
            }
        }
 
        /// <summary>
        /// Dialog Command Execute handler
        /// Right now we only have DialogCancel Command, which closes window if it's dialog and return false for DialogResult.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="e"></param>
        private static void OnDialogCommand(object target, ExecutedRoutedEventArgs e)
        {
            //close dialog & return result
            Window w = target as Window;
 
            Debug.Assert(w != null, "Target must be of type Window.");
            w.OnDialogCancelCommand();
        }
 
        /// <summary>
        /// Close window if it's dialog and return false for DialogResult.
        /// </summary>
        private void OnDialogCancelCommand()
        {
            if (_showingAsDialog)
            {
                DialogResult = false;
            }
        }
 
        /// <summary>
        /// The callback function for EnumThreadWindows
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lparam"></param>
        /// <returns></returns>
        private bool ThreadWindowsCallback(IntPtr hWnd, IntPtr lparam)
        {
            Debug.Assert(_threadWindowHandles != null, "_threadWindowHandles must not be null at this point");
 
            // the dialog's hwnd has not been created yet when calling into this function.
            // so its hwnd won't be in the list.
 
            // We only do visible && enabled windows.
            // We need to check Visible because there might be hidden windows that do message looping,
            // We don't want to disable them.
            if (SafeNativeMethods.IsWindowVisible(new HandleRef(null, hWnd)) &&
                SafeNativeMethods.IsWindowEnabled(new HandleRef(null, hWnd)))
            {
                _threadWindowHandles.Add(hWnd);
            }
 
            return true;
        }
 
        /// <summary>
        /// Enables/disables all Windows on this thread
        /// </summary>
        /// <param name="state"></param>
        private void EnableThreadWindows(bool state)
        {
            Debug.Assert(_threadWindowHandles != null, "_threadWindowHandles must not be null at this point");
 
            for (int i = 0; i < _threadWindowHandles.Count; i++)
            {
                IntPtr hWnd = _threadWindowHandles[i];
 
                if (UnsafeNativeMethods.IsWindow(new HandleRef(null, hWnd)))
                {
                    // Calls EnableWindow which returns the previous Window state
                    // (enable/disable) and we don't care about that here
#pragma warning disable 6523
                    UnsafeNativeMethods.EnableWindowNoThrow(new HandleRef(null, hWnd), state);
#pragma warning enable 6523
 
                }
            }
 
            // EnableThreadWindows is called with true only when dialog is going away.  Now
            // we've enabled the windows that we had earlier disabled; thus, disposing
            // _threadWindowHandles.
            if (state == true)
            {
                _threadWindowHandles = null;
            }
        }
 
        /// <summary>
        /// Intialization when Window is constructed
        /// </summary>
        ///     Initializes the Width/Height, Top/Left properties to use windows
        ///     default. Updates Application object properties if inside app.
        ///
        ///     Also, window style is set to WS_CHILD inside CreateSourceWindow
        ///     for browser hosted case
        private void Initialize()
        {
 
            //  this makes MeasureCore / ArrangeCore to defer to direct MeasureOverride and ArrangeOverride calls
            //  without reading Width / Height properties and modifying input constraint size parameter...
            BypassLayoutPolicies = true;
 
            // check if within an app && on the same thread
            if (IsInsideApp == true)
            {
                if (Application.Current.Dispatcher.Thread == Dispatcher.CurrentDispatcher.Thread)
                {
                    // add to window collection
                    // use internal version since we want to update the underlying collection
                    App.WindowsInternal.Add(this);
                    if (App.MainWindow == null)
                    {
                        App.MainWindow = this;
                    }
                }
                else
                {
                    App.NonAppWindowsInternal.Add(this);
                }
            }
        }
 
 
        internal void VerifyContextAndObjectState()
        {
            // Verify that we are executing on the right context
            VerifyAccess();
 
        // WCP Window:  Define the dispose behavior for Window
#if DISPOSE
            if (_disposed)
            {
                throw new ObjectDisposedException(null, SR.WindowDisposed);
            }
#endif
        }
 
        private void VerifyCanShow()
        {
            if (_disposed == true)
            {
                throw new InvalidOperationException(SR.ReshowNotAllowed);
            }
        }
 
        private void VerifyNotClosing()
        {
            if (_isClosing == true)
            {
                throw new InvalidOperationException(SR.InvalidOperationDuringClosing);
            }
 
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == true)
            {
                throw new InvalidOperationException(SR.InvalidCompositionTarget);
            }
        }
 
        private void VerifyHwndCreateShowState()
        {
            if (HwndCreatedButNotShown)
            {
                throw new InvalidOperationException(SR.NotAllowedBeforeShow);
            }
        }
 
        /// <summary>
        ///     sets the IWindowService attached property
        /// </summary>
        private void SetIWindowService()
        {
            if (GetValue(IWindowServiceProperty) == null)
            {
                SetValue(IWindowServiceProperty, (IWindowService)this);
            }
        }
 
        IntPtr GetCurrentMonitorFromMousePosition()
        {
            // center on the screen on which the mouse is on
            NativeMethods.POINT pt = default;
 
            UnsafeNativeMethods.TryGetCursorPos(ref pt);
 
            return SafeNativeMethods.MonitorFromPoint(pt, NativeMethods.MONITOR_DEFAULTTONEAREST);
        }
 
        // <summary>
        //     Calculates the window location based on the WindowStartupLocation property
        //     If values for CenterScreen, CenterOwner cannot be determined, then we return
        //     unmodified values.
        // </summary>
        // <remarks>
        //     This method can be called before or after the hwnd is created.  So, we have
        //     to accout for both scenarios.
        // </remarks>
        // <param name="left"></param>
        // <param name="top"></param>
        // <param name="currentSize"></param>
        private bool CalculateWindowLocation(ref double leftDeviceUnits, ref double topDeviceUnits, Size currentSizeDeviceUnits)
        {
            Debug.Assert(IsSourceWindowNull == false, "_swh should not be null here");
            double inLeft = leftDeviceUnits;
            double inTop = topDeviceUnits;
 
            switch (_windowStartupLocation)
            {
                case WindowStartupLocation.Manual:
                    break;
                case WindowStartupLocation.CenterScreen:
                    // NOTE:
                    // Which screen to center the
                    // window on?
                    //
                    // If Window has a parent handle, then center the Window on the
                    // same monitor as the parent hwnd.  If theres no parent hwnd,
                    // center the Window on the monitor where the mouse is currently
                    // on.
                    //
                    // The exception to this rule is when ShowInTaskbar is set to false
                    // and we parent to window to achieve that.  That's the reason for
                    // having the extra condition in the if statement below
                    //
 
                    IntPtr hMonitor = IntPtr.Zero;
                    if ((_ownerHandle == IntPtr.Zero) ||
                        ((_hiddenWindow != null) && (_hiddenWindow.Handle == _ownerHandle)))
                    {
                        hMonitor = GetCurrentMonitorFromMousePosition();
                    }
                    else
                    {
                        // have a parent hwnd; center on the screen on
                        // which our parent hwnd is.
                        hMonitor = MonitorFromWindow(_ownerHandle);
                    }
 
                    if (hMonitor != IntPtr.Zero)
                    {
                        CalculateCenterScreenPosition(hMonitor, currentSizeDeviceUnits, ref leftDeviceUnits, ref topDeviceUnits);
                    }
                    break;
                case WindowStartupLocation.CenterOwner:
                    Rect ownerRectDeviceUnits = Rect.Empty;
 
                    // If the owner is WPF window.
                    // The owner can be non-WPF window. It can be set via WindowInteropHelper.Owner.
                    if (CanCenterOverWPFOwner == true)
                    {
                        // If the owner is in a non-normal state use the screen bounds for centering the window.
                        // Top/Left/Width/Height reflect the restore bounds, so they can't be used in this scenario.
                        if (Owner.WindowState == WindowState.Maximized || Owner.WindowState == WindowState.Minimized)
                        {
                            goto case WindowStartupLocation.CenterScreen;
                        }
 
                        Point ownerSizeDeviceUnits;
                        // if owner hwnd is created, we use WindowSize to get its size. Note: we cannot use ActualWidth/Height here,
                        // because it is possible that the hwnd is created (WIH.EnsureHandle) but it is not shown yet; layout has not
                        // happen; ActualWidth/Height is not calculated yet.
                        // If the owner hwnd is not yet created, we use Owner.Width/Height.
                        if (Owner.Handle == IntPtr.Zero)
                        {
                            ownerSizeDeviceUnits = Owner.LogicalToDeviceUnits(new Point(Owner.Width, Owner.Height));
                        }
                        else
                        {
                            Size size = Owner.WindowSize;
                            ownerSizeDeviceUnits = new Point(size.Width, size.Height);
                        }
 
                        // A minimized window doesn't have valid Top,Left; that's why RestoreBounds.TopLeft is used.
                        Point ownerLocationDeviceUnits = Owner.LogicalToDeviceUnits(new Point(Owner.Left, Owner.Top));
                        ownerRectDeviceUnits = new Rect(ownerLocationDeviceUnits.X, ownerLocationDeviceUnits.Y,
                            ownerSizeDeviceUnits.X, ownerSizeDeviceUnits.Y);
                    }
                    else
                    {
                        // non-WPF owner
                        if ((_ownerHandle != IntPtr.Zero) && UnsafeNativeMethods.IsWindow(new HandleRef(null, _ownerHandle)))
                        {
                            ownerRectDeviceUnits = GetNormalRectDeviceUnits(_ownerHandle);
                        }
                    }
 
                    if (! ownerRectDeviceUnits.IsEmpty)
                    {
                        leftDeviceUnits = ownerRectDeviceUnits.X + ((ownerRectDeviceUnits.Width - currentSizeDeviceUnits.Width) / 2);
                        topDeviceUnits = ownerRectDeviceUnits.Y + ((ownerRectDeviceUnits.Height - currentSizeDeviceUnits.Height) / 2);
 
                        // (Window.CenterOwner doesn't make sure the window fits entirely on screen)
                        // Check the screen rect to make sure the window is shown on screen.
                        // It is the same as WinForms' behavior.
                        NativeMethods.RECT workAreaRectDeviceUnits = WorkAreaBoundsForHwnd(_ownerHandle);
                        leftDeviceUnits = Math.Min(leftDeviceUnits, workAreaRectDeviceUnits.right - currentSizeDeviceUnits.Width);
                        leftDeviceUnits = Math.Max(leftDeviceUnits, workAreaRectDeviceUnits.left);
                        topDeviceUnits = Math.Min(topDeviceUnits, workAreaRectDeviceUnits.bottom - currentSizeDeviceUnits.Height);
                        topDeviceUnits = Math.Max(topDeviceUnits, workAreaRectDeviceUnits.top);
                    }
 
                    break;
                default:
                    break;
            }
            return (!DoubleUtil.AreClose(inLeft, leftDeviceUnits) || !DoubleUtil.AreClose(inTop, topDeviceUnits));
        }
 
        private static NativeMethods.RECT WorkAreaBoundsForHwnd(IntPtr hwnd)
        {
            IntPtr hMonitor = MonitorFromWindow(hwnd);
 
            return WorkAreaBoundsForMointor(hMonitor);
        }
 
        private static NativeMethods.RECT WorkAreaBoundsForMointor(IntPtr hMonitor)
        {
            NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX();
 
            Debug.Assert(hMonitor != IntPtr.Zero);
            SafeNativeMethods.GetMonitorInfo(new HandleRef(null, hMonitor), monitorInfo);
 
            return monitorInfo.rcWork;
        }
 
        private static IntPtr MonitorFromWindow(IntPtr hwnd)
        {
            IntPtr hMonitor = SafeNativeMethods.MonitorFromWindow(new HandleRef(null, hwnd), NativeMethods.MONITOR_DEFAULTTONEAREST);
            if (hMonitor == IntPtr.Zero)
            {
                throw new Win32Exception();
            }
            return hMonitor;
        }
 
        /// <summary>
        /// Calculates the left and right coordinates of a window
        /// when centered on a given monitor.
        /// </summary>
        /// <param name="hMonitor">Handle to the monitor to center the window on</param>
        /// <param name="currentSizeDeviceUnits">Size of the window, in device units</param>
        /// <param name="leftDeviceUnits">Receives the new left location in device units</param>
        /// <param name="topDeviceUnits">Receives the new top location in device units</param>
        internal static void CalculateCenterScreenPosition(IntPtr hMonitor, Size currentSizeDeviceUnits, ref double leftDeviceUnits, ref double topDeviceUnits)
        {
            NativeMethods.RECT workAreaRectDeviceUnits = WorkAreaBoundsForMointor(hMonitor);
 
            // We're using Width/Height here as opposed to ActualWidth/Height
            // as layout hasn't happened yet.
            double workAreaWidthDeviceUnits = workAreaRectDeviceUnits.right - workAreaRectDeviceUnits.left;
            double workAreaHeightDeviceUnits = workAreaRectDeviceUnits.bottom - workAreaRectDeviceUnits.top;
 
            Debug.Assert(workAreaWidthDeviceUnits >= 0, string.Create(CultureInfo.InvariantCulture, $"workAreaWidth ({hMonitor})for monitor ({workAreaWidthDeviceUnits}) is negative"));
            Debug.Assert(workAreaHeightDeviceUnits >= 0, string.Create(CultureInfo.InvariantCulture, $"workAreaHeight ({hMonitor}) for monitor ({workAreaHeightDeviceUnits}) is negative"));
 
            leftDeviceUnits = (workAreaRectDeviceUnits.left + ((workAreaWidthDeviceUnits - currentSizeDeviceUnits.Width) / 2));
            topDeviceUnits = (workAreaRectDeviceUnits.top + ((workAreaHeightDeviceUnits - currentSizeDeviceUnits.Height) / 2));
        }
 
        private bool CanCenterOverWPFOwner
        {
            get
            {
                Debug.Assert(IsSourceWindowNull == false, "_swh should not be null here");
 
                // if Owner is null, we cannot CenterOwner
                if (Owner == null)
                {
                    return false;
                }
 
                // if Owner._sourceWindow is null, and if Owner's Width or Height is not specified
                // then we cannot CenterOwner
                if (Owner.IsSourceWindowNull)
                {
                    if ((double.IsNaN(Owner.Width)) ||
                        (double.IsNaN(Owner.Height)))
                    {
                        return false;
                    }
                }
 
                // if Owner's Top or Left is not specified, we cannot CenterOwner
                if ((double.IsNaN(Owner.Left)) ||
                    (double.IsNaN(Owner.Top)))
                {
                    return false;
                }
                return true;
            }
        }
 
        private Rect GetNormalRectDeviceUnits(IntPtr hwndHandle)
        {
            int styleEx = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, hwndHandle), NativeMethods.GWL_EXSTYLE);
 
            NativeMethods.WINDOWPLACEMENT wp = new NativeMethods.WINDOWPLACEMENT();
            wp.length = Marshal.SizeOf(typeof(NativeMethods.WINDOWPLACEMENT));
            UnsafeNativeMethods.GetWindowPlacement(new HandleRef(this, hwndHandle), ref wp);
            Point locationDeviceUnits = new Point(wp.rcNormalPosition_left, wp.rcNormalPosition_top);
 
            // GetWindowPlacement returns workarea co-ods for a top level window whose
            // WS_EX_TOOLWINDOW bit is clear.  If this bit is set, then the co-ods
            // returned are relative to the screen co-ods of the monitor.
            // TransfromWorkAreaScreenArea can transform a point from work area co-ods
            // to screen area co-ods and vice versa depending on TransformType value passed.
            // So, in our case, if the window is not a ToolWindow we want to transform
            // the point from work area co-ods to screen co-ods.
            if ((styleEx & NativeMethods.WS_EX_TOOLWINDOW) == 0)
            {
                locationDeviceUnits = TransformWorkAreaScreenArea(locationDeviceUnits, TransformType.WorkAreaToScreenArea);
            }
 
            Point sizeDeviceUnits = new Point(wp.rcNormalPosition_right - wp.rcNormalPosition_left,
                                              wp.rcNormalPosition_bottom - wp.rcNormalPosition_top);
 
            return new Rect(locationDeviceUnits.X, locationDeviceUnits.Y, sizeDeviceUnits.X, sizeDeviceUnits.Y);
        }
 
        private Rect GetNormalRectLogicalUnits(IntPtr hwndHandle)
        {
            Rect rectDeviceUnits = GetNormalRectDeviceUnits(hwndHandle);
 
            Point sizeLogicalUnits = DeviceToLogicalUnits(new Point(rectDeviceUnits.Width, rectDeviceUnits.Height));
            Point locationLogicalUnits = DeviceToLogicalUnits(new Point(rectDeviceUnits.X, rectDeviceUnits.Y));
 
            return new Rect(locationLogicalUnits.X, locationLogicalUnits.Y, sizeLogicalUnits.X, sizeLogicalUnits.Y);
        }
 
        /// <summary>
        ///     Update style bits for window state
        /// </summary>
        private void CreateWindowState()
        {
            switch (WindowState)
            {
                case WindowState.Normal:
                    break;
                case WindowState.Maximized:
                    _Style |= NativeMethods.WS_MAXIMIZE;
                    break;
                case WindowState.Minimized:
                    _Style |= NativeMethods.WS_MINIMIZE;
                    break;
#if THEATRE_FULLSCREEN
                case WindowState.Theatre:
                    throw new NotImplementedException(SR.NotImplementedException);
 
                case WindowState.FullScreen:
                    throw new NotImplementedException(SR.NotImplementedException);
#endif //THEATRE_FULLSCREEN
            }
        }
 
        /// <summary>
        ///     creates topmost window
        /// </summary>
        private void CreateTopmost()
        {
            // check for topmost
            if ( Topmost )
            {
                _StyleEx |= NativeMethods.WS_EX_TOPMOST;
            }
            else
            {
                _StyleEx &= ~NativeMethods.WS_EX_TOPMOST;
            }
        }
 
        /// <summary>
        ///     set's resizibility for the window
        /// </summary>
        private void CreateResizibility()
        {
            _Style &= ~(NativeMethods.WS_THICKFRAME | NativeMethods.WS_MAXIMIZEBOX | NativeMethods.WS_MINIMIZEBOX);
 
 
            switch(ResizeMode)
            {
                case ResizeMode.NoResize:
                    break;
                case ResizeMode.CanMinimize:
                    _Style |= NativeMethods.WS_MINIMIZEBOX;
                    break;
                case ResizeMode.CanResize:
                case ResizeMode.CanResizeWithGrip:
                    _Style |= NativeMethods.WS_THICKFRAME | NativeMethods.WS_MAXIMIZEBOX | NativeMethods.WS_MINIMIZEBOX;
                    break;
                default:
                    Debug.Assert(false, "Invalid value for ResizeMode");
                    break;
            }
        }
 
        /// <summary>
        ///     Updates the window icon
        /// </summary>
        private void UpdateIcon()
        {
            // NOTE: Set Window.Icon = null causes NullReferenceException
 
            // if _icon is null, set _defaultLargeIconHandle and _defaultSmallIconHandle
            //  to the app icon (embedded in the exe).  _icon is used as window icon if it
            // is not null, else default icons from exe are used.  If both are null,
            // we set IntPtr.Zero as the icons for the window and Win32 defaults
            // come into play.
            //
 
            NativeMethods.IconHandle largeIconHandle;
            NativeMethods.IconHandle smallIconHandle;
 
            if (_icon != null)
            {
                IconHelper.GetIconHandlesFromImageSource(_icon, out largeIconHandle, out smallIconHandle);
            }
            else
            {
                // these both should be null before we've queried that exe for icons.
                // Once, we looked in the exe, these are no longer null and hence we
                // don't want to re-query in the exe anymore
                if (_defaultLargeIconHandle == null && _defaultSmallIconHandle == null)
                {
                     // sets the default small and large icon handles
                     IconHelper.GetDefaultIconHandles(out largeIconHandle, out smallIconHandle);
                    _defaultLargeIconHandle = largeIconHandle;
                    _defaultSmallIconHandle = smallIconHandle;
                }
                else
                {
                    largeIconHandle = _defaultLargeIconHandle;
                    smallIconHandle = _defaultSmallIconHandle;
                }
                // get default icons
            }
 
            // One of the steps necessary to hide a Window's taskbar button is to parent it off another HWND.
            // On XP when this is done the Window's alt-tab icon takes on the icon of the parent.  If we've created
            // a hidden parent window for the sake of ShowInTaskbar=false, then we need to keep its icon in sync
            // with the Window's.
            // On Vista this isn't necessary.
 
            // Make the array big enough to hold anything we need to update.
            // We'll keep track of the true count separately.
            var iconWindows = new HandleRef[]
            {
                new HandleRef(this, Handle),
                default(HandleRef)
            };
            int iconWindowsCount = 1;
 
            if (_hiddenWindow != null)
            {
                iconWindows[1] = new HandleRef(_hiddenWindow, _hiddenWindow.Handle);
                ++iconWindowsCount;
            }
 
            for (int i = 0; i < iconWindowsCount; ++i)
            {
                HandleRef hwnd = iconWindows[i];
 
                UnsafeNativeMethods.SendMessage(
                                        hwnd,
                                        WindowMessage.WM_SETICON,
                                        (IntPtr)NativeMethods.ICON_BIG,
                                        largeIconHandle);
 
                UnsafeNativeMethods.SendMessage(
                                        hwnd,
                                        WindowMessage.WM_SETICON,
                                        (IntPtr)NativeMethods.ICON_SMALL,
                                        smallIconHandle);
            }
 
            // dispose the previous icon handle if it's not the default handle
            if (_currentLargeIconHandle != null && _currentLargeIconHandle != _defaultLargeIconHandle)
            {
                _currentLargeIconHandle.Dispose();
            }
 
            if (_currentSmallIconHandle != null && _currentSmallIconHandle != _defaultSmallIconHandle)
            {
                _currentSmallIconHandle.Dispose();
            }
 
            _currentLargeIconHandle = largeIconHandle;
            _currentSmallIconHandle = smallIconHandle;
        }
 
        /// <summary>
        ///     Sets the parent hwnd (Owner) for this window. This could be called as a result of
        ///     setting one of the following
        ///
        ///         Window Owner {set;}
        ///         IntPtr OwnerHandle {set;}  -- this is used by WindowInteropHelper
        /// </summary>
        /// <param name="ownerHandle">IntPtr of the parent window</param>
        private void SetOwnerHandle(IntPtr ownerHandle)
        {
            // Note:
            // "SetWindowLong failed.  Error = 1400" appears in console when setting
            // Window.Owner to a Window hasn't been shown (chk build)
            //
            // SetWindowLong with GWL_HWNDPARENT fails if the new parent/owner is IntPtr.Zero
            // and the old owner was also IntPtr.Zero.  The if check below works around this
            // issue.
            if (_ownerHandle == ownerHandle && _ownerHandle == IntPtr.Zero)
            {
                return;
            }
 
            // If this call is removing the owner then we possibly need to reparent it with
            // the hidden window (ShowInTaskbar==false)
            // Once the hidden window is created we keep its icon in sync with the Window's.
            _ownerHandle = (IntPtr.Zero == ownerHandle && !ShowInTaskbar)
                ? EnsureHiddenWindow().Handle
                : ownerHandle;
 
            if (IsSourceWindowNull == false)
            {
                UnsafeNativeMethods.SetWindowLong(new HandleRef(null, Handle),
                    NativeMethods.GWL_HWNDPARENT,
                    _ownerHandle);
 
                // Update and reset the Owner Window if this is set through WindowInteropHelper.
                // We want to do this because once we are passed in the IntPtr for
                // the parent window, the Owner window is not the parent anymore.
 
                if ((_ownerWindow != null) && (_ownerWindow.Handle != _ownerHandle))
                {
                    _ownerWindow.OwnedWindowsInternal.Remove(this);
                    _ownerWindow = null;
                }
            }
        }
 
        /// <summary>
        ///     This is called back into when HwndSouce being used by this object is disposed, or if the
        ///     hwnd is destroyed.
        ///
        ///     When that happens on the same thread, we receive WM_CLOSE, WM_DESTROY and
        ///     everything works fine.  However, if that happened on another thread, we don't get
        ///     WM_CLOSE, WM_DESTROY until later, but we get this disposed callback and we
        ///     set dispose this object.  If we don't do this, there could be timing related issues if
        ///     we get called into after the HwndSource or hwnd has been disposed/destoyed but before
        ///     we receive WM_CLOSE, WM_DESTROY messages.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private void OnSourceWindowDisposed(object sender, EventArgs e)
        {
            if ( _disposed == false)
            {
                InternalDispose();
            }
        }
 
        /// <summary>
        ///     This is the hook to HwndSource that is called when window messages related to
        ///     this window occur. Currently, we listen to the following messages
        ///
        ///         WM_CLOSE        : We listen to this message in order to fire the Closing event.
        ///                           If the user cancels window closing, we set handled to true so
        ///                           that the DefWindowProc does not handle this message. Otherwise,
        ///                           we set handled to false.
        ///         WM_DESTROY      : We listen to this message in order to fire the Closed event.
        ///                           Handled is always set to false.
        ///         WM_ACTIVATE     : Used for Activated and deactivated events
        ///         WM_SIZE         : Used for SizeChanged, StateChanged events. Also, helps us keep our
        ///                           size updated
        ///         WM_MOVE:        : Used for location changed event and to keep our cached top/left
        ///                           updated
        ///         WM_GETMINMAXINFO: Used to enforce Max/MinHeight and Max/MinWidth
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="msg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <param name="handled"></param>
        /// <returns></returns>
        private IntPtr WindowFilterMessage( IntPtr hwnd,
            int msg,
            IntPtr wParam,
            IntPtr lParam,
            ref bool handled)
        {
            IntPtr retInt = IntPtr.Zero ;
            WindowMessage message = (WindowMessage)msg;
 
            //
            // we need to process WM_GETMINMAXINFO before _swh is assigned to
            // b/c we want to store the max/min size allowed by win32 for the hwnd
            // which is later used in GetWindowMinMax.  WmGetMinMaxInfo can handle
            // _swh == null case.
            switch (message)
            {
                case WindowMessage.WM_GETMINMAXINFO:
                    handled = WmGetMinMaxInfo(lParam);
                    break;
                case WindowMessage.WM_SIZE:
                    handled = WmSizeChanged(wParam);
                    break;
            }
 
            if(_swh != null && _swh.CompositionTarget != null) // For extraneous messages during shutdown
            {
                // Can't case this in the switch statement since it's dynamically generated.
                if (message == WM_TASKBARBUTTONCREATED || message == WM_APPLYTASKBARITEMINFO)
                {
                    // Either Explorer's created a new button or it's time to try again.
                    // Stop deferring updates to the Taskbar.
                    if (_taskbarRetryTimer != null)
                    {
                        _taskbarRetryTimer.Stop();
                    }
 
                    // We'll receive WM_TASKBARBUTTONCREATED at times other than when the Window was created,
                    //    e.g. Explorer restarting, in response to ShowInTaskbar=true, etc.
                    // We'll receive WM_APPLYTASKBARITEMINFO when we'ved posted it to ourself after a failed ITaskbarList3 call.
                    ApplyTaskbarItemInfo();
                }
                else switch (message)
                {
                    case WindowMessage.WM_CLOSE:
                        handled = WmClose();
                        break;
                    case WindowMessage.WM_DESTROY:
                        handled = WmDestroy();
                        break;
                    case WindowMessage.WM_ACTIVATE:
                        handled = WmActivate(wParam);
                        break;
                    case WindowMessage.WM_MOVE:
                        handled = WmMoveChanged();
                        break;
                    case WindowMessage.WM_NCHITTEST:
                        handled = WmNcHitTest(lParam, ref retInt);
                        break;
                    case WindowMessage.WM_SHOWWINDOW:
                        handled = WmShowWindow(wParam, lParam);
                        break;
                    case WindowMessage.WM_COMMAND:
                        handled = WmCommand(wParam, lParam);
                        break;
                    default:
                        handled = false;
                        break;
                }
            }
 
            return retInt;
        }
 
        /// <summary>
        ///     Called on WM_COMMAND message.
        /// </summary>
        /// <returns>
        ///     True if we want to handle the command, false otherwise.
        /// </returns>
        private bool WmCommand(IntPtr wParam, IntPtr lParam)
        {
            if (NativeMethods.SignedHIWORD(wParam.ToInt32()) == THUMBBUTTON.THBN_CLICKED)
            {
                TaskbarItemInfo taskbar = TaskbarItemInfo;
                if (taskbar != null)
                {
                    int index = NativeMethods.SignedLOWORD(wParam.ToInt32());
                    if (index >= 0 && index < taskbar.ThumbButtonInfos.Count)
                    {
                        taskbar.ThumbButtonInfos[index].InvokeClick();
                    }
                }
                return true;
            }
            return false;
        }
 
        /// <summary>
        ///     Called on WM_CLOSE message. Fires the Closing event.
        /// </summary>
        /// <returns>
        ///     True if we want to stop the window from closing, else false
        /// </returns>
        private bool WmClose()
        {
            // For WS_CHILD window, WM_SIZE, WM_MOVE (and maybe others) are called
            // synchronously from CreateWindowEx call and we run into issues if
            // _sourceWindow in null.  We only care to listen to WM_CREATE &
            // WM_GETMINMAXINFO synchronously from CreateWindowEx thus we want
            // to explicitly add the null check below at all other places.
            //
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            // if DialogResult is set from within a Closing event then
            // the window is in the closing state.  In such a case, we
            // should not call Close() from DialogResult.set and thus
            // we have this variable.
            //
            // Note: Windows OS bug # 934500 Setting DialogResult
            // on the Closing EventHandler of a Dialog causes StackOverFlowException
            _isClosing = true;
 
            // Event handler exception continuality: if exception occurs in Closing event handler, the
            // cleanup action is to finish closing.
            CancelEventArgs e = new CancelEventArgs(false);
            try
            {
                OnClosing(e);
            }
            catch
            {
                CloseWindowFromWmClose();
                throw;
            }
 
            if (ShouldCloseWindow(e.Cancel))
            {
                CloseWindowFromWmClose();
                return false;
            }
            else
            {
                // close cancelled
                _isClosing = false;
 
                // Dialog does not close with ESC key after it has been cancelled
                //
                // Since closing is cancelled, DialogResult should be reset to null b/c
                // 1) DialogResult = true/false means that dialog has been accepeted/rejected (since dialog didn't
                //                   close (closing cancelled), DialogResult should be null)
                _dialogResult = null;
 
                return true;
            }
        }
 
        private void CloseWindowFromWmClose()
        {
            if (_showingAsDialog)
            {
                DoDialogHide();
            }
 
            // We should ClearRootVisual here instead of in InternalDispose. InternalDispose is called either as a result of HwndSource
            // disposing itself or it will try to dispose HwndSource. HwndSource will clear the root visual when it is disposed.
            ClearRootVisual();
 
            // We should also ClearHiddenWindow here, because in InternalDispose the window handle could be null if the dispose happens as
            // a result of HwndSource dispose. Our InternalDispose has been changed to handle reantrance, so the issue (bug 953988) described in
            // ClearHiddenWindowIfAny should not happen any more.
            ClearHiddenWindowIfAny();
        }
 
        private bool ShouldCloseWindow(bool cancelled)
        {
            // if shutdown Closing cannot be cancelled
            // if parent window is closing, child window Closing cannot be cancelled.
            return ((!cancelled) || (_appShuttingDown) || (_ignoreCancel));
        }
 
        private void DoDialogHide()
        {
 
            Debug.Assert(_showingAsDialog == true, "_showingAsDialog must be true when DoDialogHide is called");
 
            bool wasActive = false;
 
            //It's possible that _dispatcherFrame could be null at this time.
            //The scenario is: When showing the window as a modal dialog, the window Activated event is fired
            //before _dispatcherFrame is instantiated. In the Activated handler, if user closes the
            //window (setting DialogResult fires the WM_CLOSE event), the _dispatcherFrame is still null.
            //Bug 874463 addressed this.
            if (_dispatcherFrame != null)
            {
                // un block the push frame call
                _dispatcherFrame.Continue = false;
                _dispatcherFrame = null;
            }
 
            // Fix for Close Dialog Window should not return null
            //
            // The consensus here is that DialogResult should never be null when ShowDialog returns
            // As such, we coerce it to be false.  Furthermore, we don't use the DialogResult property
            // to update _dialogResult here since that does more than just updating the underlying
            // variable
            if (_dialogResult == null)
            {
                _dialogResult = false;
            }
 
            // clears _showingAsDialog
            _showingAsDialog = false;
 
            // enable previous window stuff goes here...
            wasActive = _swh.IsActiveWindow;
 
            // We assert here b/c I think _threadWindowHandles should never be null when we get
            // called in here.
            //
            // However, if inside ShowDialog we hit an exception after showing the dialog and the
            // exception handler is run, then _threadWindowHandles will be null here.
            //
            // Keeping this as assert.  If this turn out to be an over active assert, we'll switch to
            // an if condition.
            Debug.Assert(_threadWindowHandles != null, "_threadWindowHandles must not be null at this point");
            // reenable windows in the thread that were disabled
            EnableThreadWindows(true);
 
            // if dialog that is closing was active window and there was a previously active window,
            // set the active window.  The owner window may not be the previously active window. See DevDiv bug 122467 for details.
            // Furthermore, verify that _dialogPreviousActiveHandle is still a window b/c it
            // could have been destroyed by now by some other thread/codepath etc.
            // (BVT BLOCKER: System.ComponentModel.Win32Exception thrown when
            // trying to shutdown app inside a Dialog Window)
            if ((wasActive == true) &&
                (_dialogPreviousActiveHandle != IntPtr.Zero) &&
                (UnsafeNativeMethods.IsWindow(new HandleRef(this, _dialogPreviousActiveHandle)) == true))
            {
                UnsafeNativeMethods.SetActiveWindow(new HandleRef(this, _dialogPreviousActiveHandle));
            }
            else
            {
                // WCP: Fix code for a rare scenario when dialog is going away
 
                // rare situation, figure this out later
                // talk to user team as to what we need to do here
            }
        }
 
        private void UpdateWindowListsOnClose()
        {
            // Close all owned windows
            // use internal version since we want to update the underlying collection
            WindowCollection ownedWindows = OwnedWindowsInternal;
 
            // need to discuss what the correct behavior is if one of the owned window throws exception
            // when closing.
            // Although we explicitly do this here, we don't really need to. (see PS # 857285)
            // We use a while loop like this because closing an owned window will modify the owned windows list.
            while (ownedWindows.Count > 0)
            {
                // if parent window is closing, child window Closing cannot be cancelled.
                ownedWindows[0].InternalClose(false, true /* Ignore cancel */);
            }
 
            Debug.Assert(ownedWindows.Count == 0, "All owned windows should now be gone");
 
            // Update OwnerWindows of our Owner
            if (IsOwnerNull == false)
            {
                // use internal version since we want to update the underlying collection
                Owner.OwnedWindowsInternal.Remove(this);
            }
 
            if (this.IsInsideApp)
            {
                if (Application.Current.Dispatcher.Thread == Dispatcher.CurrentDispatcher.Thread)
                {
                    // use internal version since we want to update the underlying collection
                    App.WindowsInternal.Remove(this);
 
                    // Check to see if app should shut down--this behavior really belongs in Application
                    if (_appShuttingDown == false)
                    {
                        // If this is the last window that's closing and shutdownmode is onlastwindowclose, or
                        // if this is the main window closing and shutdownmode is onmainwindowclose, shutdown
                        // the app
                        if (((App.Windows.Count == 0) && (App.ShutdownMode == ShutdownMode.OnLastWindowClose))
                         || ((App.MainWindow == this) && (App.ShutdownMode == ShutdownMode.OnMainWindowClose)))
                        {
                            App.CriticalShutdown(0);
                        }
                    }
 
                    TryClearingMainWindow();
                }
                else
                {
                    App.NonAppWindowsInternal.Remove(this);
                }
            }
}
        private bool  WmDestroy()
        {
            // For WS_CHILD window, WM_SIZE, WM_MOVE (and maybe others) are called
            // synchronously from CreateWindowEx call and we run into issues if
            // _sourceWindow in null.  We only care to listen to WM_CREATE &
            // WM_GETMINMAXINFO synchronously from CreateWindowEx thus we want
            // to explicitly add the null check below at all other places.
            if (IsSourceWindowNull)
            {
                return false;
            }
 
            if (_disposed == false)
            {
                InternalDispose();
            }
 
            // STRESS: System.NullReferenceException @ System.Windows.Window.DeviceToLogicalUnits
            //
            // We're intentionally not adding a check for IsCompositionTargetInvlaid here since we
            // feel that it is okay to fire the Closed event to notify the developer that window has
            // closed.
 
            // Event handler exception continuality: if exception occurs in Closed event handler, the
            // cleanup action is to finish closing.
            // raise Closed event
            OnClosed(EventArgs.Empty);
 
            return false;
        }
 
        private bool WmActivate( IntPtr wParam )
        {
            // For WS_CHILD window, WM_SIZE, WM_MOVE (and maybe others) are called
            // synchronously from CreateWindowEx call and we run into issues if
            // _sourceWindow in null.  We only care to listen to WM_CREATE &
            // WM_GETMINMAXINFO synchronously from CreateWindowEx thus we want
            // to explicitly add the null check below at all other places.
            //
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            int loWord = NativeMethods.SignedLOWORD(wParam);
            bool windowActivated;
 
 
            if ( loWord == NativeMethods.WA_INACTIVE )
            {
                windowActivated = false;
            }
            else
            {
                windowActivated = true;
            }
 
            HandleActivate(windowActivated);
 
            return false;
        }
 
        // When the window is in a maximized or minimized state, we want the dimension properties
        // to reflect what it would be when it's restored.
        private void UpdateDimensionsToRestoreBounds()
        {
            Rect restoreRect = RestoreBounds;
            SetValue(LeftProperty, restoreRect.Left);
            SetValue(TopProperty, restoreRect.Top);
            SetValue(WidthProperty, restoreRect.Width);
            SetValue(HeightProperty, restoreRect.Height);
        }
 
        private bool WmSizeChanged(IntPtr wParam)
        {
            // For WS_CHILD window, WM_SIZE, WM_MOVE (and maybe others) are called
            // synchronously from CreateWindowEx call and we run into issues if
            // _sourceWindow in null.  We only care to listen to WM_CREATE &
            // WM_GETMINMAXINFO synchronously from CreateWindowEx thus we want
            // to explicitly add the null check below, at all other places.
            //
            // Adding IsCompositionTargetInvalid check here
            // Add this check here means that we won't fire WindowStateChanged event.
            // However, since the hwnd is going away anyways, not firing StateChanged
            // should not be a big deal.  The other side effect is that Width/Height DPs
            // won't be updated that should be fine too since window is going away.
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            NativeMethods.RECT rc = WindowBounds;
            Point windowSize = new Point(rc.right - rc.left, rc.bottom - rc.top);
            Point ptLogicalUnits = DeviceToLogicalUnits(windowSize);
 
            try
            {
                _updateHwndSize = false;
                SetValue(FrameworkElement.WidthProperty, ptLogicalUnits.X);
                SetValue(FrameworkElement.HeightProperty, ptLogicalUnits.Y);
            }
            finally
            {
                _updateHwndSize = true;
            }
 
            // Update the Taskbar's data about this window.  This can intermittently fail if Explorer gets busy.
            // It's not worth handling failures here since if there is a clip we'll try again on the next resize
            // and it doesn't affect the window itself.
            HRESULT hr = UpdateTaskbarThumbnailClipping();
 
            switch ((int)wParam)
            {
                // We introduced _previousWindowState for the following scenario:
                //
                // win1.WindowState = WindowState.Maximized; // or stateA
                // ...
                // win1.WindowState = WindowState.Normal; // or stateB
                //
                // Developer sets WindowState to Maximized/Minimized then return to Normal.
                // OnStateChanged should be fired. However, We were comparing that to WindowState.Normal.
                // The value in property engine had been updated to Normal in the CLR setter, so OnStateChanged
                // was never fired.
                // This is addressed in bug 937458.
                //
                // Another reason for remembering the previous state is that
                // WM_SIZE is sent when the client area size of the hwnd changes.
                // Thus, if the hwnd is maximized, and the border style changes,
                // WM_SIZE is sent.  In such cases, we don't want to fire
                // StateChanged since the previous state was maximized too.
                // (NullReferenceException thrown when changing ResizeMode from CanMinimize
                // to CanResizeWithGrip inside StateChanged event handler).
                //
                // There are two places we update _previousWindowState.
 
                // WindowState can be changed as a result of the following two passes
                // 1. User interaction changes WindowState
                // 2. Developer programmatically changes WindowState
                // We update _previousWindowState at two places
                // 1. Before Hwnd is created, when developer programmatically changes WindowState, we update it when WindowState is invalidated.
                // 2. After Hwnd is created, we update it here because both passes comes here eventually.
 
                // Event handler exception continuality: if exception occurs in StateChanged event handler, our state will not be
                // corrupted because the state related to StateChanged, WindowStateProperty and _previousWindowState, are set before the event is fired.
                // Please check Event handler exception continuality if the logic changes.
                case NativeMethods.SIZE_MAXIMIZED:
                    if (_previousWindowState != WindowState.Maximized)
                    {
                        // Do not set local value unless it is from user interaction.
                        // User interaction is considered as the same pri as SetValue
                        // If WindowState is not the same as the current win32 value, it means the change is
                        // not from the DP system but from user interaction.
                        if (WindowState != WindowState.Maximized)
                        {
                            try
                            {
                                _updateHwndLocation = false;
                                _updateHwndSize = false;
                                UpdateDimensionsToRestoreBounds();
                            }
                            finally
                            {
                                _updateHwndSize = true;
                                _updateHwndLocation = true;
                            }
                            WindowState = WindowState.Maximized;
                        }
                        // The maximizing size we get from WM_GETMINMAXINFO is only valid for the primary monitor, if the primary monitor
                        // happens to be smaller than the secondary monitor, we may end up not maximizing correctly in the secondary monitor.
                        // Here we are sure that this size value is coming from the OS so it is safe to update our maximizing size.
                        _windowMaxWidthDeviceUnits = Math.Max(_windowMaxWidthDeviceUnits, windowSize.X);
                        _windowMaxHeightDeviceUnits = Math.Max(_windowMaxHeightDeviceUnits, windowSize.Y);
 
                        _previousWindowState = WindowState.Maximized;
                        OnStateChanged(EventArgs.Empty);
                    }
                    break;
                case NativeMethods.SIZE_MINIMIZED:
                    if (_previousWindowState != WindowState.Minimized)
                    {
                        if (WindowState != WindowState.Minimized)
                        {
                            try
                            {
                                _updateHwndSize = false;
                                _updateHwndLocation = false;
                                UpdateDimensionsToRestoreBounds();
                            }
                            finally
                            {
                                _updateHwndSize = true;
                                _updateHwndLocation = true;
                            }
                            WindowState = WindowState.Minimized;
                        }
                        _previousWindowState = WindowState.Minimized;
                        OnStateChanged(EventArgs.Empty);
                    }
                    break;
                case NativeMethods.SIZE_RESTORED:
                    if (_previousWindowState != WindowState.Normal)
                    {
                        if (WindowState != WindowState.Normal)
                        {
                            WindowState = WindowState.Normal;
                            WmMoveChangedHelper();
                        }
                        _previousWindowState = WindowState.Normal;
                        OnStateChanged(EventArgs.Empty);
                    }
                    break;
                default:
                    break;
            }
 
            // DON'T DO ANYTHIHG HERE SINCE WE FIRE STATECHANGED ABOVE.  USER CODE
            // RUNS IN STATE CHANGED AND WINDOW COULD HAVE BEEN CLOSED.  THUS, THE
            // STATE OF VARIABLES IS UNKNOWN.
 
            // HwndSource passes the win32 msgs to the public hookds first before
            // passing layout hook etc.  Thus we get the WM_SIZE msg before
            // layout filter has processed it and we were reporting stale
            // value for height/width.  Now, UIElement fires SizeChanged event.
 
            return false;
        }
 
 
        private bool WmMoveChanged()
        {
            // We want to listen to WM_MOVE synchronously since if a Window is
            // created minimized/maximized we get this message as a result of
            // calling CreateWindowEx.  Here, sourceWindow is null but we still
            // need to update _actual[Top/Left] to reflect the correct Top/Left
            // when Show() returns.  Thus we input hwnd and process top/left info
            //
            // We won't fire LocationChanged unless Show has returned meaning
            // IsSourceWindowNull is false.  Furthermore, LocationChanged is
            // fired only if the top/left values really changed
 
            // Adding IsCompositionTargetInvalid check here
            // Since hwnd is going away, not updating Top/Left DPs and not firing
            // LocationChanged should not matter.
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            // the input lparam gives the client location,
            // so just call GetWindowRect for Left and Top.
            NativeMethods.RECT rc = WindowBounds;
 
            Point ptLogicalUnits = DeviceToLogicalUnits(new Point(rc.left, rc.top));
 
 
            if (!DoubleUtil.AreClose(_actualLeft, ptLogicalUnits.X) ||
                !DoubleUtil.AreClose(_actualTop, ptLogicalUnits.Y))
            {
                _actualLeft = ptLogicalUnits.X;
                _actualTop = ptLogicalUnits.Y;
 
                // In Window, WmMoveChangedHelper write the local value of Top/Left
                // (if necessary) or updates the property system values for
                // Top/Left by calling CoerceValue.  Furthermore, it fires the
                // LocationChanged event.  RBW overrides WmMoveChangedHelper to do
                // nothing as writing Top/Left is not supported for RBW and
                // LocationChanged is never fired for it either.
                WmMoveChangedHelper();
 
                //Invalidate AutomationPeer if it was created/used by Automation.
                //This will schedule a deferred update of bounding rectangle and
                //corresponding notification to the Automation layer.
                AutomationPeer peer = UIElementAutomationPeer.FromElement(this);
                if(peer != null)
                {
                    peer.InvalidatePeer();
                }
}
 
            return false;
        }
 
        // This method updates the Left/Top values and fires the location changed event.
        // It is virtual so that RBW can override it.
        internal virtual void WmMoveChangedHelper()
        {
            if (WindowState == WindowState.Normal)
            {
                try
                {
                    _updateHwndLocation = false;
                    SetValue(LeftProperty, _actualLeft);
                    SetValue(TopProperty, _actualTop);
                }
                finally
                {
                    _updateHwndLocation = true;
                }
 
                // Event handler exception continuality: if exception occurs in LocationChanged event handler, our state will not be
                // corrupted because the states related to LocationChanged, LeftProperty, TopProperty, Left and Top are set before the event is fired.
                // Please check event handler exception continuality if the logic changes.
                OnLocationChanged(EventArgs.Empty);
            }
        }
 
 
        private bool WmGetMinMaxInfo( IntPtr lParam )
        {
            NativeMethods.MINMAXINFO mmi;
            unsafe
            {
                mmi = *(NativeMethods.MINMAXINFO*)lParam;
            }
 
            //
            // For Bug 1380569: Window SizeToContent does not work after changing Max size properties
            //
            // When Min/Max size is changed in this Window instance, we want to make sure the correct
            // final Min/Max size is used to measure the window layout and notify the Win32 of the required
            // Min/Max size.
            //
            // This method is responsible to notify Win32 of the new Min/Max size.
            // MeasureOverride( ) is responisble to use the right Min/Max size to calculate the desired layout size.
            //
            // But only this method knows the Win32 restricted Min/Max value for the HWND when it responds to WM_GETMINMAXINFO message.
            //
            // To generate the right final Min/Max size value in both places ( here and MeasureOverride), we should
            // cache the Win32 restricted size here.
            //
 
 
 
            // We need to store the max/min size the hwnd can take.  This is used in GetWindowMinMax to determine
            // the size passed to children for their layout.  These are stored in device units here so later
            // we change them to logical units.  Fixes the following bugs:
            //
            // Wrong window actual size returned if Autosize window
            // content is smaller than the actual window (seems to return content
            // size as opposed to window size)
            //
            // Window content should respect Window's Max/Min size
 
            _trackMinWidthDeviceUnits = mmi.ptMinTrackSize.x;
            _trackMinHeightDeviceUnits = mmi.ptMinTrackSize.y;
            _trackMaxWidthDeviceUnits = mmi.ptMaxTrackSize.x;
            _trackMaxHeightDeviceUnits = mmi.ptMaxTrackSize.y;
            _windowMaxWidthDeviceUnits = mmi.ptMaxSize.x;
            _windowMaxHeightDeviceUnits = mmi.ptMaxSize.y;
 
 
            // if IsCompositionTargetInvalid is true, then it means that the CompositionTarget is not available.
            // This can happen at hwnd creation or destruction time.
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                //
                // Get the final MinMax size for this HWND based on Win32 track value and Min/Max setting
                // in this instance.
                //
                WindowMinMax finalMinMax = GetWindowMinMax( );
 
                // The finalMinMax struct keeps the desired Min/Max size for this hwnd in Logic Units.
                Point minSizeDeviceUnits = LogicalToDeviceUnits(new Point(finalMinMax.minWidth, finalMinMax.minHeight));
                Point maxSizeDeviceUnits = LogicalToDeviceUnits(new Point(finalMinMax.maxWidth, finalMinMax.maxHeight));
 
                // Put the new value in mmi
                mmi.ptMinTrackSize.x = DoubleUtil.DoubleToInt(minSizeDeviceUnits.X);
                mmi.ptMinTrackSize.y = DoubleUtil.DoubleToInt(minSizeDeviceUnits.Y);
 
                mmi.ptMaxTrackSize.x = DoubleUtil.DoubleToInt(maxSizeDeviceUnits.X);
                mmi.ptMaxTrackSize.y = DoubleUtil.DoubleToInt(maxSizeDeviceUnits.Y);
 
                // Notify Win32 of the new Min/Max value for this HWND.
 
                unsafe
                {
                    *(NativeMethods.MINMAXINFO*)lParam = mmi;
                }
            }
 
            return true;
        }
 
        private bool WmNcHitTest( IntPtr lParam, ref IntPtr refInt )
        {
            // For WS_CHILD window, WM_SIZE, WM_MOVE (and maybe others) are called
            // synchronously from CreateWindowEx call and we run into issues if
            // _sourceWindow in null.  We only care to listen to WM_CREATE &
            // WM_GETMINMAXINFO synchronously from CreateWindowEx thus we want
            // to explicitly add the null check below at all other places.
            //
            // Adding check for IsCompositionTargetInvalid
            // This can be true either at HwndSource creation time or when hwnd is going
            // away.
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            // WmNcHitTest is necessary to enable ResizeGrip and it only
            // relevant for Window.  Doing this processing in a virtual so
            // that RBW can override it
            return HandleWmNcHitTestMsg(lParam, ref refInt);
        }
 
        internal virtual bool HandleWmNcHitTestMsg(IntPtr lParam, ref IntPtr refInt)
        {
            // We need to make sure that the calculation to find out
            // whether the mouse is over the ResizeGrip control works
            // for localized version of Windows (Arabic, Hebrew) which
            // uses RTL.  Also, we need to make sure it works for
            // multi-mon case
 
            if ((_resizeGripControl == null) || (ResizeMode != ResizeMode.CanResizeWithGrip))
            {
                return false;
            }
 
            // mouse position wrt to the left/top of the screen
            int x = NativeMethods.SignedLOWORD(lParam);
            int y = NativeMethods.SignedHIWORD(lParam);
 
            // Find the client area 0,0 of the Window wrt the screen
            // This will be used to transform the mouse position from screen co-od
            // to window's client area co-od.  We need this to be able to figure out
            // whether the mouse is currently over the resize grip control or not
 
 
            NativeMethods.POINT pt = GetPointRelativeToWindow(x, y);
            Point ptLogicalUnits = DeviceToLogicalUnits(new Point(pt.x, pt.y));
 
            // Now, (ptLogicalUnits.X, ptLogicalUnits.Y) is the mouse postion wrt to the
            // Window's client region.
            // The next step is to find out whether the mouse is on top of the
            // ResizeGrip control
            // For this we first need to find out mouse location wrt to the ResizeGrip
            // control and then check whether the mouse location is on the control
            // Conditions when mouse is on top of the control:
            //     x,y should be not be less than zero
            //     x,y should not be greater than RenderSize.Width and RenderSize.Height
 
            GeneralTransform transfromFromWindow = this.TransformToDescendant(_resizeGripControl);
            Point mousePositionWRTResizeGripControl = ptLogicalUnits;
            if (transfromFromWindow == null || transfromFromWindow.TryTransform(ptLogicalUnits, out mousePositionWRTResizeGripControl) == false)
            {
                return false;
            }
 
            // check if the mouse is outside the ResizeGripControl region
            if ((mousePositionWRTResizeGripControl.X < 0) ||
                (mousePositionWRTResizeGripControl.Y < 0 ) ||
                (mousePositionWRTResizeGripControl.X > _resizeGripControl.RenderSize.Width) ||
                (mousePositionWRTResizeGripControl.Y > _resizeGripControl.RenderSize.Height))
            {
                // mouse not over ResizeGripControl; just let the DefWndProc handle this
                return false;
            }
 
            if (FlowDirection == FlowDirection.RightToLeft)
            {
                refInt = new IntPtr(NativeMethods.HTBOTTOMLEFT);
            }
            else
            {
                refInt = new IntPtr(NativeMethods.HTBOTTOMRIGHT);
            }
            // we've handled the WM_NCHITTEST msg thus return true
            return true;
        }
 
        private bool WmShowWindow(IntPtr wParam, IntPtr lParam)
        {
            // For WS_CHILD window, WM_SIZE, WM_MOVE (and maybe others) are called
            // synchronously from CreateWindowEx call and we run into issues if
            // _sourceWindow in null.  We only care to listen to WM_CREATE &
            // WM_GETMINMAXINFO synchronously from CreateWindowEx thus we want
            // to explicitly add the null check below at all other places.
            //
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }
 
            //lParam has five values: 0(programtically show/hide), 1(SW_PARENTCLOSING),
            //2(SW_OTHERMAXIMIZED), 3(SW_PARENTOPENING), 4(SW_OTHERRESTORED). We only care
            //about 1 and 3.
            switch (NativeMethods.IntPtrToInt32(lParam))
            {
                //The window's owner window is being minimized.
                //In Win32, when lParam is SW_PARENTCLOSING, wParam is false,
                //which means the window is being hidden.
                case NativeMethods.SW_PARENTCLOSING:
                    //This window will be hidden. Update _isVisible to reflect the
                    // new state.  Furthermore update visibility such that we
                    // do not call ShowHelper again and thus calling
                    // UpdateVisibilityProperty.
                    _isVisible = false;
                    UpdateVisibilityProperty(Visibility.Hidden);
                    break;
 
                //The window's owner window is being restored.
                //In Win32, when lParam is SW_PARENTOPENING, wParam is true,
                //which means the window is being shown.
                case NativeMethods.SW_PARENTOPENING:
                    //This window will be shown. Update _isVisible to reflect the
                    // new state.  Furthermore update visibility such that we
                    // do not call ShowHelper again and thus calling
                    // UpdateVisibilityProperty.
                    _isVisible = true;
                    UpdateVisibilityProperty(Visibility.Visible);
                    break;
 
                default:
                    break;
            }
 
            return false;
        }
 
        private static void _OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
 
            // We'll support most kinds of Images.  If it's not a BitmapFrame we'll rasterize it.
            w.OnIconChanged(e.NewValue as ImageSource);
        }
 
 
        private void OnIconChanged(ImageSource newIcon)
        {
            // No need to dispose previous _icon.
            // _icon is a ref to the ImageSource object
            // set by the developer.  Since the dev created
            // the ImageSource object it is his responsibility to
            // dispose it.
            _icon = newIcon;
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                UpdateIcon();
            }
        }
 
        private static void _OnTitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
 
            w.OnTitleChanged();
        }
 
        private static bool _ValidateText(object value)
        {
            return (value != null);
        }
 
        private void OnTitleChanged()
        {
            UpdateTitle(Title);
        }
 
        private static void _OnShowInTaskbarChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
 
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
            w.OnShowInTaskbarChanged();
        }
 
        private void OnShowInTaskbarChanged()
        {
            // this call ends up throwing an exception if accessing
            // ShowInTaskbar is not allowed
            VerifyApiSupported();
 
            // There are 2 cases
            // Case 1 : being set before source window is created
            // Case 2 : being set after the source window is created
            // Case 3 : bet set when CompositionTarget is invalid meaning we're in a bad state
 
            // Adding check for IsCompositionTargetInvalid
            if ( IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                bool fHideWindow = false;
                // Win32 bug. For ShowInTaskbar to change dynamically, we need to hide then show the window.
                // It is recommended to hide the window, chnage the style bits and then show it again.
                if (_isVisible)
                {
                    UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0,
                                       NativeMethods.SWP_NOMOVE |
                                       NativeMethods.SWP_NOSIZE |
                                       NativeMethods.SWP_NOZORDER |
                                       NativeMethods.SWP_NOACTIVATE |
                                       NativeMethods.SWP_NOSENDCHANGING |
                                       NativeMethods.SWP_HIDEWINDOW);
                    fHideWindow = true;
                }
                using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd  ))
                {
                    SetTaskbarStatus();
                }
                // Use fHideWindow instead of _isVisible in case if we listen to HideWindow messages and update _isVisible value,
                // it won't break this code.
                if (fHideWindow)
                {
                    UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0,
                                                    NativeMethods.SWP_NOMOVE |
                                                    NativeMethods.SWP_NOSIZE |
                                                    NativeMethods.SWP_NOZORDER |
                                                    NativeMethods.SWP_NOACTIVATE |
                                                    NativeMethods.SWP_NOSENDCHANGING |
                                                    NativeMethods.SWP_SHOWWINDOW);
                }
            }
        }
 
        private static bool _ValidateWindowStateCallback(object value)
        {
            return IsValidWindowState((WindowState)value);
        }
 
        private static void _OnWindowStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
 
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
            w.OnWindowStateChanged((WindowState) e.NewValue);
        }
 
        private void OnWindowStateChanged(WindowState windowState)
        {
 
            //      WCP:  Window.Visible.Set : Make sure that window updates the styles
            //      when set while window is hidden
            //
            // We can only change the window state if window is currently
            // visible.  Win32 does not provide a way to change the window
            // state without showing the window.  Thus, for the case where
            // window is hidden, we defer the acutal state change till the
            // window is shown again.
            //
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                if (_isVisible == true)
                {
                    HandleRef hr = new HandleRef(this,  Handle);
 
                    int style = _Style;
 
                    // Only call ShowWindow if window is in a different state
                    switch (windowState)
                    {
                        case WindowState.Normal:
                            if ((style & NativeMethods.WS_MAXIMIZE) == NativeMethods.WS_MAXIMIZE)
                            {
                                //
                                // The old behavior of this case is to restore the window using SW_RESTORE.
                                // With the ShowActivated property set to false we want this restore operation
                                // to take the current activation state into account when restoring the window.
                                //
                                if (ShowActivated || IsActive)
                                    UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_RESTORE);
                                else
                                    UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_SHOWNOACTIVATE);
                            }
                            else if ((style & NativeMethods.WS_MINIMIZE) == NativeMethods.WS_MINIMIZE)
                            {
                                //
                                // We query to WINDOWPLACEMENT to get an indication about the state before the
                                // minimize operation happened. If we were coming from a maximized state and now we
                                // switch to normal, we want activation to happen since the maximized state is always
                                // activated and transitioning from activated to non-activated would be weird.
                                //
                                NativeMethods.WINDOWPLACEMENT placement = new NativeMethods.WINDOWPLACEMENT();
                                placement.length = Marshal.SizeOf(placement);
                                UnsafeNativeMethods.GetWindowPlacement(hr, ref placement);
 
                                if ((placement.flags & NativeMethods.WPF_RESTORETOMAXIMIZED) == NativeMethods.WPF_RESTORETOMAXIMIZED)
                                    UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_RESTORE);
                                else
                                {
                                    if (ShowActivated)
                                        UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_RESTORE);
                                    else
                                        UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_SHOWNOACTIVATE);
                                }
                            }
                            break;
 
                        case WindowState.Maximized:
                            if ((style & NativeMethods.WS_MAXIMIZE) != NativeMethods.WS_MAXIMIZE)
                            {
                                //
                                // The OS doesn't provide support for non-activated maximized windows.
                                //
                                UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_MAXIMIZE);
                            }
                            break;
 
                        case WindowState.Minimized:
                            if ((style & NativeMethods.WS_MINIMIZE) != NativeMethods.WS_MINIMIZE)
                            {
                                //
                                // Historically, we used SW_MINIMIZE in here which activates the next top-level
                                // window in the Z order. Therefore, our ShowActivated property can't affect the
                                // minimized state since this would incur a breaking change requiring us to use
                                // SW_SHOWMINIMIZED instead in case ShowActivated is set to true (bw compat case).
                                //
                                UnsafeNativeMethods.ShowWindow(hr, NativeMethods.SW_MINIMIZE);
                            }
                            break;
                        // WCP: Window.WindowState should implement FullScreen and Theatre
                        // modes
                    }
                }
            }
            else
            {
                // WindowState can be changed as a result of the following two passes
                // 1. User interaction changes WindowState
                // 2. Developer programmatically changes WindowState
                // We update _previousWindowState at two places
                // 1. Before Hwnd is created, when developer programmatically changes WindowState, we update it here.
                // 2. After Hwnd is created, we update it when we get to WM_SIZE because both passes eventally meet there.
                _previousWindowState = windowState;
            }
 
            // The value of Top and Left is affected by WindowState and WindowStartupLocation.
            // we need to coerce Top and Left whenever these deciding factors change.
            // More info in CoerceTop.
            try
            {
                _updateHwndLocation = false;
                CoerceValue(TopProperty);
                CoerceValue(LeftProperty);
            }
            finally
            {
                _updateHwndLocation = true;
            }
        }
 
        private static bool _ValidateWindowStyleCallback(object value)
        {
            return IsValidWindowStyle((WindowStyle)value);
        }
 
        private static void _OnWindowStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
 
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
            w.OnWindowStyleChanged((WindowStyle) e.NewValue);
        }
 
        private void OnWindowStyleChanged(WindowStyle windowStyle)
        {
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd ))
                {
                    CreateWindowStyle();
                }
            }
        }
 
        private static void _OnTopmostChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
 
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
            w.OnTopmostChanged((bool) e.NewValue);
        }
 
        private void OnTopmostChanged(bool topmost)
        {
 
            // this call ends up throwing an exception if accessing
            // Topmost is not allowed
            VerifyApiSupported();
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false  && IsCompositionTargetInvalid == false)
            {
                HandleRef hWnd = topmost ? NativeMethods.HWND_TOPMOST : NativeMethods.HWND_NOTOPMOST;
                UnsafeNativeMethods.SetWindowPos(new HandleRef(null, Handle),
                       hWnd,
                       0, 0, 0, 0,
                       NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOACTIVATE);
            }
        }
 
        private static object CoerceVisibility(DependencyObject d, object value)
        {
            Window w = (Window)d;
 
            Visibility newValue = (Visibility)value;
            if (newValue == Visibility.Visible)
            {
                w.VerifyCanShow();
                w.VerifyConsistencyWithAllowsTransparency();
                w.VerifyNotClosing();
                w.VerifyConsistencyWithShowActivated();
            }
 
            return value;
        }
 
        /// <summary>
        /// Called when VisiblityProperty is invalidated
        /// The actual window is created when the Visibility property is set
        /// to Visibility.Visible for the first time or when Show is called.
        /// For Window, Visibility.Visible means the Window is visible.
        /// Visibility.Hidden and Visibility.Collapsed mean the Window is not visible.
        /// Visibility.Hidden and Visibility.Collapsed are treated the same.
        /// </summary>
        private static void _OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = (Window)d;
 
            // Indicate Visibility has been set
            // This works fine because Window is always the root.  So Visibility property
            // would not be invalidated usless it is set to a value.  But if that changes,
            // we will get invalidation when Window it added to the tree and this would be broken.
            w._isVisibilitySet = true;
 
            // _visibilitySetInternally is used to identify a call from Show/Hide in
            // _OnVisibilityInvalidated callback.  If a call originates in Show/Hide,
            // we DO NOT want to do anything in the _OnVisibilityCallback since, we
            // synchronously call ShowHelper from Show/Hide
            if (w._visibilitySetInternally == true)
            {
                return;
            }
 
            bool visibilityValue = VisibilityToBool((Visibility) e.NewValue);
 
            w.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                new DispatcherOperationCallback(w.ShowHelper),
                visibilityValue ? BooleanBoxes.TrueBox : BooleanBoxes.FalseBox);
        }
 
        private void SafeCreateWindowDuringShow()
        {
            //this is true the first time the window is created
            if (IsSourceWindowNull == true)
            {
                // _isVisible is false at this moment.  Thus CreateAllStyle
                // called by CreateSourceWindow does not set WS_VISIBLE style
 
                CreateSourceWindowDuringShow();
            }
                // If the hwnd has been created via WindowsInteropHelper.EnsureHandle,
                // we just need to hook up the RootVisual and update the size according to STC before Show.
            else if (HwndCreatedButNotShown)
            {
                SetRootVisualAndUpdateSTC();
                _hwndCreatedButNotShown = false;
            }
        }
 
        // We set/clear ShowKeyboardCue when Show(ShowDialog)/Hide is called.
        // We do not clear the state of ShowKeyboardCue when Window is closed.
        private void SetShowKeyboardCueState()
        {
            // set property on AccessKey control indicating the
            // invocation device
            if (KeyboardNavigation.IsKeyboardMostRecentInputDevice())
            {
                _previousKeyboardCuesProperty = (bool)GetValue(KeyboardNavigation.ShowKeyboardCuesProperty);
                SetValue(KeyboardNavigation.ShowKeyboardCuesProperty, BooleanBoxes.TrueBox);
                _resetKeyboardCuesProperty = true;
            }
        }
 
        // We set/clear ShowKeyboardCue when Show(ShowDialog)/Hide is called.
        // We do not clear the state of ShowKeyboardCue when Window is closed.
        private void ClearShowKeyboardCueState()
        {
            // if we set KeyboradNavigation.ShowKeyboardCuesProperty in ShowDialog,
            // set it to false here.
            if (_resetKeyboardCuesProperty == true)
            {
                _resetKeyboardCuesProperty = false;
                SetValue(KeyboardNavigation.ShowKeyboardCuesProperty, BooleanBoxes.Box(_previousKeyboardCuesProperty));
            }
        }
 
        private void UpdateVisibilityProperty(Visibility value)
        {
            // _visibilitySetInternally is used to identify a call (in _OnVisibilityInvalidated
            // callback) for updating the property value only and not changing the actual
            // visibility state of the hwnd.
            try
            {
                _visibilitySetInternally = true;
                SetValue(VisibilityProperty, value);
            }
            finally
            {
                _visibilitySetInternally = false;
            }
        }
 
        /// <summary>
        /// update _isVisible and call CreateSourceWindow if
        /// it's the first time window is set to Visibile
        /// </summary>
        private object ShowHelper(object booleanBox)
        {
            // Setting Visiblilty is async. When this is called from the async callback,
            // check whether the window is already closed.
            // E.g. window.Visibility = true;
            //      ...
            //      window.Close();
            // We should not do anything if the window is already closed.
            if (_disposed == true)
            {
                return null;
            }
 
            bool value = (bool) booleanBox;
            _isClosing = false;
 
            // (BVT Blocker: Invariant Assert when calling
            // Window.Show after setting Visibility=Hidden)
 
            // We should optimize for when visibilityValue == _isVisible only in ShowHelper
            // since this is called from a sync and async call.  We cannot optimize it there
            // since _isVisible may not reflect the exact state requested by the OM call.
            if (_isVisible == value)
            {
                return null;
            }
 
            // _isVisible should always be set after calling SafeCreateWindow, because
            // if exception occurs in Loading event (fired as a result of setting Visibility to visible) handler,
            // we set Visibility back to Collapsed. Otherwise we could get into a loop.
            if (value == true)
            {
                if (Application.IsShuttingDown)
                    return null;
 
                SetShowKeyboardCueState();
 
                SafeCreateWindowDuringShow();
                _isVisible = true;
            }
            else
            {
 
                ClearShowKeyboardCueState();
 
                if (_showingAsDialog == true)
                {
                    DoDialogHide();
                }
                _isVisible = false;
            }
 
            // we need this check here again, b/c creating the window fires the
            // Activted event and if user closes the window from it, then by
            // the time we get to this point _sourceWindow is already disposed.
            if ( IsSourceWindowNull == false )
            {
 
                // Specifying an Avalon app to start
                // maximized from a shortcut does not work.
 
                // ShowWindow MSDN documentation says that the first time ShowWindow
                // is called, nCmd passed in STARTUPINFO is used instead of the one
                // passed in via ShowWindow call. However, that is not the case.
                // ShowWindow implementation in user32 uses nCmd of STARTUPINFO only
                // if we pass SW_SHOW, SW_SHOWNORMAL, SW_SHOWDEFAULT to ShowWindow.
                // If anything else is passed, it does not use nCmd of STARTUPINFO.
 
                int nCmd = 0;
                if (value == true)
                {
                    // nCmdForShow access WindowState which is inaccessible for RBW.
                    // Thus doing so in a virtual that RBW overrides
                    nCmd = nCmdForShow();
                }
                else
                {
                    nCmd = NativeMethods.SW_HIDE;
                }
 
                // If this is a Topmost window, and the option is enabled to use SetWindowPos() when possible
                // for topmost windows, and this is SW_SHOW or SW_SHOWNA, then use SetWindowPos().  (Ideally
                // all SW_SHOW* options would use SetWindowPos, but (1) it is difficult to handle the maximize
                // and minimize options without ShowWindow, and (2) the z-order issue happens as soon as the
                // topmost window gets activated, which happens for SW_SHOWMAXIMIZED and SW_SHOWMINIMIZED.  So
                // to minimize complexity and risk those cases will continue to use ShowWindow.)
                //
                // Determine whether this is a Topmost window without calling
                // the Topmost property.  (This isn't allowed for xbap windows.)
                bool isTopmost = (bool)GetValue(TopmostProperty);
                if (isTopmost &&
                    FrameworkCompatibilityPreferences.GetUseSetWindowPosForTopmostWindows() &&
                    (nCmd == NativeMethods.SW_SHOW || nCmd == NativeMethods.SW_SHOWNA))
                {
                    int flags = (nCmd == NativeMethods.SW_SHOWNA) ? NativeMethods.SWP_NOACTIVATE : 0;
                    UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle),
                        NativeMethods.HWND_TOPMOST,
                        0, 0, 0, 0,
                        flags | NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOOWNERZORDER | NativeMethods.SWP_SHOWWINDOW);
                }
                else
                {
                    UnsafeNativeMethods.ShowWindow(new HandleRef(this, Handle), nCmd);
                }
 
                // We already did a ShowWindow upabove and then because of the using, we will flush which
                // will cause us to set the visibility. Ideally I would like to simply not have the ShowWindow
                // call above, *but* there is this SHOWNA stuff which is tied to Focus/Activation cleanup
                // scheduled for M8.
                //set the style
                SafeStyleSetter();
            }
 
 
            // dialog functionality; start dispatcher loop to block the call
            if ((_showingAsDialog == true) && (_isVisible == true))
            {
                //
                // Since we exited the Context, we need to make sure
                // we enter it before returning even if there is an
                // exception
                //
                Debug.Assert(_dispatcherFrame == null, "_dispatcherFrame must be null here");
 
                try
                {
                    // tell users we're going modal
                    ComponentDispatcher.PushModal();
 
                    _dispatcherFrame = new DispatcherFrame();
                    Dispatcher.PushFrame(_dispatcherFrame);
                }
                finally
                {
                    // tell users we're going non-modal
                    ComponentDispatcher.PopModal();
                }
            }
 
            return null;
        }
 
        internal virtual int nCmdForShow()
        {
            int nCmd = 0;
            switch(WindowState)
            {
                case WindowState.Maximized:
                    nCmd = NativeMethods.SW_SHOWMAXIMIZED; // The OS doesn't provide support for non-activated maximized windows.
                    break;
                case WindowState.Minimized:
                    nCmd = ShowActivated ? NativeMethods.SW_SHOWMINIMIZED : NativeMethods.SW_SHOWMINNOACTIVE;
                    break;
                 default:
                    nCmd = ShowActivated ? NativeMethods.SW_SHOW : NativeMethods.SW_SHOWNA;
                    break;
            }
            return nCmd;
        }
 
        private void SafeStyleSetter()
        {
            using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd))
            {
                _Style = _isVisible ? (_Style | NativeMethods.WS_VISIBLE) : _Style;
            }
        }
        private static bool _ValidateSizeToContentCallback(object value)
        {
            return IsValidSizeToContent((SizeToContent)value);
        }
 
        /// <summary>
        /// SizeToContent property GetValue override
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private static object _SizeToContentGetValueOverride(DependencyObject d)
        {
            Window w = d as Window;
 
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
            return w.SizeToContent;
        }
 
        /// <summary>
        /// SizeToContent property invalidation callback
        /// </summary>
        private static void _OnSizeToContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
 
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
            w.OnSizeToContentChanged((SizeToContent) e.NewValue);
        }
 
        private void OnSizeToContentChanged(SizeToContent sizeToContent)
        {
            // this call ends up throwing an exception if accessing
            // SizeToContent is not allowed
            VerifyApiSupported();
 
            // Update HwndSource's SizeToContent.
            // HwndSource will only update layout if the value has changed.
            //
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                HwndSourceSizeToContent = sizeToContent;
            }
        }
 
        /// <summary>
        /// Validate [Max/Min]Width/Height and Top/Left value.
        /// </summary>
        /// Length takes Double; Win32 handles Int.
        /// We throw exception when the value goes below Int32Min and Int32Max.
        /// WorkItem 26263: ValidateValueCallback needs to move to PropertyMetadata so Window can
        /// add its own validation and validate before invalid value is set. Right now, we can only
        /// validate this in PropertyInalidatinonCallback because of this. (We couldn't make it virtual on
        /// FrameworkELement because ValidateValueCallback doesn't provide context. Work item 25275).
        private static void ValidateLengthForHeightWidth(double l)
        {
            //basically, NaN and PositiveInfinity are ok, and then anything
            //that can be converted to Int32
            if (!Double.IsPositiveInfinity(l) && !double.IsNaN(l) &&
                ((l > Int32.MaxValue) || (l < Int32.MinValue)))
            {
                throw new ArgumentException(SR.Format(SR.ValueNotBetweenInt32MinMax, l));
            }
        }
 
        private static void ValidateTopLeft(double length)
        {
            // Values not allowed: PositiveInfinity, NegativeInfinity
            // and values that are beyond the range of Int32
            if (Double.IsPositiveInfinity(length) ||
                Double.IsNegativeInfinity(length))
            {
                throw new ArgumentException(SR.Format(SR.InvalidValueForTopLeft, length));
            }
 
            if ((length > Int32.MaxValue) ||
                (length < Int32.MinValue))
            {
                throw new ArgumentException(SR.Format(SR.ValueNotBetweenInt32MinMax, length));
            }
        }
 
        private static void _OnHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "d must be typeof Window");
            if (w._updateHwndSize)
            {
                w.OnHeightChanged((double) e.NewValue);
            }
        }
 
        private void OnHeightChanged(double height)
        {
            //  Move ValidateLengthForHeightWidth calls from property
            // invalidation callback to PropertyMetadata
            ValidateLengthForHeightWidth(height);
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false && !double.IsNaN(height))
            {
                UpdateHeight(height);
            }
        }
 
        private static void _OnMinHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "d must be typeof Window");
            w.OnMinHeightChanged((double) e.NewValue);
        }
 
        private void OnMinHeightChanged(double minHeight)
        {
            // this call ends up throwing an exception if accessing
            // MinHeight is not allowed
            VerifyApiSupported();
 
            ValidateLengthForHeightWidth(minHeight);
            // Only trigger immediate size update when hwnd has been created and MinHeight is not Auto and MinHeight is
            // greater then current HWND height.
            // If hwnd hasn't been created, size will be controlled when it is created.
            // If MinHeight is Auto or ActualHeight is greater than MinHeight, there is no need update size of the window.
            //
            // Adding check for IsCompositionTargetInvalid
            if ((IsSourceWindowNull == false ) && (IsCompositionTargetInvalid == false))
            {
                NativeMethods.RECT rcHwnd = WindowBounds;
                Point logicalSize = DeviceToLogicalUnits(new Point(rcHwnd.Width, rcHwnd.Height));
                if (minHeight > logicalSize.Y)
                {
                    if (WindowState == WindowState.Normal)
                    {
                        UpdateHwndSizeOnWidthHeightChange(logicalSize.X, minHeight);
                    }
                    else
                    {
                        // no need to do anything.  When window is restored, we get WM_GETMINMAXINFO where
                        // we restrict the max/min size of the window to [Max/Min][Height/Width]
                    }
                }
            }
        }
 
        private static void _OnMaxHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "d must be typeof Window");
            w.OnMaxHeightChanged((double) e.NewValue);
        }
 
        private void OnMaxHeightChanged(double maxHeight)
        {
            // this call ends up throwing an exception if accessing
            // MaxHeight is not allowed
            VerifyApiSupported();
 
            ValidateLengthForHeightWidth(MaxHeight);
 
            // Only trigger immediate size update when hwnd has been created and MaxHeight is not Auto and
            // the HWND's height > MaxHeight
            //
            // Adding check for IsCompositionTargetInvalid
            if ((IsSourceWindowNull == false) && (IsCompositionTargetInvalid == false))
            {
                NativeMethods.RECT rcHwnd = WindowBounds;
                Point logicalSize = DeviceToLogicalUnits(new Point(rcHwnd.Width, rcHwnd.Height));
                if (maxHeight < logicalSize.Y)
                {
                    if (WindowState == WindowState.Normal)
                    {
                        UpdateHwndSizeOnWidthHeightChange(logicalSize.X, maxHeight);
                    }
                    else
                    {
                        // no need to do anything.  When window is restored, we get WM_GETMINMAXINFO where
                        // we restrict the max/min size of the window to [Max/Min][Height/Width]
                    }
                }
            }
        }
 
        private static void _OnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "d must be typeof Window");
            if (w._updateHwndSize)
            {
                w.OnWidthChanged((double) e.NewValue);
            }
        }
 
        private void OnWidthChanged(double width)
        {
            ValidateLengthForHeightWidth(width);
 
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false && !double.IsNaN(width))
            {
                UpdateWidth(width);
            }
        }
 
        private static void _OnMinWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "d must be typeof Window");
            w.OnMinWidthChanged((double) e.NewValue);
        }
 
        private void OnMinWidthChanged(double minWidth)
        {
            // this call ends up throwing an exception if accessing
            // MinWidth is not allowed
            VerifyApiSupported();
 
            // Move ValidateLengthForHeightWidth calls from property
            // invalidation callback to PropertyMetadata
            ValidateLengthForHeightWidth(minWidth);
            // Only trigger immediate size update when hwnd has been created and MinWidth is not Auto and MinWidth is
            // greater then current ActualWidth.
            // If hwnd hasn't been created, size will be controlled when it is created.
            // If MinWidth is Auto or ActualWidth is greater than MinWidth, there is no need update size of the window.
            //
            // Adding check for IsCompositionTargetInvalid
            if ((IsSourceWindowNull == false) && (IsCompositionTargetInvalid == false))
            {
                NativeMethods.RECT rcHwnd = WindowBounds;
                Point logicalSize = DeviceToLogicalUnits(new Point(rcHwnd.Width, rcHwnd.Height));
                if (minWidth > logicalSize.X)
                {
                    if (WindowState == WindowState.Normal)
                    {
                        UpdateHwndSizeOnWidthHeightChange(minWidth, logicalSize.Y);
                    }
                    else
                    {
                        // no need to do anything.  When window is restored, we get WM_GETMINMAXINFO where
                        // we restrict the max/min size of the window to [Max/Min][Height/Width]
                    }
                }
            }
        }
 
        private static void _OnMaxWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "d must be typeof Window");
            w.OnMaxWidthChanged((double) e.NewValue);
        }
 
        private void OnMaxWidthChanged(double maxWidth)
        {
            // this call ends up throwing an exception if accessing
            // MaxWidth is not allowed
            VerifyApiSupported();
 
            ValidateLengthForHeightWidth(maxWidth);
            // Only trigger immediate size update when hwnd has been created and MaxWidth is not Auto and
            // ActualWidth > MaxWidth
            //
            // Adding check for IsCompositionTargetInvalid
            if ((IsSourceWindowNull == false ) && (IsCompositionTargetInvalid == false))
            {
                NativeMethods.RECT rcHwnd = WindowBounds;
                Point logicalSize = DeviceToLogicalUnits(new Point(rcHwnd.Width, rcHwnd.Height));
                if (maxWidth < logicalSize.X)
                {
                    if (WindowState == WindowState.Normal)
                    {
                        UpdateHwndSizeOnWidthHeightChange(maxWidth, logicalSize.Y);
                    }
                    else
                    {
                        // no need to do anything.  When window is restored, we get WM_GETMINMAXINFO where
                        // we restrict the max/min size of the window to [Max/Min][Height/Width]
                    }
                }
            }
        }
 
        // Updates the restore bounds of the hwnd based on BoundsSpecified enum values
        // OR-ing of BoundsSpecified enum is not supported.
        private void UpdateHwndRestoreBounds(double newValue, BoundsSpecified specifiedRestoreBounds)
        {
 
            NativeMethods.WINDOWPLACEMENT wp = new NativeMethods.WINDOWPLACEMENT();
            wp.length = Marshal.SizeOf(typeof(NativeMethods.WINDOWPLACEMENT));
            UnsafeNativeMethods.GetWindowPlacement(new HandleRef(this, Handle), ref wp);
 
            double convertedValue = (LogicalToDeviceUnits(new Point(newValue, 0))).X;
            switch (specifiedRestoreBounds)
            {
                case BoundsSpecified.Height:
                    wp.rcNormalPosition_bottom = wp.rcNormalPosition_top + DoubleUtil.DoubleToInt(convertedValue);
                    break;
                case BoundsSpecified.Width:
                    wp.rcNormalPosition_right = wp.rcNormalPosition_left + DoubleUtil.DoubleToInt(convertedValue);
                    break;
                case BoundsSpecified.Top:
                    // convert input value into work-area co-ods
                    double newTop = newValue;
                    // [Get/Set]WindowPlacement work with workarea co-ods for a top level
                    // window whose WS_EX_TOOLWINDOW bit is clear.  If this bit is set,
                    // then the co-ods are expected to be in screen co-ods of the monitor.
                    // TransfromWorkAreaScreenArea can transform a point from work area co-ods
                    // to screen area co-ods and vice versa depending on TransformType value passed.
                    // So, in our case, if the window is not a ToolWindow we want to transform
                    // the input value from screen co-ods to work area co-ods.
                    if ((StyleExFromHwnd & NativeMethods.WS_EX_TOOLWINDOW) == 0)
                    {
                        newTop = TransformWorkAreaScreenArea(new Point(0, newTop), TransformType.ScreenAreaToWorkArea).Y;
                    }
                    newTop = (LogicalToDeviceUnits(new Point(0, newTop))).Y;
                    int currentHeight = wp.rcNormalPosition_bottom - wp.rcNormalPosition_top;
                    wp.rcNormalPosition_top = DoubleUtil.DoubleToInt(newTop);
                    wp.rcNormalPosition_bottom = wp.rcNormalPosition_top + currentHeight;
                    break;
                case BoundsSpecified.Left:
                    // convert input value into work-area co-ods
                    double newLeft = newValue;
                    // [Get/Set]WindowPlacement work with workarea co-ods for a top level
                    // window whose WS_EX_TOOLWINDOW bit is clear.  If this bit is set,
                    // then the co-ods are expected to be in screen co-ods of the monitor.
                    // TransfromWorkAreaScreenArea can transform a point from work area co-ods
                    // to screen area co-ods and vice versa depending on TransformType value passed.
 
                    // So, in our case, if the window is not a ToolWindow we want to transform
                    // the input value from screen co-ods to work area co-ods.
                    if ((StyleExFromHwnd & NativeMethods.WS_EX_TOOLWINDOW) == 0)
                    {
                        newLeft = TransformWorkAreaScreenArea(new Point(newLeft, 0), TransformType.ScreenAreaToWorkArea).X;
                    }
                    newLeft = (LogicalToDeviceUnits(new Point(newLeft, 0))).X;
                    int currentWidth = wp.rcNormalPosition_right - wp.rcNormalPosition_left;
                    wp.rcNormalPosition_left = DoubleUtil.DoubleToInt(newLeft);
                    wp.rcNormalPosition_right = wp.rcNormalPosition_left + currentWidth;
                    break;
                default:
                    Debug.Assert(false, $"specifiedRestoreBounds can't be {specifiedRestoreBounds}");
                    break;
            }
 
            // The showCmd flag retreived by GetWindowPlacement is SW_SHOWMAXIMIZED when the window is maximized.
            // If the window is minimized, showCmd is SW_SHOWMINIMIZED. Otherwise, it is SW_SHOWNORMAL, regardless
            // of the window's visibility.
            // SetWindowPlacement with SW_SHOWMAXIMIZED and SW_SHOWMINIMIZED will cause a hidden window to show.
            // To workaround this issue, we check whether the current window is hidden and set showCmd to SW_HIDE if it is.
            if (!this._isVisible)
            {
                wp.showCmd = NativeMethods.SW_HIDE;
            }
 
 
            UnsafeNativeMethods.SetWindowPlacement(new HandleRef(this, Handle), ref wp);
        }
 
        // deltaX = workAreaOriginValue - screenOriginValue (both in virtual co-ods)
        // X(screenAreaCood) = x(workAreaCood) + deltaX
        private Point TransformWorkAreaScreenArea(Point pt, TransformType transformType)
        {
            int deltaX = 0;
            int deltaY = 0;
            Point retPt;
 
            // First we get the monitor on which the window is on.  [Get/Set]WindowPlacement
            // co-ods are dependent on the monitor on which the window is on.
            IntPtr hMonitor = SafeNativeMethods.MonitorFromWindow(new HandleRef(this, Handle), NativeMethods.MONITOR_DEFAULTTONULL);
 
            if (hMonitor != IntPtr.Zero)
            {
                NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX();
                monitorInfo.cbSize = Marshal.SizeOf(typeof(NativeMethods.MONITORINFOEX));
 
                SafeNativeMethods.GetMonitorInfo(new HandleRef(this, hMonitor), monitorInfo);
                NativeMethods.RECT workAreaRect = monitorInfo.rcWork;
                NativeMethods.RECT screenAreaRect = monitorInfo.rcMonitor;
                deltaX = workAreaRect.left - screenAreaRect.left;
                deltaY = workAreaRect.top - screenAreaRect.top;
            }
 
            if (transformType == TransformType.WorkAreaToScreenArea)
            {
                retPt = new Point(pt.X + deltaX, pt.Y + deltaY);
            }
            else
            {
                retPt = new Point(pt.X - deltaX, pt.Y - deltaY);
            }
            return retPt;
        }
 
        // The logic for coerce Top & Left
        // 1.   Before Window is first shown (w.IsSourceWindowNull == false)
        //      The value can come from 3 parties
        //          a. default
        //          b. SetValue
        //          c. Style, trigger...
        //      In all those 3 cases, we would like to pass the value because we don't have a
        //      different value from hwnd before it is shown.
        //
        // To understarnd the below 2 cases better, you will need to know the Window position API precedence as following:
        //      WindowState > WindowStartupLocation (only works the first time shown) > Top/Left
        //
        // 2.   During show
        //      There are 3 places that can coerce value during show. Right now they are all in
        //      SetupInitialState.
        //          a. After CreateWindowEx.
        //                  i. We should always update with the win32 default position when it is Nan.
        //                  ii. If WindowState is maxmized, we should always return from the hwnd (_actualTop/Left),
        //                  but update the hwnd restorebounds. So setting Top/Left WindowState to to Maxmized before show would
        //                  work for restorebounds (details in bug 1217802).
        //          b. If Top/Left is set and/or WindowStartupLocation is effective.
        //                  WindowState must be normal here because it takes precedence over WindowStartupLocation and Top/Left.
        //                  Since WindowStartupLocation only works the first time shown, we have a flag (_updateStartupLocation)
        //                  to help indicating that.
        //                  If StartupLocation is effective, we should return from the hwnd (_actualTop/Left).
        //          c. If SizeToContent is set and WindowStartupLocation is effective.
        //                  Same as b.
        //
        // 3.   After show
        //      a. User moves the Window.
        //          If user resize, we set local value (SetValue).
        //      b. User maximizes or minimizes. Or WindowState is changed programmtically
        //          We coerce Top and Left's value when WindowState is changed no matter whether it is
        //          from user action or programmtically.
        //      c. SetValue
        //
        //      For b and c, when WindowState is max or min, the hwnd value should always be returned.
        //      The new value should be set as restorebounds. Otherwise update with the new value.
        //
        // Note: as we can see from above logic, _actualTop/Left should always be updated with the current hwnd position before we
        // coerce Top and Left after hwnd is created.
        private static object CoerceTop(DependencyObject d, object value)
        {
            Window w = d as Window;
 
            // this call ends up throwing an exception if accessing Top
            // is not allowed
            w.VerifyApiSupported();
 
            double top = (double)value;
 
            // Move ValidateTopLeft calls from property
            // invalidation callback to PropertyMetadata
            ValidateTopLeft(top);
 
            if (w.IsSourceWindowNull || w.IsCompositionTargetInvalid)
            {
                return value;
            }
 
            if (double.IsNaN(top))
            {
                return w._actualTop;
            }
 
            if (w.WindowState != WindowState.Normal)
            {
                return value;
            }
 
            if (w._updateStartupLocation && (w.WindowStartupLocation != WindowStartupLocation.Manual))
            {
                return w._actualTop;
            }
 
            return value;
        }
 
        private static void _OnTopChanged (DependencyObject d , DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert( w != null, "DependencyObject must be of type Window." );
 
            if (w._updateHwndLocation)
            {
                w.OnTopChanged((double) e.NewValue);
            }
        }
 
        private void OnTopChanged(double newTop)
        {
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                // NaN is special and indicates using Win32 default,
                // so we exclude that.
                if (double.IsNaN(newTop) == false)
                {
                    if (WindowState == WindowState.Normal)
                    {
                        Invariant.Assert(!Double.IsNaN(_actualLeft), "_actualLeft cannot be NaN after show");
                        UpdateHwndPositionOnTopLeftChange(Double.IsNaN(Left) ? _actualLeft : Left, newTop);
                    }
                    else
                    {
                        UpdateHwndRestoreBounds(newTop, BoundsSpecified.Top);
                    }
                }
            }
            else
            {
                // here the value is stored as measure units as newTop is in measure/logical units
                _actualTop = newTop;
            }
        }
 
        // Please see comments for CoerceTop.
        private static object CoerceLeft(DependencyObject d, object value)
        {
            Window w = d as Window;
 
            // this call ends up throwing an exception if setting property is not allowed
            w.VerifyApiSupported();
 
            double left = (double)value;
 
            // Move ValidateTopLeft calls from property
            // invalidation callback to PropertyMetadata
            ValidateTopLeft(left);
 
            if (w.IsSourceWindowNull || w.IsCompositionTargetInvalid)
            {
                return value;
            }
 
            if (double.IsNaN(left))
            {
                return w._actualLeft;
            }
 
            if (w.WindowState != WindowState.Normal)
            {
                return value;
            }
 
            if (w._updateStartupLocation && (w.WindowStartupLocation != WindowStartupLocation.Manual))
            {
                return w._actualLeft;
            }
 
            return value;
        }
 
        private static void _OnLeftChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert( w != null, "DependencyObject must be of type Window." );
 
            if (w._updateHwndLocation)
            {
                w.OnLeftChanged((double) e.NewValue);
            }
        }
 
        // _actualLeft is used to determine if LocationChanged should be fired in WMMoveChagnged.
        // We need it b/c we need to remember the last hwnd Left location to decide whether
        // we need to fire the event or not.  Why do we need to update here?  Well, for the following
        // scenario:
        //    Window w = new Window();
        //    w.Left = 100;
        //    w.WindowStyle = WindowStyle.None;
        //    w.Show();
        //
        //  In this case, we want to not fire LocationChanged from SetWindowPos called called
        //  from CorrectStyleForBorderlessWindowCase().
        //
        //  _actualLeft is update from the following places:
        //
        //
        // 1) In WM_MOVE handler
        //
        // 2) In OnLeftChanged for the case when the hwnd is not created yet.
        //
        // 3) SetupInitialState
        private void OnLeftChanged(double newLeft)
        {
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                // NaN is special and indicates using Win32 default,
                // so we exclude that here.
                if (double.IsNaN(newLeft) == false)
                {
                    if (WindowState == WindowState.Normal)
                    {
                        Invariant.Assert(!Double.IsNaN(_actualTop), "_actualTop cannot be NaN after show");
                        UpdateHwndPositionOnTopLeftChange(newLeft, Double.IsNaN(Top) ? _actualTop : Top);
                    }
                    else
                    {
                        UpdateHwndRestoreBounds(newLeft, BoundsSpecified.Left);
                    }
                }
            }
            else
            {
                // here the value is stored as measure units as newLeft is in measure/logical units
                _actualLeft = newLeft;
            }
        }
 
        private void UpdateHwndPositionOnTopLeftChange(double leftLogicalUnits, double topLogicalUnits)
        {
            Debug.Assert( IsSourceWindowNull == false , "IsSourceWindowNull cannot be true when calling this function");
 
            Point ptDeviceUnits = LogicalToDeviceUnits(new Point(leftLogicalUnits, topLogicalUnits));
 
            UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle),
                        new HandleRef(null, IntPtr.Zero),
                        DoubleUtil.DoubleToInt(ptDeviceUnits.X),
                        DoubleUtil.DoubleToInt(ptDeviceUnits.Y),
                        0,
                        0,
                        NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE
                        );
        }
 
        private static bool _ValidateResizeModeCallback(object value)
        {
            return IsValidResizeMode((ResizeMode)value);
        }
 
        private static void _OnResizeModeChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert( w != null, "DependencyObject must be of type Window." );
 
            w.OnResizeModeChanged();
        }
 
        private void OnResizeModeChanged()
        {
            // this call ends up throwing an exception if accessing
            // ResizeMode is not allowed
            VerifyApiSupported();
 
            // Adding check for IsCompositionTargetInvalid
            if ( IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd  ))
                {
                    CreateResizibility();
                }
            }
        }
 
        private static object VerifyAccessCoercion(DependencyObject d, object value)
        {
            // this call ends up throwing an exception if setting property is not allowed
            ((Window)d).VerifyApiSupported();
 
            return value;
        }
 
        private static void _OnFlowDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Window w = d as Window;
            Debug.Assert(w != null, "DependencyObject must be of type Window.");
 
            w.OnFlowDirectionChanged();
        }
 
        /// <summary>
        ///     Right to Left
        /// </summary>
        private void OnFlowDirectionChanged()
        {
            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull == false && IsCompositionTargetInvalid == false)
            {
                using (HwndStyleManager sm = HwndStyleManager.StartManaging(this, StyleFromHwnd, StyleExFromHwnd ))
                {
                    CreateRtl();
                }
            }
        }
 
        private static object CoerceRenderTransform(DependencyObject d, object value)
        {
            Transform renderTransformValue = (Transform)value;
 
            if ((value == null) ||
                (renderTransformValue != null && renderTransformValue.Value.IsIdentity == true))
            {
                // setting this value is allowed.
            }
            else
            {
                throw new InvalidOperationException(SR.TransformNotSupported);
            }
 
            return value;
        }
 
        private static void _OnRenderTransformChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }
 
        private static object CoerceClipToBounds(DependencyObject d, object value)
        {
            if ((bool)value != false)
            {
                throw new InvalidOperationException(SR.ClipToBoundsNotSupported);
            }
            return value;
        }
 
        private static void _OnClipToBoundsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }
 
 
        /// <summary>
        ///     Get or create the hidden window used for parenting when ShowInTaskbar == false.
        /// </summary>
        private HwndWrapper EnsureHiddenWindow()
        {
            if (_hiddenWindow == null)
            {
                _hiddenWindow = new HwndWrapper(
                    0, // classStyle
                    NativeMethods.WS_OVERLAPPEDWINDOW, // style
                    0, // exStyle
                    NativeMethods.CW_USEDEFAULT, // x
                    NativeMethods.CW_USEDEFAULT, // y
                    NativeMethods.CW_USEDEFAULT, // width
                    NativeMethods.CW_USEDEFAULT, // height
                    "Hidden Window", // name
                    IntPtr.Zero,
                    null
                );
            }
 
            return _hiddenWindow;
        }
 
        /// <summary>
        ///     sets taskbar status
        /// </summary>
        private void SetTaskbarStatus()
        {
            if (ShowInTaskbar == false) // don't show in taskbar
            {
                // To remove the taskbar button for this window it needs to have a non-null parent
                // (we'll create a hidden window for this purpose) and not have WS_EX_APPWINDOW
 
                // Create this now, even if we're not currently going to parent it.
                // If the Owner changes, we'll need to switch to this.
                EnsureHiddenWindow();
 
                // when this window is unowned
                if (_ownerHandle == IntPtr.Zero)
                {
                    SetOwnerHandle(_hiddenWindow.Handle);
 
                    // When we do this parenting trick on XP the alt-tab icon for the window takes on
                    // the parent's icon.  To keep things working right we need to apply Icon to the
                    // hidden window.  On Vista this is redundant.
                    if (!(IsSourceWindowNull || IsCompositionTargetInvalid))
                    {
                        UpdateIcon();
                    }
                }
 
                _StyleEx &= ~NativeMethods.WS_EX_APPWINDOW;
            }
            else // (ShowInTaskbar == true) show in task bar
            {
                _StyleEx |= NativeMethods.WS_EX_APPWINDOW;
                if( ! IsSourceWindowNull )
                {
                    if ((_hiddenWindow != null) && (_ownerHandle == _hiddenWindow.Handle))
                    {
                        SetOwnerHandle(IntPtr.Zero);
                    }
                }
            }
        }
 
        private void OnTaskbarRetryTimerTick(object sender, EventArgs e)
        {
            UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), WM_APPLYTASKBARITEMINFO, IntPtr.Zero, IntPtr.Zero);
        }
 
        private void ApplyTaskbarItemInfo()
        {
            if (!Utilities.IsOSWindows7OrNewer)
            {
                if (TraceShell.IsEnabled)
                {
                    TraceShell.Trace(TraceEventType.Warning, TraceShell.NotOnWindows7);
                }
                return;
            }
 
            // If the Window hasn't yet been shown then these calls will fail.
            // We'll try this again when the WM_TASKBARBUTTONCREATED message gets sent.
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return;
            }
 
            // If the taskbar has timed out in the last minute, don't try to do this again.
            if (_taskbarRetryTimer != null && _taskbarRetryTimer.IsEnabled)
            {
                return;
            }
 
            HRESULT hr = HRESULT.S_OK;
            if (_taskbarList == null)
            {
                // If we don't have a handle and there isn't a TaskbarItemInfo, then we don't have anything to apply or remove.
                if (TaskbarItemInfo == null)
                {
                    return;
                }
 
                ITaskbarList taskbarList = null;
                try
                {
                    taskbarList = (ITaskbarList)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(CLSID.TaskbarList)));
 
                    hr = taskbarList.HrInit();
                    if (hr != HRESULT.S_OK)
                    {
                        // Taskbar not available (no user logged in, running under terminal service, custom shell, etc.)
                        HandleTaskbarListError(hr);
                        return;
                    }
 
                    // This QI will only work on Win7.
                    _taskbarList = (ITaskbarList3)taskbarList;
                    taskbarList = null;
                }
                finally
                {
                    Utilities.SafeRelease(ref taskbarList);
                }
 
                // Don't use SystemParameters here.  We need pixels.
                _overlaySize = new Size(
                    UnsafeNativeMethods.GetSystemMetrics(SM.CXSMICON),
                    UnsafeNativeMethods.GetSystemMetrics(SM.CYSMICON));
                // IsEmpty is inclusive, in case either of these succeeded it would pass...
                Debug.Assert(0 != (int)_overlaySize.Width);
                Debug.Assert(0 != (int)_overlaySize.Height);
 
                // When we detect that Explorer is nonresponsive, use this to defer further attempts
                // at updating the TaskbarList until a specified amount of time (1 minute)
                if (_taskbarRetryTimer == null)
                {
                    _taskbarRetryTimer = new DispatcherTimer { Interval = new TimeSpan(0, 1, 0) };
                    // Explorer being non-responsive should be a transient issue.  Post back to apply the full TaskbarItemInfo.
                    _taskbarRetryTimer.Tick += OnTaskbarRetryTimerTick;
                }
            }
 
            // Apply (or clear) all aspects of the TaskbarItemInfo to this Window.
            hr = RegisterTaskbarThumbButtons();
 
            if (hr.Succeeded)
            {
                // Updating the state will also update the value, so don't call UpdateTaskbarProgressValue.
                hr = UpdateTaskbarProgressState();
            }
            if (hr.Succeeded)
            {
                hr = UpdateTaskbarOverlay();
            }
            if (hr.Succeeded)
            {
                hr = UpdateTaskbarDescription();
            }
            if (hr.Succeeded)
            {
                hr = UpdateTaskbarThumbnailClipping();
            }
            if (hr.Succeeded)
            {
                hr = UpdateTaskbarThumbButtons();
            }
 
            // We'll asynchronously retry if we failed initially setting up the TaskbarItemInfo.
            HandleTaskbarListError(hr);
        }
 
        private HRESULT UpdateTaskbarProgressState()
        {
            Debug.Assert(null != _taskbarList);
 
            TaskbarItemInfo taskbarInfo = TaskbarItemInfo;
            TBPF tbpf = TBPF.NOPROGRESS;
 
            if (taskbarInfo != null)
            {
                switch (taskbarInfo.ProgressState)
                {
                    case TaskbarItemProgressState.Error:
                        tbpf = TBPF.ERROR;
                        break;
                    case TaskbarItemProgressState.Indeterminate:
                        tbpf = TBPF.INDETERMINATE;
                        break;
                    case TaskbarItemProgressState.None:
                        tbpf = TBPF.NOPROGRESS;
                        break;
                    case TaskbarItemProgressState.Normal:
                        tbpf = TBPF.NORMAL;
                        break;
                    case TaskbarItemProgressState.Paused:
                        tbpf = TBPF.PAUSED;
                        break;
                    default:
                        // The coercion should have caught this.
                        Debug.Assert(false);
                        tbpf = TBPF.NOPROGRESS;
                        break;
                }
            }
 
            HRESULT hr = _taskbarList.SetProgressState(Handle, tbpf);
            if (hr.Succeeded)
            {
                // Explicitly update this in case this property being set
                // to None or Indeterminate before made the value not update.
                hr = UpdateTaskbarProgressValue();
            }
 
            return hr;
        }
 
        private HRESULT UpdateTaskbarProgressValue()
        {
            Debug.Assert(null != _taskbarList);
 
            TaskbarItemInfo taskbarInfo = TaskbarItemInfo;
 
            // If we're not attached then don't modify this.
            if (taskbarInfo == null
                || taskbarInfo.ProgressState == TaskbarItemProgressState.None
                || taskbarInfo.ProgressState == TaskbarItemProgressState.Indeterminate)
            {
                return HRESULT.S_OK;
            }
 
            const ulong precisionValue = 1000;
            // The coercion should enforce this.
            Debug.Assert(0 <= taskbarInfo.ProgressValue && taskbarInfo.ProgressValue <= 1);
 
            var intValue = (ulong)(taskbarInfo.ProgressValue * precisionValue);
            return _taskbarList.SetProgressValue(Handle, intValue, precisionValue);
        }
 
        private HRESULT UpdateTaskbarOverlay()
        {
            Debug.Assert(null != _taskbarList);
 
            TaskbarItemInfo taskbarInfo = TaskbarItemInfo;
            NativeMethods.IconHandle hicon = NativeMethods.IconHandle.GetInvalidIcon();
 
            // The additional string at the end of SetOverlayIcon sets the accDescription
            // for screen readers.  We don't currently have a property that utilizes this.
 
            try
            {
                if (null != taskbarInfo && null != taskbarInfo.Overlay)
                {
                    hicon = IconHelper.CreateIconHandleFromImageSource(taskbarInfo.Overlay, _overlaySize);
                }
 
                return _taskbarList.SetOverlayIcon(Handle, hicon, null);
            }
            finally
            {
                hicon.Dispose();
            }
        }
 
        private HRESULT UpdateTaskbarDescription()
        {
            Debug.Assert(null != _taskbarList);
 
            TaskbarItemInfo taskbarInfo = TaskbarItemInfo;
            string tooltip = "";
 
            if (taskbarInfo != null)
            {
                tooltip = taskbarInfo.Description ?? "";
            }
 
            return _taskbarList.SetThumbnailTooltip(Handle, tooltip);
        }
 
 
        private HRESULT UpdateTaskbarThumbnailClipping()
        {
            // If TaskbarItemInfo isn't attached and active then there's nothing to do here.
            if (_taskbarList == null)
            {
                return HRESULT.S_OK;
            }
 
            if (_taskbarRetryTimer != null && _taskbarRetryTimer.IsEnabled)
            {
                // Explorer appears to be non-responsive.  Don't try this.
                return HRESULT.S_FALSE;
            }
 
            // Don't count on Window properties being in sync at the time of this call.
            // Just use native methods to check
            if (UnsafeNativeMethods.IsIconic(Handle))
            {
                // If the window is minimized then don't try to update the clip.
                return HRESULT.S_FALSE;
            }
 
            TaskbarItemInfo taskbarInfo = TaskbarItemInfo;
            NativeMethods.RefRECT interopRc = null;
 
            // If the taskbarInfo isn't available then remove any clipping.
            if (taskbarInfo != null && !taskbarInfo.ThumbnailClipMargin.IsZero)
            {
                Thickness margin = taskbarInfo.ThumbnailClipMargin;
                // Use the native GetClientRect.  Window.ActualWidth and .ActualHeight include the non-client areas.
                NativeMethods.RECT physicalClientRc = default(NativeMethods.RECT);
                SafeNativeMethods.GetClientRect(new HandleRef(this, Handle), ref physicalClientRc);
                var logicalClientRc = new Rect(
                    DeviceToLogicalUnits(new Point(physicalClientRc.left, physicalClientRc.top)),
                    DeviceToLogicalUnits(new Point(physicalClientRc.right, physicalClientRc.bottom)));
 
                // Crop the clipping to ensure that the margin doesn't overlap itself.
                if (margin.Left + margin.Right >= logicalClientRc.Width
                    || margin.Top + margin.Bottom >= logicalClientRc.Height)
                {
                    // Empty client rectangle is different than no clipping applied.
                    interopRc = new NativeMethods.RefRECT(0, 0, 0, 0);
                }
                else
                {
                    var physicalClip = new Rect(
                        LogicalToDeviceUnits(new Point(margin.Left, margin.Top)),
                        LogicalToDeviceUnits(new Point(logicalClientRc.Width - margin.Right, logicalClientRc.Height - margin.Bottom)));
                    interopRc = new NativeMethods.RefRECT((int)physicalClip.Left, (int)physicalClip.Top, (int)physicalClip.Right, (int)physicalClip.Bottom);
                }
            }
 
            return _taskbarList.SetThumbnailClip(Handle, interopRc);
        }
 
        private HRESULT RegisterTaskbarThumbButtons()
        {
            Debug.Assert(null != _taskbarList);
 
            // The ITaskbarList3 API requires that the maximum number of buttons to ever be used
            // are registered at the beginning.  Modifications can be made to this list later.
            var nativeButtons = new THUMBBUTTON[c_MaximumThumbButtons];
 
            for (int i = 0; i < c_MaximumThumbButtons; ++i)
            {
                nativeButtons[i] = new THUMBBUTTON
                {
                    iId = (uint)i,
                    dwFlags = THBF.NOBACKGROUND | THBF.DISABLED | THBF.HIDDEN | THBF.NONINTERACTIVE,
                    dwMask = THB.FLAGS | THB.ICON | THB.TOOLTIP
                };
            }
 
            // If this gets called (successfully) more than once it usually returns E_INVALIDARG.  It's not really
            // a failure and we potentially want to retry this operation.
            HRESULT hr = _taskbarList.ThumbBarAddButtons(Handle, (uint)nativeButtons.Length, nativeButtons);
            if (hr == HRESULT.E_INVALIDARG)
            {
                hr = HRESULT.S_FALSE;
            }
            return hr;
        }
 
        private HRESULT UpdateTaskbarThumbButtons()
        {
            Debug.Assert(null != _taskbarList);
 
            var nativeButtons = new THUMBBUTTON[c_MaximumThumbButtons];
            TaskbarItemInfo taskbarInfo = TaskbarItemInfo;
            ThumbButtonInfoCollection thumbButtons = null;
 
            if (taskbarInfo != null)
            {
                thumbButtons = taskbarInfo.ThumbButtonInfos;
            }
 
            var nativeIcons = new List<NativeMethods.IconHandle>();
 
            try
            {
                uint currentButton = 0;
                if (null != thumbButtons)
                {
                    foreach (ThumbButtonInfo wrappedTB in thumbButtons)
                    {
                        var nativeTB = new THUMBBUTTON
                        {
                            iId = (uint)currentButton,
                            dwMask = THB.FLAGS | THB.TOOLTIP | THB.ICON,
                        };
 
                        switch (wrappedTB.Visibility)
                        {
                            case Visibility.Collapsed:
                                // HIDDEN removes the button from layout logic.
                                nativeTB.dwFlags = THBF.HIDDEN;
                                break;
 
                            case Visibility.Hidden:
                                // To match WPF's notion of hidden, we want this not HIDDEN
                                // but disabled, without background, and without icon.
                                nativeTB.dwFlags = THBF.DISABLED | THBF.NOBACKGROUND;
                                nativeTB.hIcon = IntPtr.Zero;
 
                                break;
                            default:
                            case Visibility.Visible:
 
                                nativeTB.szTip = wrappedTB.Description ?? "";
                                if (wrappedTB.ImageSource != null)
                                {
                                    NativeMethods.IconHandle nativeIcon = IconHelper.CreateIconHandleFromImageSource(wrappedTB.ImageSource, _overlaySize);
                                    nativeTB.hIcon = nativeIcon.CriticalGetHandle();
                                    nativeIcons.Add(nativeIcon);
                                }
 
                                if (!wrappedTB.IsBackgroundVisible)
                                {
                                    nativeTB.dwFlags |= THBF.NOBACKGROUND;
                                }
 
                                if (!wrappedTB.IsEnabled)
                                {
                                    nativeTB.dwFlags |= THBF.DISABLED;
                                }
                                else
                                {
                                    nativeTB.dwFlags |= THBF.ENABLED;
                                }
 
                                // This is separate from enabled/disabled
                                if (!wrappedTB.IsInteractive)
                                {
                                    nativeTB.dwFlags |= THBF.NONINTERACTIVE;
                                }
 
                                if (wrappedTB.DismissWhenClicked)
                                {
                                    nativeTB.dwFlags |= THBF.DISMISSONCLICK;
                                }
                                break;
                        }
 
                        nativeButtons[currentButton] = nativeTB;
 
                        ++currentButton;
                        if (currentButton == c_MaximumThumbButtons)
                        {
                            break;
                        }
                    }
                }
 
                // If we're not attached, or the list is less than the maximum number of buttons
                // then fill in the rest with collapsed, empty buttons.
                for (; currentButton < c_MaximumThumbButtons; ++currentButton)
                {
                    nativeButtons[currentButton] = new THUMBBUTTON
                    {
                        iId = (uint)currentButton,
                        dwFlags = THBF.NOBACKGROUND | THBF.DISABLED | THBF.HIDDEN,
                        dwMask = THB.FLAGS | THB.ICON | THB.TOOLTIP
                    };
                }
 
                // Finally, apply the update.
                return _taskbarList.ThumbBarUpdateButtons(Handle, (uint)nativeButtons.Length, nativeButtons);
            }
            finally
            {
                foreach (var icon in nativeIcons)
                {
                    icon.Dispose();
                }
            }
        }
 
        private void CreateRtl()
        {
            if ( this.FlowDirection == FlowDirection.LeftToRight )
            {
                _StyleEx &= ~NativeMethods.WS_EX_LAYOUTRTL;
            }
            else if ( this.FlowDirection == FlowDirection.RightToLeft )
            {
                _StyleEx |= NativeMethods.WS_EX_LAYOUTRTL;
            }
            else
            {
                throw new InvalidOperationException(SR.IncorrectFlowDirection);
            }
}
 
        /// <summary>
        ///     Updates both style and styleEx for the window
        ///
        ///     WCP: Figure out how to update window styles after calling SetWindowLong
        ///     Currently hides the window and then shows it to make it update. Have to
        ///     find a better way of doing this.
        /// </summary>
        internal void Flush()
        {
            // (A NullReferenceException occurs when animating
            // the WindowStyle enum via a custom animation).  This bug contains details of
            // why we were seeing the null ref.
            //
            // Sometimes, the SetWindowPos call below results in sending certain window messages
            // like (WM_SIZE) and their handling leads to setting some property on the Window leading
            // to a call to HwndStyleManager.StartManaging.  Thus, we end up calling
            // dispose on the "new" usage of the Manager before we complete this run of Flush method.
            // This resulted in null ref in setting the Dirty bit below since we were not using
            // a local copy and the window member copy was already set to null by the "new" usage
            // of Manager.  To fix this bug, we do the following two things:
            //
            // 1) Keep a local copy of HwndStyleManager in this method to make it re-entrant.
            // 2) null out _window.Manager in HwndStyleMangager.Dispose only if _window.Manager is
            //    this instance of the Manager.
            //
            HwndStyleManager manager = Manager;
            if (manager.Dirty && Handle != IntPtr.Zero)
            {
                UnsafeNativeMethods.CriticalSetWindowLong(new HandleRef(this,Handle), NativeMethods.GWL_STYLE, (IntPtr)_styleDoNotUse);
                UnsafeNativeMethods.CriticalSetWindowLong(new HandleRef(this,Handle), NativeMethods.GWL_EXSTYLE, (IntPtr)_styleExDoNotUse);
 
                UnsafeNativeMethods.SetWindowPos(new HandleRef(this, Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0,
                                               NativeMethods.SWP_NOMOVE |
                                               NativeMethods.SWP_NOSIZE |
                                               NativeMethods.SWP_NOZORDER |
                                               NativeMethods.SWP_FRAMECHANGED |
                                               NativeMethods.SWP_DRAWFRAME |
                                               NativeMethods.SWP_NOACTIVATE);
                manager.Dirty = false;
            }
        }
        private void ClearRootVisual()
        {
            if (_swh != null)
            {
                _swh.ClearRootVisual();
            }
        }
 
 
        private NativeMethods.POINT GetPointRelativeToWindow( int x, int y )
        {
            return _swh.GetPointRelativeToWindow( x, y, this.FlowDirection);
        }
 
        //     If you're in the middle of changing the window's _style or _styleEx and call this function,
        //     you may get inconsistent results.
        private Size GetHwndNonClientAreaSizeInMeasureUnits()
        {
            // HwndSource expands the client area to cover the entire window when it is in UsesPerPixelOpacity mode,
            // So non client area is (0,0)
            return AllowsTransparency ? new Size(0, 0) : _swh.GetHwndNonClientAreaSizeInMeasureUnits();
        }
 
        private void ClearSourceWindow()
        {
            if (_swh != null)
            {
                try
                {
                    _swh.RemoveDisposedHandler(OnSourceWindowDisposed);
                }
                finally
                {
                    HwndSource source = _swh.HwndSourceWindow;
                    _swh = null;
 
                    if (source != null)
                    {
                        source.SizeToContentChanged -= new EventHandler(OnSourceSizeToContentChanged);
                    }
                }
            }
        }
 
        private void ClearHiddenWindowIfAny()
        {
            // If there is a hiddenWindow and it's the owner of the current one as the result of setting ShowInTaskbar,
            // we need to unparent it. Because when we dipose the hiddenWindow, if it's still the parent
            // of the current window, the current Window will get a second WM_DESTORY because its owner being distoried.
            // See detail in bug 953988.
            // Unparent it in WM_CLOSE because when we get to WM_DESTROY, _sourceWindow.Handle could be IntPtr.Zero;
            // InternalDispose() is where _hiddenWindow is disposed. It could be called from two places: 1. WmDestroy 2. OnSourceWindowDisposed.
            // When it's called from OnSourceWindowDisposed, _sourceWindow.Handle could have been set to IntPtr.Zero.
            if ((_hiddenWindow != null) && (_hiddenWindow.Handle == _ownerHandle))
            {
                SetOwnerHandle(IntPtr.Zero);
            }
        }
 
        private void VerifyConsistencyWithAllowsTransparency()
        {
            if (AllowsTransparency)
            {
                VerifyConsistencyWithAllowsTransparency(WindowStyle);
            }
        }
 
        private void VerifyConsistencyWithAllowsTransparency(WindowStyle style)
        {
            if (AllowsTransparency && style != WindowStyle.None)
            {
                throw new InvalidOperationException(SR.MustUseWindowStyleNone);
            }
        }
 
        private void VerifyConsistencyWithShowActivated()
        {
            //
            // We don't support to show a maximized non-activated window.
            // Don't check this consistency in a RBW (would break because Visibility is set when launching the RBW).
            //
            if (!_inTrustedSubWindow && WindowState == WindowState.Maximized && !ShowActivated)
                throw new InvalidOperationException(SR.ShowNonActivatedAndMaximized);
        }
 
        private static bool IsValidSizeToContent(SizeToContent value)
        {
            return value == SizeToContent.Manual ||
                   value == SizeToContent.Width ||
                   value == SizeToContent.Height ||
                   value == SizeToContent.WidthAndHeight;
        }
 
        private static bool IsValidResizeMode(ResizeMode value)
        {
            return value == ResizeMode.NoResize
                || value == ResizeMode.CanMinimize
                || value == ResizeMode.CanResize
                || value == ResizeMode.CanResizeWithGrip;
        }
 
        private static bool IsValidWindowStartupLocation(WindowStartupLocation value)
        {
            return value == WindowStartupLocation.CenterOwner
                || value == WindowStartupLocation.CenterScreen
                || value == WindowStartupLocation.Manual;
        }
 
        private static bool IsValidWindowState(WindowState value)
        {
            return value == WindowState.Maximized
                || value == WindowState.Minimized
                || value == WindowState.Normal;
        }
 
        private static bool IsValidWindowStyle(WindowStyle value)
        {
            return value == WindowStyle.None
                || value == WindowStyle.SingleBorderWindow
                || value == WindowStyle.ThreeDBorderWindow
                || value == WindowStyle.ToolWindow;
        }
 
        #endregion Private Methods
 
        #region Manipulation Boundary Feedback
 
        /// <summary>
        ///     Provides feedback when a manipulation has encountered a boundary by nudging the window.
        /// </summary>
        /// <remarks>
        ///     PanningFeedback is reported on Handle of the Window using Begin/Update/EndPanningFeedback
        ///     APIs. When the Handle reported to these APIs is not of a top-level window, these APIs
        ///     do a GetAncestor call to get the top-level window and apply the effect of it. For eg.
        ///     in the case of XBAPs we report the feedback to the Handle of RootBrowserWindow which is
        ///     a child window, but still the panning feedback effect gets applied to the browser window
        ///     itself. Security wise this also assumes that PanningFeedback will not move the Window
        ///     by an arbitrary distance.
        /// </remarks>
        protected override void OnManipulationBoundaryFeedback(ManipulationBoundaryFeedbackEventArgs e)
        {
            base.OnManipulationBoundaryFeedback(e);
 
            // If the original source is not from the same PresentationSource as of the Window,
            // then do not act on the PanningFeedback.
            if (!PresentationSource.UnderSamePresentationSource(e.OriginalSource as DependencyObject, this))
            {
                return;
            }
 
            if (!e.Handled)
            {
                if (_currentPanningTarget == null ||
                    !_currentPanningTarget.IsAlive ||
                    _currentPanningTarget.Target != e.OriginalSource)
                {
                    if (_swh != null)
                    {
                        // Cache location if starting the panning feedback.
                        // Using SourceWindowHelper.WindowBounds instead of Window.Left
                        // and Window.Top so that the implementation works with
                        // RootBrowserWindow.
                        NativeMethods.RECT rc = WindowBounds;
                        _prePanningLocation = DeviceToLogicalUnits(new Point(rc.left, rc.top));
                    }
                }
                ManipulationDelta manipulation = e.BoundaryFeedback;
                UpdatePanningFeedback(manipulation.Translation, e.OriginalSource);
                e.CompensateForBoundaryFeedback = CompensateForPanningFeedback;
            }
        }
 
        private static void OnStaticManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
        {
            Window window = sender as Window;
            if (window != null)
            {
                // Transitioning from direct manipulation to inertia, animate the window
                // back to its original position.
                window.EndPanningFeedback(true);
            }
        }
 
        private static void OnStaticManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            Window window = sender as Window;
            if (window != null)
            {
                // A complete was encountered. If this was a forced complete, snap the window
                // back to its original position.
                window.EndPanningFeedback(false);
            }
        }
 
        /// <summary>
        ///     Provides feedback by nudging the window.
        /// </summary>
        private void UpdatePanningFeedback(Vector totalOverpanOffset, object originalSource)
        {
            if ((_currentPanningTarget != null) && !_currentPanningTarget.IsAlive)
            {
                // The old source is gone, end any pending feedback
                _currentPanningTarget = null;
                EndPanningFeedback(false);
            }
 
            if (_swh != null)
            {
                if (_currentPanningTarget == null)
                {
                    // Provide feedback for this source's events
                    _currentPanningTarget = new WeakReference(originalSource);
                }
 
                // Only provide feedback for one source at a time
                if (originalSource == _currentPanningTarget.Target)
                {
                    // Update the window position
                    _swh.UpdatePanningFeedback(totalOverpanOffset, false);
                }
            }
        }
 
        /// <summary>
        ///     Returns the window to its original position.
        /// </summary>
        private void EndPanningFeedback(bool animateBack)
        {
            if (_swh != null)
            {
                // Restore the window to its original position
                _swh.EndPanningFeedback(animateBack);
            }
            _currentPanningTarget = null;
            _prePanningLocation = new Point(double.NaN, double.NaN);
        }
 
        /// <summary>
        ///     Method to compensate a point for PanningFeedback.
        /// </summary>
        Point CompensateForPanningFeedback(Point point)
        {
            if (!double.IsNaN(_prePanningLocation.X) && !double.IsNaN(_prePanningLocation.Y) && (_swh != null))
            {
                // transform the point to pre pan coordinate system
                NativeMethods.RECT rc = WindowBounds;
                Point windowLocation = DeviceToLogicalUnits(new Point(rc.left, rc.top));
                return new Point(point.X - (_prePanningLocation.X - windowLocation.X), point.Y - (_prePanningLocation.Y - windowLocation.Y));
            }
            return point;
        }
 
        #endregion
 
        //----------------------------------------------
        //
        // Private Properties
        //
        //----------------------------------------------
        #region Private Properties
 
        private SizeToContent HwndSourceSizeToContent
        {
            get
            {
                return _swh.HwndSourceSizeToContent;
            }
            set
            {
                _swh.HwndSourceSizeToContent = value;
            }
        }
 
        private NativeMethods.RECT WindowBounds
        {
            get
            {
                Debug.Assert( _swh != null );
                return _swh.WindowBounds;
            }
        }
 
        private int StyleFromHwnd
        {
            get
            {
                return _swh != null ? _swh.StyleFromHwnd : 0;
            }
        }
 
        private int StyleExFromHwnd
        {
            get
            {
                return _swh != null ? _swh.StyleExFromHwnd : 0;
            }
        }
 
        /// <summary>
        ///     Private helper for OwnedWindows property.
        ///     The public version returns a copy of the WindowCollection.
        ///     For internal Window usage, we use OwnedWindowInternal
        ///     so that we can modify the underlying collection.
        /// </summary>
        private WindowCollection OwnedWindowsInternal
        {
            get
            {
                if (_ownedWindows == null)
                {
                    _ownedWindows = new WindowCollection();
                }
                return _ownedWindows;
            }
        }
 
        /// <summary>
        ///     Application Instance
        /// </summary>
        private System.Windows.Application App
        {
            get {return System.Windows.Application.Current;}
        }
 
        /// <summary>
        ///     Tells whether the Application object exists or not
        /// </summary>
        private bool IsInsideApp
        {
            get
            {
                return (Application.Current != null);
            }
        }
 
        /// <summary>
        ///     List of events on this Window
        /// </summary>
        private EventHandlerList Events
        {
            get
            {
                if (_events == null)
                {
                    _events = new EventHandlerList();
                }
                return _events;
            }
        }
 
        #endregion Private Properties
 
 
        //----------------------------------------------
        //
        // Private Fields
        //
        //----------------------------------------------
        #region Private Fields
 
        private SourceWindowHelper  _swh;                               // object that will hold the window
        private Window              _ownerWindow;                       // owner window
        private bool _reloadFluentDictionary = false;
        private bool _resourcesInitialized = false;
 
        // keeps track of the owner hwnd
        // we need this one b/c a owner/parent
        // can be set through the WindowInteropHandler
        // which is different than the owner Window object
        private IntPtr              _ownerHandle = IntPtr.Zero;   // no need to dispose this
        private WindowCollection    _ownedWindows;
        private List<IntPtr>        _threadWindowHandles;
 
        private bool                _updateHwndSize     = true;
        private bool                _updateHwndLocation = true;
        private bool                _updateStartupLocation;
        private bool                _isVisible;
        private bool                _isVisibilitySet;           // use this to tell whether Visibility is set or not.
        private bool                _resetKeyboardCuesProperty; // true if we set ShowKeyboradCuesProperty in ShowDialog
        private bool                _previousKeyboardCuesProperty;
 
        private static bool         _dialogCommandAdded;
        private bool                _postContentRenderedFromLoadedHandler;
 
        // WCP Window:  Define the dispose behavior for Window
        private bool                _disposed;
 
        private bool                _appShuttingDown;
        private bool                _ignoreCancel;
        private bool                _showingAsDialog;
        private bool                _isClosing;
        private bool                _visibilitySetInternally;
 
        // The hwnd can be created before window is shown via WindowInteropHelper.EnsureHandle.
        private bool                _hwndCreatedButNotShown;
 
        private double              _trackMinWidthDeviceUnits = 0;
        private double              _trackMinHeightDeviceUnits = 0;
        private double              _trackMaxWidthDeviceUnits = Double.PositiveInfinity;
        private double              _trackMaxHeightDeviceUnits = Double.PositiveInfinity;
        private double              _windowMaxWidthDeviceUnits = Double.PositiveInfinity;
        private double              _windowMaxHeightDeviceUnits = Double.PositiveInfinity;
 
        private double              _actualTop = Double.NaN;
 
        private double              _actualLeft = Double.NaN;
 
 
        private ThemeMode           _themeMode = ThemeMode.None;
        internal bool               _deferThemeLoading = false;
        private bool                _useDarkMode = false;
 
        //Never expose this at any cost
        private bool                        _inTrustedSubWindow;
 
        private ImageSource _icon;
 
        private NativeMethods.IconHandle    _defaultLargeIconHandle;
        private NativeMethods.IconHandle    _defaultSmallIconHandle;
        private NativeMethods.IconHandle    _currentLargeIconHandle;
        private NativeMethods.IconHandle    _currentSmallIconHandle;
 
        private bool?                       _dialogResult = null;
        private IntPtr                      _dialogOwnerHandle = IntPtr.Zero;
        private IntPtr                      _dialogPreviousActiveHandle;
        private DispatcherFrame             _dispatcherFrame;
 
        private WindowStartupLocation       _windowStartupLocation = WindowStartupLocation.Manual;
 
        // The previous WindowState value before WindowState changes
        private WindowState                 _previousWindowState = WindowState.Normal;
        private HwndWrapper         _hiddenWindow;
        private EventHandlerList    _events;
 
        // These should never be used directly, access only through property accessors
 
        private int                 _styleDoNotUse;
        private int                 _styleExDoNotUse;
        private HwndStyleManager    _manager;
 
        // reference to Resize Grip control; this is used to find out whether
        // the mouse of over the resizegrip control
        private Control                 _resizeGripControl;
 
        Point _prePanningLocation = new Point(double.NaN, double.NaN);
 
        // static objects for Events
        private static readonly object EVENT_SOURCEINITIALIZED = new object();
        private static readonly object EVENT_CLOSING = new object();
        private static readonly object EVENT_CLOSED = new object();
        private static readonly object EVENT_ACTIVATED = new object();
        private static readonly object EVENT_DEACTIVATED = new object();
        private static readonly object EVENT_STATECHANGED = new object();
        private static readonly object EVENT_LOCATIONCHANGED = new object();
        private static readonly object EVENT_CONTENTRENDERED = new object();
        private static readonly object EVENT_VISUALCHILDRENCHANGED = new object();
 
        #region Windows 7 Taskbar related fields
 
        // Register Window Message used by Shell to notify that the corresponding taskbar button has been added to the taskbar.
        private static readonly WindowMessage WM_TASKBARBUTTONCREATED;
 
        // Register Window Message used by Window to signal that we need to apply the taskbar button information again.
        private static readonly WindowMessage WM_APPLYTASKBARITEMINFO;
 
        // Magic constant determined by Shell.
        private const int c_MaximumThumbButtons = 7;
 
        private ITaskbarList3 _taskbarList;
 
        // When a taskbarList update fails because Explorer is non-responsive, defer further changes for a little while
        // to avoid causing the app to be non-responsive as well.
        private DispatcherTimer _taskbarRetryTimer;
 
        private Size _overlaySize;
 
        #endregion
 
        internal static readonly DependencyProperty IWindowServiceProperty
            = DependencyProperty.RegisterAttached("IWindowService", typeof(IWindowService), typeof(Window),
                                          new FrameworkPropertyMetadata((IWindowService)null,
                                          FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior));
 
        DispatcherOperation         _contentRenderedCallback;
 
        private WeakReference _currentPanningTarget;
 
        #endregion Private Fields
 
        #region Private Class
 
        internal class SourceWindowHelper
        {
                internal SourceWindowHelper( HwndSource sourceWindow )
                {
                    Debug.Assert( sourceWindow != null );
                    _sourceWindow = sourceWindow;
                }
 
                internal bool IsSourceWindowNull
                {
                    get
                    {
                        return ( _sourceWindow == null );
                    }
                }
 
                internal bool IsCompositionTargetInvalid
                {
                    get
                    {
                        return (CompositionTarget == null);
                    }
                }
 
                internal IntPtr Handle
                {
                    get
                    {
                        if (_sourceWindow != null)
                        {
                            return _sourceWindow.Handle;
                        }
                        else
                        {
                            return IntPtr.Zero;
                        }
                    }
                }
 
                ///<summary>
                /// Get the work area bounds for this window - taking multi-mon into account.
                ///</summary>
                internal NativeMethods.RECT WorkAreaBoundsForNearestMonitor
                {
                    get
                    {
                        IntPtr monitor;
                        NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX();
                        monitorInfo.cbSize = Marshal.SizeOf(typeof(NativeMethods.MONITORINFOEX));
 
                        monitor = SafeNativeMethods.MonitorFromWindow( new HandleRef( this, Handle), NativeMethods.MONITOR_DEFAULTTONEAREST  );
                        if ( monitor != IntPtr.Zero )
                        {
                            SafeNativeMethods.GetMonitorInfo( new HandleRef ( this, monitor ) , monitorInfo);
                        }
 
                        return monitorInfo.rcWork;
}
                }
 
                private NativeMethods.RECT ClientBounds
                {
                    get
                    {
                        NativeMethods.RECT rc = new NativeMethods.RECT(0,0,0,0);
                        SafeNativeMethods.GetClientRect(new HandleRef(this, Handle), ref rc);
 
                        return rc;
                    }
                }
 
                internal NativeMethods.RECT WindowBounds
                {
                    get
                    {
                        NativeMethods.RECT rc = new NativeMethods.RECT(0,0,0,0);
                        SafeNativeMethods.GetWindowRect(new HandleRef(this, Handle), ref rc);
 
                        return rc;
                    }
                }
 
 
                private NativeMethods.POINT GetWindowScreenLocation(FlowDirection flowDirection)
                {
                    Debug.Assert(IsSourceWindowNull != true, "IsSourceWindowNull cannot be true here");
                    NativeMethods.POINT pt = default;
                    if (flowDirection == FlowDirection.RightToLeft)
                    {
                        NativeMethods.RECT rc = new NativeMethods.RECT(0, 0, 0, 0);
 
                        // with RTL window, GetClientRect returns reversed coordinates
                        SafeNativeMethods.GetClientRect(new HandleRef(this, Handle), ref rc);
 
                        // note that we use rc.right here for the RTL case and client to screen that point
                        pt = new NativeMethods.POINT(rc.right, rc.top);
                    }
                    UnsafeNativeMethods.ClientToScreen(new HandleRef(this, _sourceWindow.Handle), ref pt);
 
                    return pt;
                }
 
                internal SizeToContent HwndSourceSizeToContent
                {
                    get
                    {
                        return _sourceWindow.SizeToContent;
                    }
 
                    set
                    {
                        _sourceWindow.SizeToContent = value;
                    }
                }
 
                internal Visual RootVisual
                {
                    set
                    {
                        _sourceWindow.RootVisual = value;
                    }
                }
 
                internal bool IsActiveWindow
                {
                    get
                    {
                        return (_sourceWindow.Handle == UnsafeNativeMethods.GetActiveWindow());
                    }
                }
 
                internal HwndSource HwndSourceWindow
                {
                    get
                    {
                        return _sourceWindow;
                    }
                }
 
                internal HwndTarget CompositionTarget
                {
                    get
                    {
                        if (_sourceWindow != null)
                        {
                            HwndTarget compositionTarget = _sourceWindow.CompositionTarget;
                            if (compositionTarget != null && compositionTarget.IsDisposed == false)
                            {
                                return compositionTarget;
                            }
                        }
                        return null;
                    }
                }
 
                ///<summary>
                /// Return the relative window width and height.
                ///</summary>
                internal Size WindowSize
                {
                    get
                    {
                        // Get the size of the avalon window and pass it to
                        // the base implementation.
 
                        NativeMethods.RECT rc = WindowBounds;
 
                        return new Size(rc.right - rc.left, rc.bottom - rc.top);
                    }
                }
 
                internal int StyleExFromHwnd
                {
                    get
                    {
                        // Should never be called when Handle is non-null
                        Debug.Assert( IsSourceWindowNull == false , "Should only be invoked when we know Handle is non-null" );
                        return UnsafeNativeMethods.GetWindowLong(new HandleRef(this,Handle), NativeMethods.GWL_EXSTYLE);
                    }
                }
 
                internal int StyleFromHwnd
                {
                    get
                    {
                        // Should never be called when Handle is non-null
                        Debug.Assert( IsSourceWindowNull == false , "Should only be invoked when we know Handle is non-null" );
                        return UnsafeNativeMethods.GetWindowLong(new HandleRef(this,Handle), NativeMethods.GWL_STYLE);
                    }
                }
 
 
                ///<summary>
                ///     Transform global coords of window location
                ///     to coords relative to top/left of the window.
                ///</summary>
                internal NativeMethods.POINT GetPointRelativeToWindow( int x, int y, FlowDirection flowDirection )
                {
                    NativeMethods.POINT ptWindow = GetWindowScreenLocation(flowDirection);
 
                    // At this point ptWindow contains the location of the client area's top/left wrt
                    // the screen
 
                    return new NativeMethods.POINT( x - ptWindow.x, y - ptWindow.y );
                }
 
                /// <summary>
                ///     Gets the size from the hwnd
                /// </summary>
                internal Size GetSizeFromHwndInMeasureUnits()
                {
                    Debug.Assert( IsSourceWindowNull == false , "IsSourceWindowNull can't be true here");
 
                    Point pt = new Point(0,0);
                    NativeMethods.RECT rect = WindowBounds;
                    pt.X = rect.right - rect.left;
                    pt.Y = rect.bottom - rect.top;
                    pt = _sourceWindow.CompositionTarget.TransformFromDevice.Transform(pt);
                    return new Size(pt.X,pt.Y);
                }
 
 
                /// <summary>
                ///     Gets the frame size of the hwnd.
                ///     Note that we use the current Hwnd's style information.
                ///     If you're in the middle of changing the window's _style or _styleEx and call this function,
                ///     you may get inconsistent results.
                /// </summary>
                internal Size GetHwndNonClientAreaSizeInMeasureUnits()
                {
                    Debug.Assert( IsSourceWindowNull == false , "IsSourceWindowNull can't be true here");
 
                    // Diff the Client and Window sizes to get the dimensions of the frame.
                    NativeMethods.RECT clientRect = ClientBounds;
                    NativeMethods.RECT windowRect = WindowBounds;
 
                    Point pt = new Point(
                        (windowRect.right - windowRect.left) - (clientRect.right - clientRect.left),
                        (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top));
 
                    pt = _sourceWindow.CompositionTarget.TransformFromDevice.Transform(pt);
 
                    // it's possible that the client rect is actually larger than the window rect
                    // Presumably this happens because the rects are changing
                    // out from under us, and it's just a transient state.  The Max calls
                    // avoid a crash when this happens.
                    return new Size(Math.Max(0.0, pt.X), Math.Max(0.0, pt.Y));
                }
 
                internal void ClearRootVisual()
                {
                    if ( _sourceWindow.RootVisual != null )
                    {
                        _sourceWindow.RootVisual = null;
                    }
                }
 
                internal void AddDisposedHandler( EventHandler theHandler )
                {
                    if (_sourceWindow != null)
                    {
                        _sourceWindow.Disposed += theHandler;
                    }
                }
 
                internal void RemoveDisposedHandler( EventHandler theHandler )
                {
                    if (_sourceWindow != null)
                    {
                        _sourceWindow.Disposed -= theHandler;
                    }
                }
 
                /// <summary>
                ///     Updates panning feedback for this window based on the offset.
                /// </summary>
                /// <param name="totalOverpanOffset">The amount of over-panning being reported.</param>
                /// <param name="animate">Whether to animate to the new feedback position.</param>
                internal void UpdatePanningFeedback(Vector totalOverpanOffset, bool animate)
                {
                    if ((_panningFeedback == null) && (_sourceWindow != null))
                    {
                        _panningFeedback = new HwndPanningFeedback(_sourceWindow);
                    }
 
                    if (_panningFeedback != null)
                    {
                        // Update the window position
                        _panningFeedback.UpdatePanningFeedback(totalOverpanOffset, animate);
                    }
                }
 
                /// <summary>
                ///     Return the window back to its original position.
                /// </summary>
                /// <param name="animateBack">Whether to animate to the original position.</param>
                internal void EndPanningFeedback(bool animateBack)
                {
                    if (_panningFeedback != null)
                    {
                        // Restore the window to its original position
                        _panningFeedback.EndPanningFeedback(animateBack);
                        _panningFeedback = null;
                    }
                }
 
                private HwndSource _sourceWindow;
 
                private HwndPanningFeedback _panningFeedback;
        }
 
        internal class HwndStyleManager : IDisposable
        {
            static internal HwndStyleManager StartManaging(Window w, int Style, int StyleEx )
            {
                if (w.Manager == null)
                {
                    return new HwndStyleManager(w, Style, StyleEx);
                }
                else
                {
                    w.Manager._refCount++;
                    return w.Manager;
                }
            }
 
            private HwndStyleManager(Window w, int Style, int StyleEx  )
            {
                _window = w;
                _window.Manager = this;
 
                if ( w.IsSourceWindowNull == false )
                {
                    _window._Style    =  Style;
                    _window._StyleEx  = StyleEx;
 
                    // Dirty ==> _style and hwnd are out of sync. Since we just got
                    // the style from hwnd, it obviously is not Dirty.
                    Dirty = false;
                }
                _refCount = 1;
            }
 
            void IDisposable.Dispose()
            {
                _refCount--;
 
                // (A NullReferenceException occurs when animating
                // the WindowStyle enum via a custom animation).  This bug contains details of
                // why we were seeing the null ref.
                //
                // Sometimes, the Flush call below results in sending certain window messages
                // and their handling leads to setting some property on the Window leading
                // to a call to HwndStyleManager.StartManaging.  Thus, we end up calling
                // dispose on that before we complete this run of the Dispose method.  This
                // resulted in null ref in Flush.  To fix this bug, we do the following two things:
                //
                // 1) Keep a local copy of HwndStyleManager in Flush to make it re-entrant
                // 2) null out _window.Manager below only if _window.Manager is this instance
                //    of the Manager.
 
                if (_refCount == 0)
                {
                    _window.Flush();
 
                    if (_window.Manager == this)
                    {
                        _window.Manager = null;
                    }
                }
            }
 
            internal bool Dirty
            {
                get { return _fDirty; }
                set { _fDirty = value; }
            }
 
            private Window          _window;
            private int             _refCount;
            private bool            _fDirty;
        }
 
 
        /// <summary>
        /// A helper class to convert (Left, Top) <see cref="Point"/> expressed
        /// in WPF-space (1/96" units) to Screen units.
        /// </summary>
        /// <remarks>
        /// Initially, an HWND created in <see cref="Window"/> in a Per-Monitor Aware process may not
        /// have a relaible DPI. Instead, it would be associated with the monitor where the screen point (0,0)
        /// happens to be, but the screen point corresponding to a WPF Window's (requestedLeft, requestedTop) may not map
        /// to that monitor. Our initial DeviceToLogicalUnits and LogicalToDeviceUnits transforms
        /// would normally have to rely on the DPI obtained from this HWND, which may lead us to
        /// an incorrect result when calculating screen points. To avoid this, we use a special heuristic here
        /// to identify the (screenLeft, screenTop) initially without relying on the HWND, and then
        /// supply it to HwndSourceParameters at the time of HWND creation. This would in turn set up the HWND
        /// with the correct DPI from the start, and all our transformations would also follow suit.
        /// </remarks>
        private class WindowStartupTopLeftPointHelper
        {
            /// <summary>
            /// The (Left, Top) logical point, in WPF coordinate space,
            /// that must be translated into Screen space.
            /// </summary>
            internal Point LogicalTopLeft { get; }
 
            /// <summary>
            /// The Screen-space translation of <see cref="LogicalTopLeft"/>
            /// </summary>
            internal Point? ScreenTopLeft { get; private set; } = null;
 
            /// <summary>
            /// Creates a new instance of <see cref="WindowStartupTopLeftPointHelper"/>
            /// </summary>
            /// <param name="topLeft">(left, top) point in WPF-space to be converted to a Screen-space point</param>
            internal WindowStartupTopLeftPointHelper(Point topLeft)
            {
                LogicalTopLeft = topLeft;
 
                if (IsHelperNeeded)
                {
                    IdentifyScreenTopLeft();
                }
            }
 
            /// <summary>
            /// Decides whether this helper should be used.
            /// This helper is used when -
            ///     a. WPF supports DPI scaling (HwndTarget.IsPerMonitorDpiScalingEnabled), and
            ///     b. The process is PMA (HwndTarget.IsProcessPerMonitorDpiAware)
            /// </summary>
            /// <remarks>
            /// <see cref="CoreAppContextSwitches.DoNotUsePresentationDpiCapabilityTier2OrGreater"/>
            /// is tested to determine whether accurate window placement behavior should be enabled, or not. This is a
            /// compatibility measure put in place to ensure that our improvement/fix does not clash with workarounds
            /// that developers might have built into their applications to correct this problem.
            /// </remarks>
            private bool IsHelperNeeded
            {
                get
                {
                    if (CoreAppContextSwitches.DoNotUsePresentationDpiCapabilityTier2OrGreater)
                    {
                        return false;
                    }
 
                    if (!HwndTarget.IsPerMonitorDpiScalingEnabled)
                    {
                        return false;
                    }
 
                    if (HwndTarget.IsProcessPerMonitorDpiAware.HasValue)
                    {
                        return HwndTarget.IsProcessPerMonitorDpiAware.Value;
                    }
 
                    // WPF supports Per-Monitor scaling, but HwndTarget has not
                    // yet been initialized with the first HWND, and therefore
                    // HwndTarget.IsProcessPerMonitorDpiAware is not queryable.
                    // Let's use the current process' DPI awareness as a proxy.
                    return DpiUtil.GetProcessDpiAwareness(IntPtr.Zero) == NativeMethods.PROCESS_DPI_AWARENESS.PROCESS_PER_MONITOR_DPI_AWARE;
                }
            }
 
            /// <summary>
            /// Uses EnumDisplayDevices to iterate through each monitor, and looks to see if
            /// <see cref="LogicalTopLeft"/> exists within that monitor's rectangle. To do this,
            /// it scales that monitors coordinate space by its corresponding DPI scale factor (this
            /// happens in <see cref="MonitorEnumProc(IntPtr, IntPtr, ref Runtime.InteropServices.NativeMethods.RECT, IntPtr)"/>)
            /// and normalizes it to a 96 DPI space - which is the space in which WPF itself operates - and then sees whether
            /// <see cref="LogicalTopLeft"/> lies within that rectangle. If it does, then it updates <see cref="ScreenTopLeft"/>
            /// with the corresponding unscaled monitor-space point.
            /// </summary>
            private void IdentifyScreenTopLeft()
            {
                var nullHandle = new HandleRef(null, IntPtr.Zero);
                var hdc = UnsafeNativeMethods.GetDC(nullHandle);
                UnsafeNativeMethods.EnumDisplayMonitors(
                    hdc,
                    IntPtr.Zero,
                    MonitorEnumProc,
                    IntPtr.Zero);
                UnsafeNativeMethods.ReleaseDC(nullHandle, new HandleRef(null, hdc));
            }
 
            /// <summary>
            /// Helper for <see cref="IdentifyScreenTopLeft"/>
            /// </summary>
            /// <remarks>See summary and remarks for <see cref="IdentifyScreenTopLeft"/></remarks>
            /// <param name="hMonitor">A handle to the display monitor. This value will always be non-NULL.</param>
            /// <param name="hdcMonitor">A handle to the device context</param>
            /// <param name="lprcMonitor">
            /// A pointer to a RECT structure.
            ///
            /// If hdcMonitor is non-NULL, this rectangle is the intersection of the clipping area of the device
            /// context identified by hdcMonitor and the display monitor rectangle.The rectangle coordinates are
            /// device-context coordinates.
            ///
            /// If hdcMonitor is NULL, this rectangle is the display monitor rectangle. The rectangle coordinates
            /// are virtual-screen coordinates.
            /// </param>
            /// <param name="dwData">
            /// Application-defined data that EnumDisplayMonitors passes directly to
            /// the enumeration function.
            /// </param>
            /// <returns>
            /// To continue the enumeration, return true.
            /// To stop the enumeration, return false.
            /// </returns>
            private bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeMethods.RECT lprcMonitor, IntPtr dwData)
            {
                // The call the EnumDisplayMonitors set hdc to null
                // This means that hdcMonitor will be null, and
                // lprcMonitor will represent the RECT of the whole monitor
                // skip the checks and trust the API contract that this will
                // be so
 
                bool continueMonitorEnumeration = true;
 
                uint dpiX, dpiY;
                var hr =
                    UnsafeNativeMethods.GetDpiForMonitor(
                        new HandleRef(null, hMonitor),
                        NativeMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI,
                        out dpiX, out dpiY);
 
                if (hr == NativeMethods.S_OK)
                {
                    double dpiScaleX = dpiX * 1.0d / 96.0d;
                    double dpiScaleY = dpiY * 1.0d / 96.0d;
 
                    Rect monitorRectInWpfScale = new Rect
                    {
                        X = lprcMonitor.left / dpiScaleX,
                        Y = lprcMonitor.top / dpiScaleY,
                        Width = (lprcMonitor.right - lprcMonitor.left) / dpiScaleX,
                        Height = (lprcMonitor.bottom - lprcMonitor.top) / dpiScaleY
                    };
 
                    if (monitorRectInWpfScale.Contains(LogicalTopLeft))
                    {
                        ScreenTopLeft = new Point
                        {
                            X = LogicalTopLeft.X * dpiScaleX,
                            Y = LogicalTopLeft.Y * dpiScaleY
                        };
 
                        continueMonitorEnumeration = false;
                    }
                }
 
                return continueMonitorEnumeration;
            }
        }
 
        #endregion PrivateClass
 
        #region Private Enums
        private enum TransformType
        {
            WorkAreaToScreenArea = 0,
            ScreenAreaToWorkArea = 1
        }
 
        private enum BoundsSpecified
        {
            Height = 0,
            Width = 1,
            Top = 2,
            Left = 3
        }
        #endregion Private Enums
 
        #region DTypeThemeStyleKey
 
        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types.
        internal override DependencyObjectType DTypeThemeStyleKey
        {
            get { return _dType; }
        }
 
        private static DependencyObjectType _dType;
 
        #endregion DTypeThemeStyleKey
    }
 
    #region Enums
 
    /// <summary>
    /// WindowStyle
    /// </summary>
    public enum WindowStyle
    {
        /// <summary>
        /// no border at all  also implies no caption
        /// </summary>
        None = 0,                                               // no border at all  also implies no caption
 
        /// <summary>
        /// SingleBorderWindow
        /// </summary>
        SingleBorderWindow = 1,                                    // WS_BORDER
 
        /// <summary>
        /// 3DBorderWindow
        /// </summary>
        ThreeDBorderWindow = 2,                                    // WS_BORDER | WS_EX_CLIENTEDGE
 
        /// <summary>
        /// FixedToolWindow
        /// </summary>
        ToolWindow = 3,                                           // WS_BORDER | WS_EX_TOOLWINDOW
 
        // NOTE: if you add or remove any values in this enum, be sure to update Window.IsValidWindowStyle()
    }
 
 
    /// <summary>
    /// WindowState
    /// </summary>
    public enum WindowState
    {
        /// <summary>
        /// Default size
        /// </summary>
        Normal = 0,
 
        /// <summary>
        /// Minimized
        /// </summary>
        Minimized = 1,   // WS_MINIMIZE
 
        /// <summary>
        /// Maximized
        /// </summary>
        Maximized = 2   // WS_MAXIMIZE
 
        // NOTE: if you add or remove any values in this enum, be sure to update Window.IsValidWindowState()
 
#if THEATRE_FULLSCREEN
        // The following Two are not Implement yet
        /// <summary>
        /// Theatre
        /// </summary>
        Theatre = 3,
 
        /// <summary>
        /// FullScreen
        /// </summary>
        FullScreen = 4
#endif //THEATRE_FULLSCREEN
    }
 
    /// <summary>
    ///
    /// </summary>
    [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
    public enum WindowStartupLocation
    {
        /// <summary>
        /// Uses the values specified by Left and Top properties to position the Window
        /// </summary>
        Manual = 0,
 
        /// <summary>
        /// Centers the Window on the screen.  If there are more than one monitors, then
        /// the Window is centered on the monitor that has the mouse on it
        /// </summary>
        CenterScreen = 1,
 
        /// <summary>
        /// Centers the Window on its owner.  If there is no owner window defined or if
        /// it is not possible to center it on the owner, then defaults to Manual
        /// </summary>
        CenterOwner = 2,
 
        // NOTE: if you add or remove any values in this enum, be sure to update Window.IsValidWindowStartupLocation()
    }
 
    /// <summary>
    ///     ResizeMode
    /// </summary>
    [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
    public enum ResizeMode
    {
        /// <summary>
        ///     User cannot resize the Window. Maximize and Minimize boxes
        ///     do not show in the caption bar.
        /// </summary>
        NoResize = 0,
 
        /// <summary>
        ///     User can only minimize the Window.  Minimize box is shown and enabled
        ///     in the caption bar while the Maximize box is disabled.
        /// </summary>
        CanMinimize = 1,
 
        /// <summary>
        ///     User can fully resize the Window including minimize and maximize.
        ///     Both Maximize and Minimize boxes are shown and enabled in the caption
        ///     bar.
        /// </summary>
        CanResize = 2,
 
        /// <summary>
        ///     Same as CanResize and ResizeGrip will show
        /// </summary>
        CanResizeWithGrip = 3
 
        // NOTE: if you add or remove any values in this enum, be sure to update Window.IsValidResizeMode()
    }
    #endregion Enums
 
    internal class SingleChildEnumerator : IEnumerator
    {
        internal SingleChildEnumerator(object Child)
        {
            _child = Child;
            _count = Child == null ? 0 : 1;
        }
 
        object IEnumerator.Current
        {
            get { return (_index == 0) ? _child : null; }
        }
 
        bool IEnumerator.MoveNext()
        {
            _index++;
            return _index < _count;
        }
 
        void IEnumerator.Reset()
        {
            _index = -1;
        }
 
        private int _index = -1;
        private int _count = 0;
        private object _child;
    }
}