Symbian对话框
Symbian OS的对话框首先需要在资源文件中定义(对话框所容纳的控件也需要在资源文件中定义),然后在程序中建立对话框对象并使用资源文件中的对话框id进行初始化,最后执行对话框并显示相关内容。
所有的对话框都有一些基本的属性。所有的对话框都继承于CCoeControl(冲CAknDialog 可以追溯到 CCoeControl)这个类。对话框构架管理器负责管理对话框的所有行为,包括布局,外观,以及用户输入。典型的,不管对话框有多复杂,它们都是定义在资源文件里的。通常情况下,对话框的布局和坐标都是自动的。
S60大部分的对话框都继承于CAknDialog。S60提供一些具体的类来创建表单,查询,或通知,当然我们也可以编写自己的类来实现更复杂的对话框,不过对于我们自己写的类来说,也需要继承CAknDialog,这很重要,因为这个基类提供了对话框所需要的基本属性。
Symbian OS的对话框可以是模态(modal)或无模态(modeless)的,同时还可以是等待(waiting)或非等待(nonwaiting)的。对话框含有若干个竖直排列的行,每行包含一个或多个控件。模态对话框在被关闭之前会阻止用户与应用程序UI的其他部分交互,而无模态对话框处于活动状态时,用户仍能与应用程序UI的其他部分交互。非等待对话框允许应用程序在后台继续处理,而等待对话框会阻止应用程序在该对话框关闭前的执行的任何进一步的处理。 Series 60的对话框默认是模态和非等待对话框。在Series 60中很少会用到无模态对话框,因为Series 60中显示的对话框在关闭之前一般都拥有输入焦点。
对话框的种类很多,除了标准对话框外,还有窗体、通知对话框、查询对话框、列表对话框等类型。
* 窗体:与列表控件相似,但不同的是,窗体的每一个数据项都是可以编辑的。
* 通知对话框:主要用于显示用户的提示信息。
* 查询对话框:包含一个编辑框,用户可以向文本编辑器输入数据供程序查询,主要用于数据查询中。
* 列表对话框:包含一个列表控件,可以显示多项数据。查询对话框:
Symbian中建立简单常用对话框的较快方法,无须使用资源::
1:static TBool CEikonEnv::QueryWinL(const TDesC &aFirstLine, const TDesC &aSecondLine);
显示一个带有指定文本行的询问对话框,提供Yes/No。如选Yes,返回ETrue
2:static void CEikonEnv::InfoWinL(const TDesC &aFirstLine, const TDesC &aSecondLine);
显示一个带有指定文本行的信息对话框
CEikonEnv::Static()->InfoWinL(_L("note:"), _L("text"));
CEikonEnv::InfoWinL(_L("note:"), _L("text"));
iEikonEnv->InfoWinL(_L("note:"), _L("text"));
3:void CEikonEnv::AlertWin(const TDesC &aFirstLine, const TDesC &aSecondLine);
显示一个带有指定文本行的报警对话框
AlertWin为CEikonEnv类的非静态成员函数,InfoWinL为CEikonEnv类的静态成员函数。
AlertWin只能在ui、view和container中使用,使用方法如下:
iEikonEnv->AlertWin(_L("text"));
CEikonEnv::Static()->AlertWin(_L("text"));
4:symbian定义了几个提示类(这几个都是非阻塞提示框),分别是:
confirm类:CAknConfirmationNote
info类: CAknInformationNote
warning类:CAknWarningNote
error类: CAknErrorNote
头文件:aknnotewrappers.h
lib:avkon.lib eikcdlg.lib eikctl.lib
使用方法:
TBuf<32> buf;
buf.Copy(_L("info note"));
CAknInformationNote* iInfoNote = new (ELeave) CAknInformationNote;
iInfoNote->ExecuteLD(buf);
5:(这几个都是阻塞提示框)
void CEikonEnv::AlertWin(const TDesC& aMsg);
void CEikonEnv::AlertWin(const TDesC& aMsg1,const TDesC& aMsg2);
static void CEikonEnv::InfoWinL(const TDesC& aFirstLine,const TDesC& aSecondLine);
AlertWin为CEikonEnv类的非静态成员函数,InfoWinL为CEikonEnv类的静态成员函数。
AlertWin只能在ui、view和container中使用,使用方法如下:
iEikonEnv->AlertWin(_L("text"));
InfoWinL可以在任意类中使用,使用方法如下:
CEikonEnv::Static()->InfoWinL(_L("note:"), _L("text"));
此类提示框阻塞线程,只有用户按键退出提示框后,后面的程序才能接着运行。
6、等待对话框(无须定义资源)
等待对话框要用到的类:
CAknGlobalNote
头文件:aknglobalnote.h
lib:aknnotify.lib eiksrv.lib
使用方法:
//显示等待对话框
CAknGlobalNote* globalNote = CAknGlobalNote::NewL();
CleanupStack::PushL( globalNote );
TInt iWaitNoteId = globalNote->ShowNoteL( EAknGlobalWaitNote, _L("对话框中显示的文字") );
CleanupStack::PopAndDestroy();
//结束等待对话框
CAknGlobalNote * note = CAknGlobalNote::NewL();
CleanupStack::PushL( note );
note->CancelNoteL( iWaitNoteId );
CleanupStack::PopAndDestroy();
注:
CAknGlobalNote类除了显示等待对话框外还可显示多种类型的全局对话框,具体类型可通过ShowNoteL的第一个参数指定,可能的类型如下:
enum TAknGlobalNoteType
{
EAknGlobalInformationNote = 1,
EAknGlobalWarningNote,
EAknGlobalConfirmationNote,
EAknGlobalErrorNote,
EAknGlobalChargingNote,
EAknGlobalWaitNote,
EAknGlobalPermanentNote,
EAknGlobalNotChargingNote,
EAknGlobalBatteryFullNote,
EAknGlobalBatteryLowNote,
EAknGlobalRechargeBatteryNote,
EAknCancelGlobalNote,
EAknGlobalTextNote
};
Symbian常用对话框举例:
1、询问对话框
询问对话框用到的类:
CAknQueryDialog
头文件:AknQueryDialog.h
lib:avkon.lib
使用方法:
CAknQueryDialog* dlg;
dlg = CAknQueryDialog::NewL( CAknQueryDialog::ENoTone );
dlg->PrepareLC( R_RESOURCE_QUERY_DIALOG ); //从资源文件构造对话框,资源见下面的定义
TInt ret = dlg->RunLD(); //若用户选择“是”,返回非0,选择“否”,则返回0
RESOURCE DIALOG R_RESOURCE_QUERY_DIALOG //询问对话框资源
{
flags = EGeneralQueryFlags;
buttons = R_AVKON_SOFTKEYS_YES_NO; //CBA显示“是”和“否”两个按钮
items =
{
DLG_LINE
{
type = EAknCtQuery;
id = EGeneralQuery;
control = AVKON_CONFIRMATION_QUERY //表示这是confirm询问对话框,用户选择“是”或“否”
{
layout = EConfirmationQueryLayout;
label = "对话框中显示的文字";
};
}
};
}
此类对话框可以有声音提示,由NewL的const TTone& aTone参数指定,可能的值如下:
enum TTone {
/// No tone is played
ENoTone = 0,
/// A confirmation tone is played
EConfirmationTone = EAvkonSIDConfirmationTone,
/// A warning tone is played
EWarningTone = EAvkonSIDWarningTone,
/// An error tone is played
EErrorTone = EAvkonSIDErrorTone
};
通过定义不同的询问对话框资源或使用不同的CAknQueryDialog的子类(使用不同的类,资源文件会有所不同),可实现不同的询问对话框,如让用户输入文字的询问对话框资源定义如下:
RESOURCE DIALOG R_RESOURCE_DATA_QUERY
{
flags = EGeneralQueryFlags;
buttons = R_AVKON_SOFTKEYS_OK_CANCEL; //CBA按钮显示“确定”和“取消”
items =
{
DLG_LINE
{
type = EAknCtQuery;
id = EGeneralQuery;
control = AVKON_DATA_QUERY //表示这是data询问对话框,需要用户输入内容
{
layout = EDataLayout;
label = "提示内容";
control = EDWIN
{
flags = EEikEdwinNoHorizScrolling | EEikEdwinResizable;
width = 30;
lines = 2;
maxlength = 159;
};
};
}
};
}
使用方法1:
TBuf<128> msg;
CAknTextQueryDialog* dlg =
new (ELeave) CAknTextQueryDialog(msg,CAknQueryDialog::ENoTone);
// CAknTextQueryDialog 有两个构造函数
// CAknTextQueryDialog (TDes &aDataText, const TTone &aTone=ENoTone)
// CAknTextQueryDialog (TDes &aDataText, TDesC &aPrompt, const TTone //&aTone=ENoTone)
TInt ret = dlg->ExecuteLD(R_RESOURCE_DATA_QUERY);
用户输入内容后按“确定”,内容就存储到msg中,函数返回非0;按“取消”,函数返回0。
使用方法2:
TBuf<128> text; //保存用户输入信息
TBuf<128> prompt(_L("Enter text:")); //提示
CAknTextQueryDialog *dlg = new(ELeave)CAknTextQueryDialog(text, prompt);
dlg->SetMaxLength(20);
if (dlg->ExecuteLD(R_TEXT_QUERY))
{
//OK被按下
}
这里用到的类是CAknQueryDialog的子类CAknTextQueryDialog。
CAknQueryDialog的子类有:
CAknFloatingPointQueryDialog //This class should be used when user is reguest to enter a flotaing point number
CAknFixedPointQueryDialog //...
CAknDurationQueryDialog //This class should be used when user is reguest to enter duration
CAknIpAddressQueryDialog //This class should be used when user is reguest to enter IP address,@since 2.1
CAknMultiLineDataQueryDialog //Query Dialog with data input on more than one line (2 lines at the moment)
Create using NewL methods and passing parameters as appropriate.
Attention: When deriving from this class, you must call SetDataL during
second phase construction.
CAknMultiLineIpQueryDialog //...
CAknNumberQueryDialog //This class should be used when user is reguest to enter number
CAknTextQueryDialog //This class should be used when user is reguest to enter plain text, secret text,
phonenumber or PIN-code
CAknTimeQueryDialog //This class should be used when user is reguest to enter time or date
使用不同的类,资源文件会有所不同。
另外,在资源中定义EDWIN时,可指定输入法,如:
control = EDWIN
{
flags = EEikEdwinNoHorizScrolling | EEikEdwinResizable;
width = 11;
lines = 1;
maxlength = 11;
avkon_flags = EAknEditorFlagFixedCase |
EAknEditorFlagNoT9 | EAknEditorFlagSupressShiftMenu; //EAknEditorFlagSupressShiftMenu屏蔽切换输入法键
allowed_input_modes = EAknEditorNumericInputMode;
default_input_mode = EAknEditorNumericInputMode;
numeric_keymap = EAknEditorPlainNumberModeKeymap;
};
以上写法表示默认输入法为数字,并且屏蔽了输入法切换键,即不能通过输入法切换键来切换输入法。
2. 查询对话框
在程序中首先要在资源文件中定义查询对话框:
RESOURCE DIALOG r_data_query_dialog
{
flags = EGeneralQueryFlags;
buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
items =
{
DLG_LINE
{
type = EAknCtQuery;
id = EDataQueryId;
control = AVKON_DATA_QUERY
{
layout = EDataLayout;
control = EDWIN
{
width = 20;
lines = 1;
maxlength = 20;
};
};
}
};
}
在查询对话框里还定义了一个编辑器控件,在资源文件中定义为EDWIN,并指定了它的宽度,行数和最大长度的属性。
3、列表对话框
RESOURCE AVKON_LIST_QUERY r_demo_list_query
{
flags = EGeneralQueryFlags;
softkeys = R_AVKON_SOFTKEYS_OK_CANCEL;
items =
{
AVKON_LIST_QUERY_DLG_LINE
{
control = AVKON_LIST_QUERY_CONTROL
{
listtype = EAknCtSinglePopupMenuListBox;
listbox = AVKON_LIST_QUERY_LIST
{
array_id = r_demo_list_query_item;
};
heading = "Select one item:";
};
}
};
}
RESOURCE ARRAY r_demo_list_query_item
{
items =
{
LBUF {txt = "First item"; },
LBUF {txt = "Second item"; },
LBUF {txt = "Third item"; }
};
}
调用的该资源代码
TInt index( 0 );
CAknListQueryDialog* dlg = new( ELeave ) CAknListQueryDialog( &index );
if ( dlg->ExecuteLD(R_DEMO_LIST_QUERY) )
{
// ok pressed, index is the selected item index.
}
程序中动态设置列表项例子
TInt index( 0 );
CAknListQueryDialog* dlg = new( ELeave ) CAknListQueryDialog( &index );
CDesCArrayFlat *aArray = new(ELeave)CDesCArrayFlat(3);
TBuf<16> aString;
aString.Format(_L("Item %d"), 1);
aArray->AppendL(aString);
aString.Format(_L("Item %d"), 2);
aArray->AppendL(aString);
aString.Format(_L("Item %d"), 3);
aArray->AppendL(aString);
dlg->PrepareLC(R_DEMO_LIST_QUERY);
dlg->SetItemTextArray(aArray);
dlg->SetOwnershipType(ELbmOwnsItemArray);
if (dlg->RunLD()){}
4、进度条对话框
进度条对话框类为:
CAknProgressDialog
头文件:aknprogressdialog.h
lib: avkon.lib eikcdlg.lib eikctl.lib
RESOURCE DIALOG r_resource_progress_note //进度条对话框资源
{
flags = EAknProgressNoteFlags;
buttons = R_AVKON_SOFTKEYS_CANCEL;
items =
{
DLG_LINE
{
type = EAknCtNote;
id = EMagicBoxCtrlIdProgressNote;
control = AVKON_NOTE
{
layout = EProgressLayout;
singular_label = "对话框中显示的文字";
plural_label = "download";
imagefile = AVKON_BMPFILE_NAME; //第二版中 图标文件为 #define AVKON_BMPFILE_NAME
"z://system//data//avkon.mbm"
imageid = EMbmAvkonQgn_note_sml; //这两项可更改显示不同图标
imagemask = EMbmAvkonQgn_note_sml_mask;
};
}
};
}
使用方法:
//初始化进度条
CAknProgressDialog* iProgressDialog;
CEikProgressInfo* iProgressInfo;
iProgressDialog = new ( ELeave ) CAknProgressDialog( reinterpret_cast
<CEikDialog**>
( &iProgressDialog ) );
iProgressDialog->SetCallback( this );
iProgressDialog->PrepareLC( R_RESOURCE_PROGRESS_NOTE ); //从资源文件构造对话框
iProgressInfo = iProgressDialog->GetProgressInfoL();
iProgressInfo->SetFinalValue( aMaxValue ); //设置进度条的最大值(结束值)
iProgressDialog->RunLD();
//更新进度条
iProgressInfo->IncrementAndDraw( aStep );
//结束进度条
iProgressDialog->ProcessFinishedL();
delete iProgressDialog;
5、编辑框(不是对话框)
编辑框使用的类:
CEikGlobalTextEditor
头文件:eikgted.h
使用方法:
CEikGlobalTextEditor* iGKeyEd;
TBuf<128> iKeyText;
TResourceReader reader;
iCoeEnv->CreateResourceReaderLC( reader, R_RESOURCE_EDITOR ); //从资源文件构造编辑框,资源见下面的定义
iGKeyEd = new ( ELeave ) CEikGlobalTextEditor;
iGKeyEd->SetContainerWindowL( *this );
iGKeyEd->ConstructFromResourceL( reader );
CleanupStack::PopAndDestroy(); // Resource reader
//设置编辑框的初始文本和位置,编辑框大小在资源中定义
TBuf<32> buf;
buf.Copy(_L("demo"));
iGKeyEd->SetTextL(&buf);
iGKeyEd->SetExtent( TPoint(5,2), iGKeyEd->MinimumSize() );
iGKeyEd->SetFocus(ETrue);
// iGKeyEd->SetReadOnly(ETrue); //设置编辑框为只读
//使文字居中
CParaFormat paraFormat;
TParaFormatMask paraFormatMask;
paraFormatMask.SetAttrib( EAttAlignment ); // set mask
paraFormat.iHorizontalAlignment = CParaFormat::ECenterAlign;
iGKeyEd->ApplyParaFormatL( ¶Format, paraFormatMask );
iGKeyEd->GetText(iKeyText); //获取编辑框中的内容,保存到iKeyText中
RESOURCE GTXTED r_resource_editor //编辑框资源
{
flags = EAknEditorFlagDefault;
width = 53;
height = 16;
numlines = 1;
textlimit= 1;
fontcontrolflags = EGulFontControlAll;
fontnameflags = EGulNoSymbolFonts;
//这里也可设置输入法
// avkon_flags = EAknEditorFlagFixedCase |
EAknEditorFlagNoT9 | EAknEditorFlagSupressShiftMenu; //EAknEditorFlagSupressShiftMenu
屏蔽切换输入法键
// allowed_input_modes = EAknEditorNumericInputMode;
// default_input_mode = EAknEditorNumericInputMode;
// numeric_keymap = EAknEditorPlainNumberModeKeymap;
}
注意:
要使编辑框正常显示,记得更改container的CountComponentControls和ComponentControl函数,正确处理控件数目和编辑框指针。
另外,要使编辑框能正常接收按键事件,要显式调用编辑框的OfferKeyEventL函数,如下:
TKeyResponse CMobileGuardSetKeyContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
{
return iGKeyEd->OfferKeyEventL( aKeyEvent, aType );
}
6. 带有编辑框的对话框
Symbian OS中的对话框都从CAknDialog中继承,大多数对话框是一个容器,可以容纳其他控件。下面示例如何在资源文件中定义一个带有编辑框的对话框:
RESOURCE DIALOG r_dialog_edit_dialog
{
flags = EEikDialogFlagNoDrag | EEikDialogFlagCbaButtons | EEikDialogFlagWait;
buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
items = {
DLG_LINE
{
id = EConfirmationNoteDlgCIdFileName;
type = EEikCtLabel;
control = LABEL { };
},
DLG_LINE
{
id = EConfirmationNoteDlgCIdEditor;
type = EEikCtEdwin;
control = EDWIN { maxlength = 20; };
}
};
}
DIALOG有以下几个属性需要设置:
1.flag属性。定义对话框自身的性质。示例中定义了三个属性--EEikDialogFlagNoDrag(不可拖动), EEikDialogFlagCbaButtons(使用软键),
EEikDialogFlagWait(等待)。这些标志在uikon.hrh中定义。
2.buttons属性。指出对话框使用的软键。在avkon.rsg中定义。
3.items属性。定义了对话框中实际包含的内容。items由一些DLG_LINE组成,每一个DLG_LINE包含了一个控件。
4.DLG_LINE属性。表示对话框的每一行,控件通常由id,type和control组成。
在资源文件中定义好对话框之后,即可以编写自己的对话框类,Symbian OS的所有对话框类都从CAknDialog继承而来。需要包含头文件akndialog.h。
以下是CAknDialog的几个重要函数:
1.PreLayoutDynInitL(),完成对话框装载前的初始化工作。对话框中控件的初始化在此函数中进行,通过对话框的成员函数ControlOrNull()来通过id得到控件指针;如果id存在,返回CCoeControl指针,如果不存在,返回NULL。可以使用函数Control()来得到控件指针,与ControlOrNull()不同的是,如果id不存在,Control()返回一个错误。
2.OkToExitL(),点击OK键(EAknSoftkeyOk),对话框退出之前调用此函数以获取对话框中控件的数据。
3.静态函数TBool RunDlgLD(),该函数包含一个对话框的一阶构造函数ExecuteLD(),该函数用来构造、显示和销毁对话框。在程序中显示对话框,只需调用CXXXDialog::RunDlgLD()即可。
TBool CSimpleDialog::RunDlgLD()
{
CSimpleDialog* dialog=new(ELeave) CSimpleDialog();
return dialog->ExecuteLD(R_DIALOG_EDIT_DIALOG);
}
ExecuteLD()调用了CAknDialog的两个函数PrepareLC()和RunLD()。其中PrepareLC()负责将对话框指针放到清理栈,完成对话框的构建。RunLD()负责对话框的显示。