了网上的方法也无法设置成全屏。其实,归根结底还是不明白Symbian框架的调用机制。这篇文章里我就来彻底研究一下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:

 

         通过上面的分析我们知道,UI在构造我们的Container时传递一个所谓的"客户矩形区域",这个"客户矩形区域"的top-left坐标是(0,45),从而也就知道如果要让我们的程序全屏显示,那么我们需要改变的是构造Container的时候传递的矩形大小。

       那么就有如下几种方法:

如果我们知道屏幕尺寸,那么就可以把iAppContainer->ConstructL(  );里面的参数改为TRect  (0,0,176,208)。

 

上面的程序不具有适配性,因为我们把屏幕的宽度和高度写死了。

       我们来看Symbian给我们提供的一个方法

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 <eikspane.h>

        为了使用CEikButtonGroupContainer类要加入头文件#include <eikbtgpc.h>

        其中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里传递的"矩形区域"的大小了。