Author:孫東風
Date:04/01/2008
http://blog.csdn.net/dongfengsun/article/details/2234513
我們知道,在大多數GUI的Applications中,視圖之間的切換是極其頻繁的。那麼如何組織這些視圖以及視圖之間的通訊,就成爲大多數Applications所要面對的問題。
在Symbian中多視圖應用程序之間的視圖管理可以用下圖來表示:
其中AppUI管理AppView,而AppView又管理Container。
AppUI繼承自CAknViewAppUi,其管理AppView的代碼如下:
CAppView1* iView1 = new(ELeave) CAppView1; CAppView2* iView2 = new(ELeave) CAppView2; SetDefaultViewL(*iView1); |
而其中每個View又繼承自
class CAppView1: public CAknView , public MCoeControlObserver class CAppView2: public CAknView , public MCoeControlObserver |
View之間要想實現自由的切換,就必須定義一個TUid作爲自身的唯一標識並實現CAknView的方法
// UID of view /** |
那麼從一個View跳轉到另一個View就需要下面的代碼
((CAknViewAppUi*)(iEikonEnv->AppUi()))->ActivateLocalViewL( TUid::Uid( 3 ));或 static_cast<CApplicationAppUi*>(iEikonEnv->AppUi())->ActivateLocalViewL( TUid::Uid( 3 )); |
上面的代碼講述了AppUI如何管理衆多的View以及View之間的切換,那麼下面講述每個View是如何管理它裏面衆多的Containers的。
首先要明白View繼承自CAknView,它做爲Container(繼承自CCoeControl)的容器通過以下的代碼激活某個Container
iContainer = new (ELeave) CApplicationContainerSetting; iContainer->ConstructL( KFullScreen ); iContainer->SetMopParent(this); iContainer->SetObserver(this); iContainer->SetApplicationDbEngine(iDbEngine); AppUi()->AddToStackL( *this, iContainer ); |
那麼在DoActivateL()中通過以上代碼放置初始顯示的Container。
那麼View是如何管理衆多的Container的呢?
從以上代碼可以看出,負責Container管理的View都繼承自MCoeControlObserver,而iContainer->SetObserver(this)則把當前的Container註冊到MCoeControlObserver,從而實現了View對其內部Container的監聽。
View中繼承自MCoeControlObserver的接口void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)則負責每個Container所報告的事件的處理。
注意:如果View中並沒Container,那麼就沒必要繼承自MCoeControlObserver。
而Container繼承自CCoeControl(它是HandleControlEventL的一個參數),CCoeControl中提供下面的方法對View中的HandleControlEventL()報告事件。
case EStdKeyDevice1: //右鍵 { ReportEventL((MCoeControlObserver::TCoeEvent)ECmdDeleteVideoContainer); break; } |
而View通過以下方法對上面代碼所報告的事件進行處理。
void CAppView1::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType) case EMenuItemCmdBack: |
從上面的分析可以看出:
AppView通過繼承自CAknView並通過ActivateLocalViewL()切換視圖。
而AppView通過繼承自MCoeControlObserver監聽衆多的Container,並在HandleControlEventL()裏對Container所報告的事件進行響應。
/////////////////////////////////////////////
APPUI類負責視圖的創建和切換,它繼承自CAknViewAppUi ,調用AppUi()->ActivateLocalViewL(uid)方法根據Tuid可以激活視圖。
所有的視圖必須在視圖服務器(CAknViewAppUi )類註冊纔可以使用。(註冊方法如:AddViewL(iMainView);)
在任意時刻只有一個視圖處於激活狀態。視圖必須在資源文件中定義,每一個視圖都可以有自己的菜單,所以定義視圖也定義各自的cba按鈕類型和菜單項。定義完後在二階構造中調用BaseConstructL( aResId );函數構造視圖。視圖類繼承自CAknView ,它有以下三個方法必須覆寫:
TUid Id() const; //根據id判斷視圖,此id 在hrh 文件中定義
void DoActivateL( const TVwsViewId& aPrevViewId,
TUid aCustomMessageId,
const TDesC8& aCustomMessage ); //負責激活視圖或容器
此函數中構造容器類對象,容器類繼承自CcoeControl.負責視圖的顯示
void DoDeactivate(); //負責刪除視圖或容器
每個視圖類有自己的命令處理函數 void HandleCommandL( TInt aCommand ); 處理自己的菜單命令也可以調用AppUi類的菜單命令處理(AppUi()->HandleCommandL( aCommand );)
注意:使用AppUi()需要 #include <aknviewappui.h>