Symbian活动对象练习
Symbian C++ 开发

编写优秀的Symbian OS代码
一般技巧 设计技巧 编码技巧 测试技巧 调试技巧
一般技巧
Symbian开发人员网络站点 (/developer)提供了有价 值的信息来帮助编写应用程序。 Symbian的授权使用者还可以运行开发者相关 的程序。 Symbian开发人员网站提供了Symbian OS FAQ数据库 (/developer/techlib/f aq.html),对于开发者是无价的信息资源,它 涵盖了设计和编码中最经常问到的问题。
TRAP和Leave Cleanup栈 两步构造函数
严重错误
User::Panic
static void Panic(Tint aPanic) { _LIT(KPanicCategory, “MY-APP”); User::Panic(KPanicCategory, aPanic); }
断言宏
enum TMyAppPanic { EMyAppIndexNegative=12, } _ASSERT_ALWAYS(aIndex>0, Panic(EMyappIndexNegative));
设计技巧
最重要的Symbian OS设计技巧就是将 “引擎”和UI代码分置在不同的模块中。 要始终注意,让设计支持本地化。 注意坚持使用有说明文档并得到SDK和 Symbian OS版本支持的API。
编码技巧
保证应用程序可以响应系统关闭事件。 要响应输入的系统事件。 Symbian OS上的内存处理是一个关键问题。 KERN-EXEC3崩溃通常是栈溢出的征兆——按照Symbian SDK的建议,优先使用堆来代替栈。 低内存条件下,完美处理错误很重要——一个应用程序出现错误,表明代码中的确存在漏洞。 对于具有Close()方法的R类,总是使用CleanupClosePushL()。 另外,记住清除栈是一种可扩展机制、可以用于异常退出时清除任何东西。 在删除成员变量HBufC后,总是将其置为NULL。 如果有理由使用自己的TRAP,那么不要忽略所有的错误。 不要等待通过PushL()将对象清入清除栈。 注意在名称中带后缀C的函数自动将对象放入清除栈中。 两阶段构造是Symbian OS内存管理的一个关键部分。 代码中不要使用_L()宏。 当使用描述符作为函数的参数时,默认时使用基类。 活动对象(AO)是Symbian OS功能中的一个关键部分。 尽可能使用活动对象框架。 对于即时性游戏,编写忙碌的应用程序时,ViewSrv11错误是一种危险。 不需要利用HBuf::Des()来使用HBufC。 使用标准应用程序.INI文件功能时,确认在流中写入了版本号信息。
Symbian OS基础知识

1第章S y m b i a n O S基础知识在探讨Symbian OS的高级知识之前,有必要花一些时间先学习所有应用程序中共有的一些基本操作、编程模式和类,实际上,这些内容几乎是系统中所有运行代码所共有的。
这里要探讨的是人们反复使用的基本模式:构建可以生成安全、高效代码的单元块。
Symbian OS采用了面向对象技术,它用C++编写而成,仅在最底层使用了极少量的汇编语言。
这意味着,绝大多数应用程序都采用C++编写。
但是,Symbian OS中使用的C++与其他环境中的C++并非完全相同,主要表现在:• C++的功能比Symbian OS所需的功能要强大。
例如,C++语言拥有成熟的多重继承功能。
• C++也在一定程度上满足不了Symbian OS的要求。
例如,C++对用于表达基本类型的字节数并没有严格地指定,同时,C++对于DLL也一无所知。
•不同的C++阵营由于需求不同,他们的处理方法也不相同。
而对于Symbian OS而言,大规模的系统设计与错误处理和清除这一重点相结合,而且通过对ROM和RAM的使用安排而获得效率。
1.1 对象的创建与销毁面对对象系统的基本特征之一就是对象的创建与销毁。
对象一经创建,就拥有一个有限生命周期,一旦其物尽其用,必将它销毁。
对象的创建和销毁与内存的清除紧密相关,程序员应该确保应用程序不会发生内存泄漏,这对长时间不重启、甚至根本不启动的系统来说是非常实际的问题。
下面先介绍Symbian OS中创建和销毁对象的基础知识。
但是,从某种程度上讲,这里所介绍的部分知识也许会给人以错觉,因为只有学习了错误处理和清除之后,才可能对此有全面的把握。
因为对象创建、对象销毁、错误处理和清除是紧密联系在一起的,它们共同确保系统能正确地销毁任何不再需要的对象。
对于Symbian OS,可以在堆和程序栈两个地方创建对象。
1.1.1 堆(动态对象)所有的线程都有一个关联堆,称做默认堆,可以在运行时从这个堆分配内存。
Symbian OS环境中用活动对象处理非抢占式多任务的安全性分析

手 机 市 场 中 的 主要 成 员 . y inOS包 括 联 络 、 S mba 消息 、 浏览 和 无 线 电话 4大 主要 功 能 ; 以使 用 诸 可
如S MTP, OP ,MAP , P 3I 4 HTMI, MS等 通 信 协 S
议 收发 电子 邮件 和短 信 ; 持 TC /P, AP, 支 PI W 蓝
牙, 红外 , 串行 通 信 等多 种 协 议 ; 有强 大 的加 密 具 和 认 证 管 理 功 能 ( 括 HT S W T S和 S I 包 TP , L S
等) 支 持对 象 交换 和 多媒体 服 务 ( 音 、 像 ) 支 ; 语 图 ;
1 1 智 能 手 机 .
用程 序是 否 可 以访 问受 能力 保护 的AP ;3 授 权 I()
(uh r ain , a t oi t ) 由鉴定 过 程 来执 行 , z o 一般 由 S m— y ba in的 Sg e in d程序 来 执行 . 于某 些 受 能力 保 护 对
的 AP ,y inOS只对 应用 程 序 授 予经 过授权 IS mba 智 能手 机 之所 以被 称 为 “ 能 ” 就是 因为 在 智 ,
S mba y i OS是一 个 开放 的 、 n 高级 的 、 准 的 、 标 多任 务 的 嵌入 式 手机 操 作 系 统. 是 由许 多重 要 它 的非 集成 模 块 和 一 个 集 成 内 核组 成 , 已成 为 智 能
些 操 作 系统都 有 丰 富 的功 能支 持 , 以运行 以 C 可 /
持 国际通用 字 符 ( 持Unc d 支 io e字 符 ) 包括 4个 开 ; 发选 项 , 与 P 的应 用程 序 进 行数 据 同 步 , 支 可 C 并 持 多用 户接 口.
基于Symbian套接字使用SMTP协议发送邮件

计 算机光盘软件 与应用
2 1年第 1 01 期
C m u e D S fwr n p lc to s op tr C o ta e adA p ia in
工程技术
基于 S m i y ba n套接字使用 S P协议发送邮件 MT
周 墨 颂
( 河北师范大学软件学院, 石家庄 0 0 3 ) 5 0 2
s se o c pe h r ets ae o e s r h n r k t a r e n mb ro e eo e sa d u e sS mb a o k t o y tm. c u ist e l g s h r f mat o ema e . sa l g u e fd v lp r n s r .y i OS S c e mmu iai n a h t p h a n c nc t o
基于SYMBIAN%20OS的智能手机应用软件开发免费范文精选

基于SymbianOS的智能手机J世用软件开发
基于Symbianos的智能手机应用软件开发
作者简介:董佩嘉(1976.),男,成都理工大学计算机应用技术专业2004
级硕士研究生,主要研究方向为计算机通信。
摘要
目前,智能手机发展非常迅速,仅去年在中国的销售量就早已突破五百万大关,具有广阔的市场前景。
之所以称之为智能手机,就是因为这种手机象Pc
一样,具有操作系统,能够安装运行软件。
在智能手机操作系统的大家族中,主
要以诺基亚的SymbJan,微软的WindowsMobile和Linux。
由于手机巨头诺基亚公
司的大力支持,Symbian占据了最主要的市场地位。
因此,研究开发基于Symbian
的智能手机软件具有重要的意义。
本文详细分析了软件的界面设计,提出了怎样改进界面设计;分析了视图切
换技术,怎样灵活运用它以达到节省系统资源和源代码的目的,并通过工程实践
分析了独特的视图切换技巧;分析了怎样在智能手机软件中节省资源,并给出了
具体处理方法;分析TiN何根据实际情况处理手机软件异常,论述了怎样有效地
预防异常的发生;通过实例分析了系统MMF机制以及怎样处理动画,结合本软件,
本文提出了处理动画的改进方法;分析了如何传输多字段的信息,,制定了信息数
据包的组装和解析格式。
此外,本文还阐述TSymbian的清除栈机制、活动对象
架构以及如何使用这些机制和架构。
本文是以工程实践为依据,因此,对于那些¥60平台下的软件开发人员具
有非常重要的参考价值。
关键词:智能手机清除栈活动对象异常。
Symbian类基础知识(二)

术语表〗活动对象—负责向异步服务提供器发出请求和处理这些请示的完成的类。
它必须从CActive 派生而来。
活动规划器—在事件处理程序中,负责为活动对象规划事件的类。
类必须派生于CActiveScheduler。
应用程序信息文件(AIP,Application Information File)—包含应用程序标题、图标、功能和MIME优先级支持信息的文件。
文件扩展名为.aif。
AIF生成器—用于生成应用程序信息文件及其图标的GUI程序。
SDK程序运行在开发的机器上(不是运行在设备或模拟器上)。
应用程序编程接口(API,Application Programming Interface)—系统对象或组件向其他对象或组件暴露的可见公共行为。
应用程序架构(Apparc,Application Architecture)—为Symbian OS应用程序及CONE 提供了部分基本框架。
应用程序框架—处理应用程序的启动和对应用程序数据(它的文档)的访问。
应用程序启动器—Series 60设备的默认视图,以网格或列表视图模式显示可供选择的应用程序。
AppWizard—可以IDE集成的工具,用以快速生成GUI应用程序骨架。
ARM处理器—运行32位(或16位)嵌入式ARM RISC的处理器。
ARM4—用于基于ARM处理器的32位指令集和二进制接口。
如果应用程序针对ARM4进行编译,它仅调用针对ARM4或ARMI编译的函数。
ARM4代码运行速度比THUMB代码快,但却占用更多的ROM空间。
ARMI—用于基于ARM处理器的32位指令集和二进制接口,并带有Interwork模式。
如果应用程序针对ARM进行编译,它调用针对ARM4、THUMB或ARMI编译的函数。
ARM 代码运行速度比THUMB代码快,但却占用更多的ROM空间。
这是推荐使用的默认生成兼容性格式。
ASCII(美国信息交换标准码)—计算机使用的编码数字标准,用于表示所有大小写拉丁字母、数字、标点符号等等。
symbian活动对象
活动对象活动对象被用于事件驱动的多任务处理它们是Symbian OS的一个基本部分本讲要讲解为什么活动对象非常重要解释它们是如何怎样设计以进行响应式、高效率的处理事件Symbian OS中的事件驱动多任务处理✧理解同步请求和异步请求的区别之处,并且能够对它们的典型进行区分✧认识活动对象的典型应用——处理异步任务并且不阻塞线程时被请求✧理解用多线程和多活动对象实现多任务的区别,以及为什么后者在Symbian OS 编码中要优先使用Symbian OS 中的事件驱动多任务处理同步和异步请求--当程序的函数代码中要调用一个服务请求时,这个服务不是同步执行就是异步执行同步函数--执行一个服务直到完成,然后返回其调用者,通常返回的是一个成功或者失败指示异步函数--提交一个请求作为函数调用的一部分,并且马上返回到其调用者继续执行--在一段时间之后请求再完成调用一个异步请求以后--调用者可以自由处理其他问题或者简单的等待,后者就是常说的“阻塞”--一旦服务完成,调用者可以接收到一个信号,显示请求是否成功这个信号就是一个事件--这段代码被称为事件驱动定时器等待是一个典型的异步调用的例子--另一个例子是Read()方法,它在Symbian OS的RSocket类中,这个方法是从远程主机收取数据Symbian OS 中的线程✧线程被内核以抢占的方式调度✧内核执行已经就绪的最高优先级的线程✧每个线程都可能由于等待一个事件的发生而暂停执行,而在适当的条件下恢复执行内核控制线程的调度✧允许线程通过时间片分割的方式共享系统资源,如果有更高级的线程处于就绪态,则抢先执行这个高优先级的线程✧这种总是运行已就绪的最高优先级线程的方式是占先式多任务处理的基础当当前线程挂起时会发生上下文切换✧上下文切换导致了运行时内核调度器的负载✧如果原来的和替换的线程在不同的进程执行,会因为要交换进程内存以及写入缓存而带来更大开销✧比线程上下文切换要慢100倍事件驱动多任务处理异步事件可发生在如下情况:从外部资源——例如用户输入或者硬件外设接收到数据。
symbian练习
选择题:在单视图应用程序中,当用户选中菜单项运行后,应用程序框架调用的函数是()A、视图类的HandleCommandL( );B、用户界面类的HandleCommandL( );C、视图类的ConstructL( );D、用户界面类的ConstructL( );下面哪个类属于对话框类()。
下面有关模拟器的使用,错误的是()A、修改资源文件后,必须关掉模拟器再编译才有效B、打包图片后,必须关掉模拟器再编译才有效C、修改源程序文件后,不必关掉模拟器编译照样有效D、模拟器中打开多个应用程序时,都运行在不同进程中,这点与目标手机是相同的在自定义控件中,如果AppView类是主控件,设置控件在容器中的位置和大小是下面哪个方法()。
A、V oid SizeChanged( )B.TkeyResponse OfferKeyEventL(const TkeyEvent& aKeyEvent,TeventCode aType)C、Tint CountComponentControl(Tint aIndex)const;D、V oid Draw( );利用Symbian 的活动对象机制在单线程实现非抢先式多任务,它的含义是()A、在程序中,同时可以在一个活动对象上发布多个异步请求B、活动对象的优先级一般都设置成标准优先级,所以不会发生抢先式多任务C、活动对象上发布的异步请求被系统完成,活动对象类的Runl( )处理请求的响应时,尽管有其它的活动对象发出更高的请求,也不会中断正在响应的Runl( ),所以是非抢先式多任务。
D、在Symbian程序中,不支持多线程有关静态链接库LIB和动态链接库DLL的叙述,下面叙述正确的是()A、.DLL程序有静态DLL和多态DLL两种,这两种链接库都是自动卸载的,不需要显示的代码B、当多个应用程序使用动态链接库时,DLL在内存中只有一份拷贝,实现内存的共享。
C、当没有应用程序使用时不能卸载.DLL程序D. 当多个应用程序使用静态链接库时,LIB在内存中只有一份拷贝。
vc Symbian开发18
symbian学习笔记十八:活动对象练习-- 未审核编辑文档上一此,我们讲解了活动对象的使用,虽然内容不多但是却非常重要,这次我们就来巩固学习的成果来练习一番,呵呵。
练习的题目就是:在用户输入完一段英文并按回车键后,计算出用户输入的单词数目。
下面是主函数关系图CAOExample.RunL的实现CAOExample-.Cancel()的实现以上就是程序的结构图或者说流程图,当然,光有这些我们仍然无法编写程序,但是,我们仍旧不知道如何让用户进入输入状态,呵呵,也许你会说我们可以利用console->Getch()方法,虽然,console->Getch()确实可以完成类似的功能,但在这里要素说的是,实际上,console->Getch()方法在CActive下是不起作用的,环境话说,它不能在活动对象中起作用从而接受用户的输入,因此,在这里我们将隆重介绍另一个方法——console->Read(iStatus)方法,这其中iStatus是活动对象自身的属性,实际上这个方法的作用就是想服务器请求一个用户输入状态,当用用户输入一个任意字符之后,该状态就宣告结束,因此,当我们要连续输入时,我们就要连续的请求这个状态!另外,刚才说了由于console->Getch()已经不起作用,那么当用户输入后,我们就需要靠别的方法来取得用户输入的字符,这个方法就是c onsole->KeyCode(),它返回一个TKeyCode对象,我们可以将此对象直接强转为TChar类型,从而判断字符。
好啦,废话不多说了,看程序吧~//========== AOExample.cpp ==========#include "CommonFramework.h"static TInt word;static TInt num;class CWord:public CBase{public:static CWord* NewLC(TInt aMaxLength); private:CWord(TInt aMaxLength);void ConstructL(TInt aMaxLength); public:TInt WordNumCountL(TChar aChar);void OutputWord();TInt WordNum();TInt Length();TInt MaxLength();~CWord();private:TInt iLength;TInt iMaxLength;HBufC* iHBufC;};class CAOExample:public CActive{public:static CAOExample* CAOExample::NewLC(); ~CAOExample();private:CAOExample();void ConstructL();public:void Start();void PrintWord();void PrintWordNum();void KeyPressInput(TChar aChar); private:void RunL();void Cancel();void DoCancel();public:CWord* iCWord;};CWord* CWord::NewLC(TInt aMaxLength){CWord* self = new(ELeave) CWord(aMaxLength); CleanupStack::PushL(self);self->ConstructL(aMaxLength);return self;}void CWord::ConstructL(TInt aMaxLength){iHBufC = HBufC::NewL(aMaxLength);}CWord::CWord(TInt aMaxLength){iMaxLength = aMaxLength;iLength = 0;}TInt CWord::WordNumCountL(TChar aChar){TPtr ptr=iHBufC->Des();if(iLength<iMaxLength){ptr.Append(aChar);//如果输入的字符不在A~Z或a~z之间,则word设置为0,即不为字母if(!('A'<=aChar && aChar<='Z'||'a'<=aChar && aChar<='z')){word = 0;}//如果输入的字符在A~Z或a~z之间,则word设置为1,即为字母if('A'<=aChar && aChar<='Z'||'a'<=aChar && aChar<='z'){if(word==0)//上一个如果不是字母,如果不是0则证明一直都在输入字母{word = 1;//当前是字母,则设置为1num++;//单词数加1}}iLength++;return 1;}else{return 0;}}void CWord::OutputWord(){console->Printf(iHBufC->Des());//输出iHBufC的数据iHBufC->Des().Zero();//情况数据iLength = 0;}TInt CWord::WordNum(){return num;}TInt CWord::Length(){return iLength;}TInt CWord::MaxLength(){return iMaxLength;}CWord::~CWord(){delete iHBufC;iHBufC = NULL;iLength = 0;iMaxLength = 0;}CAOExample* CAOExample::NewLC(){CAOExample* self = new(ELeave) CAOExample(); CleanupStack::PushL(self);self->ConstructL();return self;}void CAOExample::ConstructL(){iCWord = CWord::NewLC(1);CActiveScheduler::Add(this);//让活动对象调度器加载当前活动对象}CAOExample::CAOExample():CActive(CActive::EPriorityStandard) {}void CAOExample::Start(){console->Read(iStatus);//请求Read()状态SetActive();//激活当前活动对象}void CAOExample::PrintWord(){iCWord->OutputWord();}void CAOExample::PrintWordNum(){_LIT(KPrint,"You Input %d Word!\n");console->Printf(KPrint,iCWord->WordNum());console->Printf(_L("Please input the new word!\n"));}void CAOExample::KeyPressInput(TChar aChar){iCWord->WordNumCountL(aChar);if(iCWord->Length() == iCWord->MaxLength()){PrintWord();}if(aChar == EKeyEnter)//如果输入的是EKeyEnter,即回车,则输出单词数{PrintWordNum();word = 0;num = 0;}Start();//再次请求状态}CAOExample::~CAOExample(){delete iCWord;iCWord = NULL;}void CAOExample::RunL(){//console-KeyCode()取得用户输入的键码(KeyCode)并强转为TChar KeyPressInput((TChar)console->KeyCode());}void CAOExample::Cancel(){DoCancel();}void CAOExample::DoCancel(){console->ReadCancel();//取消Read状态或请求}void doExampleL(){CActiveScheduler* AS = new(ELeave)CActiveScheduler;//建立调度器CleanupStack::PushL(AS);CActiveScheduler::Install(AS);//安装调度器CAOExample* activeObject=CAOExample::NewLC();console->Printf(_L("Please input the new words!\n")); activeObject->Start();//激活活动对象CActiveScheduler::Start();//激活调度器CleanupStack::PopAndDestroy();}最后给出两张运行图^0^:。
Symbian手机程序设计大作业 - 俄罗斯方块
Symbian手机程序设计大作业俄罗斯方块游戏学院(系):专业:班级:学号:姓名:大连理工大学Dalian University of Technology1程序功能描述俄罗斯方块一直都是游戏里的经典,每个方块由四个格子组成,不同形状的方块不同颜色,每次从顶部开始下降,可以通过按上键变换方块的形状,也可以通过左右键来移动方块的位置方向,直到方块坠入最底部,由于引擎类,使得可以按下键加速方块下降。
当某一行充满了方块,该行方块消失,并加分。
另外,与老师FTP上的俄罗斯方块的程序不太相同的地方,是本程序增添了下一方块提示功能。
在界面的右侧部分,会显示下一个要到来的方块的形状,来帮助玩者调整本次方块的位置,来达到更好的效果。
2 程序类图图1本程序主要的类为视图类CS60TestAppView,负责展现界面的各个元素。
TGrid,TPreGrid,TBlock是为了实现俄罗斯方块的背板和方块以及实现下一方块预览功能设置的类。
同时设置了引擎类CS60TestEngine,使用户可按下键实现方块的快速下移。
如图1示3程序运行截图左边是游戏主界面,右边有下一个方块的提示.不同形状的方块不同颜色,每次从顶部开始下降,可以通过按上键变换方块的形状,也可以通过左右键来移动方块的位置方向,直到方块坠入最底部。
当某一行充满了方块,该行方块消失,并加分。
如图2图24 程序代码分析4.1 S60test类分析#include"S60TestApplication.h"//系统调用ne wap plication()函数得到新的CApaapplication对象,GLDEF_C TInt E32Dll(TDllReason /*aReason*/){return KErrNone;}//在avkon(for series60)中返回一个CAknapplication子类的对象,在s60testapplication.cpp 实现的CS60testapplication,EXPORT_C CApaApplication* NewApplication(){return (new CS60TestApplication);}s60testapplication.cpp#include"S60TestDocument.h"#include"S60TestApplication.h"/*在每次执行中下面两个函数必须重载,第一个,在AppDllUid将返回该程序唯一的UID,我们例子中的UID不会出现在实际发布的程序中.第二个函数是创建CApaDocument类对象的CreateDocumentL函数*/ CApaDocument* CS60TestApplication::CreateDocumentL(){CApaDocument* document = CS60TestDocument::NewL(*this);return document;}TUid CS60TestApplication::AppDllUid() const{return KUidS60TestApp;}4.2CS60TestDocument类分析#include"S60TestAppUi.h"#include"S60TestDocument.h"CS60TestDocument *CS60TestDocument::NewL(CEikApplication& aApp){CS60TestDocument *self=NewLC(aApp);CleanupStack::Pop(self);return self;}CS60TestDocument *CS60TestDocument::NewLC(CEikApplication& aApp){CS60TestDocument *self=new(ELeave) CS60TestDocument(aApp); CleanupStack::PushL(self);self->ConstructL();return self;}void CS60TestDocument::ConstructL(){TTime time;time.HomeTime();seed=time.Int64();Reset();}CS60TestDocument::CS60TestDocument(CEikApplication& aApp) :CAknDocument(aApp),iGrid(),iPreGrid(),iCurrBlock(),iPreBlock(),iBlockPos(3, -4),iPreBlockPos(3, 2){}CS60TestDocument::~CS60TestDocument(){}void CS60TestDocument::Reset(){iGrid.Clear();iPreGrid.Clear() ;iBlockPos=TPoint(3, -4);iPreBlockPos=TPoint(0, 1) ;iScore=0;iLines=0;iLevel=1;iCurrBlock=TBlock::RandomBlock(seed);iPreBlock=TBlock::RandomBlock(seed) ;}void CS60TestDocument::NewBlock(){iCurrBlock=iPreBlock ;iBlockPos=TPoint(3, -4);iPreBlock=TBlock::RandomBlock(seed); iPreBlockPos=TPoint(0, 1);}bool CS60TestDocument::MoveBlock(const TPoint &p) {if (iGrid.DoesCollide(iCurrBlock, p)) returnfalse; iBlockPos=p;iAppUi->UpdateBoard();returntrue;}bool CS60TestDocument::FixBlock(){int i;// check if it is outside the boardfor (i=0; i<-iBlockPos.iY; i++)if (iCurrBlock.RowMask(i))returnfalse;iGrid.PutBlock(iCurrBlock, iBlockPos); returntrue;}int CS60TestDocument::CheckRows(){int offset=0, i, j;for (i=KGridY-1; i>=0; i--){if (iGrid.iMask[i]==0xffffU){offset++;iScore++;iLines++;continue;}if (offset>0){iGrid.iMask[i+offset]=iGrid.iMask[i];for (j=0; j<KGridX; j++)iGrid.iContent[i+offset][j]=iGrid.iContent[i][j];}}for (i=0; i<offset; i++){iGrid.iMask[i]=0x003f;for (j=0; j<KGridX; j++)iGrid.iContent[i][j]=0;}if (offset>0) iAppUi->UpdateBoard();return offset;}bool CS60TestDocument::RotateBlock(int dir){iCurrBlock.Rotate(dir);if (iGrid.DoesCollide(iCurrBlock, iBlockPos)){iCurrBlock.Rotate(-dir);returnfalse;}iAppUi->UpdateBoard();returntrue;}bool CS60TestDocument::IsBlock(const TPoint &p) const{if (p.iX>=iBlockPos.iX && p.iX<iBlockPos.iX+4 &&p.iY>=iBlockPos.iY && p.iY<iBlockPos.iY+4)return (iCurrBlock.RowMask(p.iY-iBlockPos.iY)&(1<<(3-p.iX+iBlockPos.iX)))>0; returnfalse;}//判断是否为将要显示的方块bool CS60TestDocument::IsPreBlock(const TPoint &p) const{if (p.iX>=iPreBlockPos.iX && p.iX<iPreBlockPos.iX+4 &&p.iY>=iPreBlockPos.iY && p.iY<iPreBlockPos.iY+4)return(iPreBlock.RowMask(p.iY-iPreBlockPos.iY)&(1<<(3-p.iX+iPreBlockPos.iX)))>0;returnfalse;}void CS60TestDocument::GetRowContent(int nr, TFixedArray<TInt8, KGridX>&row) const {int i;for (i=0; i<KGridX; i++){if (IsBlock(TPoint(i, nr))) row[i]=iCurrBlock.Color();else row[i]=iGrid.iContent[nr][i];}}//获取将要显示的行的内容void CS60TestDocument::GetPreRowContent(int nr, TFixedArray<TInt8, KGridX>&row) const{int i;for (i=0; i<KPreGridX; i++){if (IsPreBlock(TPoint(i, nr))) row[i]=iPreBlock.Color();else row[i]=iPreGrid.iContent[nr][i];}}//要重载CreateAppUil,此函数是用来建立用户接口响应对象的,CEikAppUi *CS60TestDocument::CreateAppUiL(){iAppUi=new(ELeave) CS60TestAppUi(this);return iAppUi;}4.3CS60TestAppUi类分析#include<avkon.hrh>#include<aknnotewrappers.h>#include<eikmenup.h>#include"S60Test.pan"#include"S60TestDocument.h"#include"S60TestAppUi.h"#include"S60TestAppView.h"#include"S60Test.hrh"#include"Step6.rsg"//在该类中ConstructL函数首先调用BaseConstructL函数进行初始化,从资源中装载软键盘和菜单定义void CS60TestAppUi::ConstructL(){BaseConstructL();iAppView=CS60TestAppView::NewL(ClientRect(), iDoc);AddToStackL(iAppView);}CS60TestAppUi::CS60TestAppUi(CS60TestDocument *aDoc):iEngine(NULL){iDoc=aDoc;}CS60TestAppUi::~CS60TestAppUi(){if (iAppView){RemoveFromStack(iAppView);deleteiAppView;iAppView = NULL;}deleteiEngine;}/*方格有变化时,我们将重画屏幕,CS60TestAppUi::UpdateBroad里的DrawDeferred来刷新整个屏幕。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
活动对象练习1
任务2.1 完成CActiveTimer类的定义1)打开ActiveTimer.h文件
2)添加MActiveTimerNotify类的前置声明:class MactiveTimerNotify;
3)为两阶段构造函数添加参数MActiveTimerNotify&
4)为C++构造函数添加参数MActiveTimerNotify&
5)添加两个新的成员变量,一个是RTimer类型的成员变量,一个是MActiveTimerNotify引有类型的成员变量
任务2.2 实现CActiveTimer
1)打开ActiveTimer.cpp文件
2)为函数CActiveTimer::NewL添加参数MActiveTimerNotify&,并将参数MActiveTimerNotify&传递给C++构造函数
3)为C++构造函数添加操作。
首先,为该函数添加参数MActiveTimerNotify&,然后通过成员
变量iNotifer添加到初始化列表对其进行初始化,然后,使用活动对象调度器对CActiveTimer对象进行注册。
4)在函数CActiveTimer::ConstructL 中通过调用函数RTimer::CreateLocal 来构造成员变量iTimer,而且如果出现错误,将导致Leave异常退出。
任务2.3 实现定时器请求函数和定时器结束函数
1)在函数CActiveTimer::After中,在成员变量iTimer上调用函数RTimer::After,并将iStatus和anInterval作为传递参数。
还要调用CActive::SetActive来通知应用程序活动对象调度器,有一个异步请求需要响应。
2)在函数CActiveTimer::RunL中,在成员变量iNotifer上调用函数MActiveTimerNotify::TimerComplete ,并将iStatus.Int( )作为参数传递。
当定时器结束时,该函数将通知构造类的代码。
3)在函数CActiveTimer::DoCancel 中,在成员变量iTimer上调用函数RTimer::Cancel来取消未响应的定时器请求。
任务2.4 实现活动对象析构函数
1)在CActiveTimer类析构函数中,调用函数CActive::Cancel来取消所有未被响应的请求,还需要在成员变量iTimer上调用函数Close来释放资源任务2.5使用活动对象
1)打开CAOLabTextFlashContainer 2)在函数CAOLabTextFlashContainer::ConstructL中添加代码创建活动对象3)在CAOLabTextFlashContainer类的析构函数中,添加代码来删除活动对象
4)在CAOLabTextFlashContainer::Flashin gText中,添加代码来处理定时器活动对象调用
5)在函数
CAOLabTextFlashContainer::TimerC omplete中添加代码来重新启动定时器活动对象
6)在函数CAOLabTextFlashContainer::StopFla shing中,添加代码来取消定时器活动对象。