Symbian 面板

来源:互联网 发布:win10软件右下角盾牌 编辑:程序博客网 时间:2024/04/27 17:50

面板分为状态面板、主面板和软键面板。其中以针对状态面板的操作为主。

状态面板分为下列子面板:标题面板、上下文面板、导航面板、信号面板、电池面板和通用指示符面板。

要操作状态面板,首先应该通过CEikStatusPane* CAknAppUi::StatusPane()得到状态面板的指针。

CEikStatusPane提供了对状态面板进行操作的各种方法:

class CEikStatusPane : public CEikStatusPaneBase, public MCoeForegroundObserver;

Members

Defined in CEikStatusPane:

ApplyCurrentSettingsL(), HandleResourceChange(), MakeVisible(), NewL(), SetDimmed(), SetFaded(), ~CEikStatusPane()

Inherited from CBase:

operator new()

Inherited from CEikStatusPaneBase:

ContainerControlL(), ControlL(), Current(), GetShapeL(), IsDimmed(), IsFaded(), IsVisible(), PaneCapabilities(), PaneRectL(), ReduceRect(), SetFlags(), SetObserver(), SwapControlL(), SwitchLayoutL(), TPaneCapabilities, WindowGroup()

Inherited from MCoeForegroundObserver:

HandleGainingForeground(), HandleLosingForeground()

1.可见性操作

    CEikStatusPane* statusPane = StatusPane();

     if (statusPane->CurrentLayoutResId() != R_AVKON_STATUS_PANE_LAYOUT_EMPTY)

     {

      statusPane->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_EMPTY);

     }

     else

     {

      statusPane->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_USUAL);

     }

CurrentLayoutResId()返回当前布局的资源ID,关于资源ID的定义可参照<avkon.rsg>,有以下几种, R_AVKON_STATUS_PANE_LAYOUT_IDLE,R_AVKON_STATUS_PANE_LAYOUT_USUAL, R_AVKON_STATUS_PANE_LAYOUT_POWER_OFF_RECHARGE, R_AVKON_STATUS_PANE_LAYOUT_EMPTY等。

SwitchLayoutL()把状态面板的布局更改为指定的资源ID。

注意,不应使用CEikStatusPane的IsVisible()和MakeVisible()来检查和设置面板的可见性,因为它们同时会隐藏电话拨入图标。

在对状态面板的子面板操作时,需要通过下面方法得到子面板(以更改标题面板文本为例):

TUid titlePaneUid;

titlePaneUid.iUid = EEikStatusPaneUidTitle;

CEikStatusPane* statusPane = StatusPane();

CEikStatusPaneBase::TPaneCapabilities subPane = statusPane->PaneCapabilities(titlePaneUid);

if (subPane.IsPresent() && subPane.IsAppOwned())

{

   CAknTitlePane* titlePane = (CAknTitlePane*)statusPane->ControlL(titlePaneUid);

   HBufC* titleText = StringLoader::LoadLC(R_HEWB_TITLE_TEXT);

   titlePane->SetTextL(*titleText);

   CleanupStack::PopAndDestroy(titleText);

}

要得到子面板,需要实现准备好子面板的ID,它们定义在<avkon.hrh>中,有下列几种: EEikStatusPaneUidSignal(信号面板),EEikStatusPaneUidBattery(电池面板), EEikStatusPaneUidContext(上下文面板),EEikStatusPaneUidTitle(标题面板), EEikStatusPaneUidNavi(导航面板),EEikStatusPaneUidIndic, EEikStatusPaneUidMessage,EEikStatusPaneUidClock。

TPaneCapabilities PaneCapabilities(TPaneId aPaneId)方法获取子面板的相关信息。TPaneCapabilities 是CEikStatusPaneBase的嵌套类,有IsPresent(),IsAppOwned(),IsInCurrentLayout()等方法。IsPresent()检查标题面板是否存在;IsAppOwned()检查面板是否能被应用程序更改;IsCurrentLayout()检测面板是否为当前面板布局的一部分。

一旦确定了面板存在并可修改,调用CCoeControl* CEikStatusPaneBase::ControlL(TPaneId aPaneId)得到子面板的指针,然后即可对其进行操作。关于标题面板和上下文面板的操作均较简单,可参照SDK中CAknTitlePane和 CAknContextPane。比较复杂的是导航面板,将另文介绍。

导航面板

2007-12-27 14:24

导航面板的主要用途是向用户显示与应用程序当前的视图和状态相关的信息,并帮助用户在应用程序内导航。导航面板默认为空,但可以使用它显示选项卡、标签、图像、指示符或自定义控件。为了用控件装饰导航面板,需要在代码中使用一个CAknNavigationControlContainer对象,或在资源文件中使用NAVI_DECORATOR资源。

在AppUi类中定义CAknNavigationDecorator* iNaviDecorator;

以下代码示例了在导航面板显示两个选项卡:

    TUid naviPaneUid;

    naviPaneUid.iUid = EEikStatusPaneUidNavi;

    CEikStatusPane* statusPane = StatusPane();

    CEikStatusPaneBase::TPaneCapabilities subPane =

     statusPane->PaneCapabilities(naviPaneUid);

     // if we can access the navigation pane

    if (subPane.IsPresent() && subPane.IsAppOwned())

     {

     CAknNavigationControlContainer* naviPane =

      (CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);

      delete iNaviDecorator;

      iNaviDecorator = NULL;

     // ownership is transferred to us here

     iNaviDecorator = naviPane->CreateTabGroupL();

     // ownership not transferred

    CAknTabGroup* tabGroup = (CAknTabGroup*) iNaviDecorator->DecoratedControl();

     // Display two tabs of normal length on the navigation pane at a time

     tabGroup->SetTabFixedWidthL(KTabWidthWithTwoTabs);

     TInt tabId = 0;

     // load the text to be displayed in the tabs

     HBufC* tab1Text = StringLoader::LoadLC(R_TAB1_TEXT);

     tabGroup->AddTabL(tabId++, *tab1Text);

     CleanupStack::PopAndDestroy(tab1Text);

     HBufC* tab2Text = StringLoader::LoadLC(R_TAB2_TEXT);

     tabGroup->AddTabL(tabId++, *tab2Text);

     CleanupStack::PopAndDestroy(tab2Text);

     // highlight the first tab

     tabGroup->SetActiveTabByIndex(0);

     naviPane->PushL(*iNaviDecorator);

    

比标题面板和上下文面板复杂了些,但并不难理解,前两者在ControlL()返回CAknTitlePane和CAknContextPane指针,这里返回的是CAknNavigationControlContainer,从命名上就可以看出,它是一个Container,可以盛放TagGroup,Label,Bitmap或其他控件,这样可以从该类的一系列成员函数CAknNavigationDecorator* CreateXXXL()看出。

CAknTabGroup::SetTabFixedWidthL()控制导航面板显示的选项卡个数和尺寸。

最后两句,No.1是把第一个选项卡设置为活动选项卡;No.2是吧选项卡组推入导航面板的对象栈,只有这样,选项卡组才能实际出现在导航面板中。

下面代码示例了在选项卡中显示位图,使用了AddTabL()的重载版本。

// ..........

TInt tabId = 0;

// load the bitmap to be displayed in the tabs

CFbsBitmap* bitmap = iEikonEnv->CreateBitmapL(KTitleBitMapFile, EMbmTitlepaneTab);

// display a bitmap in the tab

tabGroup->AddTabL(tabId++, bitmap);

// ...........

显示标签

// ...............

delete iNaviDecorator;

iNaviDecorator = NULL;

HBufC* labelText = StringLoader::LoadLC(R_NAVIGATION_LABEL_TEXT);

   //set the navigation pane's label

iNaviDecorator = naviPane->CreateNavigationLabelL(*labelText);

CleanupStack::PopAndDestroy(labelText);

naviPane->PushL(*iNaviDecorator);

// .....................

显示控件(以音量控件为例)

// ...........

// if we can access the navigation pane

if (subPane.IsPresent() && subPane.IsAppOwned())

     {

    CAknNavigationControlContainer* naviPane = (CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);

     delete iNaviDecorator;

      iNaviDecorator = NULL;

      // create a volume indicator on the navigation pane

     iNaviDecorator = naviPane->CreateVolumeIndicatorL(R_AVKON_NAVI_PANE_VOLUME_INDICATOR);

    naviPane->PushL(*iNaviDecorator);

    }

CAknVolumeControl* volumeControl = (CAknVolumeControl*) iNaviDecorator->DecoratedControl();

// Get the current volume level

TInt curVolume = volumeControl->Value();

// Increase the volume level by one                

volumeControl->SetValue(++curVolume);

// ...........

显示图片

// ...........

delete iNaviDecorator;

iNaviDecorator = NULL;

// Create a bitmap to display

CFbsBitmap* bitmap = iEikonEnv->CreateBitmapL(KTitleBitMapFile, EMbmTitlepaneNavigation);

// create an image on the navigation pane

iNaviDecorator = naviPane->CreateNavigationImageL(bitmap);

naviPane->PushL(*iNaviDecorator);

// ...........

1. 使用资源更改标题面板的文本

除了可以动态地设置标题面板的文本外,还可以在资源文件中设置它们,这通过指定一个TITLE_PANE资源来实现,例如:
RESOURCE TITLE_PANE r_my_title_pane
{
txt = TITLE_TEXT;
}

txt字段用于指定显示在标题面板中的文本,可以在本地化文件中定义#define TITLE_TEXT "New Title"

之后在状态面板资源STATUS_PANE_APP_MODEL中引用该TITLE_PANE资源,而在EIK_APP_INFO资源中引用状态面板资源:

RESOURCE STATUS_PANE_APP_MODEL r_my_status_pane
{
panes =
    {
    SPANE_PANE
        {
        id = EEikStatusPaneUidTitle;
        type = EAknCtTitlePane;
        resource = r_my_title_pane;
        }
    };
}

RESOURCE EIK_APP_INFO
{
status_pane = r_my_status_pane;
}

2. 使用资源在标题面板中显示图像
可以通过指定TITLE_PANE结构中的bmpfile,bmpid和bmpmask字段定义显示在标题面板中的图像。bmpfile指定用于从中获取图像的.mbm文件;bmpid字段指定使用的位图在多位图文件中的索引;bmpmask字段根据需要指定使用的遮罩的索引。

RESOURCE TITLE_PANE r_my_title_pane
{
bmpid = EMbmMyBitmapIndex;
bmpmask = EMbmMyBitmapMaskIndex;
bmpfile = "//system//apps//myapplication//myapplication.mbm";
}

3. 使用资源在上下文面板中显示图像
可以在资源文件中指定CONTEXT_PANE资源可以设置上下文面板的图标。该资源和TITLE_PANE资源的工作方式相同。
RESOURCE CONTEXT_PANE r_my_context_pane
{
bmpid = EMbmMyBitmapIndex;
bmpmask = EMbmMyBitmapMaskIndex;
bmpfile = "//system//apps//myapplication//myapplication.mbm";
}

下面是STATUS_PANE_APP_MODEL的结构,可见panes为面板数组,当同时在资源中指定多个面板时,可以在此数组中挨个指定。
STRUCT STATUS_PANE_APP_MODEL     // Application specific status pane
{
LLINK layout=EEikStatusPaneUseDefaults;   // STATUS_PANE_LAYOUT to use for this app
STRUCT panes[];        // SPANE_PANE overrides to use for this app
}

4. 使用资源在导航面板中显示选项卡

可以在资源文件中使用NAVI_DECORATOR资源定义应用程序启动时出现的选项卡。使用tab_width字段指定显示的选择卡的个数和宽度;使用active字段指定初始时突出显示的选项卡的索引;使用tab字段指定所有选项卡:选项卡的ID和内容。
NAVI_DECORATOR结构如下:
STRUCT NAVI_DECORATOR
{
WORD type=ENaviDecoratorControlNone;
STRUCT control;
}

下面示例:

RESOURCE NAVI_DECORATOR r_navigationpane_navi_tabgroup
    {
    type = ENaviDecoratorControlTabGroup;
    control = TAB_GROUP
        {
        tab_width = EAknTabWidthWithTwoTabs; // display two tabs
        active = 0;
        tabs = {
            TAB
                {
                id = ENavigationPaneTab1;
                txt = TAB1_TEXT;
                },
            TAB
                {
                id = ENavigationPaneTab2;
                txt = TAB2_TEXT;
                }
            };
        };
    }
   
RESOURCE STATUS_PANE_APP_MODEL r_navigationpane_status_pane
{
panes=
   {
  SPANE_PANE
    {
            id = EEikStatusPaneUidNavi;
            type = EAknCtNaviPane;
            resource = r_navigationpane_navi_tabgroup;
    }
   };
}

RESOURCE EIK_APP_INFO
{
status_pane = r_navigationpane_status_pane;
}

除了在应用程序中动态创建选项卡和在资源文件中定义选项卡外,还可以在运行期使用在资源文件中指定的资源创建选项卡,为此,首先需要在资源文件中指定资源TAB_GROUP;然后在代码中使用TResourceReader对象读取该资源。
RESOURCE TAB_GROUP r_navigationpane_tabgroup
    {
    tab_width = EAknTabWidthWithTwoTabs; // display two tabs
    active = 0;
    tabs = {
        TAB
            {
            id = ENavigationPaneTab1;
            txt = TAB1_TEXT;
            },
        TAB
            {
            id = ENavigationPaneTab2;
            txt = TAB2_TEXT;
            }
        };
    }
   
    TUid naviPaneUid;
    naviPaneUid.iUid = EEikStatusPaneUidNavi;

    CEikStatusPane* statusPane = StatusPane();

    CEikStatusPaneBase::TPaneCapabilities subPane =
     statusPane->PaneCapabilities(naviPaneUid);

            // if we can access the navigation pane
    if (subPane.IsPresent() && subPane.IsAppOwned())
     {

     CAknNavigationControlContainer* naviPane =
      (CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);

                // read the tab group resource
                TResourceReader reader;
                iCoeEnv->CreateResourceReaderLC(reader, R_NAVIGATIONPANE_TABGROUP);

                if (iNaviDecorator)
                    {
                    delete iNaviDecorator;
                    iNaviDecorator = NULL;
                    }

                // set the navigation pane tab group
                iNaviDecorator = naviPane->CreateTabGroupL(reader);
                CleanupStack::PopAndDestroy(); // pushed by CreateResourceReaderLC
     naviPane->PushL(*iNaviDecorator);
     }

5. 使用资源在导航面板显示标签
在资源文件中使用NAVI_LABEL资源为导航面板指定标签,此资源只有一个txt字段,用于指定在导航面板中显示的文本。
RESOURCE NAVI_LABEL r_navigationpane_navi_text
{
txt = LABEL_TEXT;
}

之后在应用程序中读取该资源,并使用它设置导航面板的标签:
TUid naviPaneUid;
    naviPaneUid.iUid = EEikStatusPaneUidNavi;
    CEikStatusPane* statusPane = StatusPane();


    CEikStatusPaneBase::TPaneCapabilities subPane =
     statusPane->PaneCapabilities(naviPaneUid);

     // if we can access the navigation pane
    if (subPane.IsPresent() && subPane.IsAppOwned())
     {

          CAknNavigationControlContainer* naviPane =
        (CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);

                // read the navigation pane text resource
                TResourceReader reader;
                iCoeEnv->CreateResourceReaderLC(reader, R_NAVIGATIONPANE_NAVI_TEXT);

                if (iNaviDecorator)
                    {
                    delete iNaviDecorator;
                    iNaviDecorator = NULL;
                    }

                // set the navigation pane label
             iNaviDecorator = naviPane->CreateNavigationLabelL(reader);
                CleanupStack::PopAndDestroy(); // pushed by CreateResourceReaderLC
     
                naviPane->PushL(*iNaviDecorator);
              }


6. 使用资源在导航面板中显示图像

在资源文件中使用NAVI_IMAGE资源为导航面板指定图像,跟前面指定图像的方法相同。
RESOURCE NAVI_IMAGE r_navigationpane_navi_image
{
bmpfile = "z://system/data/avkon.mbm";
bmpid = EMbmAvkonQgn_stat_keyguard;
}

    TUid naviPaneUid;
    naviPaneUid.iUid = EEikStatusPaneUidNavi;
    CEikStatusPane* statusPane = StatusPane();


    CEikStatusPaneBase::TPaneCapabilities subPane =
     statusPane->PaneCapabilities(naviPaneUid);

   // if we can access the navigation pane
    if (subPane.IsPresent() && subPane.IsAppOwned())
     {

          CAknNavigationControlContainer* naviPane =
        (CAknNavigationControlContainer *) statusPane->ControlL(naviPaneUid);

                // read the navigation pane image resource
                TResourceReader reader;
                iCoeEnv->CreateResourceReaderLC(reader, R_NAVIGATIONPANE_NAVI_IMAGE);

                if (iNaviDecorator)
                    {
                    delete iNaviDecorator;
                    iNaviDecorator = NULL;
                    }

                // set the navigation pane image
             iNaviDecorator = naviPane->CreateNavigationImageL(reader);
                CleanupStack::PopAndDestroy(); // pushed by CreateResourceReaderLC
     
                naviPane->PushL(*iNaviDecorator);

      }