Win10下的Blur(Aero玻璃效果)用c#实现完整方案
金坷居士2016/04/21软件综合 IP:澳大利亚
在Win10中Aero回来了,不过这次的Aero默认没有给窗口用,因为Aero实现似乎不在DWM中,而在User32中
这是效果图,做的丑了点
QQ图片20160421232604.png


为了为咱们的窗体启用Blur,需要调用一个Undocumented的API,它接受窗口句柄和1个结构体,结构体里有一些迷之参数
其实我也说不太清楚里面都是什么东西,主要是参考了Github上面的代码
主要的代码如下:
public static void EnableBlur(IntPtr HWnd, bool hasFrame = true)
      {
 
          AccentPolicy accent = new AccentPolicy();
          accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
          if (hasFrame)
              accent.AccentFlags = 0x20 | 0x40 | 0x80 | 0x100;
 
          int accentStructSize = Marshal.SizeOf(accent);
 
          IntPtr accentPtr = Marshal.AllocHGlobal(accentStructSize);
          Marshal.StructureToPtr(accent, accentPtr, false);
 
          WindowCompositionAttributeData data = new WindowCompositionAttributeData();
          data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
          data.SizeOfData = accentStructSize;
          data.Data = accentPtr;
 
          WinAPI.SetWindowCompositionAttribute(HWnd, ref data);
 
          Marshal.FreeHGlobal(accentPtr);
      }


可以在WinForm的Load里调用:
BackColor = Color.Black;
Win10Style.EnableBlur(this.Handle);
这样确实能让Blur出来,不过如果在上面放一个按钮就马上发现问题了,按钮的字的部分也是透明的
经过研究,是由于控件不支持alpha通道的原因
于是在这里卡了几天,之后看到一个用UpdatedLayeredWindow的解决方法,实际是创建了一个窗体充当背景,我觉得这样太蛋疼
借用了一些里面的代码
首先给WinForm加上WS_EX_LAYERED属性,这样就是多层窗体了,不过这样就会发生个问题,上面的控件都不显示了,不过点击却有反应,很神奇!
查了下需要用UpdatedLayeredWindow手动绘制窗口上面的内容...
相关代码在LayeredWindowHelper.cs里,比较长,就不贴了
原理其实也不难,就是遍历窗口上的所有控件,把它们都画到一个内存位图中,这个位图带有alpha通道,能正确被显示
最后的调用方法如下:
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cParms = base.CreateParams;
                cParms.Style |= Constants.WS_SYSMENU;
                cParms.ExStyle |= Constants.WS_EX_LAYERED;
                return cParms;
            }
        }
 
        public Form1()
        {
            InitializeComponent();
 
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            (new LayeredWindowHelper(this)).BackColor = Color.FromArgb(128, Win7Style.GetThemeColor());
            Win7Style.EnableBlurBehindWindow(this.Handle);
            Win10Style.EnableBlur(this.Handle);
        }

我这种解决方案还是有点问题:
第一,窗口的OnPaint失效,只能在LayeredWindowHelper.cs 77行的位置加入原本在OnPaint那里的代码
第二,某些控件不能用,比如WebBrowser,这种的,只能弄第二个窗体,把WebBrowser放在上面


Win7Style.EnableBlurBehindWindow(this.Handle);
这行是在Win7\Vista下开Aero的,下面的是在Win10下开的
两个同时开,程序在Vista 7 10下都有Aero效果,不过在xp和8中只有半透明效果


程序还附带了一个轻量级的我封装的代码库,有一些.net库没提供的东西,比如vista的TaskDialog,在Win10下正确获取系统版本的库等
源码和程序下载地址:
attachment icon BlurTest.zip 150.78KB ZIP 581次下载

程序使用的几乎全部是Win32 API,Native C++和WPF等也能够实现的哦
来自:计算机科学 / 软件综合
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
acmilan
8年3个月前 修改于 8年3个月前 IP:四川
826999
好像这个不能开WS_SIZEBOX,不然上边一直有一块蓝条去不掉。。。

开不开Win8式粗边框也是问题,不开放到纯色上边就看不见了,开了又和原窗口大小不同了。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
金坷居士
学者 机友 笔友
文章
170
回复
1711
学术分
11
2011/09/23注册,4个月7天前活动

怪哉!灵异的三极管电流流向! 这素一个在仿真的RCC电路,示波器上绿色的是集电极电流红色的是发射极电流。窝萌都知道发射姬电流素集电极电流和基极电流之和,所以讲道理发射极电流一定比集电极略大。可仿真结果刷了三观,Q1集电极电流一部分流经基极,然后流经Q2的C->E。

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}