Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 我可以将WPF窗口覆盖在另一个窗口上吗?_.net_Wpf_Interop_Windowsformshost - Fatal编程技术网

.net 我可以将WPF窗口覆盖在另一个窗口上吗?

.net 我可以将WPF窗口覆盖在另一个窗口上吗?,.net,wpf,interop,windowsformshost,.net,Wpf,Interop,Windowsformshost,我有一个WPF窗口,其中包含一个WindowsFormsHost元素。我需要在这个元素的顶部绘制东西,但是WindowsFormsHost的性质意味着它总是在绘图堆的顶部。由于我无法在WindowsFormsHost组件顶部绘制相同的WPF窗口,我可以在其顶部覆盖另一个窗口吗 我已经初步尝试过了,但我有几个问题: 1) 我无法阻止其他应用程序在主窗口和覆盖窗口之间运行windows 2) 当我选择Alt Tab时,叠加窗口出现在窗口列表中,这非常难看 基本上,我需要一个“子窗口”的概念,这个窗口

我有一个WPF窗口,其中包含一个
WindowsFormsHost
元素。我需要在这个元素的顶部绘制东西,但是
WindowsFormsHost
的性质意味着它总是在绘图堆的顶部。由于我无法在
WindowsFormsHost
组件顶部绘制相同的WPF窗口,我可以在其顶部覆盖另一个窗口吗

我已经初步尝试过了,但我有几个问题:

1) 我无法阻止其他应用程序在主窗口和覆盖窗口之间运行windows

2) 当我选择Alt Tab时,叠加窗口出现在窗口列表中,这非常难看

基本上,我需要一个“子窗口”的概念,这个窗口在所有意图和目的上都是另一个窗口的一部分。用户控件对我不起作用,因为
WindowsFormsHost
总是在它上面绘制

有什么想法吗


更新[2011年5月23日10:13]

谢谢你们两位的回答

我尝试了
ChildWindow
方法,而
WindowsFormsHost
元素仍然在顶部绘制。据我所知,只有真正的窗口才能在
WindowsFormsHost
上绘制,同一窗口中的任何内容都将位于
WindowsFormsHost

<Grid>
    <local:AirspacePopup PlacementTarget="{Binding ElementName=webBrowser}"
                         FollowPlacementTarget="True"
                         AllowOutsideScreenPlacement="True"
                         ParentWindow="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                         IsOpen="True"
                         AllowsTransparency="True"
                         Placement="Center"
                         Width="{Binding ElementName=googleBrowser, Path=ActualWidth}"
                         Height="{Binding ElementName=googleBrowser, Path=ActualHeight}">
        <Grid>
            <Ellipse Width="100" Height="100" Fill="Green" Margin="100"/>
        </Grid>
    </local:AirspacePopup>
    <WebBrowser Name="webBrowser" Loaded="WebBrowser_Loaded"/>
</Grid>
带有
WindowsFormsHost
的元素仍将在WinForms组件下绘制,它们始终绘制在顶部,这似乎是不可协商的


我想我要找的是一种方法,可以停靠一个外部窗口,作为主窗口的一部分。在Mac电脑上,有一个真正的“子窗口”的概念,我正在寻找类似的东西。

你可以在
WindowsFormsHost
中做“覆盖”部分。因此,您可以在托管元素中的其他内容之上有一个子元素。

在使用CAL或事件聚合器的典型MVP应用程序中,您可能需要创建另一个窗口并将其命名为popup或child(
ChildWindow.XAML
),并在(
ChildWindow.XAML.CS
)中有一个get方法,如

在maniwindow中有一个属性,可以在需要时返回Childwindow类型。 像


希望这能有所帮助,

我已经通过使用
弹出窗口而不是透明的
窗口解决了这个问题

更新

我最终得到了一个子类
Popup
,我称之为
airspaceppopup

AirspacePopup
的作用是什么

  • 遵循其
    位置目标
  • 不总是在顶部,而是相对于要放置它的
    窗口
    放置。这个解决方案来自于
  • 允许移动到“屏幕外”。这是通过剪切弹出窗口
并在其子项移出屏幕后设置负的
边距
来实现的。这个解决方案来自Rick Sladkey 下面是一个示例,其中使用
AirspacePopup
WebBrowser
控件(实际上是一个WinForms控件)上绘制一个
Ellipse
,但它同样适用于任何
WindowsFormsHost

<Grid>
    <local:AirspacePopup PlacementTarget="{Binding ElementName=webBrowser}"
                         FollowPlacementTarget="True"
                         AllowOutsideScreenPlacement="True"
                         ParentWindow="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                         IsOpen="True"
                         AllowsTransparency="True"
                         Placement="Center"
                         Width="{Binding ElementName=googleBrowser, Path=ActualWidth}"
                         Height="{Binding ElementName=googleBrowser, Path=ActualHeight}">
        <Grid>
            <Ellipse Width="100" Height="100" Fill="Green" Margin="100"/>
        </Grid>
    </local:AirspacePopup>
    <WebBrowser Name="webBrowser" Loaded="WebBrowser_Loaded"/>
</Grid>
空中空间弹出窗口

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interop;

public class AirspacePopup : Popup
{
    public static readonly DependencyProperty IsTopmostProperty =
        DependencyProperty.Register("IsTopmost",
                                    typeof(bool),
                                    typeof(AirspacePopup),
                                    new FrameworkPropertyMetadata(false, OnIsTopmostChanged));

    public static readonly DependencyProperty FollowPlacementTargetProperty =
        DependencyProperty.RegisterAttached("FollowPlacementTarget",
                                            typeof(bool),
                                            typeof(AirspacePopup),
                                            new UIPropertyMetadata(false));

    public static readonly DependencyProperty AllowOutsideScreenPlacementProperty =
        DependencyProperty.RegisterAttached("AllowOutsideScreenPlacement",
                                            typeof(bool),
                                            typeof(AirspacePopup),
                                            new UIPropertyMetadata(false));

    public static readonly DependencyProperty ParentWindowProperty =
        DependencyProperty.RegisterAttached("ParentWindow",
                                            typeof(Window),
                                            typeof(AirspacePopup),
                                            new UIPropertyMetadata(null, ParentWindowPropertyChanged));

    private static void OnIsTopmostChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        AirspacePopup airspacePopup = source as AirspacePopup;
        airspacePopup.SetTopmostState(airspacePopup.IsTopmost);
    }

    private static void ParentWindowPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        AirspacePopup airspacePopup = source as AirspacePopup;
        airspacePopup.ParentWindowChanged();
    }

    private bool? m_appliedTopMost;
    private bool m_alreadyLoaded;
    private Window m_parentWindow;

    public AirspacePopup()
    {
        Loaded += OnPopupLoaded;
        Unloaded += OnPopupUnloaded;

        DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(PlacementTargetProperty, typeof(AirspacePopup));
        descriptor.AddValueChanged(this, PlacementTargetChanged);
    }

    public bool IsTopmost
    {
        get { return (bool)GetValue(IsTopmostProperty); }
        set { SetValue(IsTopmostProperty, value); }
    }
    public bool FollowPlacementTarget
    {
        get { return (bool)GetValue(FollowPlacementTargetProperty); }
        set { SetValue(FollowPlacementTargetProperty, value); }
    }
    public bool AllowOutsideScreenPlacement
    {
        get { return (bool)GetValue(AllowOutsideScreenPlacementProperty); }
        set { SetValue(AllowOutsideScreenPlacementProperty, value); }
    }
    public Window ParentWindow
    {
        get { return (Window)GetValue(ParentWindowProperty); }
        set { SetValue(ParentWindowProperty, value); }
    }

    private void ParentWindowChanged()
    {
        if (ParentWindow != null)
        {
            ParentWindow.LocationChanged += (sender, e2) =>
            {
                UpdatePopupPosition();
            };
            ParentWindow.SizeChanged += (sender, e2) =>
            {
                UpdatePopupPosition();
            };
        }
    }
    private void PlacementTargetChanged(object sender, EventArgs e)
    {
        FrameworkElement placementTarget = this.PlacementTarget as FrameworkElement;
        if (placementTarget != null)
        {
            placementTarget.SizeChanged += (sender2, e2) =>
            {
                UpdatePopupPosition();
            };
        }
    }

    private void UpdatePopupPosition()
    {
        FrameworkElement placementTarget = this.PlacementTarget as FrameworkElement;
        FrameworkElement child = this.Child as FrameworkElement;

        if (PresentationSource.FromVisual(placementTarget) != null &&
            AllowOutsideScreenPlacement == true)
        {
            double leftOffset = CutLeft(placementTarget);
            double topOffset = CutTop(placementTarget);
            double rightOffset = CutRight(placementTarget);
            double bottomOffset = CutBottom(placementTarget);
            Debug.WriteLine(bottomOffset);
            this.Width = Math.Max(0, Math.Min(leftOffset, rightOffset) + placementTarget.ActualWidth);
            this.Height = Math.Max(0, Math.Min(topOffset, bottomOffset) + placementTarget.ActualHeight);

            if (child != null)
            {
                child.Margin = new Thickness(leftOffset, topOffset, rightOffset, bottomOffset);
            }
        }
        if (FollowPlacementTarget == true)
        {
            this.HorizontalOffset += 0.01;
            this.HorizontalOffset -= 0.01;
        }
    }
    private double CutLeft(FrameworkElement placementTarget)
    {
        Point point = placementTarget.PointToScreen(new Point(0, placementTarget.ActualWidth));
        return Math.Min(0, point.X);
    }
    private double CutTop(FrameworkElement placementTarget)
    {
        Point point = placementTarget.PointToScreen(new Point(placementTarget.ActualHeight, 0));
        return Math.Min(0, point.Y);
    }
    private double CutRight(FrameworkElement placementTarget)
    {
        Point point = placementTarget.PointToScreen(new Point(0, placementTarget.ActualWidth));
        point.X += placementTarget.ActualWidth;
        return Math.Min(0, SystemParameters.VirtualScreenWidth - (Math.Max(SystemParameters.VirtualScreenWidth, point.X)));
    }
    private double CutBottom(FrameworkElement placementTarget)
    {
        Point point = placementTarget.PointToScreen(new Point(placementTarget.ActualHeight, 0));
        point.Y += placementTarget.ActualHeight;
        return Math.Min(0, SystemParameters.VirtualScreenHeight - (Math.Max(SystemParameters.VirtualScreenHeight, point.Y)));
    }

    private void OnPopupLoaded(object sender, RoutedEventArgs e)
    {
        if (m_alreadyLoaded) 
            return;

        m_alreadyLoaded = true;

        if (Child != null)
        {
            Child.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(OnChildPreviewMouseLeftButtonDown), true);
        }

        m_parentWindow = Window.GetWindow(this);

        if (m_parentWindow == null) 
            return;

        m_parentWindow.Activated += OnParentWindowActivated;
        m_parentWindow.Deactivated += OnParentWindowDeactivated;
    }

    private void OnPopupUnloaded(object sender, RoutedEventArgs e)
    {
        if (m_parentWindow == null)
            return;
        m_parentWindow.Activated -= OnParentWindowActivated;
        m_parentWindow.Deactivated -= OnParentWindowDeactivated;
    }

    private void OnParentWindowActivated(object sender, EventArgs e)
    {
        SetTopmostState(true);
    }

    private void OnParentWindowDeactivated(object sender, EventArgs e)
    {
        if (IsTopmost == false)
        {
            SetTopmostState(IsTopmost);
        }
    }

    private void OnChildPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        SetTopmostState(true);
        if (!m_parentWindow.IsActive && IsTopmost == false)
        {
            m_parentWindow.Activate();
        }
    }

    protected override void OnOpened(EventArgs e)
    {
        SetTopmostState(IsTopmost);
        base.OnOpened(e);
    }

    private void SetTopmostState(bool isTop)
    {
        // Don’t apply state if it’s the same as incoming state
        if (m_appliedTopMost.HasValue && m_appliedTopMost == isTop)
        {
            return;
        }

        if (Child == null) 
            return;

        var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource;

        if (hwndSource == null) 
            return;
        var hwnd = hwndSource.Handle;

        RECT rect;

        if (!GetWindowRect(hwnd, out rect)) 
            return;

        Debug.WriteLine("setting z-order " + isTop);

        if (isTop)
        {
            SetWindowPos(hwnd, HWND_TOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
        }
        else
        {
            // Z-Order would only get refreshed/reflected if clicking the
            // the titlebar (as opposed to other parts of the external
            // window) unless I first set the popup to HWND_BOTTOM
            // then HWND_TOP before HWND_NOTOPMOST
            SetWindowPos(hwnd, HWND_BOTTOM, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
            SetWindowPos(hwnd, HWND_TOP, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
            SetWindowPos(hwnd, HWND_NOTOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
        }

        m_appliedTopMost = isTop;
    }

    #region P/Invoke imports & definitions
    #pragma warning disable 1591 //Xml-doc
    #pragma warning disable 169 //Never used-warning
    // ReSharper disable InconsistentNaming
    // Imports etc. with their naming rules

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT

    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
    int Y, int cx, int cy, uint uFlags);

    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
    static readonly IntPtr HWND_TOP = new IntPtr(0);
    static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

    private const UInt32 SWP_NOSIZE = 0x0001;
    const UInt32 SWP_NOMOVE = 0x0002;
    const UInt32 SWP_NOZORDER = 0x0004;
    const UInt32 SWP_NOREDRAW = 0x0008;
    const UInt32 SWP_NOACTIVATE = 0x0010;

    const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
    const UInt32 SWP_SHOWWINDOW = 0x0040;
    const UInt32 SWP_HIDEWINDOW = 0x0080;
    const UInt32 SWP_NOCOPYBITS = 0x0100;
    const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don’t do owner Z ordering */
    const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don’t send WM_WINDOWPOSCHANGING */

    const UInt32 TOPMOST_FLAGS = 
        SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSENDCHANGING;

    // ReSharper restore InconsistentNaming
    #pragma warning restore 1591
    #pragma warning restore 169
    #endregion
}
我建议用这个

我一直在努力解决这个问题有一段时间了,发现MahApps库在没有任何配置的情况下修复了空域问题。有关更多信息,请参阅他们的常见问题解答:


对不同的溶液进行大量测试后:

  • Microsoft.dwayneeed()

    赞成的意见: 就我所知,
    • 工作得很好(我没有对它进行过太多测试,但它看起来很像)
    • 这场演出似乎太低了

    欺骗: 相对较大的图书馆。

  • 空中定位器()

    赞成的意见:
    • 效果很好(没有测试过那么多,但看起来很像)

      • 欺骗:
        • 有一个小的性能冲击。(据我所知,比Microsoft.dwayneed更大)

      • Fredrik Hedblad()

        赞成的意见:
        • 简单的代码。主要是:D

        欺骗:
        • 在全屏上,底部的一部分缺失
        • 多监视器问题:当从一个窗口移动到另一个窗口时,覆盖并不完全覆盖winformshostwindow。
      • 对我来说,最好的解决方案是使用Microsoft.dwayneed。(我用它将Winforms导入WPF应用程序)

        因为让它工作并不是简单的,她只是一个小教程:

      • 单击下载
      • 打开Microsoft.dwayneeed.sln
      • 编译它
      • 在创建的调试或Releas文件夹中引用Microsoft.dwayneeed.dll
      • 加 xmlns:interop=“clr命名空间:Microsoft.dwayneeed.interop;assembly=Microsoft.dwayneeed 到你的窗口
      • 加 到你的网格
      • 例如:

        
        
        如何使此HitTestVisible可见?我尝试将网格背景设置为“透明”,但无效。当我将背景设置为“白色”时“并将“不透明度”设置为0.01它是可见的!也许有人有想法?当窗口最大化时,底部有一个小间隙,弹出窗口不能正确跟随。如何解决此问题?从最小化状态恢复窗口时,dwm动画无法很好地解决此问题。当主窗口仍在设置动画时,椭圆立即出现。有解决方案吗?截至2021年,似乎仍然是没有WinAPI的最可靠的解决方案,第三方库对我不起作用:System.NullReferenceException对象引用未设置为对象的实例。位于Microsoft.dwayneed.Interop.RedirectedHwndHost.UpdateOutputRedirection()的Microsoft.dwayneed.Interop.RedirectedHwndHost.b_u_31_2(对象e,事件参数a)的System.Windows.Threading.Dispatchermer.FireTick(未使用的对象)的System.Windows.Threading.ExceptionWra
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        
            private void WebBrowser_Loaded(object sender, RoutedEventArgs e)
            {
                WebBrowser webbrowser = sender as WebBrowser;
                webbrowser.Navigate("http://www.stackoverflow.com");
            }
        }
        
        using System;
        using System.ComponentModel;
        using System.Diagnostics;
        using System.Runtime.InteropServices;
        using System.Windows;
        using System.Windows.Controls.Primitives;
        using System.Windows.Input;
        using System.Windows.Interop;
        
        public class AirspacePopup : Popup
        {
            public static readonly DependencyProperty IsTopmostProperty =
                DependencyProperty.Register("IsTopmost",
                                            typeof(bool),
                                            typeof(AirspacePopup),
                                            new FrameworkPropertyMetadata(false, OnIsTopmostChanged));
        
            public static readonly DependencyProperty FollowPlacementTargetProperty =
                DependencyProperty.RegisterAttached("FollowPlacementTarget",
                                                    typeof(bool),
                                                    typeof(AirspacePopup),
                                                    new UIPropertyMetadata(false));
        
            public static readonly DependencyProperty AllowOutsideScreenPlacementProperty =
                DependencyProperty.RegisterAttached("AllowOutsideScreenPlacement",
                                                    typeof(bool),
                                                    typeof(AirspacePopup),
                                                    new UIPropertyMetadata(false));
        
            public static readonly DependencyProperty ParentWindowProperty =
                DependencyProperty.RegisterAttached("ParentWindow",
                                                    typeof(Window),
                                                    typeof(AirspacePopup),
                                                    new UIPropertyMetadata(null, ParentWindowPropertyChanged));
        
            private static void OnIsTopmostChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
            {
                AirspacePopup airspacePopup = source as AirspacePopup;
                airspacePopup.SetTopmostState(airspacePopup.IsTopmost);
            }
        
            private static void ParentWindowPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
            {
                AirspacePopup airspacePopup = source as AirspacePopup;
                airspacePopup.ParentWindowChanged();
            }
        
            private bool? m_appliedTopMost;
            private bool m_alreadyLoaded;
            private Window m_parentWindow;
        
            public AirspacePopup()
            {
                Loaded += OnPopupLoaded;
                Unloaded += OnPopupUnloaded;
        
                DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(PlacementTargetProperty, typeof(AirspacePopup));
                descriptor.AddValueChanged(this, PlacementTargetChanged);
            }
        
            public bool IsTopmost
            {
                get { return (bool)GetValue(IsTopmostProperty); }
                set { SetValue(IsTopmostProperty, value); }
            }
            public bool FollowPlacementTarget
            {
                get { return (bool)GetValue(FollowPlacementTargetProperty); }
                set { SetValue(FollowPlacementTargetProperty, value); }
            }
            public bool AllowOutsideScreenPlacement
            {
                get { return (bool)GetValue(AllowOutsideScreenPlacementProperty); }
                set { SetValue(AllowOutsideScreenPlacementProperty, value); }
            }
            public Window ParentWindow
            {
                get { return (Window)GetValue(ParentWindowProperty); }
                set { SetValue(ParentWindowProperty, value); }
            }
        
            private void ParentWindowChanged()
            {
                if (ParentWindow != null)
                {
                    ParentWindow.LocationChanged += (sender, e2) =>
                    {
                        UpdatePopupPosition();
                    };
                    ParentWindow.SizeChanged += (sender, e2) =>
                    {
                        UpdatePopupPosition();
                    };
                }
            }
            private void PlacementTargetChanged(object sender, EventArgs e)
            {
                FrameworkElement placementTarget = this.PlacementTarget as FrameworkElement;
                if (placementTarget != null)
                {
                    placementTarget.SizeChanged += (sender2, e2) =>
                    {
                        UpdatePopupPosition();
                    };
                }
            }
        
            private void UpdatePopupPosition()
            {
                FrameworkElement placementTarget = this.PlacementTarget as FrameworkElement;
                FrameworkElement child = this.Child as FrameworkElement;
        
                if (PresentationSource.FromVisual(placementTarget) != null &&
                    AllowOutsideScreenPlacement == true)
                {
                    double leftOffset = CutLeft(placementTarget);
                    double topOffset = CutTop(placementTarget);
                    double rightOffset = CutRight(placementTarget);
                    double bottomOffset = CutBottom(placementTarget);
                    Debug.WriteLine(bottomOffset);
                    this.Width = Math.Max(0, Math.Min(leftOffset, rightOffset) + placementTarget.ActualWidth);
                    this.Height = Math.Max(0, Math.Min(topOffset, bottomOffset) + placementTarget.ActualHeight);
        
                    if (child != null)
                    {
                        child.Margin = new Thickness(leftOffset, topOffset, rightOffset, bottomOffset);
                    }
                }
                if (FollowPlacementTarget == true)
                {
                    this.HorizontalOffset += 0.01;
                    this.HorizontalOffset -= 0.01;
                }
            }
            private double CutLeft(FrameworkElement placementTarget)
            {
                Point point = placementTarget.PointToScreen(new Point(0, placementTarget.ActualWidth));
                return Math.Min(0, point.X);
            }
            private double CutTop(FrameworkElement placementTarget)
            {
                Point point = placementTarget.PointToScreen(new Point(placementTarget.ActualHeight, 0));
                return Math.Min(0, point.Y);
            }
            private double CutRight(FrameworkElement placementTarget)
            {
                Point point = placementTarget.PointToScreen(new Point(0, placementTarget.ActualWidth));
                point.X += placementTarget.ActualWidth;
                return Math.Min(0, SystemParameters.VirtualScreenWidth - (Math.Max(SystemParameters.VirtualScreenWidth, point.X)));
            }
            private double CutBottom(FrameworkElement placementTarget)
            {
                Point point = placementTarget.PointToScreen(new Point(placementTarget.ActualHeight, 0));
                point.Y += placementTarget.ActualHeight;
                return Math.Min(0, SystemParameters.VirtualScreenHeight - (Math.Max(SystemParameters.VirtualScreenHeight, point.Y)));
            }
        
            private void OnPopupLoaded(object sender, RoutedEventArgs e)
            {
                if (m_alreadyLoaded) 
                    return;
        
                m_alreadyLoaded = true;
        
                if (Child != null)
                {
                    Child.AddHandler(PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(OnChildPreviewMouseLeftButtonDown), true);
                }
        
                m_parentWindow = Window.GetWindow(this);
        
                if (m_parentWindow == null) 
                    return;
        
                m_parentWindow.Activated += OnParentWindowActivated;
                m_parentWindow.Deactivated += OnParentWindowDeactivated;
            }
        
            private void OnPopupUnloaded(object sender, RoutedEventArgs e)
            {
                if (m_parentWindow == null)
                    return;
                m_parentWindow.Activated -= OnParentWindowActivated;
                m_parentWindow.Deactivated -= OnParentWindowDeactivated;
            }
        
            private void OnParentWindowActivated(object sender, EventArgs e)
            {
                SetTopmostState(true);
            }
        
            private void OnParentWindowDeactivated(object sender, EventArgs e)
            {
                if (IsTopmost == false)
                {
                    SetTopmostState(IsTopmost);
                }
            }
        
            private void OnChildPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                SetTopmostState(true);
                if (!m_parentWindow.IsActive && IsTopmost == false)
                {
                    m_parentWindow.Activate();
                }
            }
        
            protected override void OnOpened(EventArgs e)
            {
                SetTopmostState(IsTopmost);
                base.OnOpened(e);
            }
        
            private void SetTopmostState(bool isTop)
            {
                // Don’t apply state if it’s the same as incoming state
                if (m_appliedTopMost.HasValue && m_appliedTopMost == isTop)
                {
                    return;
                }
        
                if (Child == null) 
                    return;
        
                var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource;
        
                if (hwndSource == null) 
                    return;
                var hwnd = hwndSource.Handle;
        
                RECT rect;
        
                if (!GetWindowRect(hwnd, out rect)) 
                    return;
        
                Debug.WriteLine("setting z-order " + isTop);
        
                if (isTop)
                {
                    SetWindowPos(hwnd, HWND_TOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
                }
                else
                {
                    // Z-Order would only get refreshed/reflected if clicking the
                    // the titlebar (as opposed to other parts of the external
                    // window) unless I first set the popup to HWND_BOTTOM
                    // then HWND_TOP before HWND_NOTOPMOST
                    SetWindowPos(hwnd, HWND_BOTTOM, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
                    SetWindowPos(hwnd, HWND_TOP, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
                    SetWindowPos(hwnd, HWND_NOTOPMOST, rect.Left, rect.Top, (int)Width, (int)Height, TOPMOST_FLAGS);
                }
        
                m_appliedTopMost = isTop;
            }
        
            #region P/Invoke imports & definitions
            #pragma warning disable 1591 //Xml-doc
            #pragma warning disable 169 //Never used-warning
            // ReSharper disable InconsistentNaming
            // Imports etc. with their naming rules
        
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
        
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }
        
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
        
            [DllImport("user32.dll")]
            private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
            int Y, int cx, int cy, uint uFlags);
        
            static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
            static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
            static readonly IntPtr HWND_TOP = new IntPtr(0);
            static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
        
            private const UInt32 SWP_NOSIZE = 0x0001;
            const UInt32 SWP_NOMOVE = 0x0002;
            const UInt32 SWP_NOZORDER = 0x0004;
            const UInt32 SWP_NOREDRAW = 0x0008;
            const UInt32 SWP_NOACTIVATE = 0x0010;
        
            const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
            const UInt32 SWP_SHOWWINDOW = 0x0040;
            const UInt32 SWP_HIDEWINDOW = 0x0080;
            const UInt32 SWP_NOCOPYBITS = 0x0100;
            const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don’t do owner Z ordering */
            const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don’t send WM_WINDOWPOSCHANGING */
        
            const UInt32 TOPMOST_FLAGS = 
                SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSENDCHANGING;
        
            // ReSharper restore InconsistentNaming
            #pragma warning restore 1591
            #pragma warning restore 169
            #endregion
        }
        
        xmlns:interop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=Microsoft.DwayneNeed <interop:AirspaceDecorator AirspaceMode="Redirect" Background="White" IsInputRedirectionEnabled="True" IsOutputRedirectionEnabled="True"> <WindowsFormsHost x:Name="windowsFormsHost1" Visibility="Visible" /> </interop:AirspaceDecorator>