WPF 半透明 模糊效果 Aero效果(1)

先看看效果图

 

 

目前网上找到了2种实现方式,一种是 .NET Framework4.5及以后有自带的 WindowChrome 效果,一种是 WindowsAPI  dwmapi.dll  ,但这两种在win10下面都会失效。win10如何实现在下一篇讲。

1.WindowChrome 效果设置较为简单,代码如下。WindowChrome更多用法可以查阅官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.shell.windowchrome?view=netframework-4.7.2

 

<Window x:Class="WpfApp1.Window1"
        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"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="Window1" Height="300" Width="300" Background="Transparent" WindowStartupLocation="CenterScreen">

    <WindowChrome.WindowChrome>
        <WindowChrome  GlassFrameThickness="-1"/>
    </WindowChrome.WindowChrome>

    <Grid>
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBlock FontSize="40" TextAlignment="Center">
                Hello Wolrd
            </TextBlock>
            <TextBlock FontSize="12" TextAlignment="Center" Margin="0,30,0,0">使用 WindowChrome 实现模糊透明</TextBlock>
        </StackPanel>
    </Grid>
</Window>

 

 

2.调用 dwmapi.dll API

页面代码:

<Window x:Class="WpfApp1.Window2"
        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"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="Window2" Height="300" Width="300" WindowStartupLocation="CenterScreen">
    <Grid>
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBlock FontSize="40" TextAlignment="Center">
                Hello Wolrd
            </TextBlock>
            <TextBlock FontSize="12" TextAlignment="Center" Margin="0,30,0,0">使用 Windows 的 dwmapi 实现模糊透明</TextBlock>
        </StackPanel>
    </Grid>
</Window>

 

后端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Window2.xaml 的交互逻辑
    /// </summary>
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MARGINS
        {
            public MARGINS(Thickness t)
            {
                Left = (int)t.Left;
                Right = (int)t.Right;
                Top = (int)t.Top;
                Bottom = (int)t.Bottom;
            }
            public int Left;
            public int Right;
            public int Top;
            public int Bottom;
        }


        [DllImport("dwmapi.dll", PreserveSig = false)]
        private static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
        [DllImport("dwmapi.dll", PreserveSig = false)]
        private static extern bool DwmIsCompositionEnabled();

        /// <summary>
        /// win7
        /// </summary>
        /// <param name="window"></param>
        /// <param name="margin"></param>
        /// <returns></returns>
        public static bool ExtendGlassFrame(Window window)
        {
            if (!DwmIsCompositionEnabled())
                return false;

            IntPtr hwnd = new WindowInteropHelper(window).Handle;
            if (hwnd == IntPtr.Zero) throw new InvalidOperationException("The Window must be shown before extending glass.");

            // 将WPF和Win32透视图的背景设置为透明
            window.Background = Brushes.Transparent;
            HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

            MARGINS margins = new MARGINS(new Thickness(-1));
            DwmExtendFrameIntoClientArea(hwnd, ref margins);
            return true;
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            ExtendGlassFrame(this);
        }
    }
}

 

这两种都能实现透明模糊效果(win7下),但都各自有各自的特点,WindowChrome 的窗口内容都需要自行设置,细心看两个窗口就会发现WindowChrome 的窗口标题都没了,标题高度,边距,调整窗口大小的作用范围等,什么都可以自定义,自我感觉比较难调(可能只是因为我菜),比较适合做自定义窗口,标题栏自定义,标题栏上面还可以加其他按钮,可以隐藏系统标题栏上面的按钮,还有个特点是程序启动时立即生效,dwmapi.dll 会有一个加载的延迟,使用 dwmapi.dll 则窗口内容标题等都是保留原始窗口的内容。

 

posted @ 2020-07-30 16:32  ~木木~  阅读(1983)  评论(0编辑  收藏  举报