zoukankan      html  css  js  c++  java
  • 玻璃界面实现原理

      目前国内的非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:为了避免每次重绘,应该将内存位图保留,以后直接刷到窗体

  • 相关阅读:
    【转】js竖状伸缩导航
    大学易站暂时关闭通知
    【转】神同步!这俩熊孩子太会玩了,以前的同步都弱爆了
    【技术贴】搜狗浏览器 标签页 看后吧 解决
    四级查分步骤解决无法找到对应的分数 请确认你已安装并启动了CET查分保护盾
    解决Mysql远程连接出错不允许访问 ERROR 1130:Host is not allow
    xml 获取节点下的 属性。
    Oracle 获取日期区间数据
    js 数值转换为3位逗号分隔
    xml获取子节点
  • 原文地址:https://www.cnblogs.com/asight/p/2218517.html
Copyright © 2011-2022 走看看