目前国内的非Aero玻璃窗体实现,效果最好的是酷狗7,我机子上QQ的玻璃效果比较差,有强反差的杂色,鄙视之。2年前还在找玻璃控件,感觉那些人真是太厉害了,下载还用不了,一直很遗憾,但现在看来那些东西也没什么。因为最开始是用vc#的,窗体消息和窗体绘制被掩盖了,所以接触不到底层原理,vc#也不适合做界面,控制力度太弱小了。今年敷衍了一下MFC基础就开始编码,毕竟有win api基础和c#基础用起MFC还是比较简单的。

  SetLayeredWindowAttribute单窗体太简单了就不说了,有2个特性,全窗体透明度和透明色。UpdateLayeredWindow将当前窗体托管给系统,只提供一个位图HDC,不可以有控件,不接受WM_PAINT消息。所以透明界面的基本原理就是UpdateLayeredWindow跟SetLayeredWindowAttribute结合,codeproject有最早的实现代码。

  窗体在绘制之前必须是WS_EX_LAYERED风格,可以在OnInitXXX里面添加,可以直接可视化设置Layered风格属性,Update*窗体我称为透明窗体,SetLayered*窗体我称为面具窗体。透明窗体之所以透明是因为它有很小的alpha,加上很薄的颜色就像玻璃一样,填充的时候,应该使用Gdiplus::GraphicsPath,其他填充导致鼠标穿透,这个是我目前知道的唯一可以解决非WS_EX_TRANSPARENT窗体而鼠标却穿透的问题,我的实现方式如下。

  玻璃窗体。双层闭合的GraphicsPath路径,填充外部路径会忽略内部路径,因此这个特性用来做窗体阴影再好不过了,我用2层圆角矩形Path实现外圈阴影和内部的低alpha颜色的背景,这样玻璃效果就做好了,Gdiplus+UpdateLayeredWIndow实现。

  面具窗体。显示界面之前需要设置WS_EX_LAYERED风格,SetLayeredWindowAttributes设置一个透明色,使得窗体背景总是透明,但是不影响上面的控件使用,然后在玻璃窗体中初始化这个面具窗体就实现了玻璃界面。下面是截图:

原理图:(来自国外某小站)

酷狗7:

我实现的:

当然控件选择自绘控件或者DirectUI肯定会美观很多,这里只用系统风格控件示范。

 

  小结:目前双窗体玻璃界面的理论已经出来很久了,跟上面的实现原理差不多,这篇文章主要是经验之谈,大神们的作品都在codeproject摆着,废代码多,看着费力,好处是很完整,都可以编译。   我还用单窗体实现了一个假玻璃UI,可以显示控件,而窗体是完全透明了,可以认为不存在,边框需要自绘一下,效果和控制力跟上面的完全不在一个档次,但是实现极为简单,重载OnCtlColor(...)直接返回空刷子 return (HRBUSH)::GetStockObject(NULL_BRUSH)。窗体不可见控件可见,并且可以接受鼠标事件。只能画线,不可以填充不可以用GraphicsPath。给个截图吧

tips:为了避免每次重绘,应该将内存位图保留,以后直接刷到窗体

posted on 2011-10-20 09:31  asight  阅读(2876)  评论(1编辑  收藏  举报