徹底解決Symbian開發全屏顯示問題

首先,我們可以利用Carbide.vs嚮導建一個項目,名字就叫"TestScreen",選擇基於Eikon的傳統控件架構。

  那麼在CTestScreenAppUi的二階構造函數裏就有如下代碼:

  void CTestScreenAppUi::ConstructL()

  {

  BaseConstructL();

  iAppContainer = new (ELeave) CTestScreenContainer;

  iAppContainer->SetMopParent( this );

  iAppContainer->ConstructL( ClientRect() );

  AddToStackL(iAppContainer);

  }

  這裏面有很關鍵的一句,就是我用紅色顯示的那段代碼。它把當前UI的ClientRect()傳遞給Container類,我們都知道Container類是控件類,負責整個程序的界面顯示,那麼UI傳遞給Container的這個ClientRect()到底是什麼東東呢?我們看看SDK HELP:

  ClientRect()

  TRect ClientRect() const;

  Description

  Gets the area of the screen available to the application for drawing, not including the space that is available for any of the following, where required: non-application areas which should always be displayed, an application status pane, an application button group, an application menu bar, an application title band and an application tool bar.

  Importantly, the co-ordinates of the rectangle are relative to the whole screen area so, for example, the co-ordinate for the top, left point of the area available for drawing may be (0, 45).

  Return value

  TRect The area of the screen available to the application for drawing.

  從Description我們可以看到:ClientRect()獲得應用程序繪製的有效屏幕區域,但是這個區域不包括那些總是顯示的非應用程序區域,比如:應用程序狀態面板(application status pane)、按鈕(button group)、應用程序的菜單bar、標題、工具條。

  而且更重要的是從下面一行可以看出,這個ClientRect()所獲得區域的top-left座標是(0,45)。

  通過上面的分析我們知道,UI在構造我們的Container時傳遞一個所謂的"客戶矩形區域",這個"客戶矩形區域"的top-left座標是(0,45),從而也就知道如果要讓我們的程序全屏顯示,那麼我們需要改變的是構造Container的時候傳遞的矩形大小。

  那麼就有如下幾種方法:

  ①如果我們知道屏幕尺寸,那麼就可以把iAppContainer->ConstructL( );裏面的參數改爲TRect (0,0,176,208)。

  ②上面的程序不具有適配性,因爲我們把屏幕的寬度和高度寫死了。

  我們來看Symbian給我們提供的一個方法

  ApplicationRect()

  TRect ApplicationRect() const;

  Description

  Gets the total area of the screen available to the application. This includes the space that is available for a toolbar, toolband or title band, if the application requires them.

  Return value

  TRect The total area of the screen available to the application.

  Description寫的很明顯了,我就不翻譯了。這個方法可以獲得屏幕的整個尺寸,我們把程序可以改爲:

  iAppContainer->ConstructL( ApplicationRect() );從而實現程序的全屏顯示。

  ③第三中方法是最笨的方法了,那就是不改變UI所傳遞的"客戶矩形區域"的大小,傳遞的仍然是ClientRect()。但是到了Container後再採用"亡羊補牢"的做法!把status pane、menu bar等隱藏起來。

  而且這種方法也容易出錯誤,下面是一個同行犯的錯誤,他在Container類裏寫入下面代碼:

  void CTestScreenContainer::ConstructL(const TRect& aRect)

  {

  CreateWindowL();

  iLabel = new (ELeave) CEikLabel;

  iLabel->SetContainerWindowL( *this );

  iLabel->SetTextL( _L("Example View") );

  iToDoLabel = new (ELeave) CEikLabel;

  iToDoLabel->SetContainerWindowL( *this );

  iToDoLabel->SetTextL( _L("Add Your controls/n here") );

  SetRect(aRect);

  CEikStatusPane* statusp = iEikonEnv->AppUiFactory()->StatusPane();

  if(statusp)

  statusp->MakeVisible(EFalse);

  iEikonEnv->AppUiFactory()->Cba()->MakeVisible(EFalse);

  ActivateL();

  }

  爲了使用CEikStatusPane類要加入頭文件#include

  爲了使用CEikButtonGroupContainer類要加入頭文件#include

  其中iEikonEnv->AppUiFactory()是在Symbian中獲取UI實例常用的方法,這和MFC是一樣,你千萬不能new一個CTestScreenAppUi出來,因爲他們是由框架調用的,我們並不知道何時調用。

  但是因爲他是在Container類裏調用這兩個方法,也就是說ClientRect()獲取"矩形區域"之後程序才設置status pane、Cba爲不可見!所以當然也沒什麼用,程序仍然無法全屏顯示。

  所以說即使你在UI類裏寫下面的代碼,但因爲代碼是在獲取"矩形區域"之後才設置status pane、Cba爲不可見,程序仍然無法全屏顯示!

  void CTestScreenAppUi::ConstructL()

  {

  BaseConstructL();

  iAppContainer = new (ELeave) CTestScreenContainer;

  iAppContainer->SetMopParent( this );

  iAppContainer->ConstructL( ClientRect() );

  //在獲取"矩形區域"後設置status pane、Cba爲不見

  CEikStatusPane* statusp = StatusPane();

  if(statusp)

  statusp->MakeVisible(EFalse);

  Cba()->MakeVisible(EFalse);

  AddToStackL( iAppContainer );

  }

  所以千萬記住:如果要通過設置status pane、Cba爲不可見的方法獲得全屏,千萬要在獲取"矩形區域"之前設置!

  ④上面集中方法都是通過在UI類設置"矩形區域"的大小,或者通過設置status pane、Cba不可見隱式改變"矩形區域"的大小實現全屏的。

  這裏我們介紹一種在Container類裏,在UI設置完"矩形區域"後再改變屏幕爲全屏顯示的方法。void CTestScreenContainer::ConstructL(const TRect& aRect)

  {

  CreateWindowL();

  iLabel = new (ELeave) CEikLabel;

  iLabel->SetContainerWindowL( *this );

  iLabel->SetTextL( _L("Example View") );

  iToDoLabel = new (ELeave) CEikLabel;

  iToDoLabel->SetContainerWindowL( *this );

  iToDoLabel->SetTextL( _L("Add Your controls/n here") );

  SetRect(aRect);

  SetExtentToWholeScreen();

  ActivateL();

  }

  但是要千萬記得:SetExtentToWholeScreen()一定要在SetRect(aRect)之後調用纔有效果。這點很容易理解,因爲如果SetExtentToWholeScreen()改變屏幕爲全屏後,再調用SetRect(aRect)又把屏幕尺寸設置爲UI裏傳遞的"矩形區域"的大小了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章