异形窗口的实现一般有两种方法:1、SetWindowRgn() 2、UpdateLayeredWindow() 。第一种方法很通用,但是由于计算机表达Rgn的局限,做出的界面时常有毛边而影响效果。UpdateLayeredWindow只实用于32位带alpha通道的图片,由于Windows直接拿图片与桌面进行叠加透明处理,所以窗口边缘的毛边一般可通过阴影消除掉。使用UpdateLayeredWindow后的窗口将不在响应WM_PAINT消息,使得原本的控件不能显示。
我的问题 :需要用一张png图片来产生一个不规则窗体,在不规则窗体上要显示控件(其实我是要在上面弄个RichEdit,来显示富文本)。
几个方案: 1.使用CXimage派生的类贴图及SetWIndowrgn()函数
2.使用GDI+及UpdateLayeredWindow()函数
方案1的问题: 使用CXimage贴png图,但是要从png图中得到图片的区域感觉比较棘手。没有发现CXimage有生成Region的接口,如果要自己添加接口函数的话,需要对png的格式以及CXimage的处理方式有比较深的了解,可以参考下png32_helper中的HRGN Png32_MakeRgn(PNGINFO *pPngInfo)方法。但是如果你采用png贴图的话就不推荐使用SetWIndowrgn方法了,你可以自己添加接口函数,实现CXimage+UpdateLayeredWindow 的方法,在codeproject上CXimage文章“12:00 23 Aug '08”那天的回复有个法国人(估计是)讲到这个问题,他发了一篇文章,你可以找来看看。因为我们这边是对CXimage进行了再封装,如果要添加接口就比较麻烦,所以我没有采用这种方法。
方案2的问题: 使用GDI+来贴png图,对于原本控件的显示,可以使用两个对话框分层操作的方法,可以参考:
http://www.codeproject.com/KB/dialog/SemiTranDlgWithCtrls.aspx
http://www.codeproject.com/KB/dialog/PerfectTranlucentDlg.aspx
我的解决过程: 我后面采用的是使用CXimage贴png图,然后使用SetLayeredWindowAttributes() 函数把COLORREF crKey 设置为RGB(0,0,0)将png的透明色过滤掉。具体方法可参照:
透明窗体的又一实现 http://www.vckbase.com/document/viewdoc/?id=1148
xp下实现窗体透明特效SetLayeredWindowAttributes函数 http://blog.csdn.net/keke13/archive/2009/04/23/4102649.aspx
当然开始的效果还是不错的,但是当使用了有本来就有半透明效果的png图片 的时候问题出现了,那些半透明的区域会显示有问题。最后还是采用了上面方案二的方法。使用过程中要更改几个函数的变量类型,以及要注意宽字节的问题。
---------修改于20090925-----------
相关阅读:
1.如果你使用的是bmp图像,那么下面的文章已经够用了
SetWIndowrgn()方法
Windows 中不规则窗体的编程实现 http://www.vckbase.com/document/viewdoc/?id=1345
不规则对话框的又一实现 http://www.vckbase.com/document/viewdoc/?id=759
http://69.10.233.10/KB/graphics/WBContourBitmap.aspx
http://www.codeguru.com/cpp/g-m/bitmap/usingregions/article.php/c1751
UpdateLayeredWindow()方法
在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口http://www.vckbase.com/document/viewdoc/?id=1745
2.了解png文件存储格式 http://www.fix.ac.cn/liao-jie-png-wen-jian-cun-chu-ge-shi.html
3.Alpha混合浅谈 http://dev.gameres.com/Program/Visual/2D/AlphaQiantan.htm