此文摘譯自SDK 3rd MR中:/9.1/S60_3rd_MR/S60Doc/s60_platform_avkon_ui_resources_dialogs_v1_1_en.pdf 對話方塊分為single-page對話方塊和multi-page對話方塊。這裡將分別介紹之。 顯示了對話方塊的terminology和philosophy: Multi-page tabs只在多頁對話方塊中存在,它們用來訪問獨立的對話方塊頁。多頁對話方塊與視圖切換架構的區別是,視圖中視圖切換時檢視狀態和資料需要被儲存,每個視圖都可以從外界啟用;而多頁對話方塊在關閉對話方塊事,資料才被儲存,並且不能從外界進入對話方塊的任意Tab頁。大多數Avkon架構是基於對話方塊架構的. 實現對話方塊 S60環境中實現對話方塊有兩個階段: ①在.rss檔案中定義對話方塊資源 ②定義CAknDialog的子類,並實行其中部分虛方法 對話方塊資源定義 對話方塊資源定義使用DIALOG結構,它在eikon.rh中定義: STRUCT DIALOG { LONG flags=0; LTEXT title=""; LLINK pages=0; LLINK buttons=0; STRUCT items[]; LLINK form=0; } Dialog flags DIALOG中的flags指定了對話方塊類型。flags的值在eikon.hrh和avkon.hrh中定義。下面是具體值和含義: 因為相容性的原因,在S60平台中仍保留著一些flags,但在S60平台中它們並沒有使用,下面列舉之: Items — dialog lines 對話方塊行結構在eikon.rh中定義: 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 = "" ; } Dialog items flags 對話方塊行可以有自己的flags。如下表: 下面的flags只為了相容性而仍保留著: Buttons — softkeys 軟體通過CBA資源來定義。下面是avkon.rsg中的預定義軟鍵: 如果上面的軟鍵不能滿足需求,可以通過定義新的CBA資源來定義新的軟體。下面樣本: RESOURCE CBA r_softkeys_options_next { buttons = { CBA_BUTTON { id = EAknSoftkeyOptions; txt = qtn_aknexeditor_cba_options; }, CBA_BUTTON { id = EAknMyCmdNext; txt = qtn_Myapp_cba_next; } }; } 單頁對話方塊資源定義 樣本如下: RESOURCE DIALOG r_demo_singlepage_dialog { flags = EEikDialogFlagNoDrag | EEikDialogFlagFillAppClientRect | EEikDialogFlagCbaButtons | EEikDialogFlagWait; buttons = R_AVKON_SOFTKEYS_OK_CANCEL; items = { DLG_LINE { type = EEikCtNumberEditor; // The caption(prompt) prompt = "Number1:"; id = ESinglePageDlgC1Id; // The control control = NUMBER_EDITOR { min=0; max=999; }; // The tag, indicating the measurement unit trailer = "cm"; }, DLG_LINE { type = EEikCtNumberEditor; // The caption(prompt) prompt = "Number2:"; id = EsinglePageDlgC2Id; // The control control = NUMBER_EDITOR { min=0; max=999; }; // The tag, indicating the measurement unit trailer = "cm"; } }; }多頁對話方塊資源定義 與單頁對話方塊不同,多頁對話方塊定義了一個pages list(單頁對話方塊是item列表)。軟鍵定義一般是針對整個對話方塊的,而不是針對每個頁。 樣本如下: RESOURCE DIALOG r_multipage_form { flags = EEikDialogFlagNoDrag | EEikDialogFlagFillAppClientRect | EEikDialogFlagNoTitleBar | EEikDialogFlagNoBorder | EEikDialogFlagCbaButtons; buttons = R_AVKON_SOFTKEYS_OPTIONS_BACK; pages = r_multipage_form_pages; }RESOURCE ARRAY r_multipage_form_pages { items = { PAGE { id = EAknExFormPageCtrlIdPage01; text = qtn_multipage_form_label_page1; form = r_multipage_form_text_field_form; }, PAGE { id = EAknExFormPageCtrlIdPage02; text = qtn_multipage_form_label_page2; form = r_aknexform_text_number_field_form; }, . . . }; }RESOURCE FORM r_multipage_form_text_field_form { flags = EEikFormUseDoubleSpacedFormat; items = { DLG_LINE { type = EEikCtEdwin; prompt = qtn_multipage_form_label_edwin; id = EAknExFormDlgCtrlIdEdwin11; itemflags = EEikDlgItemTakesEnterKey | EEikDlgItemOfferAllHotKeys; control = EDWIN { flags = EEikEdwinNoHorizScrolling | EEikEdwinResizable; width = AKNEXFORM_EDWIN_WIDTH; lines = AKNEXFORM_EDWIN_LINES; maxlength = EAknExFormEdwinMaxLength; // added to limit expanding in forms. // If you want full screen use 5 here max_view_height_in_lines = 5; // if you have the line above, you must have this. // It's calculable from LAF base_line_delta = 21; }; tooltip = qtn_multipage_hint_text_edwin; }, }; } 對話方塊類的實現 對話方塊類的實現分為四個大步: 1. 重寫繼承自CAknDialog的類,或直接使用CAknDialog 2. 如果對話方塊控制項需要用來自外部資料初始化,需要重寫PressLayoutDynInitL() 3. 如果類是繼承自CAknDialog,一般需要實現一個RunDlgLD()方法,方法中執行個體化一個對話方塊 ,並使用相應對話方塊資源運行它 4. 如果需要儲存控制項的資料,需要重新OkToExitL()方法,該方法中儲存資料,並判斷是否退 出對話方塊 類定義的標頭檔樣本如下: Class CMyDialog::public CAknDialog { public: // the static RunDlgLD launch function static TInt RunDlgLD(TInt aResouceId); private: // From CAknDialog // base constructor - CAknDialog::CAknDialog() is used // Destructor ~CMyDialog() // the control initializer function void PreLayoutDynInitL(); // the function that collects final control values as well as // checking the exit condition TBool OkToExitL(TInt aButtonId); private: //data items }; 另外,還有一些方法可用來初始化對話方塊或對對話方塊資料進行有效性校正。 PostLayoutDynInitL() 與PreLayoutDynInitL()不同的是,PreLayoutDynInitL()是在對話方塊sized和layed out之前被調用的; PostLayoutDynInitL()是在sized和layed out之後,但在actived之前被調用。 SetInitialCurrentLine() 設定第一個擷取焦點的對話方塊行。預設情況下,第一個對話方塊頁的第一行擷取焦點。子類可 以重寫該方法,但子類必須通過調用ActivateFirstPageL()來啟用對話方塊頁 HandleControlStateChangeL() 重寫後處理控制項狀態的變化。這個方法在控制項的事件類型為EEventStateChanged被調用。 PageChangedL(TInt aPageId ) 切換到指定對話方塊頁時被調用,預設為空白。 LineChangedL(TInt aControlId ) 切換到指定對話方塊行時被調用,預設為空白。 PrepareForFocusTransitionL() 切換行的時候被調用,可以用來校正當前控制項的內容是否合法等。 對話方塊類方法的實現 1. RunDlgLD() TInt CMyDialog::RunDlgLD() { CMyDialog* dlg = new (ELeave) CMyDialog(); return dlg->ExecuteLD(R_DEMO_SINGLEPAGE_DIALOG); } 2. PreLayoutDynInitL() void CMyDialog::PreLayoutDynInitL() { // Get the Number1 editor control CEikNumberEditor* editor1 = (CEikNumberEditor*) Control(ESinglePageDlgC1Id); // Set the value to the Number1 editor editor1->SetNumber(100); // Get the Number2 editor control CEikNumberEditor* editor2 = (CEikNumberEditor*) Control(EsinglePageDlgC2Id); // Set the value to the Number2 editor editor2->SetNumber(200); } 3. OkToExitL() TBool CMyDialog::OkToExitL (TInt aButtonId) { // Get the Number1 editor control CEikNumberEditor* editor1 = (CEikNumberEditor*) Control(ESingleDlgId); // Get the Number2 editor control CEikNumberEditor* editor2 = (CEikNumberEditor*) Control(ESingleDlg2Id); // Check the validity of the values in the two editors if ( editor1->Number() > editor2->Number()) { // Show an error note CAknErrorNote* note = new (ELeave) CAknErrorNote; note->ExecuteLD(_L("Number1 should be less than number2")); return EFalse; } return ETrue; } 對話方塊使用 使用對話方塊包括兩步: 1. 使用new(ELeave)或NewL()建立對話方塊類執行個體 2. 調用ExecuteLD(TInt aResourceId)。它將調用PrepareLC(TInt aResourceId)和RunLD()。 有時候對話方塊類實現了RunDlgLD()方法,我們可以直接調用它來初始化和運行對話方塊。 |