不规则窗体实现 收藏
异形窗口的实现一般有两种方法: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
发表于 @ 2009年09月17日 11:50:00 | 评论( 3 ) | 编辑| 举报| 收藏
旧一篇:error LNK2001: unresolved external symbol "__declspec(dllimport) const CNoteMgr::`vftable'" | 新一篇:_BLOCK_TYPE_VALID(pHead->nBlockUse),_CrtIsValidHeapPointer(pUserData),动态链接库内存分配magictong 发表于2009年9月20日 14:21:08 IP:举报删除
alpha通道和窗口渐变只能用一个,这个好纠结;你用了窗口的淡入淡出再想用alpha通道就不行了,因为是同一个API,我熄; 好东东。magictong 发表于2009年9月20日 14:23:11 IP:举报删除
gdi 一直还没用过,遗憾啊。bao_qibiao 发表于2009年9月20日 16:28:21 IP:举报删除
这个还在进一步研究,刚看到一句话: UpdateLayeredWindow函数可使整个窗口每个点有不同的通明度;SetLayeredWindowAttributes函数是不能实现每点有不同透明度的。呃~~
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bao_qibiao/archive/2009/09/17/4562142.aspx