透明 WPF 窗口后面的模糊

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31778017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:19:05  来源:igfitidea点击:

Blur behind transparent WPF window

c#wpfwinapi

提问by Tom

I am trying to create a WPF application with a semi transparent border-less window that blurs the background behind it.

我正在尝试创建一个带有半透明无边框窗口的 WPF 应用程序,该窗口模糊了其背后的背景。

Here is an example of what I want to do. Screenshot

这是我想要做的一个例子。截屏

I have tried to use DwmEnableBlurBehindWindowwhich works only on windows Vista/7.

我尝试使用DwmEnableBlurBehindWindow仅适用于 Windows Vista/7 的方法。

I am trying to find a solution that will work on Windows 7, 8 and 10.

我正在尝试找到适用于 Windows 7、8 和 10 的解决方案。

回答by Tom

For anyone interested I have found a solution for Windows 10, It looks as though it isn't possible on Windows 8, like David Heffernan mentioned, DwmEnableBlurBehindWindow was removed from Windows 8, however Microsoft re-introduced a solution for achieving this effect in Windows 10.

对于任何感兴趣的人,我已经找到了适用于 Windows 10 的解决方案,看起来好像在 Windows 8 上不可能,就像 David Heffernan 提到的那样,DwmEnableBlurBehindWindow 从 Windows 8 中删除,但是微软重新引入了一个解决方案来在 Windows 中实现这种效果10.

回答by J?rg Flechsig

I hope I am not late to the party. You can use the SetWindowCompositionAttribute, but you are then forced to set the WindowStyle to "None" and implement your own native Window funtionality and handles. Also inheriting from a custom control is quite complicated. However, long story short. There's BlurryControls.

我希望我没有迟到。您可以使用 SetWindowCompositionAttribute,但随后您必须将 WindowStyle 设置为“None”并实现您自己的本机 Window 功能和句柄。从自定义控件继承也是相当复杂的。然而,长话短说。有 BlurryControls。

You can find it via NuGetby browsing for "BlurryControls" or check out the code yourself on GitHub. Eitherway, I hope this is helpful.

你可以通过NuGet通过浏览“BlurryControls”找到它,或者自己在GitHub 上查看代码。不管怎样,我希望这会有所帮助。

On GitHub you will also find a sample application.

在 GitHub 上,您还可以找到一个示例应用程序。

回答by Gábor

Windows 8

视窗 8

As much as a dead end that'd better be completely forgotten, we might need to make sure our programs behave consistently across versions. If there is no need for a dynamic background and especially if the window is relatively small (a prime candidate would be a message box or similar over our own application window), the solution of capturing the screen behind the window and blurring it manually might work. In the Loadedevent handler:

尽管最好完全忘记一个死胡同,我们可能需要确保我们的程序在不同版本中的行为一致。如果不需要动态背景,特别是如果窗口相对较小(主要候选者是我们自己的应用程序窗口上的消息框或类似物),则捕获窗口后面的屏幕并手动模糊它的解决方案可能会奏效. 在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,
};

where borderis an outermost Border, normally left completely empty, only used on Windows 8.

whereborder是最外层Border,通常完全为空,仅在 Windows 8 上使用。

The helper function is the usual bitmap conversion:

辅助函数是通常的位图转换:

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()is best solved with a direct bitmap manipulation package like WriteableBitmapEx, with the necessary modifications.

ApplyGaussianBlur()最好使用直接位图操作包(如WriteableBitmapEx,并进行必要的修改)来解决。

回答by David Heffernan

Microsoft removed glass effects starting from Windows 8. That explains why the blur effect that you are expecting is not observed on Windows 8 and later. You will have to learn to live without it on those operating systems.

Microsoft 从 Windows 8 开始删除了玻璃效果。这就解释了为什么在 Windows 8 及更高版本上没有观察到您期望的模糊效果。你将不得不学会在那些操作系统上没有它。