我正在尝试创建一个 WPF 应用程序,它有一个半透明的无边框窗口,模糊了它背后的背景。
这是我想做的一个例子:
我尝试使用 DwmEnableBlurBehindWindow 只适用于 Windows Vista/7.
我正在尝试找到适用于 Windows 7、8 和 10 的解决方案。
对于任何感兴趣的人,我已经找到了适用于 Windows 10 的解决方案。不过看起来它在 Windows 8 上是不可能的;正如 David Heffernan 提到的那样,
DwmEnableBlurBehindWindow
已从 Windows 8 中删除。但是,Microsoft 重新引入了在 Windows 10 中实现此效果的解决方案。
DwmEnableBlurBehindWindow
我希望我没有迟到。您可以使用 SetWindowCompositionAttribute,但随后您必须将 WindowStyle 设置为“None”并实现您自己的本机 Window 功能和句柄。从自定义控件继承也是相当复杂的。然而,长话短说。有 BlurryControls.
您可以通过 NuGet 浏览“BlurryControls”找到它,或者自己在 GitHub 上查看代码。不管怎样,我希望这会有所帮助。
在 GitHub 上,您还将找到一个示例应用程序。
Windows 8
就像最好完全忘记的死胡同一样,我们可能需要确保我们的程序在各个版本中表现一致。如果不需要动态背景,特别是如果窗口相对较小(主要候选者是消息框或我们自己的应用程序窗口上的类似内容),捕获窗口后面的屏幕并手动模糊它的解决方案可能会起作用.在
Loaded
事件处理程序中:
var screen = window.Owner.PointToScreen(new System.Windows.Point((window.Owner.ActualWidth - window.ActualWidth) / 2, (window.Owner.ActualHeight - window.ActualHeight) / 2));
var rect = new Rectangle((int)screen.X, (int)screen.Y, (int)window.ActualWidth, (int)window.ActualHeight);
var bitmap = new Bitmap(rect.Width, rect.Height);
using (var graphics = Graphics.FromImage(bitmap))
graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);
border.Background = new ImageBrush(ApplyGaussianBlur(bitmap.ToBitmapImage())) {
TileMode = TileMode.None,
Stretch = Stretch.None,
AlignmentX = AlignmentX.Center,
AlignmentY = AlignmentY.Center,
};
其中
border
是最外层的 Border
,通常完全留空,仅在 Windows 8 上使用。
辅助函数就是通常的位图转换:
public static BitmapSource ToBitmapImage(this System.Drawing.Bitmap image) {
var hBitmap = image.GetHbitmap();
var bitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(hBitmap);
return bitmap;
}
ApplyGaussianBlur()
最好用像WriteableBitmapEx
这样的直接位图操作包来解决,并进行必要的修改。
Microsoft 从 Windows 8 开始删除了玻璃效果。这解释了为什么在 Windows 8 及更高版本上没有观察到您期望的模糊效果。在这些操作系统上,您将不得不学会在没有它的情况下生活。