在Win10中Aero回来了,不过这次的Aero默认没有给窗口用,因为Aero实现似乎不在DWM中,而在User32中
这是效果图,做的丑了点
为了为咱们的窗体启用Blur,需要调用一个Undocumented的API,它接受窗口句柄和1个结构体,结构体里有一些迷之参数
其实我也说不太清楚里面都是什么东西,主要是参考了Github上面的代码
主要的代码如下:
<code class="lang-c">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);
}</code>
可以在WinForm的Load里调用:
BackColor = Color.Black;
Win10Style.EnableBlur(this.Handle);
这样确实能让Blur出来,不过如果在上面放一个按钮就马上发现问题了,按钮的字的部分也是透明的
经过研究,是由于控件不支持alpha通道的原因
于是在这里卡了几天,之后看到一个用UpdatedLayeredWindow的解决方法,实际是创建了一个窗体充当背景,我觉得这样太蛋疼
借用了一些里面的代码
首先给WinForm加上WS_EX_LAYERED属性,这样就是多层窗体了,不过这样就会发生个问题,上面的控件都不显示了,不过点击却有反应,很神奇!
查了下需要用UpdatedLayeredWindow手动绘制窗口上面的内容...
相关代码在LayeredWindowHelper.cs里,比较长,就不贴了
原理其实也不难,就是遍历窗口上的所有控件,把它们都画到一个内存位图中,这个位图带有alpha通道,能正确被显示
最后的调用方法如下:
<code class="lang-c"> 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);
}</code>
我这种解决方案还是有点问题:
第一,窗口的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下正确获取系统版本的库等
源码和程序下载地址:
BlurTest.zip
150.78KB
ZIP
577次下载
程序使用的几乎全部是Win32 API,Native C++和WPF等也能够实现的哦