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

  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/asight/p/2218517.html
Copyright © 2011-2022 走看看