控件(control)和窗口(window)
1、控件(control)
控件是UI应用程序中用户与应用程序交互的基本元素。在Symbian OS中所能看到的用户界面元素大多都属于控件。所有控件都派生于抽象基类CCoeControl,该类为控件提供了基本的功能。
控件可以分为简单控件和复合控件。简单控件是不包含任何其他控件的控件,独自负责绘制所表示的区域。复合控件是包含一个或多个其他控件的控件,包含在复合 控件中的控件被称为组件控件。复合控件的绘制任务部分或全部由组件控件负责。这些被复合控件包含的组件控件又可以是简单或复合控件。
1.1、创建简单控件
简单控件的创建步骤如下:
- 创建一个派生于CCoeControl 的类。
- 实现构造函数ConstructL() 。
- 重写虚方法Draw() ,为控件提供绘制代码。
- 重写虚方法SizeChanged() ,为控件大小更改时重新绘制控件。
每个控件都应该拥有一个ConstructL()方法完成控件的第二阶段构造。一般情况下,该方法至少完成一下任务:
- 设置控件是否为拥有窗口的控件(CreateWindowL()、SetContainerWindowL())。
- 设置控件的工作区域 — 即控件负责绘制的屏幕区域。
- 激活控件。
1.2、创建复合控件
复合控件的创建步骤如下:
- 创建一个派生于CCoeControl 的类。
- 实现构造函数ConstructL() 。
- 重写虚方法Draw() ,为控件提供绘制代码。
- 重写虚方法SizeChanged() ,为控件大小更改时重新绘制控件。
- 为复合控件添加组件控件,通常组件控件为复合控件的数据成员。
- 重新虚方法CountComponentControls()和ComponentControl(),确保组件控件绘制。
2、窗口(window)
每个控件都必须在窗口上绘制,因此每个控件都有一个关联的窗口。除了给予每个控件各自的窗口外,还可以在多个控件间共享同一个窗口。也就是说,控件既可以"拥有窗口"(有自己的窗口),也可以"不拥有窗口"(与拥有窗口的控件共享窗口)。
窗口是一种昂贵的资源,因此为每个控件创建各自的窗口是不适合的做法。通过使用不拥有窗口的控件,可以减少窗口数量,节省系统资源。通常不拥有窗口的控件都以组件控件的形式出现,包含它的控件容器(Container)拥有窗口。
拥有窗口的控件不能共享其他控件的窗口,必须在创建自己的窗口。拥有窗口的控件和创建的窗口有相同的大小。拥有窗口的控件一般作为简单控件和复合控件的控件容器。
视图资源
一般情况下,每个视图都需要自己的特殊设置,例如菜单项、CBA、热键。通过 将视图与资源关联,可以容易的实现视图的设置。因此,为了让视图定义自己的菜单等,可以在资源文件中创建一个AVKON_VIEW资源,然后将资源ID传 递到视图的BaseConstructL()中。
视图资源定义:
STRUCT AVKON_VIEW
{
LLINK hotkeys = 0;
LLINK menubar = 0;
LLINK cba = 0;
}
- hotkeys:定义了一个LLINK类型变量,引用一个HOTKEYS结构的资源ID。
- menubar: 定义了一个LLINK类型变量,引用一个MENUBAR结构的资源ID。
- cba: 定义了一个LLINK类型变量,引用一个CBA结构的资源ID(在avkon.rsg中定义)。
常用的CBA结构的资源ID:
R_AVKON_SOFTKEYS_OPTIONS_BACK
R_AVKON_SOFTKEYS_OPTIONS_EXIT
R_AVKON_SOFTKEYS_OPTIONS_CANCEL
R_AVKON_SOFTKEYS_OK_CANCEL
R_AVKON_SOFTKEYS_OK_BACK
视图资源的使用:
STRUCT AVKON_VIEW r_my_view
{
hotkeys = r_my_hotkeys;
menubar = r_my_menubar;
cba = R_AVKON_SOFTKEYS_OK_BACK ;
}
应用程序与视图资源关联:
void CMyView::ConstructL()
{
BaseConstruct(R_MY_VIEW);
菜单(Menu)
菜单是当用户按下选项(Options)键(CBA按键)时显示的命令列表窗口。菜单由多个菜单项(菜单命令)组成,每个菜单项表示为一个文本标签。菜单可以通过在资源文件中指定菜单条(menu bar)和菜单面板(menu pane)资源创建。菜单条可以包含一个或多个由菜单项组成的菜单面板。一旦用户选择了一条菜单项,应用框架将调用应用程序命令处理器响应相应的选择。
菜单可以添加到主应用程序屏幕、应用程序视图、对话框和其他一些控件上。一旦显示了菜单,软件(CBA)即会更改为左键选择(Select)右键取消(Cancel)。
菜单项可以含有一个子菜单。子菜单包含与此菜单项相关的其他命令集合。每个菜单项最多只能包含一个子菜单,子菜单不能再包含子菜单。
1、使用菜单资源定义菜单
1.1、MENU_BAR
菜单资源通过在MENU_BAR结构体中定义:
RESOURCE MENU_BAR r_my_menu_bar
{
titles =
{
MENU_TITLE { txt = ""; menu_pane = r_my_menu_pane1; },
MENU_TITLE { txt = ""; menu_pane = r_my_menu_pane2; }
};
}
MENU_BAR结构体中包含一个titles数组,数组的每个元素是一个 MENU_TITLE结构。MENU_TITLE结构由两个字段组成:txt字段指定菜单的标题,但在S60中菜单标题并不显示,所以通常设置为空,但某 些时候提供一个有意义的菜单标题可以作为提示信息。menu_pane字段引用一个MENU_PANE结构,包含了菜单项。当titles数组中包含多个 元素时,菜单在显示菜单项的顺序时,将按照数组元素定义的先后顺序从上而下的显示每个元素引用的MENU_PANE结构中定义的菜单项。
1.2、MENU_PANE
菜单的菜单项通过在MENU_PANE结构体中定义:
RESOURCE MENU_PANE r_my_menu_pane1
{
items =
{
MENU_ITEM { command = EMyAppCmdCom1; txt = "item1"; },
MENU_ITEM { command = EMyAppCmdCom2; txt = "item2"; }
};
}
MENU_PANE结构体中包含了一个items数组,数组的每个元素是一个 MENU_ITEM结构,也就是一个菜单项。MENU_ITEM结构由以下个字段组成:command字段指定了菜单项的命令ID。命令ID是一个应用程 序内唯一的枚举值,在扩展名为.hrh的头文件中定义(通常命令ID的名称格式为:E<应用程序名>Cmd<命令名>);txt 字段指定了菜单项显示的文本信息;cascade字段指定了子菜单项,需要引用一个MENU_PANE结构。
2、应用程序与菜单关联
2.1、主应用程序与菜单关联
通过设置资源文件中的EIK_APP_INFO结构中的menubar和cba字段:
RESOURCE EIK_APP_INFO
{
menubar = r_my_menu_bar;
cba = R_AVKON_SOFTKEYS_OPTIONS_BACK;
}
2.2、视图与菜单关联
通过设置资源文件中的AVKON_VIEW结构中的menubar和cba字段:
RESOURCE AVKON_VIEW r_my_view
{
menubar = r_my_menu_bar;
cba = R_AVKON_SOFTKEYS_OPTIONS_BACK;
}
3、动态菜单
动态菜单是指在应用程序运行过程中,根据需要更改菜单条(menu bar)或菜单项(menu item)。
3.1、更改菜单条(menu bar)
改变应用程序所使用的菜单资源:
iEikonEnv->AppUiFactory()->MenuBar()->
SetMenuTileResourceId(MENU_BAR_RESOURCE_ID);
改变应用程序视图所使用的菜单资源:
iMyView->MenuBar()->SetMenuTitleResourceId(MENU_BAR_RESOURCE_ID);
3.2、更改菜单项(menu item)
所有可以拥有菜单的UI组件(AppUi、View)都继承了MEikMenuObserver混合类。该类定义了虚方法DyInitMenuPaneL(),通过重写此方法可以动态更改菜单项(隐藏菜单项)。当应用程序将菜单面板(menu pane)添加到菜单后由应用程序框架调用,aResourceId为添加的菜单面板资源ID。
void CMyAppUi::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane )
{
aMenuPane->SetItemDimmed(EMyAppCmdCom1, ETrue);
aMenuPane->SetItemDimmed(EMyAppCmdCom2, ETrue);
}
状态面板(Status Pane)
Symbian S60应用程序窗口的标准面板由状态面板、主面板和控制面板组成。
1、状态面板组成
状态面板占据了屏幕区域的顶部,用于显示与当前应用程序和设备自身状态有关的信息。分别有下列子面板组成:
- 标题面板(Title pane)。
- 上下文面板(Context pane)。
- 导航面板(Navi pane)。
- 信号面板(Signal pane)。
- 电池面板(Battery pane)。
- 通用指示器面板(Universal indicator pane)。
下列子面板的内容可以在应用程序中修改:
- 标题面板(Title pane): 默认显示应用程序的名字。可以更改为显示自定义文本,或显示一幅位图图像。
- 上下文面板(Context pane): 默认显示系统指定的应用程序图标,可以根据需要更改为其他图标。
- 导航面板(Navi pane): 导航面板的主要用途是显示与应用程序的当前状态有关的信息,以及说明当前显示的是哪个视图。此外,还可以使用它在应用程序内导航(切换视图)。导航面板默认为空白,可以根据需要用选项卡、导航标签、图像、指示器或文件夹结构指示符修饰它。
2、状态面板可见性和尺寸
2.1、更改状态面板可见性
为了修改状态面板,需要获得状态面板句柄。在AppUi和View中都有获得句柄的方法StatusPane()。
CEikStatusPane* statusPane = StatusPane();