Sie sind auf Seite 1von 32

S60 5th Edition C++ Developer's Library v2.

1 > S60 C++ API reference > C++ API R


eference > S60 Platform Services > Classic UI Services > Form API
Form API: Using Form API
* Form API: Using Form API
o Defining the form resource
+ Single-page form
+ Multi-page form
o Launching the form
o Initializing form data
o Saving form data
o Reverting changes
o Modifying the menu
o Processing commands
o Managing fields
o Adding custom field
o Error handling
o Memory overhead
o Limitations of the API
To use forms, the dialog resource (RESOURCE DIALOG) must be defined in the appli
cation 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 res
ource, 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 defin
ed in the eikon.hrh file.
* pages, which is a reference to an ARRAY of PAGE. Used only in multi-page f
orms (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 DIA
LOG structure members.
STRUCT FORM
{
WORD flags = 0;
STRUCT items[];
}

The FORM structure member flags can be used to specify the style of the form. Th
e default setting is single-line display, and the predefined values are as follo
ws:
Flag Description
EEikFormUseDoubleSpacedFormat Double-line display.
EEikFormHideEmptyFields Makes empty data fields invisible.
EEikFormShowBitmaps Displays a bitmap on a label.
EEikFormEditModeOnly Displays the form in edit mode only.
EEikFormShowEmptyFields Displays 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 EEikCtEdwin, EEikCtNumberEdi
tor, EEikCtDateEditor, EEikCtTimeEditor, EEikCtDurationEditor, EEikCtSecretEd, o
r EAknCtSlider. Types are defined in the eikon.hrh or avkon.hrh files. For detai
ls 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 applicat
ion, 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 ap
plication panics when the dialog is executed.
* itemflags, such as EEikDlgItemTakesEnterKey or EEikDlgItemOfferAllHotKeys.
* control, which specifies the field control. Controls are defined in HRH fi
les.
* 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 me
mber 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 ex
ample (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 f
rom 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 val
idation failed, this indicates that the data has not been saved. In this case, t
he form remains in edit state.
Reverting changes
DoNotSaveFormDataL() is called if the user responds No in QuerySaveChangesL(). T
he 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 th
e following commands:
Command Description
EAknFormCmdEdit Switches to edit mode (if allowed).
EAknFormCmdAdd Adds field. Method AddFieldL() is called. Default implementation
is empty.
EAknFormCmdSave Saves and switches to view mode. SaveFormDataL() is call
ed. Default implementation is empty.
EAknFormCmdLabel Edits field label. Default implementation is provided.
EAknFormCmdDelete Deletes field. DeleteCurrentItemL() is called. Default i
mplementation is empty.
EAknFormMaxDefault End 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 CAknFor
m::ConstructL(). Menu items from R_MY_MENUBAR will be appended to R_AVKON_FORM_M
ENUPANE:
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 com
mands 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() a
nd CAknForm::DeleteCurrentItemL() provide default implementation for handling th
e commands EAknFormCmdAdd and EAknFormCmdDelete, 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 I
Ds of the dynamically created controls. Real-life implementations need the IDs t
o 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( EMyAppControl


IdFirstAdded ) // 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 emp
ty in the resource definition, and PreLayoutDynInitL() can be used to add approp
riate 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 ConvertCu
stomControlTypeToBaseControlType() 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 c
odes.
Memory overhead
Memory consumption of dialogs depends on the contained controls.
Limitations of the API
None.
Copyright © Nokia Corporation 2001-2008
Back to top

Das könnte Ihnen auch gefallen