How to change the active theme
Article Metadata
This document will very briefly explain how to change the active theme on a S60 3rd Edition device. The information in this document is provided as is and the code samples are not meant to be of commercial quality.
Please note that you need to download and install the Extensions Plug-ins for your S60 SDKs to gain access to APIs you need. Extensions Plug-ins are available for all S60 3rd Edition and S60 5th Edition SDKs. Fron the Extensions plug-ins you will need ExtendedSkinsAPI and PersonalisationSkinsSettingsAPI.
Connect to Skin Server
#include <AknSSrvClient.h> // aknskinsrv.lib
…
RAknsSrvSession skinsSession;
User::LeaveIfError( skinsSession.Connect( this ) );
CleanupClosePushL( skinsSession );
Fetch the package ID of the current skin
#include <centralrepository.h> // centralrepository.lib
#include <AknSkinsInternalCRKeys.h>
…
// iOriginalSkinPid is of type TAknsPkgID
void CMyThemeManager::GetCurrentSkinIdL()
{
TAknsPkgIDBuf pidBuf;
CRepository* repository =
CRepository::NewL( KCRUidPersonalisation );
TInt retVal = repository->Get( KPslnActiveSkinUid, pidBuf );
delete repository;
repository = NULL;
iOriginalSkinPid.SetFromDesL( pidBuf );
}
Get a list of installed skin packages
Please see aknssrvclient.h file for more details on how to work with skins residing on memory card.
CArrayPtr< CAknsSrvSkinInformationPkg >* skinInfoArray =
skinsSession.EnumerateSkinPackagesL();
CleanupStack::PushL( skinInfoArray );
Go through installed packages and switch to the first available new skin
TInt retValue( KErrNone );
TInt i( 0 );
if ( skinInfoArray->Count() > 0 )
{
for ( i; i < skinInfoArray->Count(); i++ )
{
TAknsPkgID pkgId = skinInfoArray->At( i )->PID();
if ( pkgId != iOriginalSkinPid )
{
//Activate a complete skin package at once.
retValue = skinsSession.SetAllDefinitionSets( pkgId );
if ( retValue == KErrNone )
{
SetNewSkinIdL( pkgId );
}
break;
}
}
}
Save the new skin package ID in central repository
void CMyThemeManager::SetNewSkinIdL( TAknsPkgID aPkgId )
{
TAknsPkgIDBuf pidBuf;
aPkgId.CopyToDes( pidBuf );
CRepository* repository =
CRepository::NewL( KCRUidPersonalisation );
TInt retVal = repository->Set( KPslnActiveSkinUid, pidBuf );
// KPslnActiveSkinLocation has to be changed also
// if new skin resides on mmc whereas old one resided in phone mem
// ...and vice versa
delete repository;
repository = NULL;
}
Free allocated resources
skinInfoArray->ResetAndDestroy();
CleanupStack::PopAndDestroy( 2 ); // skinsSession, skinInfoArray
Whole Source
#include <AknSSrvClient.h> //aknskinsrv.lib
#include <centralrepository.h> //centralrepository.lib
#include <AknSkinsInternalCRKeys.h>
#include <mmfcontrollerpluginresolver.h> // CleanupResetAndDestroyPushL
class CMyThemeManager : public CBase, public MAknsSkinChangeObserver
{
public:
void ChangeSkinL();
private:
//From MAknsSkinChangeObserver
virtual void SkinContentChanged();
virtual void SkinConfigurationChanged(const TAknsSkinStatusConfigurationChangeReason aReason);
virtual void SkinPackageChanged(const TAknsSkinStatusPackageChangeReason aReason);
//
void GetCurrentSkinIdL();
void SetNewSkinIdL(TAknsPkgID aPkgId);
private:
TAknsPkgID iOriginalSkinPid;
};
/*
* Set the current skin ID into the Central Repository
*/
void CMyThemeManager::SetNewSkinIdL( TAknsPkgID aPkgId )
{
TAknsPkgIDBuf pidBuf;
aPkgId.CopyToDes( pidBuf );
CRepository* repository = CRepository::NewLC(KCRUidPersonalisation);
User::LeaveIfError(repository->Set(KPslnActiveSkinUid, pidBuf));
// KPslnActiveSkinLocation has to be changed also
// if new skin resides on mmc whereas old one resided in phone mem
// ...and vice versa
CleanupStack::PopAndDestroy(repository);
}
/*
* Get the current skin ID from the Central Repository
*/
void CMyThemeManager::GetCurrentSkinIdL()
{
TAknsPkgIDBuf pidBuf;
CRepository* repository = CRepository::NewLC( KCRUidPersonalisation );
User::LeaveIfError(repository->Get(KPslnActiveSkinUid, pidBuf));
CleanupStack::PopAndDestroy(repository);
iOriginalSkinPid.SetFromDesL(pidBuf);
}
/*
* Change the current skin to the next available skin
*/
void CMyThemeManager::ChangeSkinL()
{
//Connect to the skin server
RAknsSrvSession skinsSession;
User::LeaveIfError( skinsSession.Connect( this ) );
CleanupClosePushL( skinsSession );
//Get the current skin package
GetCurrentSkinIdL();
//Get the list of installed skin packages
CArrayPtr<CAknsSrvSkinInformationPkg>* skinInfoArray =skinsSession.EnumerateSkinPackagesL();
CleanupStack::PushL(skinInfoArray);
CleanupResetAndDestroyPushL(*skinInfoArray);
//Go through installed skin and change it
for (TInt i=0; i < skinInfoArray->Count(); i++ )
{
TAknsPkgID pkgId = skinInfoArray->At( i )->PID();
if ( pkgId != iOriginalSkinPid )
{
//Activate a complete skin package at once.
User::LeaveIfError(skinsSession.SetAllDefinitionSets(pkgId));
SetNewSkinIdL(pkgId);
break; //stop the loop
}
}
//Cleanup everything
CleanupStack::PopAndDestroy(3,&skinsSession); //skinInfoArray, &skinInfoArray
}
void CMyThemeManager::SkinContentChanged()
{
//TODO:
}
void CMyThemeManager::SkinConfigurationChanged(const TAknsSkinStatusConfigurationChangeReason /*aReason*/)
{
//TODO:
}
void CMyThemeManager::SkinPackageChanged(const TAknsSkinStatusPackageChangeReason /*aReason*/)
{
//TODO:
}
Required capabilities
WriteDeviceData
Related topics
- Extended Skins API
- http://www.developer.nokia.com/Community/Discussion/showthread.php?129723-How-to-change-background(skin)-for-status-pane
- http://www.developer.nokia.com/Community/Discussion/showthread.php?132509-Is-it-possible-to-change-theme-programmatically-on-S60-3rd-addition&p=555185
- http://www.developer.nokia.com/Community/Discussion/showthread.php?154995-Change-Skin-Colours-S60-3rd-Ed.
- Archived:Changing the skin of the status pane on Symbian


(no comments yet)