Symbian
Symbian OS Library

FAQ-0502 CEikHorOptionButtonList can cause a panic if you don't initialise the state correctly

[Index][spacer] [Previous] [Next]



 

Classification: C++ Category: EIKON
Created: 07/19/2000 Modified: 12/04/2001
Number: FAQ-0502
Platform: ER5

Question:
CEikHorOptionButtonList can cause a panic if you don't initialise the state correctly

Answer:
If you do not initialise the state of the buttons correctly in a CEikHorOptionButtonList control and try to use the ears and/or arrow keys to toggle the state once the dialog has been displayed, you will get a Panic. This is caused by a defect in the OfferKeyEventL() implementation of the control. It can be fixed by subclassing the control and providing a new implementation. This is made easier by the fact the full Eikon source is included on the SDK CD. Thanks to Sylvain Michel who originally posted this suggestion onto the Symbian Developer Network forums:

Inside your .HRH file
// Assume there are less than 1000 Eikon controls, and they can't be defined anywhere else
    enum
    {
    EEikCtHorOptionButList2=1000
    };
    Inside your application's .RSS file
      DLG_LINE
      {
      type = EEikCtHorOptionButList2;
      ...etc...
      }
      Inside your .H file
      //
      // Class CEikHorOptionButtonList2 : Fix defect with OfferKeyEventL() when no button state is set
      //
      class CEikHorOptionButtonList2 : public CEikHorOptionButtonList
        {public:
           // Framework
          virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
          };
          Inside your dialog class
          private:
            SEikControlInfo CreateCustomControlL(TInt aControlType);
            Inside your main .CPP file
            SEikControlInfo CDlgxxx::CreateCustomControlL(TInt aControlType)
              {
              SEikControlInfo controlInfo;
              controlInfo.iControl = NULL;
              controlInfo.iTrailerTextId = 0;
              controlInfo.iFlags = 0;

              switch (aControlType)
                {case EEikCtHorOptionButList2:
                  controlInfo.iControl = new (ELeave) CEikHorOptionButtonList2;
                  break;
                  }return controlInfo;
                  }
                  //
                  // Class CEikHorOptionButtonList2
                  //
                  TKeyResponse CEikHorOptionButtonList2::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
                    {
                    if (aKeyEvent.iCode==EKeyRightArrow) // only for right arrow key
                      {
                      TInt count=CountComponentControls();
                      TInt current;
                      CEikLabeledOptionButton* button = NULL;

                      for (current=0; current
                        {
                        button=(CEikLabeledOptionButton*)ComponentControl(current);
                        if (button->State()==CEikButtonBase::ESet)
                          break;}
                              // Fix the defect

                              if ((current>=count) && (button))
                                {
                                const TInt id=button->Id(); // button *is* the last by default (right arrow will set the first)
                                SetButtonById(id);
                                } }return CEikHorOptionButtonList::OfferKeyEventL(aKeyEvent, aType);
                                }