The following resource structure should be used for the command button object (defined in eikon.rh):
STRUCT CBA { LONG flags = EEikButtonGroupAddToStack; LLINK related_buttons = 0; STRUCT buttons[]; } STRUCT CBA_BUTTON { BYTE version = 0; WORD id = 0; LTEXT txt = ""; }
A typical CBA definition looks like this (app_res_def.rss):
// contains application specific enums, commands, texts #include "app_res_def.hrh" RESOURCE CBA r_app_softkeys_prev_next__contextoptions { flags = 0; buttons = { CBA_BUTTON {id = EAppCommandPrev; txt = text_softkey_prev;}, CBA_BUTTON {id = EAppCommandNext; txt = text_softkey_next;}, CBA_BUTTON {id = EAknSoftkeyContextOptions; txt = text_softkey_contextoptions;} }; }
Many CBA controls (e.g. R_AVKON_SOFTKEYS_EMPTY
, R_AVKON_SOFTKEYS_OK_BACK__OK
)
are predefined in AVKON.RSG.
By default CBA controls do not respond when they are invisible. This prevents
hidden CBAs from receiving any type of key events. However, the feature can
be activated by setting the EAknCBAFlagRespondWhenInvisible
flag.
Changing the command set in the CBA object:
#include <app_res_def.rsg> CEikButtonGroupContainer* myCba = CEikButtonGroupContainer::Current(); CleanupStack::PushL( myCba ); myCba->SetCommandSetL( R_APP_SOFTKEYS_PREV_NEXT__CONTEXTOPTIONS ); myCba->MakeVisible( ETrue ); myCba->DrawNow(); CleanupStack::Pop(); // myCba
Text label of the command button can be changed by setting a new command:
// in application resource file RESOURCE TBUF r_app_softkey_prev { buf = text_softkey_prev; } // Left softkey, new text is a resource HBufC* myText = StringLoader::LoadLC( R_APP_SOFTKEY_PREV ); Cba()->SetCommandL( 0, EAppCommandPrev, *myText ); Cba()->DrawDeferred(); // or DrawNow CleanupStack::PopAndDestroy(); // myText // Right softkey, new text is static text Cba()->SetCommandL( 2, EAppCommandNext, _L("next") ); Cba()->DrawDeferred(); // or DrawNow // Middle softkey, new text is static text Cba()->SetCommandL( 3, EAppCommandMSK, _L("MSK") ); Cba()->DrawDeferred(); // or DrawNow
Command stack is an advanced tool in CBA control: it stores multiple command definitions in a stack. Only the top one is active, but it also gives the possibility to remove any command and use a previous one.
Adding a new command set to the CBA command stack:
#include "app_res_def.rsg" CEikButtonGroupContainer* myCba = CEikButtonGroupContainer::Current(); CleanupStack::PushL( myCba ); myCba->AddCommandSetToStackL( R_APP_SOFTKEYS_PREV_NEXT__CONTEXTOPTIONS ); myCba->MakeVisible( ETrue ); myCba->DrawNow(); CleanupStack::Pop(); // myCba
Removing a command:
// code to remove softkeys from CBA stack if( iActualCbaResource == R_APP_SOFTKEYS_PREV_NEXT__CONTEXTOPTIONS ) { RemoveCommandFromStack(CEikButtonGroupContainer::ELeftSoftkeyPosition, EappCommandPrev }; // left softkey command RemoveCommandFromStack(CEikButtonGroupContainer::ERightSoftkeyPosition, EAppCommandNext }; // right softkey command RemoveCommandFromStack(CEikButtonGroupContainer::EMiddleSoftkeyPosition, EAknSoftkeyContextOptions }; // MSK command }
Application UIs always have a CEikButtonGroupContainer
.
Most of the Application Views and Dialogs have it too. The following functions
can be used to access their CBA object:
CEikButtonGroupContainer* CAknAppUi::Cba() CEikButtonGroupContainer* CAknView::Cba() CEikButtonGroupContainer* CEikDialog::ButtonGroupContainer()
It is also possible to create a local CEikButtonGroupContainer
:
// constructing the local button group container void CMyAppView::ConstructL() { iLocalButtonGroup = CEikButtonGroupContainer::NewL( CEikButtonGroupContainer::ECba, // type CEikButtonGroupContainer::EHorizontal, // orientation this, // command observer R_APP_SOFTKEYS_PREV_NEXT__CONTEXTOPTIONS ); // default resource to use // remove from control stack (added automatically), // because don't want to use it yet AppUi()->RemoveFromStack( iLocalButtonGroup->ButtonGroup() ); } // and using it when View is activated void CMyAppView::DoActivateL( const TVwsViewId&, TUid, const TDesC8& ) { // add to control stack to receive key events if( iLocalButtonGroupContainer ) { AppUi()->AddToStackL( iLocalButtonGroupContainer->ButtonGroup() ); } } void CMyAppView::DoDeactivate() { if( iLocalButtonGroupContainer ) { AppUi()->RemoveFromStack( iLocalButtonGroupContainer->ButtonGroup() ); } }
Softkey pressing event is reported to the Observer via the MEikCommandObserver
interface.
class CMyAppView: public CAknView // CAknView already inherited from MEikCommandObserver { public: virtual void ProcessCommandL( TInt aCommandId ); };
Processing the command:
void CMyAppView::ProcessCommandL( TInt aCommandId ) { switch( aCommandId ) { case EAppCommandPrev: if( iActualPage < iPageCount-1 ) SwitchToPage( ++iActualPage ); break; case EAppCommandNext: if( iActualPage > 0 ) SwitchToPage( --iActualPage ); break; default: CAknView::ProcessCommandL( aCommandId ); // pass it up break; } }
Buttons API uses standard Symbian OS error reporting mechanism. Leaves and system wide error codes as function return values are used if the error is recoverable. A client application can handle these errors similarly as a normal Symbian platform application.
Setting an image as a command button is a future development feature.