• Symbian系统皮肤的使用【转】


    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 );
    来自: http://hi.baidu.com/ldxcln/blog/item/92f9d512fd62778a6438db74.html
  • 相关阅读:
    Vue内置指令
    Vue计算属性
    Ubuntu下编译Bilibili/ijkplayer
    自毁程序
    Android最大可运行内存
    Android ListView onItemClick Not Work
    Java/Android 二进制数据与String互转
    JAVA/Android Map与String的转换方法
    java中打印变量地址
    Win7 关闭Window update
  • 原文地址:https://www.cnblogs.com/zziss/p/2360704.html
Copyright © 2020-2023  润新知