转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/51250537
关于半透明异形窗体的第一篇文章地址为:http://blog.csdn.net/zhuhongshu/article/details/43532791。
距离上一篇半透明窗体的博客,已经过去一年,现在这几天又对Duilib进行了一些优化和修复。这次我把CRenderEngine的渲染函数都改成了基于Gdi+的。根据我的测试,因为Duilib所需的都是最基本绘制功能,所以用Gdi+并不影响效率,同时又补充了alpha通道,让半透明异形窗体更完善。但是同时我保留了原Gdi渲染函数。通过USE_GDI_RENDER宏来控制是否使用Gdi渲染,默认使用Gdi+。
除了修改CRenderEngine,另外优化了CPaintManagerUI的WM_PAINT处理代码。针对分层窗体的alpha修复代码进行了修复,使用Gdi或者Gdi+渲染会使用不同的修复策略。
使用Gdi渲染时,因为界面整体都需要补充alpha通道,所以就遍历了整体的内存位图去补充。
使用Gdi+渲染时,因为本身就已经存在alpha通道,所以就只需要修补RichEdit控件的alpha通道。为此我在窗体属性里添加了一个richeditcorner属性:
<Attribute name="richeditcorner" default="0,0,0,0" type="RECT" comment="窗口中所有的RichEdit控件与窗体的边距,用于在异形半透明窗体中修复RichEdit控件的alpha通道(只有在bktrans为true并且使用Gdi+渲染时指定)"/>
richeditcorner属性的四个值,分别是RichEdit控件距离窗体左上右下的边距。
半透明异形窗体的缺陷还是在于无法嵌入有句柄子控件。解决方法有两个:一是用双层窗体的方法,主窗体主动控制子控件联动(迅雷用这样的方法,只要联动做得够好,效果上还是不错的)。二是在WM_PAINT中用SendMessage发子控件发送WM_PRINT效率得到子控件的位图,具体操作在官方Duilib中已经做好了。不过如果子控件是比较复杂的控件,这样的方法还是会有一些缺陷。所以最好还是用无窗模式的子控件,或者在一些比较复杂的场景里别使用半透明异形功能。
总结:
我之前一直以为使用UpdateLayeredWindow做的半透明异形窗体,在效率上会比较低。但是经过我测试居然发现,实际上效率并不低,反而会比普通的绘制方法效率还高。
如果使用半透明异形窗体,再需要加窗体阴影时也就不需要双层窗体了,直接在XML布局的最外层嵌套一个阴影图片即可。
现在的半透明异形功能差不多完善够了,加上效率也足够,用来做实际开发也差不多了。不过建议使用半透明异形功能的朋友最好对相关功能和API有一定了解,这样出了问题也能解决。
所有修改我都提交到我个人的Duilib库中,需要的朋友可以直接下载,或者进行文件对比提取对自己有用的代码:点击打开链接
Redrain QQ:491646717 2016.4.26