symbian對話框總結-標準對話框

 
Series60提供了一個全面的對話框類和基類集合,可以使用這些類創建自定義對話框,以及開發窗體(form)、通知(note)、查詢(query)和列表對話框(list dialog)等。
所有對話框共有某些基本屬性。首先,對話框都是擁有窗口的控件,所有對話框類最終都派生於CCoeControl。然後,由一個對話框框架管理對話框的行爲,包括佈局、繪製以及用戶與對話框在組件控件的交互。典型情況下,對於大多數任意複雜程度的對話框,都會在一個資源文件中完整定義,並在動態實例化之後由對話框框架從資源文件裝載此定義完成對話框的創建。對話框所有元素的佈局和定位都是通常是自動的,當然也可以干預它。
Series60的對話框默認是模態和非等待的。模態/非模態無需多述;非等待對話框允許應用程序在後臺繼續處理,而等待對話框會阻止應用程序在該對話框關閉前執行任何進一步的處理。
 
CAknDialog是大部分Series60對話框的基類。關於對話框的使用,大體分爲以下步驟:1.定義資源。2.編寫對話框類。3.保存和驗證對話框數據。4.動態地初始化標準對話框。5.構建和執行對話框。
 
下面分別敘述之:
1.定義資源
使用DIALOG定義資源,資源指定了對話框的佈局,在資源中定義對話框應該包含的行數、使用的控件、對話框是否爲模態以及使用的軟鍵等。下面以一個簡單的例子示範:
RESOURCE DIALOG r_simpledlg_dialog
{
flags=EEikDialogFlagNoDrag |
   EEikDialogFlagNoTitleBar |
   EEikDialogFlagFillAppClientRect |
   EEikDialogFlagCbaButtons |
   EEikDialogFlagModeless;
buttons=R_AVKON_SOFTKEYS_OPTIONS_BACK;
items=
   {
 DLG_LINE
    {
   id=ESimpleDlgCIdGameName;
   type=EEikCtLabel;
   control= LABEL
     {
     txt = GAME_NAME_TEXT;
     };
    }
   };
}
 
flags說明了對話框的屬性,其中的屬性值可參考<uikon.hrh>
#define EEikDialogFlagWait             
#define EEikDialogFlagNotifyEsc         
#define EEikDialogFlagButtonsBelow     
#define EEikDialogFlagButtonsRight     
#define EEikDialogFlagNoUserExit       
#define EEikDialogFlagModeless         
#define EEikDialogFlagNoTitleBar       
#define EEikDialogFlagAllKeysToButtons
#define EEikDialogFlagFillScreen       
#define EEikDialogFlagNoDrag           
#define EEikDialogFlagDensePacking     
#define EEikDialogFlagNoBackup         
#define EEikDialogFlagFillAppClientRect
#define EEikDialogFlagCbaButtons       
#define EEikDialogFlagNoBorder         
#define EEikDialogFlagNoShadow         
其中,把標準對話框定義爲等待對話框是一種良好的習慣。應該只在合理的時候(例如在主應用程序窗口中)才把標準對話框定義爲非等待。
 
buttons指定了使用的軟件,其中的取值可參考<avkon.rsg>
#define R_AVKON_SOFTKEYS_EMPTY                   
#define R_AVKON_SOFTKEYS_EMPTY_WITH_IDS          
#define R_AVKON_SOFTKEYS_OK_EMPTY                
#define R_AVKON_SOFTKEYS_SELECT_CANCEL           
#define R_AVKON_SOFTKEYS_OK_CANCEL               
#define R_AVKON_SOFTKEYS_OK_DETAILS              
#define R_AVKON_SOFTKEYS_CALL_CANCEL             
#define R_AVKON_SOFTKEYS_OPTIONS_BACK            
#define R_AVKON_SOFTKEYS_OPTIONS_DONE            
#define R_AVKON_SOFTKEYS_OPTIONS_CANCEL          
#define R_AVKON_SOFTKEYS_OPTIONS_EXIT            
#define R_AVKON_SOFTKEYS_OK_BACK                 
#define R_AVKON_SOFTKEYS_CANCEL                  
#define R_AVKON_SOFTKEYS_BACK                    
#define R_AVKON_SOFTKEYS_CLOSE                   
#define R_AVKON_SOFTKEYS_DONE_BACK               
#define R_AVKON_SOFTKEYS_DONE_CANCEL             
#define R_AVKON_SOFTKEYS_SELECT_BACK             
#define R_AVKON_SOFTKEYS_MARK_BACK               
#define R_AVKON_SOFTKEYS_UNMARK_BACK             
#define R_AVKON_SOFTKEYS_YES_NO                  
#define R_AVKON_SOFTKEYS_UNLOCK_EMPTY            
#define R_AVKON_SOFTKEYS_SAVE_BACK               
#define R_AVKON_SOFTKEYS_SHOW_CANCEL             
#define R_AVKON_SOFTKEYS_SHOW_EXIT               
#define R_AVKON_SOFTKEYS_ANSWER_EXIT             
#define R_AVKON_SOFTKEYS_EXIT                    
#define R_AVKON_SOFTKEYS_READ_EXIT               
#define R_AVKON_SOFTKEYS_LISTEN_EXIT             
#define R_AVKON_SOFTKEYS_SEARCH_BACK             
#define R_AVKON_SOFTKEYS_AGAIN_QUIT              
#define R_AVKON_SOFTKEYS_QUIT                    
#define R_AVKON_SOFTKEYS_INSERT_BACK            
 
最主要的是items組件,它定義了對話框包含的實際內容。需要爲希望包含到對話框的每個控件分別定義一個DLG_LINE,在每個DLG_LINE中至少應該指定以下字段:
* id :在應用程序中使用該值引用此對話框行,必須在應用程序的.hrh文件中枚舉它。
* type :此對話框行包含的控件類型(在avkon.hrh或uikon.hrh中定義)。
* control :在此對話框中使用的控件。
此外,還可以選擇在DLG_LINE資源中指定一個itemflags字段,使用該字段決定對話框行的行爲。例如彈出字段文本控件可以使用itemflags說明應該在“選擇”鍵被按下時打開一個彈出窗口,例如EEikDlgItemTakesEnterKey|EEikDlgItemOfferAllHotKeys。可以在uikon.hrh中找到itemflags的值。最常用的可能當屬EEikDlgItemSeparatorBefore標誌,用於在對話框行之前插入一個水平“分隔符”行。
 
2. 編寫對話框類
接下來需要編寫一個可以構建和執行此對話框、初始化控件的數據、處理從控件接收到的數據並決定如何關閉對話框的類。
通常會提供一個用於執行對話框的靜態方法,該方法包裝了第一階段構造函數和ExecuteLD() - 用於裝載、顯示和銷燬對話框的函數。通常將該靜態方法命名爲RunDlgLD(),並使它傳遞ExecuteLD()返回的TBool。
下面示例之:
#include <akndialog.h> // CAknDialog
class CSimpleDlgPlayerNameDialog : public CAknDialog
{
public: // static construction and execution
 
static TBool RunDlgLD (TDes& aPlayerName);
 
protected: // from CAknDialog
 
TBool OkToExitL(TInt aButtonId);
 
protected: // from CEikDialog
 
void PreLayoutDynInitL();
 
private: // Constructor
 
CSimpleDlgPlayerNameDialog(TDes& aPlayerName) : iPlayerName(aPlayerName){};
 
private: // data
TDes& iPlayerName;
};
 
關於RunDlgLD()的實現:
TBool CSimpleDlgPlayerNameDialog::RunDlgLD (TDes& aPlayerName)
{
   CSimpleDlgPlayerNameDialog* playerNameDialog = new (ELeave) CSimpleDlgPlayerNameDialog(aPlayerName);
   return playerNameDialog->ExecuteLD(R_SIMPLEDLG_PLAYER_NAME_DIALOG);
}
因爲對話框是模態和等待的,所以不需要使它成爲成員數據,此對話框在ExecuteLD()的最後會刪除自己。
那麼爲什麼在new之後沒有將其壓入清除棧呢?因爲ExecuteLD()擁有改對話框的所有權,該方法包裝了對其他兩個方法的調用:PrepareLC()和RunLD()。PrepareLC()會把對話框的指針放入清除棧,然後完成對話框的創建。RunLD()會顯示該對話框,然後把它從清除棧中彈出。但如果在調用ExecuteLD()之前需要調用任意可能導致異常退出的代碼,則應該將其放入清除棧,並在調用ExecuteLD()前把它彈出。
但,如果對話框爲非等待的,則會直接從ExecuteLD()返回而不被刪除。
 
3. 保存和驗證對話框數據
爲了使對話框能夠更新應用程序的數據,需要爲它提供對這些數據的引用。對數據的驗證和更新通常發生在OkToExitL()方法中進行,除“取消”外,按下任意軟鍵時,框架都會調用此函數(通過設定對話框的flags,使之包括EEikDialogFlagNotifyEsc,可以強制要求框架在“取消”被按下時也調用OkToExitL())。如果允許對話框退出,則OkToExitL()必須返回ETrue,如果不允許退出,則返回EFalse。下面示例之:
TBool CSimpleDlgPlayerNameDialog::OkToExitL(TInt aButtonId)
{
if (aButtonId == EAknSoftkeyOk)
   {
   CEikEdwin* editor = static_cast<CEikEdwin*>(ControlOrNull(ESimpleDlgCIdPlayerNameEditor));
   if (editor)
    {
    editor->GetText(iPlayerName);
    }
   }
return ETrue;
}
 
通過調用CEikDialog::ControlOrNull()並傳入對話框行的ID,可以獲取特定控件的句柄,如果ID有效,則返回一個CCoeControl的指針,後則返回NULL。如果ID無效需要退出,可使用CEikDialog::Control(),如果ID無效,該方法會出錯。
 
4. 動態地初始化標準對話框
動態地設置對話框中的項是在PreLayoutDynInitL()方法中執行。對話框框架會在對話框執行前調用該方法。
void CSimpleDlgPlayerNameDialog::PreLayoutDynInitL()
{
CEikLabel* label = static_cast<CEikLabel*>(ControlOrNull(ESimpleDlgCIdPlayerName));
if (label)
   {
   HBufC* labelText = StringLoader::LoadLC(R_ENTER_NAME_TEXT);
   label->SetTextL(*labelText);
   CleanupStack::PopAndDestroy(labelText);
   }
}
如果需要,可以通過重寫另外一個方法PostLayoutDynInitL(),更改對話框中控件的佈局和大小,或是在顯示對話框之前啓動一個定時器。
 
5. 構建和執行對話框
RunDlgLD()方法封裝了對話框的構建和執行。
switch (aCommand)
   {
   case ESimpleDlgCmdNewGame:
    {
    if (CSimpleDlgPlayerNameDialog::RunDlgLD (iPlayerName))
     {
     StartNewGameL();
     }
    break;
    }
   // ...
   }
通過檢查ExecuteLD()或RunDlgLD()的返回值,可以得知對話框是如何被關閉的。返回EFalse說明關閉對話框時按下的是“取消”、“後退”或“否”,其他情況下返回ETrue。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章