Symbian OS控件開發之對話框

Symbian OS控件開發之對話框
新一篇: 深入理解Symbian控件架構

Symbian OS的對話框分爲模式對話框和非模式對話框。對話框首先需要在資源文件中定義(對話框所容納的控件也需要在資源文件中定義),然後在程序中建立對話框對象並使用資源文件中的對話框id進行初始化,最後執行對話框並顯示相關內容。
對話框的種類很多,除了標準對話框外,還有窗體、通知對話框、查詢對話框、列表對話框等類型。
* 窗體:與列表控件相似,但不同的是,窗體的每一個數據項都是可以編輯的。
* 通知對話框:主要用於顯示用戶的提示信息。
* 查詢對話框:包含一個編輯框,用戶可以向文本編輯器輸入數據供程序查詢,主要用於數據查詢中。
* 列表對話框:包含一個列表控件,可以顯示多項數據。查詢對話框:

數據查詢對話框

在程序中首先要在資源文件中定義查詢對話框:
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,並指定了它的寬度,行數和最大長度的屬性。
列表查詢對話框
它將各種選項以列表的形式顯示出來,用戶可以選取其中的任何一項。

Symbian常用對話框
2006-12-25 21:41
1、文本詢問對話框
資源的定義(注意分號)

RESOURCE DIALOG r_text_query
{
flags = EGeneralQueryFlags;
buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
items =
{
DLG_LINE
{
type = EAknCtQuery;
id = EGeneralQuery;
control = AVKON_DATA_QUERY
{
layout = EDataLayout;
label = "";
control = EDWIN
{
width = 5;
lines = 1;
maxlength = 15;
};
};
}
};
}

調用該類的代碼

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被按下
}

2、列表詢問對話框
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()){}


3、另外Symbian中建立簡單常用對話框的較快方法,無須使用資源

static TBool CEikonEnv::QueryWinL(const TDesC &aFirstLine, const TDesC &aSecondLine);
顯示一個帶有指定文本行的詢問對話框,提供Yes/No。如選Yes,返回ETrue

static void CEikonEnv::InfoWinL(const TDesC &aFirstLine, const TDesC &aSecondLine);
顯示一個帶有指定文本行的信息對話框

static void CEikonEnv::AlertWinL(const TDesC &aFirstLine, const TDesC &aSecondLine);
顯示一個帶有指定文本行的報警對話框


1、非阻塞提示框
symbian定義了幾個提示類,分別是:
confirm類:CAknConfirmationNote
info類: CAknInformationNote
warning類:CAknWarningNote
error類: CAknErrorNote
頭文件:aknnotewrappers.h
lib:avkon.lib eikcdlg.lib eikctl.lib

使用方法:

Code:
TBuf<32> buf;
buf.Copy(_L("info note"));
CAknInformationNote* iInfoNote = new (ELeave) CAknInformationNote;
iInfoNote->ExecuteLD(buf);

2、阻塞提示框
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中使用,使用方法如下:

Code:
iEikonEnv->AlertWin(_L("text"));

InfoWinL可以在任意類中使用,使用方法如下:
Code:
CEikonEnv::Static()->InfoWinL(_L("note:"), _L("text"));

爲方便使用,常定義宏來使用這類提示框,如:

Code:
#define DEBUG_DIALOG(x) iEikonEnv->AlertWin(##x);
#define DEBUG_DIALOG1(x) CEikonEnv::Static()->InfoWinL(_L("note:"), ##x);
#define DEBUG_DIALOG2(x,y) CEikonEnv::Static()->InfoWinL(##x, ##y);

可以這麼使用:
TBuf<32> buf;
buf.Copy(_L("test"));
DEBUG_DIALOG(buf);
DEBUG_DIALOG1(buf);
DEBUG_DIALOG2(buf,_L("text"));

此類提示框阻塞線程,只有用戶按鍵退出提示框後,後面的程序才能接着運行。

3、進度條對話框
進度條對話框類爲:
CAknProgressDialog
頭文件:aknprogressdialog.h
lib: avkon.lib eikcdlg.lib eikctl.lib

使用方法:

Code:
//初始化進度條
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;

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;
};
}
};
}

4、等待對話框
等待對話框要用到的類:
CAknGlobalNote
頭文件:aknglobalnote.h
lib:aknnotify.lib eiksrv.lib

使用方法:

Code:
//顯示等待對話框
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的第一個參數指定,可能的類型如下:


Code:
enum TAknGlobalNoteType
{
EAknGlobalInformationNote = 1,
EAknGlobalWarningNote,
EAknGlobalConfirmationNote,
EAknGlobalErrorNote,
EAknGlobalChargingNote,
EAknGlobalWaitNote,
EAknGlobalPermanentNote,
EAknGlobalNotChargingNote,
EAknGlobalBatteryFullNote,
EAknGlobalBatteryLowNote,
EAknGlobalRechargeBatteryNote,
EAknCancelGlobalNote,
EAknGlobalTextNote
};

5、詢問對話框
詢問對話框用到的類:
CAknQueryDialog
頭文件:AknQueryDialog.h
lib:avkon.lib

使用方法:

Code:
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參數指定,可能的值如下:

Code:
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
};

通過定義不同的詢問對話框資源,可實現不同的詢問對話框,如讓用戶輸入文字的詢問對話框資源定義如下:

Code:
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;
};
};
}
};
}
使用方法:

Code:
TBuf<128> msg;
CAknTextQueryDialog* dlg = new (ELeave) CAknTextQueryDialog(msg,CAknQueryDialog::ENoTone);
TInt ret = dlg->ExecuteLD(R_RESOURCE_DATA_QUERY);

用戶輸入內容後按“確定”,內容就存儲到msg中,函數返回非0;按“取消”,函數返回0。

這裏用到的類是CAknQueryDialog的子類CAknTextQueryDialog。
CAknQueryDialog的子類有:

Code:
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時,可指定輸入發,如:

Code:
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;
};

以上寫法表示默認輸入法爲數字,並且屏蔽了輸入法切換鍵,即不能通過輸入法切換鍵來切換輸入法。

6、編輯框
編輯框使用的類:
CEikGlobalTextEditor
頭文件:eikgted.h

使用方法:

Code:
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( &paraFormat, 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函數,如下:

Code:
TKeyResponse CMobileGuardSetKeyContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
{
return iGKeyEd->OfferKeyEventL( aKeyEvent, aType );
}

標準對話框
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()負責對話框的顯示。

等待通知和進度通知的用法
MAknBackgroundProcess有四個接口函數
void DialogDismissedL(TInt /*aButtonId*/);
TBool IsProcessDone() const;
void ProcessFinished();
void StepL();
一個MAknBackgroundProcess應該對應一個CActive
應該與CAknWaitNoteWrapper配合使用,當CAknWaitNoteWrapper調用執行方法以後。就會彈出指定對話框,然後不斷詢問是否IsProcessDone()。如果IsProcessDone就結束對話框的等待。首先你需要定義一個對話框
RESOURCE DIALOG r_waitnote_load_image_note
{
flags=EAknWaitNoteFlags;
items =
{
DLG_LINE
{
type = EAknCtNote;
id = ENoteDlgCIdOpenImageNote;
control = AVKON_NOTE
{
layout = EWaitLayout;
singular_label = "load image ,please wait";
imagefile = "z://system/data/avkon.mbm";
imageid = EMbmAvkonQgn_note_progress;
imagemask = EMbmAvkonQgn_note_progress_mask;
animation = R_QGN_GRAF_WAIT_BAR_ANIM;
};
}
};
}
在你的代碼中加入:
CAknWaitNoteWrapper* waitNoteWrapper = CAknWaitNoteWrapper::NewL();
// Required reinterpret_cast as CAknWaitNoteWrapper inherits privately from CActive
CleanupStack::PushL(reinterpret_cast<CBase*>(waitNoteWrapper));

TInt Result=0;
Result=waitNoteWrapper->ExecuteL(R_WAITNOTE_LOAD_IMAGE_NOTE, *this);
if (!Result ) // this is a blocking call, remember the wrapper isn't a dialog, so it

doesn't need the EEikDialogFlagWait flag to make it blocking
{
// Cancel
}
CleanupStack::PopAndDestroy();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章