无边框 WPF 窗口上没有玻璃效果的原生 Aero 模糊

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31151539/
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:14:17  来源:igfitidea点击:

Native Aero Blur without Glass Effect on Borderless WPF Window

c#wpfvb.netdwm

提问by Tommy Crews

I am aware that similar questions have been asked and answered. Mine, however, is a three-part question.

我知道已经提出并回答了类似的问题。然而,我的问题是一个由三部分组成的问题。

For the purposes of this question, keep the following in mind:

就本问题而言,请记住以下几点:

  • I am an amateur, early college undergraduate studying Computer Science. I am highly unskilled in complex programming, but I can understand most terminology.
  • This is a WPF project created in Visual Studio using VB.NET, but I can read C# just as easily due to the languages' similarity.
  • This is my first time experimenting with any DWM APIs.
  • 我是一名业余爱好者,本科在读计算机科学。我在复杂的编程方面非常不熟练,但我可以理解大多数术语。
  • 这是一个使用 VB.NET 在 Visual Studio 中创建的 WPF 项目,但由于语言的相似性,我可以同样轻松地阅读 C#。
  • 这是我第一次尝试任何 DWM API。

1. Applying Aero Glass to Borderless Window

1. 将 Aero Glass 应用于无边窗

First and foremost, is it possible to use the glass effect in the background of a borderless window? If so (and I believe it to be), how is this done?

首先,是否可以在无边框窗口的背景中使用玻璃效果?如果是这样(我相信是这样),这是如何完成的?

Additionally, since Windows 8 and newer no longer use the translucent glass effect, can this still be done on those operating systems?

此外,由于 Windows 8 和更新版本不再使用半透明玻璃效果,在这些操作系统上还能这样做吗?

2. Keeping Native Blur Effect without Glass

2. 在没有玻璃的情况下保持原生模糊效果

I want the smooth native DWM blur effect, but I don't want the glossy glass overlay, and I don't want the window color predefined in the user's theme settings.

我想要平滑的原生 DWM 模糊效果,但我不想要有光泽的玻璃覆盖,而且我不想要在用户主题设置中预定义的窗口颜色。

3. Customizing Blur Radius and Location

3.自定义模糊半径和位置

Is it possible to only apply this effect to a certain portion of the window? More importantly, is it possible to adjust the intensity (radius) of the blurring effect?

是否可以仅将此效果应用于窗口的特定部分?更重要的是,是否可以调整模糊效果的强度(半径)?

EDIT - Screenshot Examples

编辑 - 截图示例

By request, I have posted some examples of the effect I wish to achieve.

根据要求,我已经发布了一些我希望达到的效果的例子。

Current Program

当前程序

The image above is an actual screenshot of my WPF application (still in the works). Its minimalist design relies heavily on animation of movement and window resizing.

上图是我的 WPF 应用程序的实际屏幕截图(仍在制作中)。其极简设计在很大程度上依赖于移动动画和窗口大小调整。

Blurred Program

程序模糊

Using some photoshop skills, I've rendered the image above, demonstrating the effect I want to create, exactlythe way I want it. Note the following:

使用一些Photoshop技巧,我渲染了上面的图像,展示了我想要创建的效果,完全按照我想要的方式。请注意以下事项:

  • The blur has a much higher radius (intensity) than usual Aero blurring effects
  • The blur is only visible on one portion of the windows
  • The blur does not inherit its color from the green color theme of the desktop
  • 模糊具有比通常的航空模糊效果高得多的半径(强度)
  • 模糊仅在窗口的一部分上可见
  • 模糊不会从桌面的绿色主题继承其颜色

回答by Tom

1. Applying Aero Glass to Borderless Window

1. 将 Aero Glass 应用于无边窗

Since what you are trying to achieve is not so much a glass effect but more of a transparent+blur you can use the following methods to blur behind the window.

由于您要实现的不是玻璃效果,而是更多的透明+模糊,因此您可以使用以下方法在窗口后面进行模糊处理。

Windows 7: you can use DwmEnableBlurBehindWindowto blur behind the window.

Windows 7:您可以使用DwmEnableBlurBehindWindow在窗口后面进行模糊处理。

Window 8: I havn't found a workable solution since DwmEnableBlurBehindWindow was removed in Windows 8.

Window 8:我没有找到可行的解决方案,因为 DwmEnableBlurBehindWindow 在 Windows 8 中被删除。

Windows 10: you can use SetWindowCompositionAttributeto blur behind the window.

Windows 10:您可以使用SetWindowCompositionAttribute在窗口后面进行模糊处理。

2. Keeping Native Blur Effect without Glass

2. 在没有玻璃的情况下保持原生模糊效果

The above solutions will only apply a blur effect behind the window, it will be up to the window to define transparency and colour.

上述解决方案只会在窗口后面应用模糊效果,由窗口来定义透明度和颜色。

3. Customizing Blur Radius and Location

3.自定义模糊半径和位置

With these approaches you can only blur underneath the entire window, and it will be up to you to use an alpha channel on portions of the window you want to be transparent. I don't think you can define the blur radius either.

使用这些方法,您只能在整个窗口下方进行模糊处理,您可以在要透明的窗口部分上使用 Alpha 通道。我认为您也无法定义模糊半径。

回答by Fraser Muir

My Excuse

我的借口

Pardon my inexperience with Stackoverflow but I thought I would try and help you out a little.

请原谅我对 Stackoverflow 的缺乏经验,但我想我会尝试帮助你一点。

By following the link posted by Tom I was able to come across this block of code (originally in c#). So seen as how this code isn't readily availible to most people, here it is:

通过遵循 Tom 发布的链接,我能够遇到此代码块(最初在 c# 中)。因此,对于大多数人来说,这段代码并不容易获得,这里是:

Imports System.Runtime.InteropServices
Imports System.Windows.Interop
'Import namespace ("name of project" . "name of namespace")
Imports Blurred_Opacity.BlurBehind

Namespace BlurTest
    Enum AccentState
        ACCENT_DISABLED = 0
        ACCENT_ENABLE_GRADIENT = 1
        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2
        ACCENT_ENABLE_BLURBEHIND = 3
        ACCENT_INVALID_STATE = 4
    End Enum

    Structure AccentPolicy
        Public AccentState As AccentState
        Public AccentFlags As Integer
        Public GradientColor As Integer
        Public AnimationId As Integer
    End Structure

    Structure WindowCompositionAttributeData
        Public Attribute As WindowCompositionAttribute
        Public Data As IntPtr
        Public SizeOfData As Integer
    End Structure

    Enum WindowCompositionAttribute
        WCA_ACCENT_POLICY = 19
    End Enum
End Namespace

Class MainWindow
    <DllImport("user32.dll")>
    Friend Shared Function SetWindowCompositionAttribute(hwnd As IntPtr, ByRef data As WindowCompositionAttributeData) As Integer
    End Function

    Sub Window_Loaded() handles me.loaded
        EnableBlur()
    End Sub
    Sub Window_MouseDown() handles me.MouseLeftButtonDown
        DragMove()
    End Sub

    Sub EnableBlur()
        Dim windowHelper = New WindowInteropHelper(Me)
        Dim accent = New AccentPolicy()
        accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND
        Dim accentStructSize = Marshal.SizeOf(accent)
        Dim accentPtr = Marshal.AllocHGlobal(accentStructSize)
        Marshal.StructureToPtr(accent, accentPtr, False)
        Dim Data = New WindowCompositionAttributeData()
        Data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY
        Data.SizeOfData = accentStructSize
        Data.Data = accentPtr
        SetWindowCompositionAttribute(windowHelper.Handle, Data)
        Marshal.FreeHGlobal(accentPtr)
    End Sub
End Class

Result

结果

Once implemented, this will effect the whole Window as shown:

一旦实施,这将影响整个窗口,如下所示:

Whole window is blurred

整个窗口都模糊了

After a little tweaking

稍加调整后

After about 5 mins of trying to copy your design I came up with this:

在尝试复制您的设计大约 5 分钟后,我想出了这个:

Final Window

最终窗口

XAML

XAML

I'm sure you could do a better job of the design than I have. It is possible to change the blend colour simply by adjusting the background colour (on the window), and the opacity level can also be changed. The XAML of my design is as follows:

我相信你可以比我做得更好。可以简单地通过调整背景颜色(在窗口上)来更改混合颜色,也可以更改不透明度级别。我设计的XAML如下:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow"
    Title="Blurred Opacity" Height="623" Width="752"
    Background="#727A7A7A"
    AllowsTransparency="True"
    WindowStyle="None"
    BorderThickness="1"
    WindowStartupLocation="CenterScreen"
    Loaded="Window_Loaded" MouseLeftButtonDown="Window_MouseDown" Topmost="True" BorderBrush="#FF1E9EC5">
<Grid>
    <Rectangle Fill="#FF0143A4" Height="130" VerticalAlignment="Top"/>
    <Rectangle Fill="White" Margin="0,130,0,0" HorizontalAlignment="Right" Width="375"/>
    <StackPanel HorizontalAlignment="Left" Margin="0,130,0,0" Width="375">
        <TextBlock x:Name="textBlock" Height="50" TextWrapping="Wrap" Text="Category 1" d:LayoutOverrides="LeftPosition, RightPosition" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6"/>
        <TextBlock x:Name="textBlock_Copy" Height="50" TextWrapping="Wrap" Text="Category 2" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy1" Height="50" TextWrapping="Wrap" Text="Category 3" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy2" Height="50" TextWrapping="Wrap" Text="Category 4" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy3" Height="50" TextWrapping="Wrap" Text="Category 5" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy4" Height="50" TextWrapping="Wrap" Text="Category 6" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy5" Height="50" TextWrapping="Wrap" Text="Category 7" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy6" Height="50" TextWrapping="Wrap" Text="Category 8" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
    </StackPanel>
    <TextBlock x:Name="textBlock_Copy7" Height="90" TextWrapping="Wrap" Text="Example" FontSize="65" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" Margin="222.5,23,152.5,0" VerticalAlignment="Top" Foreground="White"/>
    <Path Data="M705,27.333333 L735.66667,10" Fill="White" HorizontalAlignment="Right" Height="24" Margin="0,7,21,0" Stretch="Fill" VerticalAlignment="Top" Width="24" StrokeThickness="3" Stroke="White"/>
    <Path Data="M705,27.333333 L735.66667,10" Fill="White" HorizontalAlignment="Right" Height="24.083" Margin="0,6.833,20.333,0" Stretch="Fill" VerticalAlignment="Top" Width="24.167" StrokeThickness="3" Stroke="White" RenderTransformOrigin="0.5,0.5">
        <Path.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="-1"/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform/>
            </TransformGroup>
        </Path.RenderTransform>
    </Path>
    <StackPanel HorizontalAlignment="Right" Margin="0,130,0,0" Width="375">
        <TextBlock x:Name="textBlock1" Height="50" TextWrapping="Wrap" Text="Item 1" d:LayoutOverrides="LeftPosition, RightPosition" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6"/>
        <TextBlock x:Name="textBlock_Copy8" Height="50" TextWrapping="Wrap" Text="Item 2" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"/>
        <TextBlock x:Name="textBlock_Copy9" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="3"/><LineBreak/><Run Text="3"/></TextBlock>
        <TextBlock x:Name="textBlock_Copy10" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="4"/></TextBlock>
        <TextBlock x:Name="textBlock_Copy11" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="5"/></TextBlock>
        <TextBlock x:Name="textBlock_Copy12" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="6"/></TextBlock>
        <TextBlock x:Name="textBlock_Copy13" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="7"/></TextBlock>
        <TextBlock x:Name="textBlock_Copy14" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="8"/></TextBlock>
        <TextBlock x:Name="textBlock_Copy15" Height="50" TextWrapping="Wrap" FontSize="35" Padding="10,0,0,0" TextOptions.TextFormattingMode="Display" LineHeight="6" d:LayoutOverrides="LeftPosition, RightPosition"><Run Text="Item "/><Run Text="9"/></TextBlock>
    </StackPanel>
</Grid>

I hope this helps!

我希望这有帮助!