(2)
基于对话框的架构
它不同于传统
Symbian OS
架构的是,它
拥有的控件直接从对话框类家族继承
而来。
对话框的主要优点是:相对于直接从
CcoeControl
派生而来的控件,它需要较少的开发工作,因为它们自动管理子控件的布局。
在
AppUi
类中完成构造和运行:
void CsimpleDlgAppUi::ConstructL()
{
BaseConstructL();
IAppDialog=new(ELeave) CsimpleDlgDialog;
IAppDialog->SetMopParent(this);
IAppDialog->ExecuteLD(R_SIMPLEDLG_DIALOG);
AddToStackL(iAppDialog);
}
因为对话框是无模式的,
ExecuteLD
()将在调用后立刻返回。必须使用
AddToStackL
()将对话框添加到控件栈中,因为无模式的对话框无法自己完成这项工作。
还有,必须在
AppUi
的析构函数中销毁该对话框:
CsimpleDlgAppUi::~CsimpleDlgAppUi()
{
if(iAppDialog)
{
RemoveFromStack(iAppDialog);
delete iAppDialog;
}
}
(3)
Avkon
视图切换架构
比前两种都复杂,引入另一个类作为
AppUi
和容器之间的媒介。另外,
AppUi
类从
CAknViewAppUi
继承,而不是继承于
CaknAppUi
。
前两个架构,
AppUi
直接负责处理视图切换,它必须管理视图提交控件的实例化、删除和显示。但是,基于
CaknView
的类在这方面可以很明显地减少
AppUi
地任务。
AppUi
仍然处理视图切换的请求,但现在,并不是删除旧的容器并实例化新的容器,
AppUi
只需要调用它的其中一个特殊视图激活函数,如
ActiveViewL
()。这些特殊的
CaknViewAppUi
函数向
View
服务器提交一个激活请求,然后通过基于
CaknView
的相关类中的激活
/
禁止成员函数,
View
服务器显式地协调当前视图地禁止和所请求视图的激活。
这种架构所需的一般特性如下:
l
必须设计应用程序,使每个
CAknView
派生的
Avkon
视图拥有一个容器,然后
AppUi
拥有每个
Avkon
视图。
l
必须从
CaknViewAppUi
派生应用程序的
AppUi
,而不是从
CAknView
派生,这是因为前者提供了注册、激活和禁止
Avkon
视图的方法。
l
必须在
View
服务器中注册所有的
Avkon
视图。
l
Avkon
视图具有激活
/
禁止成员函数,
View
服务器可以直接调用这些函数。必须重写这些函数,提供从属容器的正确处理。
View
服务器最主要的原则:确定在任意给定时刻,每个应用程序中只有一个
Avkon
视图被激活。
Avkon
视图通过两个
UID
向
View
服务器唯一性的标志自己
:一个
UID
用于标志拥有该视图的应用程序,另一个
UID
用于在该应用程序中唯一标志该视图。
对于每个基于
CAknView
的类,需要实现的激活
/
禁止函数是:
DoActiveL
()
和
DoDeactivate
()
,这些函数负责实例化和显示或者删除
Avkon
视图拥有的
UI
控件。
View
服务器将主动调用
DeactivateView
()
,从而强制遵循每个应用程序中只有一个激活视图的规则。
如何使用
Avkon
视图切换架构:
l
使用这种架构时,必须结合使用
CaknViewAppUi
和
CAknView
类。
每个
Avkon
类都从
CAknView
派生
而来,并且必须包含一个
Id
()函数
,从而
系统可以标志这个类
。它也必须实现
DoActivateL
()和
DoDeactivateL
()
函数。此外,它还必须实现
HandleForegroundEventL
()、
HandleCommandL
()和
HandleStatusPaneSizeChange
()
函数,
用于处理各种事件
。
l
用户请求激活视图时,
View
服务器将调用
DoActivateL
()
。该函数的目的是实例化并显示提交视图的控件。
注意:在
DoDeactivateL
()之前可以多次调用
DoActivateL
()。
l
将要禁止
Avkon
视图时,则会调用
DoDeactivateL
(),该函数负责销毁它的控件。当应用程序退出时,或者激活相同应用程序的另一个视图时,将禁止视图。该函数绝对不能异常退出。
l
只有在激活
Avkon
视图时才会调用
HandleForegroundEventL
(),即在调用
DoActivateL
()和
DoDeactivateL
()之间。当
视图到达前台
时,接收
HandleForegroundEventL
(
Etrue
)
,当
从前台移除视图
时,将接收
HandleForegroundEventL
(
Efalse
)
。程序员可能
希望使用这种方法来设置焦点或控制屏幕更新。
视图菜单生成一条命令时
,调用
HandleCommandL
()
,因为状态面板改变而使客户矩形大小改变时,则调用
HandleStatusPaneSizeChange
()
。
为了让
Avkon
视图定义它自己的软键和菜单资源
,可以在资源文件(
.rss
)中创建一个
AVKON_VIEW
资源
,然后将资源
ID
传递到视图的
BaseConstructL
()函数中。
通常在
AppUi
对象的
ConstructL
()方法中构造应用程序中的所有
Avkon
视图
。使用
AddViewL
()在
View
服务器中注册这些
Avkon
视图
,最终通过设置
默认的视图
来激活初始视图,使用方法
SetDefaultViewL
()
。
注意:不是由
Avkon
视图处理的命令被传递到
AppUi
,
在
AppUi
的
HandleCommandL
()方法里,只进行视图间切换的命令
。本地视图切换或者是应用程序拥有的视图切换,这些工作都通过引用目标
Avkon
视图的
UID
来执行。
为了执行外部视图切换,则需要调用
CcoeAppUi::ActivateViewL
()函数,提供一个包含目标应用程序
UID
和目标视图
UID
的
TVWsViewId
。如:
const Tuid KphoneBookUid={0x101f4cce} ;// from PbkUID.h
const Tuid kphoneBookContactViewUid={1};
ActivateViewL(TvwsViewId(KphoneBookUid,KPhoneBookContactViewUid));
注意:如果自己的程序中的某部分视图能够被其他程序使用,那么我们必须通过导出为头文件来发布应用程序
UID
和视图
UID
。