symbianUII.docx
- 文档编号:6067723
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:20
- 大小:23.06KB
symbianUII.docx
《symbianUII.docx》由会员分享,可在线阅读,更多相关《symbianUII.docx(20页珍藏版)》请在冰豆网上搜索。
symbianUII
MVC
Modelcontrolview
Observer观察者模式
UiKon:
(面向UIQ平台)Eik_开头的,一般触摸屏,有鼠标操作,symbian的
AvKon(面向S60平台)Akn_开头的,一般使用方向键,对Uikon进行了一些封装和增加了
一些函数,S60平台主要使用Akn_开头的函数.Nokia的Akn_
Symbian1.几个控件共享一个窗口,2.一个控件拥有一个窗口
Windows一个控件拥有一个窗口
控件由CCoeControl继承而来
重构CContain1为CSimpleControl(简单控件类)
1,在头文件中,选中类名,按Alt+Shift+R,将CContain1替换CSimpleControl
2,加入:
//ConstructL()的第二个参数一定要有默认值,因为框架调用的只有一个参数
VoidConstructL(constTSize&aRect,constCCoeControl*aParent=NULL);
StaticCSimpleControl*NewLC(constTSize&aRect,constCCoeControl*aParent);
StaticCSimpleControl*NewL(constTSize&aRect,constCCoeControl*aParent);
3.然后在源文件中:
VoidCSimpleControl:
:
ConstructL(constTSize&aRect,constCCoeControl*aParent)
{
If(!
aParent)
{
CreateWindowL();
}
Else
{//与*aParent共享同一窗口
SetContainerWindowL(*aParent);
}
//执行完SetRect()(即设置本窗口的位置和大小)-->调用SizeChanged()
SetRect(aRect);
ActivateL();//通知服务器可以绘图了,之后调用Draw()
}
CSimpleControl*CSimpleControl:
:
NewLC(constTSize&aRect,constCCoeControl*aParent)
{
CSimpleControl*self=new(ELeave)CSimpleControl();
CleanupStack:
:
PushL(self);
Self->ConstructL(aRect,aParent);
Returnself;
}
CSimpleControl*CSimpleControl:
:
NewL(constTSize&aRect,constCCoeControl*aParent)
{
CSimpleControl*self=NewLC(aRect,aParent);
CleanupStack:
:
Pop();
Returnself;
}
使用CSimpleControl类
在头文件前置声明:
classCSimpleControl;
然后在类中声明:
CSimpleControl*simple;
CSimpleControl*simple1;
在源文件中:
//
voidCCompoundControl:
:
ConstructL(constTRect&aRect)
{
CreateWindowL();
iSimple=CSimpleControl:
:
NewL(aRect,this);
iSimple1=CSimpleControl:
:
NewL(aRect,this);
SetRect(aRect);
ActivateL();
}
//ThefunctioniscalledwheneverSetExtent(),SetSize(),SetRect(),
//SetCornerAndSize(),orSetExtentToWholeScreen()arecalledonthecontrol.
//执行完SetRect(aRect)之后调用SizeChanged();
//设置控件的位置
voidCCompoundControl:
:
SizeChanged()
{
//TODO:
Addherecontrolresizecodeetc.
iSimple->SetExtent(TPoint(0,10),TSize(60,50));
iSimple1->SetExtent(TPoint(10,100),TSize(50,50));
}
//如果是复合控件类下面两个和上面一个必须写,它们被框架调用
//告诉框架,容器内有几个控件
TIntCCompoundControl:
:
CountComponentControls()const
{
return2;//returnnbrofcontrolsinsidethiscontainer
}
//根据索引,返回控件的指针
CCoeControl*CCompoundControl:
:
ComponentControl(TIntaIndex)const
{
switch(aIndex)
{
case0:
returniSimple;
case1:
returniSimple1;
default:
returnNULL;
}
}
ExampleAppUi.cpp
//----------------------------------------------------
//ChelloViewsAppUi:
:
TabChangedL(TIntaIndex)
//ThismethodgetscalledwhenCAknTabGroupactive
//tabhaschanged.进行视图切换
//----------------------------------------------------
//tab键,高亮显示,observer观察者模式
//按左右键时回调此函数
voidChelloViewsAppUi:
:
TabChangedL(TIntaIndex)
{
//激活视图做为前台,和视图服务器打交道,此函数为异步函数,
//对一个活动对象进行了封装
//发送了请求后,会很快返回
//调用ActivateLocalViewL()之后会调用View的DoActive()
ActivateLocalViewL(TUid:
:
Uid(iTabGroup->TabIdFromIndex(aIndex)));
}
//响应按键命令
一.继承自CAknAppUi的实例使用HandleKeyEventL
二.继承自CCoeControl的实例使用OfferKeyEventL
//响应菜单命令
voidChelloViewsAppUi:
:
HandleCommandL(TIntaCommand)
{
switch(aCommand)
{
caseEEikCmdExit:
{
Exit();
break;
}
caseEhelloViewsCmdAppTest:
{
iEikonEnv->InfoMsg(_L("test"));
break;
}
case2000:
{
//调用ActivateLocalViewL()之后会调用View的DoActive()
ActivateLocalViewL(TUid:
:
Uid
(1));
break;
}
//TODO:
AddYourcommandhandlingcodehere
default:
break;
}
}
voidChelloViewsAppUi:
:
ConstructL()
{
BaseConstructL();
//Showtabsformainviewsfromresources
CEikStatusPane*sp=StatusPane();
//Fetchpointertothedefaultnavipanecontrol
iNaviPane=(CAknNavigationControlContainer*)sp->ControlL(
TUid:
:
Uid(EEikStatusPaneUidNavi));
//Tabgrouphasbeenreadfromresourceanditwerepushedtothenavipane.
//GetpointertothenavigationdecoratorwiththeResourceDecorator()function.
//Applicationownsthedecoratorandithasresponsibilitytodeletetheobject.
iDecoratedTabGroup=iNaviPane->ResourceDecorator();
if(iDecoratedTabGroup)
{
iTabGroup=(CAknTabGroup*)iDecoratedTabGroup->DecoratedControl();
iTabGroup->SetObserver(this);
}
ChelloViewsView*view1=new(ELeave)ChelloViewsView;
CleanupStack:
:
PushL(view1);
view1->ConstructL();
//向视图服务器去注册,告诉它有几个视图
AddViewL(view1);//transferownershiptoCAknViewAppUi
CleanupStack:
:
Pop();//view1
ChelloViewsView2*view2=new(ELeave)ChelloViewsView2;
CleanupStack:
:
PushL(view2);
view2->ConstructL();
AddViewL(view2);//transferownershiptoCAknViewAppUi
CleanupStack:
:
Pop();//view2
//tab键,高亮显示,和视图没关系
//设置默认视图
SetDefaultViewL(*view3);
}
voidChelloViewsView:
:
ConstructL()
{
//指定与该视图相关的资源文件
BaseConstructL(R_HELLOVIEWS_VIEW1);
}
ChelloViewsView:
:
~ChelloViewsView()
{
if(iContainer)
{
AppUi()->RemoveFromViewStack(*this,iContainer);
}
deleteiContainer;
}
TUidChelloViewsView:
:
Id()const
{
returnKViewId;
}
voidChelloViewsView:
:
HandleCommandL(TIntaCommand)
{
switch(aCommand)
{
caseEAknSoftkeyOk:
{
iEikonEnv->InfoMsg(_L("helloview1"));
break;
}
caseEAknSoftkeyBack:
{
//不是本视图的命令,应该转给AppUi
AppUi()->HandleCommandL(EEikCmdExit);
break;
}
default:
{
//不是本视图的命令,应该转给AppUi
AppUi()->HandleCommandL(aCommand);
break;
}
}
}
voidChelloViewsView:
:
HandleClientRectChange()
{
if(iContainer)
{
iContainer->SetRect(ClientRect());
}
}
//切换到前台时调用
voidChelloViewsView:
:
DoActivateL(
constTVwsViewId&/*aPrevViewId(上一个视图的ID)*/,TUid/*aCustomMessageId*/,
constTDesC8&/*aCustomMessage*/)
{
if(!
iContainer)
{
iContainer=new(ELeave)CSimpleControl;
iContainer->SetMopParent(this);
//ClientRect()返回客户区的大小
iContainer->ConstructL(ClientRect()/*TRect(50,50,100,100)*/);//ApplicationRect()全屏
AppUi()->AddToStackL(*this,iContainer);
}
}
//视图切换到后台时执行DoDeactivate()
voidChelloViewsView:
:
DoDeactivate()
{
if(iContainer)
{
//不是销毁本视图,从ViewStack中移除,以节省资源,下次切换到时,再添加到ViewStack
AppUi()->RemoveFromViewStack(*this,iContainer);
}
deleteiContainer;
iContainer=NULL;//此句话是必须的,deleteNULL是安全的,但对同一地址进行二次释放会崩溃
}
//EndofFile
//view进行视图的管理,不绘制图形
classChelloViewsView:
publicCAknView{};
//视图的一个编号,可以自己定义,不能重复,根据编号进行视图切换
TUidId()const;
voidChelloViewsContainer:
:
ConstructL(constTRect&aRect)
{
CreateWindowL();
iLabel=new(ELeave)CEikLabel;
//设置iLabel与本窗口共享同一窗口
iLabel->SetContainerWindowL(*this);
iLabel->SetTextL(_L("ExampleView"));
iToDoLabel=new(ELeave)CEikLabel;
iToDoLabel->SetContainerWindowL(*this);
iToDoLabel->SetTextL(_L("AddYourcontrols\nhere"));
//执行完SetRect()(即设置本窗口的位置和大小)-->调用SizeChanged()
SetRect(aRect);
//通知服务器开始绘图了-->调用Draw()
ActivateL();
}
rss资源文件中定义
RESOURCETBUF32r_buffer_text
{
buf="helloresouce";
}
使用资源
注意包含头文件,查SDK
CAknInformationNote*information;
HBufC*buf=iCoeEnv->AllocReadResourceLC(R_RESOURCE_TEXT);
information=new(ELeave)CAknInformationNote();
information->ExecuteLD(*buf);
CleanupStack:
:
PopAndDestroy();
//响应按键命令
1.继承自CAknAppUi的实例使用HandleKeyEventL
2.继承自CCoeControl的实例使用OfferKeyEventL
只要接受按键,就要实现以下:
1.加入控件栈,按栈传递是从栈顶元素开始,按键消息首先传递给栈顶控件,如果栈顶控件不处理则返回EKeyWasNotConsumed,则传递给下一个控件,直到有一个控件处理之,并返
回EKeyWasConsumed.如果都不处理,最后由
TKeyResponseChello1AppUi:
:
HandleKeyEventL(
constTKeyEvent&/*aKeyEvent*/,TEventCode/*aType*/)
{
returnEKeyWasNotConsumed;
}处理.
当一个按键事件发生时,控件框架调用控件栈上的每个控件的OfferKeyEventL方法,直到它们中的一个能够处理这个按键事件(并且返回EKeyWasConsumed)。
为了接收到按键事件,应用程序应该调用CCoeAppUi:
:
AddToStackL()方法把控件增加到栈上。
尽管这个规则仅仅用在非混合控件。
混合控件应该传递按键事件给其组件:
组件自己并不在控件栈上。
复合控件,只有顶层控件被放在控件栈。
2.加入
virtualTKeyResponseOfferKeyEventL(constTKeyEvent&aKeyEvent,TEventCodeaType);函数
3.处理EEventKey,EEventKeyDown,EEventKeyUp三个事件
KeyResponseCCompoundControl:
:
OfferKeyEventL(constTKeyEvent&aKeyEvent,TEventCodeaType)
{
//控件栈只能放顶层控件
//忽略EEventKeyDown,EEventKeyUp
//因为.iCode只对应一个EEventKey产生的字符码,当按下或释放按键的时候值为0
if(aType!
=EEventKey)returnEKeyWasNotConsumed;
if(aKeyEvent.iCode==EKeyUpArrow)
{
if(iIndex>0)iIndex--;
}
elseif(aKeyEvent.iCode==EKeyDownArrow)
{
if(iIndex<1)iIndex++;//向下键,iIndex=0
}
if(iIndex==0)
{
iSimple->SetFocus(ETrue);
iSimple1->SetFocus(EFalse);
}
else
{
iSimple1->SetFocus(ETrue);
iSimple->SetFocus(EFalse);
}
DrawNow();//重绘
//DrawDeferred();//延时重绘
if(iSimple->IsFocused())
{
//控件栈只能放顶层控件,只有子控件获得焦点后,才能将按键传递过去
//注意是获得焦点时,才向子控件传递
returniSimple->OfferKeyEventL(aKeyEvent,aType);//向子控件传递
}
else
{
returniSimple1->OfferKeyEventL(aKeyEvent,aType);
}
}
iScanCode这个值是实际键盘的扫描码,也就是一个键对应一个数字。
而iCode是键的一些映射,比如EKeyLeftArrow、EKeyRightArrow、EKeyUpArrow、EKeyDownArrow、EKeyDevice3分别代表左、右、上、下、Fire键,而63554、63555分别代表左右软键等。
所以用iCode具有更强的通用性。
//利用观察者模式响应子控件的发出的事件
voidCCompoundControl:
:
ConstructL(constTRect&aRect)
{
CreateWindowL();
iSimple=CSimpleControl:
:
NewL(aRect,this);
iSimple1=CSimpleControl:
:
NewL(aRect,this);
iSimple->SetObserver(this);//设定父控件为观察者,用来监控子控件发生
//有什么事件
iSimple1->SetObserver(this);//子控件一旦有事件发生,就会回调//HandleControlEventL()方法
SetRect(aRect);//子控件用ReportEventL(EEventStateChanged)方法将事件传递给父控件
ActivateL();
}
DrawNow(),DrawDeferred()(有延时),重绘
使用中文资源:
一定要在命令行编译
注意命令行编译与Carbide的不同,使用编译器不同
Mmp定义两种0131//01英文,31中文
Loc文件
CHARACTER_SETUTF8
#ifdefLANGUAGE_01
#include"hello.l01"
#endif
#ifdefLANGUAGE_31
#include"hello.l31"
#endif
然后定义两个文件,英文的*.l01
中文资源的*.l31注意是字母’l’;
中文资源一定保存为UTF-8
注意应把所有字符串放在*.l01或*.l31文件中
注意一定先设置成UTF-8格式(点*.l31文件右键属性),再修改
在多视图架构下使用对话框资源需要加入CEikDialog的库文件eikdlg.lib
并包含资源头文件,而在对话框架构下则不用加.
注意看编译器的提示
对话框标志:
buttons=R_AVKON_SOFTKEYS_OK_CANCEL;OKCANCEL风格
EEikDialogFlagModeless非模态
EEikDialogFlagWait模态
对话框的执行:
CSampleDialog*dlg=new(ELeave)CS
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- symbianUII
![提示](https://static.bdocx.com/images/bang_tan.gif)