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