×
Namespaces

Variants
Actions

Symbian C++中的表单

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

文章
翻译:
hoolee
最后由 hamishwillee 在 22 Dec 2011 编辑

Contents

什么是表单

表单提供了一个方法让用户可以快捷一次录入多个数据。表单有一组填写区域,类似于列表的显示方式。用户可以上下滚动操作。不同与列表选项的是,每个表单行被选中时是可以编辑的。

表单有视图模式和编辑模式,或者只有一个编辑模式。视图模式的使用包含了显示在表单中的信息,用户可以编辑它们。例如在一个游戏程序中,可以用视图模式的表单显示相关信息,然后转到编辑模式改变这些信息。

mmp文件中的lib库

LIBRARY  eikdlg.lib


头文件

#include <aknform.h> 
#include <eikedwin.h>
#include <e32cmn.h>

从资源中生成表单

表单包含在DIALOG资源中,我们可以指明表单的组成部分

RESOURCE DIALOG r_myform_form_dialog
{
flags = EEikDialogFlagNoDrag |
EEikDialogFlagFillAppClientRect |
EEikDialogFlagWait |
EEikDialogFlagCbaButtons;
 
buttons = R_AVKON_SOFTKEYS_OPTIONS_BACK;
form = r_myform_form;
}


// r_myform_form is defined as :
 
RESOURCE FORM r_myform_form
{
flags = EEikFormUseDoubleSpacedFormat ;
items =
{
DLG_LINE
{
type=EEikCtEdwin;
prompt=NAME_TEXT;
id=EmyformDlgCIdEdwin;
itemflags = EEikDlgItemTakesEnterKey | EEikDlgItemOfferAllHotKeys;
control=EDWIN
{
width=50;
maxlength=50;
};
},
DLG_LINE
{
type=EEikCtEdwin;
prompt=PHONE_NO_TEXT;
id=EmyformDlgCIdEdwin2;
itemflags = EEikDlgItemTakesEnterKey | EEikDlgItemOfferAllHotKeys;
control=EDWIN
{
width=50;
maxlength=50;
};
},
DLG_LINE
{
type=EEikCtEdwin;
prompt=EMAIL_TEXT;
id=EmyformDlgCIdEdwin3;
control=EDWIN
{
width=50;
maxlength=50;
};
}
};
}


头文件

// Derive the class from CAknForm
 
class CMyForm : public CAknForm
{
public: // Constructor and destructor
/**
* NewL
* Two-phased constructor.
*/

static CMyForm* NewL();
 
/**
* ~CMyForm
* Destructor.
*/

virtual ~CMyForm();
 
public:
/**
* From CAknForm, ExecuteLD
* @return CAknForm::ExecuteLD return value
* @param aResourceId resource ID
*/

TInt ExecuteLD( TInt aResourceId );
 
/**
* From CAknForm, PrepareLC
* @param aResourceId resource ID
*/

void PrepareLC( TInt aResourceId );
 
private: // Constructor
/**
* CMyForm
* Default constructor.
*/

CMyForm();
 
/**
* ConstructL
* Second-phase constructor.
*/

void ConstructL();
 
private: // Functions from base class
/**
* From CEikDialog, PostLayoutDynInitL
* Set default field value to member data.
*/

void PreLayoutDynInitL();
 
/**
* From CAknForm , QuerySaveChangesL
* Show save query. If user answers "No" to this query.
* return field value to the value which is before editing.
*/

TBool QuerySaveChangesL();
 
/**
* From CAknForm , SaveFormDataL
* Save the contents of the form.
*/

TBool SaveFormDataL();
 
/**
* From CAknForm, DoNotSaveFormDataL
* Does not save the contents of the form.
*/

void DoNotSaveFormDataL();
 
private:
/**
* For holding controls value
*/

TBuf<EAknExFormEdwinMaxLength> iDataName;
...
};

源文件

/**
* Symbian OS 2 phase constructor.
* Constructs the CMyForm using the NewLC method, popping
* the constructed object from the CleanupStack before returning it.
*
* @return The newly constructed CMyForm
*/

 
CMyForm * CMyForm ::NewL()
{
CMyForm * self = new (ELeave) CMyForm ();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}

获得表单控件的值

/**
* Called by the framework whenver the 'Save' menu item is selected, and by the
* QuerySaveChangesL method when the user answers yes to the save query.
* Saves the data from the forms controls.
* @return TBool ETrue if the form data has been saved, EFalse otherwise.
*/

 
TBool CMyForm ::SaveFormDataL()
{
 
CEikEdwin* nEditor = static_cast <CEikEdwin*> (ControlOrNull(EmyformDlgCIdEdwin));
if ( nEditor )
{
// Save the value of Control to class member //
}
 
return ETrue;
}

Setting Form Control Value

/**
* Called when the form is executed and when the user chooses to discard changes
* in QuerySaveChangesL (via DoNotSaveFormDataL).
*/

 
void CMyForm ::LoadFormValuesFromDataL()
{
CEikEdwin* nEditor = static_cast <CEikEdwin*> (ControlOrNull(EmyformDlgCIdEdwin));
if (nEditor)
{
// Example : set the Control Text //
 
TBuf<50> myName;
myName.Copy(_L("Vasant"));
HBufC* name = myName.AllocLC();
// Setting the Value //
 
nEditor->SetTextL(name);
//CleanupStack::PopAndDestroy(name);
 
}
 
 
}
/**
* Called by QuerySaveChangeL when the user chooses to discard changes made to
* the form. Loads the form values from iOpponent
*/

 
void CMyForm ::DoNotSaveFormDataL()
{
LoadFormValuesFromDataL();
}
 
 
/**
* Called by the framework before the form is initialised
* Loads the form values from iOpponent ready for execution of the form
*/

 
void CMyForm ::PreLayoutDynInitL()
{
CAknForm::PreLayoutDynInitL();
LoadFormValuesFromDataL();
}
 
 
/**
* Called by the framework when a menu is displayed.
* Removes the default items from the options menu of the form for editing a
* fields label, adding a field and deleting a field
*/

 
void CMyForm ::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
{
CAknForm::DynInitMenuPaneL(aResourceId,aMenuPane);
 
if (aResourceId == R_AVKON_FORM_MENUPANE)
{
aMenuPane->SetItemDimmed(EAknFormCmdLabel, ETrue);
aMenuPane->SetItemDimmed(EAknFormCmdAdd, ETrue);
aMenuPane->SetItemDimmed(EAknFormCmdDelete, ETrue);
}
}

执行表单

CMyForm* form = CMyForm ::NewL();
TInt ret = form->ExecuteLD( R_MYFORM_FORM_DIALOG );

Getting Key Press Event in Form and Exiting from Form

// override OfferKeyEventL for getting key press events. //
 
TKeyResponse CMyForm::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
// We send EKeyEscape, for exiting from form if user press EKeyLeftArrow
 
if ( aKeyEvent.iCode == EKeyLeftArrow )
{
TKeyEvent key;
key.iCode = EKeyEscape;
key.iScanCode = EStdKeyEscape;
key.iRepeats = 0;
key.iModifiers = 0;
return CAknForm::OfferKeyEventL(key, EEventKey);
}
 
}

为表单添加菜单

// Override DynInitMenuPaneL  //
 
void CMyForm::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
{
CAknForm::DynInitMenuPaneL(aResourceId,aMenuPane);
 
if (aResourceId == R_AVKON_FORM_MENUPANE)
{
// Add the menu from the resource defined in the .rss file
aMenuPane->AddMenuItemsL(R_MOBICRM_ASS_MENU,0,1);
 
}
}

隐藏缺省菜单

void CMyForm::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
{
CAknForm::DynInitMenuPaneL(aResourceId,aMenuPane);
 
if (aResourceId == R_AVKON_FORM_MENUPANE)
{
// you can hide the default form menus //
 
aMenuPane->SetItemDimmed(EAknFormCmdLabel,ETrue);
aMenuPane->SetItemDimmed(EAknFormCmdAdd, ETrue);
aMenuPane->SetItemDimmed(EAknFormCmdDelete, ETrue);
}
}


处理命令

/*
* 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 ECommand1:
User::InfoPrint( _L("Pressed command1 on Form") );
break;
default:
break;
}
}


动态增加控件

在编辑模式中,可以通过CAknForm::AddItemL()动态增加或删除表单域。

void CMyForm::AddItemL()
{
_LIT( caption, "New Control" );
TInt pageId = ActivePageId();
TInt id = iTotalControls++;
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();
SetEditableL( IsEditable() ) ;
DrawNow();
}

设置表单控件获得焦点

// Pass the Id of the Control on which focus is to be set.
TryChangeFocusToL( EmyformDlgCIdEdwin2 );

更新表单

//  Only has effect on forms, call this after adding or deleting lines
UpdatePageL( ETrue );


Getting Control ID in Focus

// Gets the ID of the Control having Focus //
TInt FocusedControlId = IdOfFocusControl();
if( FocusedControlId == EmyformDlgCIdEdwin)
{
// Do Something //
}

获得表单模式(编辑或视图)

if( IsEditable() )
{
// Form is in the edit mode //
}
else
{
// Form is not in the edit mode //
}

常见错误

当从CAknForm派生时,人们可能会犯一些错误,有的甚至没有错误提示因此很难定位他们:

忘记调用基类的ConstructL()

记住,这是一个C类基类,因此需要在二次构造中调用基类的构造函数:

void CYourForm::ConstructL()
{
CAknForm::ConstructL();
}

PrepareLC (TInt aResourceId)实现为空

如果你不想自己重载它,那么需要调用基类的缺省函数,所以要么从代码中删除你的重载,要么如下编码调用缺省的实现:

void CYourForm::PrepareLC (TInt aResourceId)
{
CAknForm::PrepareLC(aResourceId);
}
This page was last modified on 22 December 2011, at 08:03.
118 page views in the last 30 days.
×