如何在uC/GUI中实现窗体半透明效果(二)
发布:much | 发布时间: 2008年8月27日
本文来源于互联网
上周 2D图形库半透明效果已经实现了.
现在考虑一下窗体半透明效果.
来看一下"raodali"写的:
也就是说修改LCD_WRITE_MEM函数,先读出该地址以前的值,用alpha进行运算得出新的值,然后再写入。
这样就会产生:在反复刷新(即反复产生WM_PAINT)消息时,该窗体的颜色一直在变量,而且由浅及深或由深及浅反复变化。
所以问题很清楚:颜色深浅有规律变化的原因在于重复写入而产生的自身颜色叠加.
如何避免自身颜色叠加?
如果能让半透明的窗体刷新的时间迟于其背景窗刷新时间,这样就可以避免自身颜色叠加.
要实现这个功能有两条路可走:
1、uc/GUI的窗体是没有Z序的,你要给它定义Z序和指定或调整刷新顺序。让有半透明的窗体最后刷新。
2、借用uc/GUI的透明效果。
很明显,方案1做起来的工作量非常大。所以我们使用方案2。
分析一下uc/GUI透明效果的实现方法:
认真分析程序或推断一下便可得知:uc/GUI是在画透明窗口之前先画透明窗口覆盖之下的所有窗口。最后再画透明窗口,在画透明窗口时,将其背景不画,于是就有透明效果了。
GUI透明窗口的这种画法正好满足了我们的要求。所以借用GUI透明效果来实现半透明效果比容易,修改工作量也少。
功能增加了,可能会出乱子,所以先定一下规则:
1、只有窗体被设置了透明属性之后,半透明度参数才能生效。(这条很重要)
2、当透明度参数为0时,透明属性失效。
3、当透明度为100时,窗体完全透明。
开始修改代码
窗体透明效果是用一个标志位来表示WM_CF_HASTRANS,所以它只能表示是否透明,不能表示透明度多少。因此要在需要半透明的窗口属性中增加一透明度参数Alpha;
如下有示
tyepdef struct{
.........
.........
U8 Alpha;
}XXXX_Obj
如何使用Alpha参数?
跟据规则在窗体创建时应该这样:
if(WM_GetHasTrans(hObj))
{
pObj->Alpha=100;
}
else
{
pObj->Alpha=0;
}
因为如果设置了透明,默认情况下,100%透明。
在画窗体时应这样
_Paint(WM_HWIN hObj,XXXX_Obj* pObj)
{
U8 TempAlpha;
if(WM_GetHasTrans(hObj))
{
TempAlpha=GUI_Context.BlendPara
GUI_Context.BlendPara=pObj->Alpha;/BlendPara这个参数在前面讲过。
}
.................
在这里使用原先窗体的画图程序
.................
if(WM_GetHasTrans(hObj))
{
GUI_Context.BlendPara=Alpha;/BlendPara这个参数在前面讲过。
}
}
这样窗体就半透明效果就可以实现了,同时自身颜色叠加的问题也得到了解决.
但还是做得不够完美。原因在于把Alpha参数放在窗体的数据结构中,你就必须修改所有的窗体数据结构。
这个问题如何解决?
WM_Obj这个数据结构是所有窗体的基础。用C++的话来说就是所有窗体类的基类。所以只要在这个数据结构中添加Alpah参数,就省事多了。
另外在WM_Obj这个数据结构中添加Alpha参数,也有利于保证Alpha参数和WM_CF_HASTRANS标志保持逻辑上的正确性。(原因 请查一下WM_SetHasTrans,和WM_ClrHasTrans函数)
就写到这里吧,需要参考代码的Email联系。
- 相关文章:
如何在uC/GUI中实现窗体半透明效果(一) (2008-8-27 0:19:3)
UC/GUI的3.24源码! (2008-7-8 22:53:38)
卡壳了,在wwm滚动条处 (2008-7-7 21:36:8)
WINDML下的WWM啊! (2008-6-3 22:30:32)
- 1.非常好
- 非常好,请给我一份源码,学习一下,如何???much 于 2008-12-22 12:49:06 回复兄弟,我这个文章也是从网上转的!
我手上没有代码!
抱歉! - 2008-12-22 1:24:34 回复该留言
发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。






