无边框WPF窗口上的本机Aero模糊效果但不带玻璃特效

12

我知道类似的问题已经被问答过。然而,我的问题分为三个部分。

针对这个问题,请记住以下几点:

  • 我是一名业余的、刚上大学的计算机科学专业本科生。我对复杂编程方面不太熟练,但我可以理解大多数术语。
  • 这是一个使用VB.NET在Visual Studio中创建的WPF项目,但由于这两种语言相似,我同样轻松地阅读C#。
  • 这是我第一次尝试任何DWM API。

1. 将Aero Glass应用于无边框窗口

首先,能否在无边框窗口的背景中使用玻璃效果?如果可以(我相信可以),那么如何做到这一点?

此外,由于Windows 8及更高版本不再使用半透明玻璃效果,这在这些操作系统上是否仍然可行?

2. 保留本地模糊效果而不使用玻璃

我想要流畅的本地DWM模糊效果,但我不想要光泽的玻璃叠加层,也不想让窗口颜色预定义为用户主题设置。

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

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

编辑 - 屏幕截图示例

根据请求,我已经发布了一些我希望实现的效果示例。

当前程序

上面的图片是我WPF应用程序的实际屏幕截图(仍在建设中)。其极简设计非常依赖于运动和窗口大小调整的动画效果。

模糊程序

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

  • 模糊效果的半径(强度)比通常的Aero模糊效果要高得多
  • 模糊效果只在窗口的一部分可见
  • 模糊效果不会继承桌面绿色主题的颜色

1
是的,但只有我问题的第一部分可以被视为重复;后面的部分需要回答可能会改变所需的方法,这些方法与您发布的问题不同,因此整个问题将导致不同的解决方案。这是一个不同于您发布的问题:我只想要本地模糊,我不想要玻璃效果。 - Tommy Crews
你能否发布一张你想要实现的屏幕截图? - vesan
已发布屏幕截图。希望这有所帮助! - Tommy Crews
请求@marcesosa:我很喜欢这个项目,但我不知道该如何实现它!您能否请附上您的可视化项目以供下载?谢谢。 - Ralf Stubner
2个回答

15

1. 应用Aero Glass到无边框窗口

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

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

Windows 8: 由于DwmEnableBlurBehindWindow在Windows 8中被移除,我没有找到可行的解决方案。

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

2. 保留本地模糊效果而无需玻璃效果

以上解决方案将仅对窗口后面应用模糊效果,窗口定义透明度和颜色。

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

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


8

我的借口

抱歉,我在Stackoverflow上的经验不足,但我想尝试为您提供一些帮助。

通过跟随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

结果

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

整个窗口都是模糊的

稍作调整后

经过约5分钟的尝试,我尝试复制您的设计,并得出了以下结果:

最终窗口

XAML

我相信您可以比我做得更好。可以通过调整背景颜色(在窗口上)来更改混合颜色,还可以改变不透明度水平。我的设计的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>

我希望这可以帮助你!


不错,但这只适用于Win7并基于操作系统设置。我正在寻找着色器效果,以便在任何Windows上(包括Citrix Receiver的服务器)使用我的自定义颜色和设置来制作类似的东西。 - Dmitry Gusarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接