Symbian系统皮肤的使用

本文介绍在Symbian平台中实现UI皮肤效果的三种方法:一句代码快速应用、深入控件实现透明背景及自定义皮肤显示,并提供代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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:既不提供也不使用皮肤参数。

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

 

通过皮肤取Bitmap
MAknsSkinInstance* skin = AknsUtils::SkinInstance();

CAknsItemData* skinItem = skin->GetCachedItemData( someUID, EAknsITBitmap );   

if( skinItem != NULL )
{
CFbsBitmap* bitmap = static_cast<CAknsBitmapItemData*>(skinItem)->Bitmap();
}
CFbsBitmap* offScreenBitmap = new (ELeave) CFbsBitmap(); 
User::LeaveIfError( offScreenBitmap->Create( aSize, aDisplayMode ) ); 
CFbsBitGc* bitGc = 0; 
CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( offScreenBitmap ); 
User::LeaveIfError( bitmapDevice->CreateContext( bitGc ) ); 
// Draw the content on the off-screen bitmap
AknsDrawUtils::DrawBackground( AknsUtils::SkinInstance(),iSkinContext,this,*bitGc, TPoint(0,0), rect,KAknsDrawParamDefault );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值