转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/43532791

半透明异形窗体的功能在之前维护的老版本的duilib里面已经有了基本的功能,但是因为一直存在较多的缺陷,所以我一直建议少用,就连我自己写仿酷狗项目也只是在几个小地方用了半透明异形窗体。不过今天在群里和其他几位朋友讨论后,发现了之前的许多问题以及解决方法。所以我立马修复了当前的库,并且写了一个半透明异形窗体的demo来测试效果。这里的半透明窗体是用UpdateLayeredWindow函数实现的,并不是双层窗体。

总体来说,为了给官方原本的duilib391版本库增加窗体半透明异形功能,需要修改的类如下:

1、CManagerUI类的WM_PAINT消息处理代码

2、CRenderEngine类的文字渲染函数、和背景填充函数、贴图函数

3、CEditUI类的win32 edit创建函数

4、CRichEditUI类的光标绘制函数(自绘光标,需要结合CManagerUI类的相关代码)

5、给CManagerUI类增加自绘CRichEditUI光标的一系列函数

6、处理窗体类的最小化还原小(需要结合CManagerUI类的相关代码)

7、给CManagerUI类增加最小化还原后的消息处理代码,为了在半透明状态下完全刷新窗体

在这篇博客里,我主要说明一下一下几点:

1、之前版本使用半透明异形窗体存在的一些问题

2、新版本里的大致解决方法

3、还没有完全解决的地方

4、使用半透明异形窗体应该注意的地方

废话不多说,先把demo的效果图展示一下:

     

存在的问题和解决办法:


       问题1:字体穿透 

这是之前的半透明窗体的最大问题,由于GDI本身的缺陷,导致渲染文字时缺少透明通道信息,导致文字穿透,之前使用heat群主的alpha修复方法,但是还不能完全解决这个问题。为此我把文字渲染函数修改。当窗体是透明模式或者用户开启了gdi+文字渲染模式,就用gdi+来渲染文字。开启半透明模式的方法是设置xml布局的Window标签的bktrans属性为true。开启gdi+文字渲染模式的方法是设置xml布局的Window标签的gdiplustext属性为true。bktrans属性和gdiplustext属性是独立的。(如果感觉默认的GDI文字渲染效果不够好时,就可以使用gdiplustext属性得到更好的渲染效果)。

GDI+的渲染效率是出名的低,不过据我测试文字渲染才用GDI+的话看不出影响效率。

问题2:字体穿透2

还是字体穿透的文字,即使把文字渲染改成gdi+再配合alpha修复,但是依然发现会出现字体穿透的问题,这也是之前让我纳闷的地方。而今天我做了许多测试后发现,原来和控件的背景色有关。如果不设置控件的背景色或者背景色是半透明的,渲染文字就不会穿透,而设置了背景色而且不透明就会穿透,背景色填充是CRenderEnghine类的DrawColor函数负责的。观察源码后发现。如果背景色的透明度设置为FF(也就是不透明)的话,就会使用GDI函数来填充背景色,而如果设置了透明度,则使用AlphaBlend函数来使用一个位图来填充背景。所以问题还是出在透明通道上(说明alpha修复还不能完全解决相关的问题)。

所以只要让duilib填充背景色时包含透明信息就不会导致穿透了,而后阅读代码发现duilib默认的alpha背景色填充代码比较多。我个人感觉不如直接用gdi+来填充背景色。代码如下:

    if( color <= 0x00FFFFFF ) return;Gdiplus::Graphics graphics( hDC );Gdiplus::SolidBrush brush(Gdiplus::Color((LOBYTE((color)>>24)), GetBValue(color), GetGValue(color), GetRValue(color)));graphics.FillRectangle(&brush, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);

这个代码比较简单,应该不会影响效率吧?

问题3:窗体刷新不完整

原来的库编译的半透明异形程序,有时会出现窗体刷新不完整的情况,比如:把一个半透明程序的一般拖到屏幕外侧,然后双击标题栏让他最大化,接着再最小化,然后把程序再拖到屏幕内,就会发现原来在屏幕外部的界面完全没有绘制出来。

导致这个问题的原因,是因为要使用异形窗体就需要使用UpdateLayeredWindow函数,而使用了这个函数后窗体的绘制就由UpdateLayeredWindow来接管了,许多情况下WM_PAINT消息就不会触发。跟踪代码后发现是因为程序还原后调用GetUpdateRect函数获取更新区域信息时信息不完整导致的。所以我在CManagerUI类中拦截了WM_SYSCOMMAND消息,发现程序从最大化还原后就设置m_bIsRestore为真,把m_bIsRestore作为标志。当在WM_PAINT中刷新界面时如果m_bIsRestore为真则刷新整个程序界面而不只是GetUpdateRtect获取的区域。另外我添加了m_rcInvalidate变量,来自己管理需要更新到区域,拟补GetUpdateRect函数获取信息不足的问题。

还没有完全解决的地方


前面说明的一些问题解决后,配合alpha修复的代码。基本就可以使用半透明异形窗体了。不过还是存在一些没有解决的问题:

1、半透明模式下Edit控件的效果不好。duilib的Edit控件内部调用了Win32的edit控件,为了在半透明模式下使用它,不得不使用WS_POPUP样式窗体Win32的edit控件。但是这样窗体后会在外观上出现一些问题。就是单击duilib的Edit控件时会闪一下。所以建议使用RichEdit控件来代替Edit,而且RichEdit控件是支持半透明或者全透明背景的。

2、RichEdit控件虽然可以正常使用,但是由于他内部渲染文字时没有处理透明通道,所以会导致文字穿透。出现文字穿透的现象只有在RichEdit控件完全无背景色或者背景图片的情况下。

使用半透明异形窗体应该注意的地方


目前需要注意的就是RichEdit控件的使用,如果让RichEdit直接暴露在全透明的地方,文字渲染就会有问题。如果RichEdit设置了背景色或者背景色,或者他的父控件设置了背景色背景图,则全完没有问题。不过好在,应该没有什么地方需要让RichEdit直接暴露在全透明的位置。前面发的效果图的文本框就是用RichEdit做的。

如果使用RichEdit的时候发现了穿透现象,建议更换textcolor的值或者bkcolor的值来修复问题。


总结:

由于这次修改的地方比较多,设计的文件和代码也比较乱,我就没办法单独的提供某个源文件了。具体的修改可以通过svn来对比新版本和旧版本的代码来得知。源码和demo我都更新到了我的库中,支持duilib和uilib:点击打开链接

Redrain  2015.2.5 

使用duilib开发半透明异形窗体程序(附源码和demo)相关推荐

  1. duilib设置透明窗口_使用duilib开发半透明异形窗体程序(补充)

    距离上一篇半透明窗体的博客,已经过去一年,现在这几天又对Duilib进行了一些优化和修复.这次我把CRenderEngine的渲染函数都改成了基于Gdi+的.根据我的测试,因为Duilib所需的都是最 ...

  2. C#中实现视频播放器窗体程序(附源码下载)

    场景 效果 实现 新建窗体程序,然后从工具箱中拖拽DataGridView控件,然后在控件右上角点击新增列,设置好每列 的Name属性和Headertext属性. 新建Video类 项目-右击-新增- ...

  3. 用ionic快速开发hybird App(已附源码,在下面+总结见解)

    用ionic快速开发hybird App(已附源码,在下面+总结见解) 1.ionic简介 ionic 是用于敏捷开发APP的解决方案.核心思路是:利用成熟的前端开发技术,来写UI和业务逻辑.也就是说 ...

  4. python 开发视频播放网站_python开发微电影视频网站教程附源码

    做为一个合格的Pythoner,只掌握一个框架是不够,如果你有过其它Python框架(例如django)的使用经验,对比不同框架的特性来学习,你将收获更多 当前信息若含有黄赌毒等违法违规不良内容,请点 ...

  5. 关于美团:零基础搭建获利的美团饿了么优惠券CPS小程序附源码

    关于美团:零基础搭建获利的美团饿了么优惠券CPS小程序附源码 下面是无裂变版本的搭建教程. 源码地址:http://y.mybei.cn 部署步骤 部署后台,填资料 登录后台 http://q.myb ...

  6. 手把手教你搭建美团饿了么电影票外卖cps小程序 附源码

    手把手教你搭建美团饿了么电影票外卖cps小程序 附源码 外卖红包项目的优势 1.刚需:吃饭是每日刚需,尤其是城市白领,上班族,宅男宅女,等群体点外卖的需求,需求更是高频率(每天). 2.门槛低:平台门 ...

  7. arcgis开发 多版本之间如何兼容_arcgis api 4.x for js 结合 react 入门开发系列初探篇(附源码下载)...

    你还在使用 JQuery 或者 Dojo 框架开发 arcgis api 4.x for js 吗?想试试模块化开发吗?随着前端技术的发展,arcgis api 4.x for js 也有了结合 re ...

  8. 基于C++开发的仓库管理系统(附源码)

    基于C++开发的仓库管理系统(附源码) 一.简介 1.开始菜单 2.登录后的菜单 二.C++代码 main.cpp   一.简介   仓库管理系统的功能有登录.注册.查询功能.入库功能.出库功能.添加 ...

  9. 世界上最短的DVD解码程序(附源码) (转)

    世界上最短的DVD解码程序(附源码) (转)[@more@] 前些天麻省理工学院的两位学生编写出世界上最短的 dvd解码 程序,而这个纪录最近被一位名为Charles M Hannum的程序员打破,他 ...

最新文章

  1. Fine-tune之后的NLP新范式:Prompt越来越火,CMU华人博士后出了篇综述文章
  2. UTL_FILE包用法小记
  3. html除左侧浮动,html清除浮动的6种方法示例
  4. 成为奥运冠军需要天赋和努力
  5. Django之模板层
  6. 如何更好的理解用户反馈? | 上
  7. 常用简体汉字unicode编码(3500个)
  8. 基于Scrapy的IP代理池搭建
  9. tomcat6\webapps\manager does not exist or is not a readable directory
  10. 大量数据导出Excel方案
  11. Payload Inject And Fake
  12. SPI的模拟应用——OLED以及时钟模块的应用(一)SPI协议介绍及利用协议实现两机通信(51单片机)
  13. Tensorflow安装过程的一些问题及解决办法
  14. 51“motorrr”寻迹小车学习1电机和寻迹模块
  15. antd vue 多个下拉 联动_antd中select下拉框值为对象选中的问题
  16. 网卡驱动编写必读-重要概念 分享
  17. 一文带你深入浅出C语言数据
  18. 屏幕一直显示android,lenovo!屏幕一直显示poweredbyandroid是什么意思
  19. java1-100猜数字代码(生成1-100随机数限制猜数字次数)简单好懂
  20. 电脑怎么进行磁盘碎片整理?

热门文章

  1. 学法减分小程序可用可运营源码附带安装教程
  2. 新版知识付费系统付费阅读小程序源码知识付费平台
  3. Linux中7个用来浏览网页和下载文件的命令
  4. Linux: 传参数给alias
  5. JavaScript输入输出
  6. redis——redis事务相关处理
  7. 全排列及相关扩展算法(七)——组合数的字典序(另含全章代码整理)
  8. 系统接口规范以及常见的接口技术概述和比较
  9. 【今日CV 计算机视觉论文速览 第111期】Fri, 3 May 2019
  10. 【今日CV 计算机视觉论文速览】Thu, 7 Mar 2019