from

http://www.forum.nokia.com/document/Cpp_Developers_Library/GUID-759FBC7F-5384-4487-8457-A8D4B76F6AA6/html/Form_API4.html

 

 

Form API: Using Form API

To use forms, the dialog resource (RESOURCE DIALOG) must be defined in the application resource file and a matching CAknForm-based class must be provided.

Example data structure TMyData is used to demonstrate the usage of most typical data fields in forms.

struct TMyData
    {
public:     // data
    TBuf<256> iText;
    TBuf<256> iGlobalText;
    TBuf<256> iRichText;
    TInt iNumber;
    TInt iInteger;
    TReal iFloat;
    TInt iFix;
    TTime iDate;
    TTime iTime;
    TTimeIntervalSeconds iDuration;
    TBuf<4> iNumPwd;
    TBuf<8> iAlphaPwd;
    TInetAddr iIpAddr;
    MAknQueryValue* iPopupVal;
    TInt iPopupTextIndex;
    TInt iSliderVal;
    };

The class CMyForm is used to display and edit the data.

class CMyForm : public CAknForm
    {
public:     // construction
    CMyForm( TMyData& aData );
    virtual ~CMyForm();
public:     // from CAknForm
    void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane );
    void ProcessCommandL( TInt aCommandId );
    TBool SaveFormDataL();
    void DoNotSaveFormDataL();
    void AddItemL() ;
    void PreLayoutDynInitL();
    MEikDialogPageObserver::TFormControlTypes
        ConvertCustomControlTypeToBaseControlType( TInt aControlType ) const;
private:
    void LoadFormDataL() ;
private:    // data
    TMyData& iData;
    TInt iAddedItemId;
    };

Defining the form resource

Since a form is a special dialog, its resource definition is within a DIALOG resource, that is, the dialog structure has the LLINK form as a member.

STRUCT DIALOG
    {
    LONG flags = 0;
    LTEXT title = "";
    LLINK pages = 0;
    LLINK buttons = 0;
    STRUCT items[];
    LLINK form = 0;
    }

When considering forms, the important members of the DIALOG structure are:

  • flags, which specifies the whole form style. The flag parameters are defined in the eikon.hrh file.
  • pages, which is a reference to an ARRAY of PAGE. Used only in multi-page forms (see Multi-page form). For single-page forms, this should not be specified.
  • buttons, which specifies softkeys.
  • form, which is a reference to the FORM structure described later. Used in single-page forms. For multi-page forms, this should not be specified.

 

See document S60 3.1 Dialogs API Specification for more information on other DIALOG structure members.

STRUCT FORM
    {
    WORD flags = 0;
    STRUCT items[];
    }

The FORM structure member flags can be used to specify the style of the form. The default setting is single-line display, and the predefined values are as follows:

FlagDescription
EEikFormUseDoubleSpacedFormatDouble-line display.
EEikFormHideEmptyFieldsMakes empty data fields invisible.
EEikFormShowBitmapsDisplays a bitmap on a label.
EEikFormEditModeOnlyDisplays the form in edit mode only.
EEikFormShowEmptyFieldsDisplays single-line display (default).

 

Form fields are described with the structure DLG_LINE in the member items of the FORM structure.

STRUCT DLG_LINE
    {
    WORD type;
    LTEXT prompt;
    WORD id = 0;
    LONG itemflags = 0;
    STRUCT control;
    LTEXT trailer = "";
    LTEXT bmpfile = ""; 
    WORD bmpid = 0xffff;
    WORD bmpmask;	
    LTEXT tooltip = "";
    }

The important members of this structure are:

  • type, which specifies a control type, such as EEikCtEdwinEEikCtNumberEditorEEikCtDateEditorEEikCtTimeEditorEEikCtDurationEditorEEikCtSecretEd, or EAknCtSlider. Types are defined in the eikon.hrh or avkon.hrh files. For details on the resource structures defining individual controls, see document S60 3.1 Editors API Specification.
  • prompt, which specifies the field label.
  • id, which specifies the control ID of the application. Within the application, the ID is used to reference the dialog line. The ID must be defined in the application's HRH file. Each dialog line must have a unique ID; otherwise the application panics when the dialog is executed.
  • itemflags, such as EEikDlgItemTakesEnterKey or EEikDlgItemOfferAllHotKeys.
  • control, which specifies the field control. Controls are defined in HRH files.
  • bmpfile, which specifies the bitmap filename.
  • bmpid, which specifies the icon image ID.
  • bmpmask, which specifies the icon mask ID.

 

Single-page form

The following resource defines a form for viewing and editing TMyStruct data in a single page.

RESOURCE DIALOG r_my_dialog
    {
    flags = EEikDialogFlagNoBorder | EEikDialogFlagNoDrag  |
            EEikDialogFlagNoTitleBar | EEikDialogFlagFillAppClientRect |
            EEikDialogFlagCbaButtons | EEikDialogFlagWait;
    buttons = R_AVKON_SOFTKEYS_OPTIONS_BACK;
    form = r_my_form;
    }

RESOURCE FORM r_my_form
    {
    flags = EEikFormUseDoubleSpacedFormat;
    items =
        {
        DLG_LINE
            {
            type = EEikCtEdwin;
            prompt = "Text" ;
            id = EMyAppControlIdTextEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = EDWIN
                {
                flags = KMultiLineExpandingEditorFlags |
                        EEikEdwinNoLineOrParaBreaks;
                maxlength = 256;
                width = 6;
                };
            },
        DLG_LINE
            {
            type = EEikCtGlobalTextEditor;
            prompt = "Global text";
            id = EMyAppControlIdGlobalTextEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = GTXTED
                {
                width = 10;
                height = 17;
                textlimit = 256;
                flags = KMultiLineExpandingEditorFlags;
                max_view_height_in_lines = 2;
                };
            },
        DLG_LINE
            {
            type = EEikCtRichTextEditor;
            prompt = "Rich text";
            id = EMyAppControlIdRichTextEd; 
            itemflags = EEikDlgItemTakesEnterKey;
            control = RTXTED
                {
                width = 10;
                height = 17;
                textlimit = 256;
                flags = KMultiLineExpandingEditorFlags;
                max_view_height_in_lines = 3;
                };
            },
        DLG_LINE
            {
            type = EEikCtNumberEditor;
            prompt = "Number" ;
            id = EMyAppControlIdNumberEd ;
            control = NUMBER_EDITOR
                {
                min = 0;
                max = 999;
                };
            },

        DLG_LINE
            {
            type = EAknCtIntegerEdwin;
            prompt = "Integer edwin" ;
            id = EMyAppControlIdIntegerEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = AVKON_INTEGER_EDWIN
                {
                maxlength = 10;
                min = 0;
                max = 999;
                };
            },
        DLG_LINE
            {
            type = EEikCtFlPtEd;
            prompt = "Floating point" ;
            id = EMyAppControlIdFloatEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = FLPTED
                {
                maxlength = 10;
                min = 0;
                max = 999;
                };
            },
        DLG_LINE
            {
            type=EEikCtFxPtEd;
            prompt = "Fixed point" ;
            id = EMyAppControlIdFixEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = FIXPTED
                {
                min = 0;
                max = 99999;
                decimalplaces = 2;
                };
            },
        DLG_LINE
            {
            type = EEikCtDateEditor;
            prompt = "Date" ;
            id = EMyAppControlIdDateEd ;
            itemflags = EEikDlgItemTakesEnterKey;
            control = DATE_EDITOR
                {
                minDate = DATE { year = 1900; };
                maxDate= DATE { year = 2100; };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EEikCtTimeEditor;
            prompt = "Time";
            id = EMyAppControlIdTimeEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = TIME_EDITOR
                {
                minTime = TIME {};
                maxTime = TIME { second = 59; minute = 59; hour = 23; };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EEikCtDurationEditor;
            prompt = "Duration";
            id = EMyAppControlIdDurationEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = DURATION_EDITOR
                {
                minDuration = DURATION {};
                maxDuration = DURATION { seconds = 3599; };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EAknCtNumericSecretEditor;
            prompt = "Secret number";
            id = EMyAppControlIdNumPwdEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = NUMSECRETED { num_code_chars = 4; };
            },
        DLG_LINE
            {
            type = EEikCtSecretEd;
            prompt = "Secret text";
            id = EMyAppControlIdAlphaPwdEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = SECRETED { num_letters = 8; };
            },
        DLG_LINE
            {
            type = EAknCtIpFieldEditor;
            prompt = "IP address";
            id = EMyAppControlIdIpAddrEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = IP_FIELD_EDITOR
                {
                min_field_values = IP_FIELD
                    {
                    first_field = 0;
                    second_field = 0;
                    third_field = 0;
                    fou?th_field = 0;
                    };
                max_field_values = IP_FIELD
                    {
                    first_field = 255;
                    second_field = 255;
                    third_field = 255;
                    fourth_field = 255;
                    };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EAknCtPopupField;
            prompt = "Popup field";
            id = EMyAppControlIdPopupField;
            itemflags = EEikDlgItemTakesEnterKey;
            control = POPUP_FIELD
                {
                flags = EAknPopupFieldFlagAllowsUserDefinedEntry;
                width = 50;
                other = "Other";
                empty = "No items";
                invalid = "Invalid item";
                };
            },
        DLG_LINE
            {
            type = EAknCtPopupFieldText;
            prompt = "Popup field text";
            id = EMyAppControlIdPopupFieldText;
            itemflags = EEikDlgItemTakesEnterKey;
            control = POPUP_FIELD_TEXT
                {
                textarray = r_my_list_popup_items;
                popupfield = POPUP_FIELD {};
                active = 0;
                };
            },
        DLG_LINE
            {
            type = EAknCtSlider;
            prompt = "Slider";
            id = EMyAppControlIdSlider;
            itemflags = EEikDlgItemTakesEnterKey;
            control = SLIDER
                {
                layout = EAknFormSliderLayout2;
                minvalue = 0;
                maxvalue = 20;
                step = 2;
                valuetype = EAknSliderValueNone;
                minlabel = "few";
                maxlabel = "many";
                valuelabel = "Slider value";
                };
            }
        };
    }

RESOURCE ARRAY r_my_list_popup_items
    {
    items =
        {
        LBUF { txt = "Monday"; },
        LBUF { txt = "Tuesday"; },
        LBUF { txt = "Wednesday"; },
        LBUF { txt = "Thursday"; },
        LBUF { txt = "Friday"; },
        LBUF { txt = "Saturday"; },
        LBUF { txt = "Sunday"; }
        };
    }

Multi-page form

Multi-page forms also use the DIALOG resource structure, but DIALOG structure member pages are needed as a reference to an ARRAY of PAGE. The PAGE structure is as follows:

STRUCT PAGE
    {
    WORD id = 0;
    LTEXT text;
    LTEXT bmpfile = "";
    WORD bmpid = 0xffff;
    WORD bmpmask; 
    LLINK lines = 0;
    LLINK form = 0;
    WORD flags = 0;
    }

The following members are concerned with forms in the PAGE structure:

  • id, which specifies the page ID of an application.
  • text, which specifies the title string of tabs.
  • form, which is a reference to the FORM structure.

 

The following resource defines a form for viewing and editing TMyStruct data in a multi-page dialog. The DLG_LINE structures are identical to the single-page example (except that the first page is decorated with icons).

RESOURCE DIALOG r_my_multipage_dialog
    {
    flags = EEikDialogFlagNoBorder | EEikDialogFlagNoDrag  |
            EEikDialogFlagNoTitleBar | EEikDialogFlagFillAppClientRect |
            EEikDialogFlagCbaButtons  | EEikDialogFlagWait;
    buttons = R_AVKON_SOFTKEYS_OPTIONS_BACK ;
    pages = r_my_pages;
    }


RESOURCE ARRAY r_my_pages
    {
    items =
        {
        PAGE { text = "text"; id = EMyAppPage1 ; form = r_my_form_1 ; },
        PAGE { text = "number"; id = EMyAppPage2 ; form = r_my_form_2 ; },
        PAGE { text = "misc"; id = EMyAppPage3 ; form = r_my_form_3 ; }
        };
    }

RESOURCE FORM r_my_form_1
    {
    flags = EEikFormUseDoubleSpacedFormat | EEikFormShowBitmaps;
    items =
        {
        DLG_LINE
            {
            type = EEikCtEdwin;
            prompt = "Text" ;
            id = EMyAppControlIdTextEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = EDWIN
                {
                flags = KMultiLineExpandingEditorFlags |
                        EEikEdwinNoLineOrParaBreaks;
                maxlength = 256;
                width = 6;
                };
            bmpfile = AVKON_ICON_FILE;
            bmpid = EMbmAvkonQgn_prop_folder_small;
            bmpmask = EMbmAvkonQgn_prop_folder_small_mask;
            },
        DLG_LINE
            {
            type = EEikCtGlobalTextEditor;
            prompt = "Global text";
            id = EMyAppControlIdGlobalTextEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = GTXTED
                {
                width = 10;
                height = 17;
                textlimit = 256;
                flags = KMultiLineExpandingEditorFlags;
                max_view_height_in_lines = 2;
                };
            bmpfile = AVKON_ICON_FILE;
            bmpid = EMbmAvkonQgn_prop_folder_small;
            bmpmask = EMbmAvkonQgn_prop_folder_small_mask;
            },
        DLG_LINE
            {
            type = EEikCtRichTextEditor;
            prompt = "Rich text";
            id = EMyAppControlIdRichTextEd; 
            itemflags = EEikDlgItemTakesEnterKey;
            control = RTXTED
                {
                width = 10;
                height = 17;
                textlimit = 256;
                flags = KMultiLineExpandingEditorFlags;
                max_view_height_in_lines = 3;
                };
            bmpfile = AVKON_ICON_FILE;
            bmpid = EMbmAvkonQgn_prop_folder_small;
            bmpmask = EMbmAvkonQgn_prop_folder_small_mask;
            }
        };
    }

RESOURCE FORM r_my_form_2
    {
    flags = EEikFormUseDoubleSpacedFormat;
    items =
        {
        DLG_LINE
            {
            type = EEikCtNumberEditor;
            prompt = "Number" ;
            id = EMyAppControlIdNumberEd ;
            control = NUMBER_EDITOR
                {
                min = 0;
                max = 999;
                };
            },

        DLG_LINE
            {
            type = EAknCtIntegerEdwin;
            prompt = "Integer edwin" ;
            id = EMyAppControlIdIntegerEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = AVKON_INTEGER_EDWIN
                {
                maxlength = 10;
                min = 0;
                max = 999;
                };
            },
        DLG_LINE
            {
            type = EEikCtFlPtEd;
            prompt = "Floating point" ;
            id = EMyAppControlIdFloatEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = FLPTED
                {
                maxlength = 10;
                min = 0;
                max = 999;
                };
            },
        DLG_LINE
            {
            type=EEikCtFxPtEd;
            prompt = "Fixed point" ;
            id = EMyAppControlIdFixEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = FIXPTED
                {
                min = 0;
                max = 99999;
                decimalplaces = 2;
                };
            },
        DLG_LINE
            {
            type = EEikCtDateEditor;
            prompt = "Date" ;
            id = EMyAppControlIdDateEd ;
            itemflags = EEikDlgItemTakesEnterKey;
            control = DATE_EDITOR
                {
                minDate = DATE { year = 1900; };
                maxDate= DATE { year = 2100; };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EEikCtTimeEditor;
            prompt = "Time";
            id = EMyAppControlIdTimeEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = TIME_EDITOR
                {
                minTime = TIME {};
                maxTime = TIME { second = 59; minute = 59; hour = 23; };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EEikCtDurationEditor;
            prompt = "Duration";
            id = EMyAppControlIdDurationEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = DURATION_EDITOR
                {
                minDuration = DURATION {};
                maxDuration = DURATION { seconds = 3599; };
                flags = 0;
                };
            }
        };
    }

RESOURCE FORM r_my_form_3
    {
    flags = EEikFormUseDoubleSpacedFormat;
    items =
        {
        DLG_LINE
            {
            type = EAknCtNumericSecretEditor;
            prompt = "Secret number";
            id = EMyAppControlIdNumPwdEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = NUMSECRETED { num_code_chars = 4; };
            },
        DLG_LINE
            {
            type = EEikCtSecretEd;
            prompt = "Secret text";
            id = EMyAppControlIdAlphaPwdEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = SECRETED { num_letters = 8; };
            },
        DLG_LINE
            {
            type = EAknCtIpFieldEditor;
            prompt = "IP address";
            id = EMyAppControlIdIpAddrEd;
            itemflags = EEikDlgItemTakesEnterKey;
            control = IP_FIELD_EDITOR
                {
                min_field_values = IP_FIELD
                    {
                    first_field = 0;
                    second_field = 0;
                    third_field = 0;
                    fourth_field = 0;
                    };
                max_field_values = IP_FIELD
                    {
                    first_field = 255;
                    second_field = 255;
                    third_field = 255;
                    fourth_field = 255;
                    };
                flags = 0;
                };
            },
        DLG_LINE
            {
            type = EAknCtPopupField;
            prompt = "Popup field";
            id = EMyAppControlIdPopupField;
            itemflags = EEikDlgItemTakesEnterKey;
            control = POPUP_FIELD
                {
                flags = EAknPopupFieldFlagAllowsUserDefinedEntry;
                width = 50;
                other = "Other";
                empty = "No items";
                invalid = "Invalid item";
                };
            },
        DLG_LINE
            {
            type = EAknCtPopupFieldText;
            prompt = "Popup field text";
            id = EMyAppControlIdPopupFieldText;
            itemflags = EEikDlgItemTakesEnterKey;
            control = POPUP_FIELD_TEXT
                {
                textarray = r_my_list_popup_items;
                popupfield = POPUP_FIELD {};
                active = 0;
                };
            },
        DLG_LINE
            {
            type = EAknCtSlider;
            prompt = "Slider";
            id = EMyAppControlIdSlider;
            itemflags = EEikDlgItemTakesEnterKey;
            control = SLIDER
                {
                layout = EAknFormSliderLayout2;
                minvalue = 0;
                maxvalue = 20;
                step = 2;
                valuetype = EAknSliderValueNone;
                minlabel = "few";
                maxlabel = "many";
                valuelabel = "Slider value";
                };
            }
        };
    }

Launching the form

The following example code initializes sample data before invoking the form.

// Create example dynamic list for the popup field.
CDesCArray* array = new (ELeave) CDesCArrayFlat( 8 );
CleanupStack::PushL( array );
array->AppendL( _L("January") );
array->AppendL( _L("February") );
array->AppendL( _L("March") );
array->AppendL( _L("April") );
array->AppendL( _L("May") );
array->AppendL( _L("June") );
CAknQueryValueTextArray* textArray = CAknQueryValueTextArray::NewLC();
textArray->SetArray( *array );
CAknQueryValueText* queryVal = CAknQueryValueText::NewLC();
queryVal->SetArrayL( textArray );
queryVal->SetCurrentValueIndex( 0 );

// Initialize example form data.
TMyData myData;
myData.iText = _L("This is a text.");
myData.iGlobalText = _L("This is global text.");
myData.iRichText = _L("This is rich text.");
myData.iNumber = 5;
myData.iInteger = 5;
myData.iFloat = 1.234;
myData.iFix = 12345;
myData.iDate.HomeTime();
myData.iTime.HomeTime();
myData.iDuration = TTimeIntervalSeconds( 1000 );
myData.iNumPwd = _L("1234");
myData.iAlphaPwd = _L("passwd");
myData.iIpAddr = TInetAddr();
myData.iPopupVal = queryVal;
myData.iPopupTextIndex = 2;
myData.iSliderVal = 10;

// Launch the dialog to view/edit data
CAknForm* dlg = new ( ELeave ) CMyForm( myData );
CleanupStack::PushL( dlg );
dlg->ConstructL( 0 ); // default menu items only
CleanupStack::Pop( dlg );
dlg->ExecuteLD( R_MY_DIALOG );
// myData now contains the edited values.

CleanupStack::PopAndDestroy( queryVal );
CleanupStack::PopAndDestroy( textArray );
CleanupStack::PopAndDestroy( array );

Initializing form data

PreLayoutDynInitL() can be overridden to initialize form controls.

void CMyForm::PreLayoutDynInitL()
    {
    CAknForm::PreLayoutDynInitL();
    LoadFormDataL();
    }

void CMyForm::LoadFormDataL()
    {
    CEikEdwin* textEd =
        (CEikEdwin*)Control( EMyAppControlIdTextEd );
    textEd->SetTextL( &iData.iText );
    CEikGlobalTextEditor* globalTextEd =
        (CEikGlobalTextEditor*)Control( EMyAppControlIdGlobalTextEd );
    globalTextEd->SetTextL( &iData.iGlobalText );
    CEikRichTextEditor* richTextEd =
        (CEikRichTextEditor*)Control( EMyAppControlIdRichTextEd );
    richTextEd->SetTextL( &iData.iRichText );
    CEikNumberEditor* numberEd =
        (CEikNumberEditor*)Control( EMyAppControlIdNumberEd );
    numberEd->SetNumber( iData.iNumber );
    CAknIntegerEdwin* integerEd =
        (CAknIntegerEdwin*)Control( EMyAppControlIdIntegerEd );
    integerEd->SetValueL( iData.iInteger );
    CEikFloatingPointEditor* floatEd =
        (CEikFloatingPointEditor*)Control( EMyAppControlIdFloatEd );
    floatEd->SetValueL( &iData.iFloat );
    CEikFixedPointEditor* fixEd =
        (CEikFixedPointEditor*)Control( EMyAppControlIdFixEd );
    fixEd->SetValueL( &iData.iFix );
    CEikDateEditor* dateEd =
        (CEikDateEditor*)Control( EMyAppControlIdDateEd );
    dateEd->SetDate( iData.iDate );
    CEikTimeEditor* timeEd =
        (CEikTimeEditor*)Control( EMyAppControlIdTimeEd );
    timeEd->SetTime( iData.iTime );
    CEikDurationEditor* durationEd =
        (CEikDurationEditor*)Control( EMyAppControlIdDurationEd );
    durationEd->SetDuration( iData.iDuration );
    CAknNumericSecretEditor* numPwdEd =
        (CAknNumericSecretEditor*)Control( EMyAppControlIdNumPwdEd );
    numPwdEd->SetText( iData.iNumPwd );
    CEikSecretEditor* alphaPwdEd =
        (CEikSecretEditor*)Control( EMyAppControlIdAlphaPwdEd );
    alphaPwdEd->SetText( iData.iAlphaPwd );
    CAknIpFieldEditor* ipAddrEd =
        (CAknIpFieldEditor*)Control( EMyAppControlIdIpAddrEd );
    ipAddrEd->SetAddress( iData.iIpAddr );
    iData.iPopupVal->SetCurrentValueIndex( 0 );
    CAknPopupField* popupField =
        (CAknPopupField*)Control( EMyAppControlIdPopupField );
    popupField->SetQueryValueL( iData.iPopupVal );
    CAknPopupFieldText* popupFieldText =
        (CAknPopupFieldText*)Control( EMyAppControlIdPopupFieldText );
    popupFieldText->SetCurrentValueIndex( iData.iPopupTextIndex );
    CAknSlider* slider =
        (CAknSlider*)Control( EMyAppControlIdSlider );
    slider->SetValueL( iData.iSliderVal );
    }

Saving form data

Pressing the Back softkey in the edit state causes calls to QuerySaveChangesL() then SaveFormDataL() or DoNotSaveFormDataL(). The following example saves data from form controls to the data structure.

TBool CMyForm::SaveFormDataL()
    {
    CEikEdwin* textEd =
        (CEikEdwin*)Control( EMyAppControlIdTextEd );
    textEd->GetText( iData.iText );
    CEikGlobalTextEditor* globalTextEd =
        (CEikGlobalTextEditor*)Control( EMyAppControlIdGlobalTextEd );
    globalTextEd->GetText( iData.iGlobalText );
    CEikRichTextEditor* richTextEd =
        (CEikRichTextEditor*)Control( EMyAppControlIdRichTextEd );
    richTextEd->GetText( iData.iRichText );
    CEikNumberEditor* numberEd =
        (CEikNumberEditor*)Control( EMyAppControlIdNumberEd );
    iData.iNumber = numberEd->Number();
    CAknIntegerEdwin* integerEd =
        (CAknIntegerEdwin*)Control( EMyAppControlIdIntegerEd );
    (void)integerEd->GetTextAsInteger( iData.iInteger );
    CEikFloatingPointEditor* floatEd =
        (CEikFloatingPointEditor*)Control( EMyAppControlIdFloatEd );
    (void)floatEd->GetValueAsReal( iData.iFloat );
    CEikFixedPointEditor* fixEd =
        (CEikFixedPointEditor*)Control( EMyAppControlIdFixEd );
    (void)fixEd->GetValueAsInteger( iData.iFix );
    CEikDateEditor* dateEd =
        (CEikDateEditor*)Control( EMyAppControlIdDateEd );
    iData.iDate = dateEd->Date();
    CEikTimeEditor* timeEd =
        (CEikTimeEditor*)Control( EMyAppControlIdTimeEd );
    iData.iTime = timeEd->Time();
    CEikDurationEditor* durationEd =
        (CEikDurationEditor*)Control( EMyAppControlIdDurationEd );
    iData.iDuration = durationEd->Duration();
    CAknNumericSecretEditor* numPwdEd =
        (CAknNumericSecretEditor*)Control( EMyAppControlIdNumPwdEd );
    numPwdEd->GetText( iData.iNumPwd );
    CEikSecretEditor* alphaPwdEd =
        (CEikSecretEditor*)Control( EMyAppControlIdAlphaPwdEd );
    alphaPwdEd->GetText( iData.iAlphaPwd );
    CAknIpFieldEditor* ipAddrEd =
        (CAknIpFieldEditor*)Control( EMyAppControlIdIpAddrEd );
    iData.iIpAddr = ipAddrEd->Address();
    iData.iPopupVal->SetCurrentValueIndex( 0 );
    CAknPopupField* popupField =
        (CAknPopupField*)Control( EMyAppControlIdPopupField );
    popupField->SetQueryValueL( iData.iPopupVal );
    CAknPopupFieldText* popupFieldText =
        (CAknPopupFieldText*)Control( EMyAppControlIdPopupFieldText );
    iData.iPopupTextIndex = popupFieldText->CurrentValueIndex();
    CAknSlider* slider =
        (CAknSlider*)Control( EMyAppControlIdSlider );
    iData.iSliderVal = slider->Value();
    return ETrue;
    }

Forms can validate the entered data. SaveFormDataL() should return EFalse if validation failed, this indicates that the data has not been saved. In this case, the form remains in edit state.

Reverting changes

DoNotSaveFormDataL() is called if the user responds No in QuerySaveChangesL(). The form should restore the original data.

void CMyForm::DoNotSaveFormDataL()
    {
    LoadFormDataL();
    }

Modifying the menu

CAknForm always uses menu pane R_AVKON_FORM_MENUPANE. This menu pane contains the following commands:

CommandDescription
EAknFormCmdEditSwitches to edit mode (if allowed).
EAknFormCmdAddAdds field. Method AddFieldL() is called. Default implementation is empty.
EAknFormCmdSaveSaves and switches to view mode. SaveFormDataL() is called. Default implementation is empty.
EAknFormCmdLabelEdits field label. Default implementation is provided.
EAknFormCmdDeleteDeletes field. DeleteCurrentItemL() is called. Default implementation is empty.
EAknFormMaxDefaultEnd marker for the enumeration.

 

CAknForm handles these commands and their associated menu items.

DynInitMenuPaneL() allows modifying the menu. The following example appends the items of a custom menu pane to the form menu:

RESOURCE MENU_PANE r_my_extra_menu
    {
    items =
        {
        MENU_ITEM { command = EMyCommand; txt = "Dynamic menu item"; }
        };
    }
void CMyForm::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane )
    {
    CAknForm::DynInitMenuPaneL( aResourceId, aMenuPane );
    if ( aResourceId == R_AVKON_FORM_MENUPANE )
        {
        aMenuPane->AddMenuItemsL
            ( R_MY_EXTRA_MENU, EAknFormMaxDefault - 1, ETrue );
        }
    }

The same effect can achieved by passing the ID of a MENU_BAR resource to CAknForm::ConstructL(). Menu items from R_MY_MENUBAR will be appended to R_AVKON_FORM_MENUPANE:

RESOURCE MENU_BAR r_my_menubar
    {
    titles=
        {
        MENU_TITLE { menu_pane = r_my_extra_menu; txt=""; }
        };
    }
// Launch the dialog to view/edit data
CAknForm* dlg = new ( ELeave ) CMyForm( myData );
CleanupStack::PushL( dlg );
dlg->ConstructL( R_MY_MENUBAR );
CleanupStack::Pop( dlg );
dlg->ExecuteLD( R_MY_DIALOG );
// myData now contains edited values.

Processing commands

ProcessCommandL() can be overridden to handle custom commands. Built-in form commands are handled by CAknForm.

void CMyForm::ProcessCommandL( TInt aCommandId )
    {
    // Form default commands.
    CAknForm::ProcessCommandL( aCommandId );
    // Custom commands.
    switch ( aCommandId )
        {
        case EMyCommand:
            User::InfoPrint( _L("my command") );
            break;
        default:
            break;
        }
    }

Managing fields

In edit mode, fields can be added or deleted dynamically. CAknForm::AddItemL() and CAknForm::DeleteCurrentItemL() provide default implementation for handling the commands EAknFormCmdAdd andEAknFormCmdDelete, respectively.

The following sample adds an editor control.

void CMyForm::AddItemL()
    {
    _LIT( caption, "Added text" );
    TInt pageId = ActivePageId();
    TInt id = iAddedItemId++; // All controls must have unique id.
    TInt type = EEikCtEdwin;
    TAny* unused=0;
    CEikEdwin* edwin = (CEikEdwin*)CreateLineByTypeL
        ( caption, pageId, id, type, unused );
    edwin->ConstructL
        ( EEikEdwinNoHorizScrolling | EEikEdwinResizable, 10, 100, 1 );
    Line( id )->ActivateL();
    SetChangesPending( ETrue );
    UpdatePageL( ETrue );
    }

Note that all controls in the dialog must have a unique ID. The sample code uses its iAddedItemId member to ensure that IDs are unique, but does not store the IDs of the dynamically created controls. Real-life implementations need the IDs to access field data later.

enum TMyControlIds
    {
    EMyAppControlIdTextEd = 100,
    EMyAppControlIdGlobalTextEd,
    EMyAppControlIdRichTextEd,
    EMyAppControlIdNumberEd,
    EMyAppControlIdIntegerEd,
    EMyAppControlIdFloatEd,
    EMyAppControlIdFixEd,
    EMyAppControlIdDateEd,
    EMyAppControlIdTimeEd,
    EMyAppControlIdDurationEd,
    EMyAppControlIdNumPwdEd,
    EMyAppControlIdAlphaPwdEd,
    EMyAppControlIdIpAddrEd,
    EMyAppControlIdPopupField,
    EMyAppControlIdPopupFieldText,
    EMyAppControlIdSlider,
    EMyAppControlIdFirstAdded   // Dynamically added items
    };
CMyForm::CMyForm( TMyData& aData ) : iData( aData ), iAddedItemId( EMyAppControlIdFirstAdded ) // Need unique control ids. { }

Adding fields dynamically is also useful if the form is used to manipulate data which has a variable structure. In this case, the FORM structure can be left empty in the resource definition, and PreLayoutDynInitL()can be used to add appropriate fields as necessary.

Adding custom field

Custom controls can be added to dialogs by overriding CreateCustomControlL(), as described in document S60 3.1 Dialogs API Specification.

In order to support laying out the custom control in forms, the method ConvertCustomControlTypeToBaseControlType() must be provided. This method determines the layout class of the custom control.

MEikDialogPageObserver::TFormControlTypes
CMyForm::ConvertCustomControlTypeToBaseControlType( TInt aControlType ) const
    {
    if ( aControlType == EAknCtIpFieldEditor )
        {
        // Help layout of custom control.
        return MEikDialogPageObserver::EMfneDerived;
        }
    return CAknForm::ConvertCustomControlTypeToBaseControlType( aControlType );
    };

Error handling

Form API uses standard Symbian OS error reporting mechanism and standard error codes.

Memory overhead

Memory consumption of dialogs depends on the contained controls.

Limitations of the API

None.


Copyright © Nokia Corporation 2001-2007
Back to top

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值