Symbian系统皮肤的使用【转】

http://careerman.blog.ccidnet.com/blog-htm-do-showone-uid-12026-type-blog-itemid-5189925.html

1.一句话的方法

最基本的一招就是在AppUi中的ConstructL()中加一句话搞定。如下:

C++代码
void CTestMIMAppUi::ConstructL() {
BaseConstructL(CAknAppUi::EAknEnableSkin);
//add your code here...
}
用上面这句话基本上能让大部分控件的透明化,显示出系统的皮肤。

但是,有时我们会发现部分控件(比如那个CEikEdwin)仍显示的一个难看的白底,此时,我们需要做一些额外的工作了。

修改Container的头文件,增加一个成员变量:



C++代码
CAknsBasicBackgroundControlContext* iBgContext;
然后在对应的ConstructL函数中初始它:



C++代码
iBgContext = CAknsBasicBackgroundControlContext::NewL(KAknsIIDQsnBgAreaMainIdle,aRect,ETrue);
这儿的KAknsIIDQsBgAreaMainIdle你可以选择其它的,不碍事的。
然后,因为CEidEdwin有一个很方便的成员方法SetSkinBackgroundControlContextL,所以接下来的代码就简单了:



C++代码
iEdWin=new(ELeave)CEikEdwin;
CleanupStack::PushL(iEdWin);
iEdWin->SetContainerWindowL(*this);
iEdWin->ConstructL();
iEdWin->SetSkinBackgroundControlContextL(iBgContext);
iEdWin->SetExtentToWholeScreen();
iEdWin->SetFocus(ETrue);
iEdWin->ActivateL();
CleanupStack::Pop(iEdWin);
这样就可以了。别忘了,在析构时delete它。

2.终极方法显示系统皮肤

再进一步,如果控件没有这么方便的成员让我们去设置它的背景,也有办法(参考http://www.newlc.com/Enable-Skin-support-in-your.html)。

很好办,先在H文件中增加一个MopSupplyObject的声明:



C++代码
TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
然后实现中,ContructL中就不用iEdWin->SetSkinBackgroundControlContextL了,而是在三个函数中分别处理:



C++代码
void CTestMIMEdtContainer::Draw(const TRect& aRect) const {
CWindowGc& gc = SystemGc();

MAknsSkinInstance* skin = AknsUtils::SkinInstance(); //皮肤的接口
MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); //得到皮肤参数
AknsDrawUtils::Background( skin, cc, this, gc, aRect ); //画皮肤
}

void CTestMIMEdtContainer::SizeChanged() {
if(iBgContext)
{
iBgContext->SetRect(Rect());
if ( &Window() )
{
iBgContext->SetParentPos( PositionRelativeToScreen() );
}
}
DrawNow();
}
TTypeUid::Ptr CTestMIMEdtContainer::MopSupplyObject(TTypeUid aId)
{
if (iBgContext )
{
return MAknsControlContext::SupplyMopObject( aId, iBgContext );
}
return CCoeControl::MopSupplyObject(aId);
}
这样也可以让控件透明显示出系统皮肤。

3.显示自定义皮肤

来说自定义皮肤的显示,关键在于那个iBgContext成员如何弄出来,前面的NewL()的第一个参数是系统定义的东西,现在我们需要自定义了。

同样,先修改一个H文件,增加一个成员:



C++代码
TAknsItemID aSkinItem;
然后实现文件中的ContructL函数中,我们要从MIF文件中取图片弄成背景:



C++代码
TFileName iMFileName;
iMFileName.Copy(KMifFileName);
CompleteWithAppPath(iMFileName);

aSkinItem.iMinor = 0xE2139689;
aSkinItem.iMajor = 1 ;

CAknsItemDef* mainBgItemDef = AknsUtils::CreateBitmapItemDefL(aSkinItem, iMFileName, EMbmTestmimGrid);
AknsUtils::SkinInstance()->SetLocalItemDefL( mainBgItemDef );
iBgContext = CAknsBasicBackgroundControlContext::NewL(aSkinItem,aRect,ETrue );
这儿的KMifFileName是定义的资源MIF文件(与其它例子中加载资源图像的方法类似)。


=================================================================================================


如果控件的container实现了MopSupplyObject()并且返回了创建CAknsBasicBackgroundControlContext对象,那么就可以在自定义控件中通过下面的代码获取并使用:
Code:

void CYourControl:ConstructL()
{
//Get parent's skin context
MAknsControlContext *context = NULL;

MopGetObject( context );

if( context )
{
iBackground = static_cast<CAknsBasicBackgroundControlContext*>( context );
}
..................
}

void CYourControl::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();

gc.Clear(aRect);

TRect rect = Rect();

if( iBackground )
{
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
AknsDrawUtils::Background( skin, iBackground, this, gc, rect );
}
........................
}

如果控件的container没有实现并提供背景上下文对象,那就需要控件自己创建 CAknsBasicBackgroundControlContext。但在实践中我碰到了自定义控件自己创建 CAknsBasicBackgroundControlContext,但是背景的大小和位置总是不正确,造成同一container添加多个控件后,背景显示混乱的问题,最后还是通过前面的代码解决的。

系统控件对于皮肤的支持有下面的几种:
Compulsorily skin-providing controls:总是提供皮肤参数,不需要开发者额外操作,比如程序上方的control pane和status pane.

Optionally skin-providing controls:是否提供皮肤参数需要显示设置,比如list和grid需要显示调用ItemDrawer()->SetSkinEnabledL()来激活对皮肤的支持。

Skin-observing controls:本身并不提供皮肤参数,但是可以通MObjectProvider链猎取并使用皮肤,这时需要container获应用提供皮肤参数。

Non-skin-aware controls:既不提供也不使用皮肤参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值