blog.TangGaowei.com

设置 Symbian 应用程序的背景图片

作者 Neot 写于 2011-12-08 | 49 次浏览 | 分类 » 软件开发 |

(红色字体为添加的代码)

1. 环境

  • Carbide C++ 2.7 (注:Carbide C++ 3.2 适于 S60 的开发,且没有 UI 编辑器)
  • S60 3rd Edition FP1 SDK(FP2 没有测过)
  • Windows 7(Windows xp 应该也不会有什么问题)

2. 新建 Symbian OS C++ Project

  • 选择 S60/GUI Application with UI Designer,Next
  • Project Name 处输入 Skinned,其它默认,Next
  • 选择 S60_3rd_FP1,其它默认,Next
  • Inital language 选择 Peoples Republic of Chinas Chinese(31),其它默认,Next
  • S60 UI Design Selection 默认,Next
  • Container Name and Type 默认,Finish

3. 在项目的 group/Skinned.mmp 文件里添加 Library 引用

LIBRARY aknskins.lib aknskinsrv.lib aknswallpaperutils.lib

4. 将图片添加到项目

将准备好的图片入在 gfx 目录下,并刷新项目。本例使用 cba_bg.bmp 文件作为 CBA 区的背景,使用 main_bg.bmp 文件作为主显示区的背景。作者还未研究过 svg 图片的使用,所以这里都使用的是 BMP 图片。还要注意,其它格式的图片,如 PNG 类型的好像用不了,作者也未深入研究。

5. 将图片添加到项目的资源库

在 MMP 文件中进行添加(红色字体部分),然后重新编译:
START BITMAP      Skinned.mbm
HEADER
TARGETPATH        \resource\apps
SOURCEPATH        ..\gfx
SOURCE      c12,1 list_icon.bmp list_icon_mask.bmp
SOURCE      c24 cba_bg.bmp main_bg.bmp END
(“c24”可能是 24 位位图的意思)

编译后,系统自动重新生成 Epoc32\include\Skinned.mbg 文件:
enum TMbmSkinned {  EMbmSkinnedList_icon, 
EMbmSkinnedList_icon_mask, EMbmSkinnedCba_bg,  EMbmSkinnedMain_bg  };
(MBG 文件是系统自动生成的,最好不要自己修改)

6.修改 inc/SkinnedContainer.h 文件

#include <AknsBasicBackgroundControlContext.h> //for CAknsBasicBackgroundControlContext
#include <AknsDrawUtils.h> //for AknsDrawUtils, CAknsItemDef and MAknskinInstance
#include <AknUtils.h> //for CompeleteWithAppPath()
class CSkinnedContainer : public CCoeControl
{
protected:
virtual TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
private:
CAknsBasicBackgroundControlContext* iBackGround;
}

7.修改 src/SkinnedContainer.cpp 文件

 // EMbmSkinnedMain_bg、EMbmSkinnedCba_bg
#include <Skinned.mbg>

// bitmapFile
_LIT( KSkinnedFile, ”\\resource\\apps\\Skinned.mbm” );

// MopSupplyObject must provide a pointer to the control context, in this example the CAknsBasicBackgroundControlContext instance.
TTypeUid::Ptr CSkinnedContainer::MopSupplyObject(TTypeUid aId)
    {
    if(aId.iUid == MAknsControlContext::ETypeId && iBackGround)
        {
        return MAknsControlContext::SupplyMopObject( aId, iBackGround);
        }
    return CCoeControl::MopSupplyObject( aId );
    }

// Init
void CSkinnedContainer::ConstructL(
            const TRect& aRect,
            const CCoeControl* aParent,
            MEikCommandObserver* aCommandObserver )
      {
      if ( aParent == NULL )
          {
            CreateWindowL();
          }
      else
          {
          SetContainerWindowL( *aParent );
          }
      iFocusControl = NULL;
      iCommandObserver = aCommandObserver;
      InitializeControlsL();
      SetRect( aRect );
      
      iBackGround = CAknsBasicBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMain, Rect(), EFalse );
      TFileName bitmapFile (KSkinnedFile);
      User::LeaveIfError(CompleteWithAppPath(bitmapFile));
            
      MAknsSkinInstance* skin = AknsUtils::SkinInstance();
      skin->SetLocalItemDefL(AknsUtils::CreateBitmapItemDefL(KAknsIIDQsnBgAreaMain, bitmapFile, EMbmSkinnedMain_bg));
      skin->SetLocalItemDefL(AknsUtils::CreateBitmapItemDefL(KAknsIIDQsnBgAreaControl, bitmapFile, EMbmSkinnedCba_bg));
            
      ActivateL();
      // [[[ begin generated region: do not modify [Post-ActivateL initializations]
      // ]]] end generated region [Post-ActivateL initializations]      
      }

// Draw container contents.
void CSkinnedContainer::Draw( const TRect& aRect ) const
      {
      // [[[ begin generated region: do not modify [Generated Contents]
      CWindowGc& gc = SystemGc();
      gc.Clear( aRect );
     
      MAknsSkinInstance* skin = AknsUtils::SkinInstance();
      MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
      AknsDrawUtils::Background( skin, cc, this, gc, aRect );
      
      // ]]] end generated region [Generated Contents]      
      }// Resize

void CSkinnedContainer::SizeChanged()

      {
      CCoeControl::SizeChanged();
      LayoutControls();
      // [[[ begin generated region: do not modify [Generated Contents]
      if ( iBackGround )
            {
            iBackGround->SetRectRect() );
            if ( &Window() )
                  iBackGround->SetParentPosPositionRelativeToScreen() );
            }
      // ]]] end generated region [Generated Contents]
      
      }


// Destroy child controls
CSkinnedContainer::~CSkinnedContainer()
      {
      // [[[ begin generated region: do not modify [Generated Contents]
      delete iBackGround;
      iBackGround = NULL;
      // ]]] end generated region [Generated Contents]
      
      }
//(如果有资源方面的错误,请做一次Clear,并重新编译)

8. 备注

如果有设置状态栏的背景,可以使用以下代码:

skin->SetLocalItemDefL(AknsUtils::CreateBitmapItemDefL(KAknsIIDQsnBgAreaStatus, bitmapFile, EMbmSkinnedStatus_bg));

但是,在 S60 3rd Edition FP1 下,设置状态栏背景的效果并不好,只对状态栏的一部分有效。在 S60 3rd Edition FP2 下设置状态栏背景可以获得满意的效果。

如果不想使用状态,可以将其隐藏:
CEikStatusPane* statusp = iEikonEnv->AppUiFactory()->StatusPane();
if(statusp)
{
statusp->MakeVisible(EFalse);
}
S60 3rd Edition FP1 下隐藏状态栏和全屏都不能达到完美的效果,在程序启动时会有一个原始默认的窗口一闪而过。S60 3rd Edition FP1 系统自带的软件也同样存在这样的问题。非全屏的应用程序也是先出现一个原始默认窗口,再出现正式的窗口。有网友称此问题无法得到解决。

 

[ 标签: symbian ]
[ 固定链接:http://blog.tanggaowei.com/2011/12/symbian-skin.html ]

发表评论


点击图片可以听验证码

订阅

 

手机访问

http://blog.tanggaowei.com/wap/

Google