如何在uC/GUI中实现窗体半透明效果(二)

发 布 时 间 : 2008-11-17 来 源 : 来自网络 作 者 : 匿名 浏 览 :

上周 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联系。



上一篇:基于S3C44B0X的PDA核心设计 下一篇:如何在uC/GUI中实现窗体半透明效果(一)