




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、诺基亚symbian 手册汇编Symbian OS Basics Basic Types 在Symbian中,很多C+基本类型都被重新定义了,最好使用Symbian的,理由如下:· 所有Symbian API都是用的Symbianc重定义的 · 将来Symbian OS由32位转为64位时,支持性更好 · 这本身就是Symbian C+ Coding Standards所要求的Integers typedef signed int TInt; C+中的signed int,32位,基本用法类似。
2、 typedef unsigned int TUint; 一般用于计数器(Counter)或者标记(Flags)。其他Int类型:TInt64, TInt32, TInt16,TInt8; 同时有一份TUint的版本。Text text类型在Symbian编程中基本不用,而一般采用描述符(descriptor)。TText默认是16位的。Boolean typedef int TBool; 有两个枚举值:ETrue和EFalse。TBool变量最好不要直接和ETure和EFalse比较。如下:TBo
3、ol flag = ETrue;if (flag) / if (!flag) flag = EFalse; Floating Point 对浮点数的支持视处理器而定,如果没有FPU,效率非常低,所以最好是不要用浮点数。 如果一定要用,尽量转化为整数操作。typedef float TReal32; typedef double TReal64; typedef double TReal;TAny typedef void TAny;TAny一般只用作指针,其他情况下用v
4、oid比较好。TAny* MyFunction(); void MyOtherFn();TAny* 在很多Symbian API中都用到了,如:static TUint8* Copy( TAny* aTrg, const TAny* aSrc, TInt aLength);Enumerations enum TState EOff, Eon, EInit;TState state = GetState();if (state = EOn) /Do something here Coding Conve
5、ntions T类:只包含值,而不包含指针以及外部的资源,在栈上分配空间。TVersion osVersion = User:Version(); C类:所有需要分配内存的类都必须从CBase继承并且以C开头。class CExample : public CBaseprivate: CDesCArrayFlat* iArray; CExample* example = new (ELeave) CExample; R类:包含指向某个资源的handler。RTimer
6、 timer;timer.CreateLocal(); M类:定义一个接口,一般只包含纯虚函数,不包含成员数据,减少类之间的依赖,用来接受回调消息。class MEikStatusPaneObserver public: virtual void HandleStatusPaneSizeChange() = 0;任何实现MEikStatusPaneObserver接口的类都必须实现HandleStatusPaneSizeChange()函数。Variable Naming
7、 Conventions · 成员变量以“i”开头 · 参数以“a”开头 · 动态变量随便,以小写字母开头 · 常量以“K”开头 · 尽量不要使用全局变量,不能使用全局静态变量。Functions · 函数以大写字母开头,如AddFileNameL(); · 以D结尾表示deletion of an object ·
8、160; 以L结尾表示函数可能leave · 以C结尾表示一个item被放到cleanup stackCasting Casting用于在类(classes)和类型(types)之间作转化,Symbian中仍然可以使用C中语法。 dynamic_cast:不支持,Symbian中没有RTTI。 static_cast:把一个基类转化为一个继承类。 TInt intValue = 0xff;TUint8 byteValue = static_cast<TUint
9、8>(intValue); reinterpret_cast:把一个指针类型转化为另外一个指针类型,如integer转化为point类型或者相反。TUint32 fourBytes = 0;TUint8* bytePtr = reinterpret_cast<TUint8*> (&fourBytes);bytePtr+;*bytePtr = 0xFF; const_cast:移除一个类的const属性。内存管理Why Memory Management Symbian OS本身就是为内存
10、和资源受限的设备开发的,应用程序运行过程中很可能碰到内存用光,或者硬件资源不可用的情况。而这种exceptions是通过修改程序无法解决的,所以遵守以下几条:尽量不要使用不必要的RAM尽早释放资源,如文件server等当你每次申请内存时,都须准备处理out-of-memory错误当 out-of-memory错误发生时,返回到一个stable的状态,并释放所有期间申请到的资源Stack and Heap Stack:默认大小8kb,自动删除,如 TInt i = 0; Heap :至少.5Mb,由程序员手动删除,如 CMyObj* obj =
11、 new (ELeave) CMyObj;Leaves 首先介绍Conventional C+ Memory Management,在Symbian看来,这是非常低效率的。NULL Pointer Checking if (myObj = new CMyObj( ) ) = NULL) /Error Handling ANSI C+ Exeption Handling try /throw an Exception catch (int e) /Error Handling 在Symbian中推
12、荐采用Leave,如果内存或者资源不能分配到,这个代码就会Leave,沿着Call Stack,直到操作系统或者在某个函数中被Handle掉。 所有可能Leave的函数最好以L结尾,保证该函数的用户知道这个函数可能Leave。 Leave的例子:动态内存分配: return new (ELeave) TUint81000;产生一个Leave:User:Leave(KErrNotFound);内存不足时Leave:User:LeaveNoMemory();NULL的时候Leave:User:LeaveIfNull(aNotify);当发生错误时
13、Leave:RFs fs; TInt err = fs.Connect(); User:LeaveIfError(err); 处理Leave: 操作系统有默认的处理Leave的方式:在程序启动过程中:直接关闭应用程序。应用程序启动后:显示一个错误消息。 开发者可以通过trap装置来处理Leave。TRAP(_r, _s)和TRAPD(_r, _s),其中:_r:是一个TInt类型的leave code,默认值为TErrNone。_s:一系列可能Leave的C+ Statements。
14、60; TRAPD(err, DoFunctionL(); if (err != KErrNone) /Error Handling else /Everything is well The Cleanup Stack
15、60; cleanup stack用于存储在leave发生后需要deallocating的局部变量(指针)。即:当一个函数leave了,所有在cleanup stack上的对象会被全部删除掉。 Cleanup Stack的使用方法:CleanupStack:PushL(ptr) :当发生leave时所有内存都会被释放CleanupClosePushL(handle):当发生leave时这个句柄(handler)会被关闭CleanupStack:Pop(pointer):第一个元素出栈CleanupStack:PopAndDestroy(pointer):第一个元素出栈
16、并释放内存 如果一个函数可能leave,检查一下两种情况:如果leave了,是否所有在堆(heap)上的元素都在cleanup stack中了如果没有leave,你是否自己恰当地将他cleanup了CMyClass* CMyClass:NewL(TInt aBufSize) CMyClass* self = new (ELeave) CMyClass; CleanupStack:PushL(self); self->ConstructL(aBufSize); Clea
17、nupStack:Pop(self); return self; 如果某个函数会在cleanup stack上留下一个对象,那么他必须以C结尾。Two Phase Construction C+构造函数一定不能leave。所有内存和资源的分配应该在第二阶段构造函数ConstructL( )中完成。编码指南,所有用户定义的C类必须:定义NewL和NewLC函数为public static定义ConstructL和C+ Constructor为privateBest Practise &
18、#160;Construction的规则:默认的C+构造函数中不能含有可能leave的代码可能发生leave的函数必须在ConstructL中被调用如果基类也有ConstructL,必须首先调用,不要忘了explicit scoping Destruction的规则:C类必须在析构函数中删除它自己所包含的对象在删除一个对象后,把它的指针设为NULL不要删除不是本类所拥有的对象在reallocation前首先删除对象,并且将其指针设为NULL Further Discussion:Preserve Stack Memory:每个进程只有8K,以
19、引用的方式传递参数,大的对象放在堆上Preallocation vs last moment allocation:一般的原则是只在使用前分配资源并且在使用后马上释放。但是 preallocation的好处是节约处理时间,并且在没有内存的情况下照常运行(资源已经分配到了)where to put trap harness:最基本的情况是依靠GUI应用程序的框架。根据应用的不同,可以自定义粒度。Error Code R
20、eturns vs. leaving functions:在执行某个处理前检测是否会出现问题,如下代码: User:LeaveIfError(fs.Connect(); Memory Leaks 如果你的程序有内存泄露,在模拟器上关闭时会crash。尽早发现并解决
21、你的内存泄露,因为你可以追查到你可能导致内存泄露的代码改动。如果实在找不到,可用下面方法: Heap Balance Checking:_UHEAP_MARK_UHEAP_MARKEND 用上述这两个宏放在你要检查的代码的开头和结尾,如果发生panic,则说明这段代码中发生了内存泄露。可以嵌套使用。 Panics Panic是一个未经处理的exception,暗示着一个无法解决的错误。一般程序有以下三类错误:程序错误:如引用一个超过数组范围的元素环境错误:内存、磁盘空间不够,或缺少其他资源等用户错误:输入错误数据&
22、#160; 可以使用trap和cleanup stack技术来解决环境和用户错误,但是对于第一类的程序错误,我们无法恢复,最好是使用User:Panic()函数,它带有两个参数,第一个是string,第二个是Tint。描述符Introduction 描述符(Descriptors)封装了字符串和二进制数据,用于替代C中的以NULL结尾的字符串。它的长度和数据都封装在了描述符中,Symbian API中用的都是描述符。如: TPtrC ptr (KHelloWorld); CEikonEnv:Static
23、()->InfoMsg(ptr);Main Types of Descriptors 主要可以分为以下几类,其中带C的是不可修改的。 · Abstract:(TDes、TDesC),其他描述符的基类,不能实例化,一般用作函数的参数。 · Literal:(TLitC,_LIT()),用于存储literal string,一般使用后者。 · Buffer:(TBuf,TBufC),数据存储于栈上,大小在编译时确定。 · Heap:(HBufC),数据存储于堆上,大小在运行时确定。 · Pointer:(TPtr,T
24、PtrC),引用存储于类之外的数据Descriptor Modification 描述符可以是可修改的和不可修改的,通常带C的都是不可修改的,不可修改的是可修改的基类。 · Moidfiable:提供了访问和修改数据的API,如TBuf · Non-Modifiable:数据只可以被访问,不可修改。但是通过Des()函数可返回一个可修改的指针Descriptor Width 在描述符类后加上8或者16影响了存储在描述符中的数据的宽度,默认是16位的,处理二进制或ASCII时采用8位。· 8
25、位:(TDesC8),用于二进制数据或者ASCII字符串 · 16位:(TDesC16),默认,Unicode下面开始对上述5类描述符进行详细介绍,首先看一下类继承关系 这里显示的是8位的,16位默认的类继承关系与此一致Abs
26、tract Descriptors 除Literal外的所有描述符的基类,提供了基本的接口和基础功能。他们本身不能实例化,一般用作函数参数。TDesC:提供了比较、复制、搜索、提取部分字符串的函数。TInt TDesCUtil:SumLengths(const TDesc& aDesC1, const TDesc& aDesC2) return aDesC1.Length() + aDesC2.Length(); TDes:继承自TDesC,添加了许多用于修改数据的函数。其最大长度是描述符被创建时确定的。T
27、Int TDesCUtil:AppendL(TDesc& aTarget, const TDesc& aDesC) TInt sumLen = aTarget.Length() + aDesC.Length(); if (aTarget.MaxLength() < sumLen) User:Leave(KErrOverflow); aTarget.AppendL(aDesC); Literal Des
28、criptors 提供了一种将字符串放在只读存储空间中的机制(实际存放在程序的数据区,而不是真的在ROM中)。一般不采用TLitC而直接采用_LIT()宏。 _LIT(KHelloWorld, "Hello World!"); 通过()操作符可以得到 const TDesC&。 TInt length = KHelloWorld().Length(); 在函数参数为const TDesC&可以直接使用KHelloWorld。iLabel->SetTe
29、xtL(KHelloWorld);Buffer Descriptors 将数据作为本身的一部分存储在stack上,他们的最大长度是在编译时确定的。 TBuf<16> helloWorld = KHelloWorld;TInt len = KHelloWorld().Length();helloWorldlen-1='?' 在内存中如下所示: TBufC的用法如下:_LIT(KHelloWorld, "Hello World");const TInt maxBuf = 32;TBufC<maxB
30、uf> buf;TInt currentLen = buf.Length(); / = 0buf = KHelloWorld;currentLen = buf.Length(); / = 11TText ch = buf2; / = 'l'TBuf的用法如下:const TInt bufLen = 6;TUInt8 objType = 1;TUInt8 objId = 1;TUInt8 xCoord = 128;TUInt8 yCoord = 192;.TBuf8<bufLen> buf; buf.Append(objType);buf.Append(objI
31、d);./we can now do something with the buffer such as writting it to a binary file or send via socket.Pointer Descriptor 用于引用存储在其他地方的数据,如:const unsigned char KBuffer = 0x00, 0x33, 0x66, 0x99, 0xbb, 0xff;TPtrC8 bufferPtr( KBuffer, sizeof(KBuffer);iSocket.Write(bufferPtr, iStatus);在内存中如下所示
32、:TPtr的用法:_LIT(KHelloWorld, "Hello World");const TInt maxBuf = 32;TBufC<maxBuf> buf;buf = KHelloWorld;TPtr ptr = buf.Des();ptr7 = 'a' ptr8 = 'l' ptr9 = 'e' ptr10 = 's' CEikonEnv:Static()->InfoMsg(ptr); / &q
33、uot;Hello Wales"Heap Descriptors 动态在堆(heap)上分配,通过HBufC的API,数据可以被set和reset,但是不能被修改。如:HBufC* heapBuf = HBufC:NewL(KHelloWorld().Length();*heapBuf = KHelloWorld();delete heapBuf; 在内存中的情况如下图所示: HBufC通常在以下几种情况下使用: · 在运行时从资源文件中加载字符串 &
34、#183; 从用户界面中接收用户输入的字符串 · 从应用程序引擎中接收字符串,如contacts database中的名字 对HBufC中的内容进行修改:_LIT(KHello, "Hello!");_LIT(KWorld, "World!"); HBufC* heapBuf = HBufC:NewL(KHello().Length();*heapBuf = KHello; /buf holds "Hello!"heapBuf = heapBuf-&g
35、t;ReAllocL(KHello().Length() + KWorld().Length();CleanupStack:PushL(heapBuf);TPtr ptr (heapBuf->Des(); /DON'T use TPtr ptr = heapBuf->Des(); this will set maxlen to 6 but not 12.ptrKHello().Length() - 1 = ' 'ptr += KWorld;iTopLabel -> SetTextL(ptr);CleanupStack:PopAnd
36、Destroy();DrawNow();下面介绍Descriptors的具体用法:Non-Modifying Methods Length(),Size(),Left(),Right(),Mid(),Compare(),Locate(),LocateReverse(),Find(),Match()等。以下代码示例描述了如何在一个descriptor中找到<>中的内容,如果不存在,返回整个字符串:static const TUint KAddressStartChar = '<' static const TUin
37、t KAddressEndChar = '>'TPtrC ExtractAddressNumber( const TDesC& aAddressString) TInt addrStart = aAddressString.Locate(KAddressStartChar ) + 1; TInt addrEnd = aAddressString.LocateReverse(KAddressEndChar ) ; if (addrStart = KErrNotFoun
38、d) | (addrEnd = KErrNotFound) | (addrStart >= addrEnd) ) addrStart = 0; addEnd = aAddressString.Length(); return (aAddressString.Mid(addrStart, (addrEnd - addrStart) ) )
39、; Modifying Methods Zero(),Copy(),Num(),Format(),Insert(),Replace(),Delete(),Append(),Trim()等。代码示例:_LIT(KText, "Hello World!");_LIT(KNewText, "New Text");_LIT(KReplaced, "Replaced");TBuf<16> buf1(KText); buf1.Delete(6, 6); / length is now 6
40、, leaving "Hello" in the bufferTBuf<16> buf2(KNewText);buf2.Copy(KReplaced); / buf2 now contains "Replaced"buf2.Append(KNewText); /buf2 now contains "Replaced New Text"buf2.Delete(99, 1); /Will Cause a PANIC! Descriptors in Method Declarations · 在函
41、数参数中尽量使用基类 · 使用中性的描述符,一般情况下使用TDesC而不是TDesC8或者TDesC16 · 当描述符内容不应该改变时,使用const修饰符 · 经典用法:void SetText(const TDesC& aText); TPtrC Text() const; Character Conversions CCnvCharacterSetConverter类提供了在Unicode和其他字符集编码之间转换的方法。ASCI
42、I本来就是Unicode的一个子集,无须使用该类。和Unicode之间的转换方法如下所示:TBuf16<64> UnicodeBuf;_LIT8(KAsciiStr, "Hello");UnicodeBuf.Copy(KAsciiStr); Unicode和拉丁语系之间的转化可使用如下的代码:TBuf8<64> Latin1Buf;_LIT16(KUnicodeStr1, "hello");_LIT16(KUnicodeStr2, "I have got 10x20AC.");
43、 /x20AC is a euroLatin1Buf.Copy(KUnicodeStr1); /OKLatin1Buf.Copy(KUnicdoeStr2); /Not as you wanted.Symbian操作系统将应用程序设计为单线程的,在大多数情况下等待异步事件的产生和完成。虽然可以使用多线程,但是不提倡这种做法,一方面是上下文切换开销导致电池使用寿命降低,另外一方面就是开发较复杂。 Symbian使用Active Object框架来处理操作系统的异步事件处理特性。由两方面构成:· The Active Scheduler: 用来调度事件
44、,每个线程只能有一个 · Active Objects:这些对象用于处理事件,在一个线程中可以有多个Asynchoronous Functions Symbian OS中包含很多异步函数,任何含有TRequestStatus&参数的函数都是异步的。如:void After (TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aInterval)· TRequestStatus:包含一个TInt类型的状态值,调用时值为TRequestStatus ·
45、; 时间请求当且仅当aStatus != TRequestStatus时完成,而非函数返回时完成Synchoronous Functions 先看如下例子:创建一个Timer,并且请求一个10秒的timeout。RTimer timer;timer.CreateLocal();TRequestStatus status;timer.After(status, 10000000);User:WaitForRequest(status); 这是同步调用,即当User:WaitForRequest(status);执行时,其他事件都被挂起,用户界面
46、停止响应。一个比较好的解决办法是:当时间请求结束后收到一个通知,而在该过程中其他事件可以被处理。Active Objects 可以被用来处理异步函数调用。从CActive继承,并有如下成员变量:优先级决定了何时被检查是否完成· TRequestStatus:类成员变量,iStatus,传入异步函数调用 · RunL():当异步请求结束时被调用 · DoCancel():当异步请求被取消时调用Active Scheduler 当应用程序启动时,都包含一个系统创建的默认Active Sche
47、duler。在主线程中进行事件循环,完成以下功能;· 同步等待任何发出请求的结束 · 根据优先级测试每个注册的active object,看是否有发出的请求、它的请求是否已经结束 · 对于每个请求已经完成的active object,调用其RunL()函数 · 在RunL()返回后,再检查其他请求 · 对于RunL()可能Leave的情况,调用需函数RunError() 通过 static void Add ( CActive* aActive)函数将一个active object注册到active scheduler
48、中。 Implementing Active Objects 要实现一个Active Object,必须遵循以下步骤:· 从CActive继承 · C+构造函数中:设置优先级EPriorityStandard,调用CActiveScheduler:Add() · 提供一个进行异步函数调用的成员函数,传入:CActive:iStatus,调用CActive:SetActive() · 实现RunL()和DoCancel()函数,因为他们都是纯虚函数,必须实现 · 在析构函数中调用CActive:Cancel()
49、; Symbian中的CPeriodic类已经是一个对timer封装的active object了。 上图展示了Active Object使用的调用流程。Active Objects Other uses· 处理异步函数调用 · 将处理器开销大的任务分成几个阶段 · 实现一个异步服务 · 调用一系列的异步函数客户端/服务器框架本课从用户角度学习客户端/服务器框架,关注如何使用客户端API而非实现服务器端功能。Introduction Symbian OS使用客户端/服务器框架来访问系统资源
50、:如打开文件、拨打、设置闹钟等。需要由服务器来管理系统资源来防止多个客户访问可能引起的问题。 服务器运行在自己的进程或者线程空间中,任何来自客户端的请求都要穿过线程边界。这表明:服务器对资源有着绝对的控制权,可以拒绝来自客户端的请求(如一个客户端请求删除另外一个客户端正在编辑的文件)。 Example Servers and Client APIs Symbian OS主要包含的服务器,如下图所示,其中:· 蓝色:在自己的进程空间中 · 绿色:在一个线程空间中,与其他服务器共享一个进程
51、 在每个Server中列出的类描述了客户端可以使用的API,以下是每个服务的概述:Kernel Server:运行在最高权限,管理系统中所有其他进程对硬件和内存的访问。· RTimer:提供异步时间服务 · RThread: 提供线程访问和创建 · RSemaphre:提供线程间同步机制File Server:提供了对文件系统的访问· RFs:提供到文件服务器的一个会话,可以完成高层次的驱动器、目录和文件的操作以及获取目录列表 · RFile:提供文件创建、读取和写入操作 · RDir:读取目录中所含的entriesWind
52、ow Server:应用程序框架使用窗口服务器来处理按键事件以及进行屏幕显示操作· RWindow:提供屏幕显示操作,开发人员一般使用CCoeControl:raw() · RAnim:与服务器端animation通信(服务器端高优先级drawing) · CWindowGc:提供屏幕绘图操作的图形上下文Font and Bitmap Server:在客户端之间共享字体和位图· RFbsSession:负责与字体和位图服务器之间的一个会话,程序开发中一般不使用该类 · CFbsBitmap:表示一个位图 · CFbsDevice:表示
53、一个用于显示位图的图形设备Telephony Server:负责设备的功能· RTelServer:提供到服务器的工具级别的访问 · RPhone:提供设备上操作 · RLine:提供一路的操作 · RCall:提供在某一路上拨打/接收的功能Socket Server:提供通过多种媒体创建一个TCP/IP或者UDP的socket· RSocketServ:连接到Socket服务器,发现所有的协议 · RSocket:提供连接到,接收和发送数据到另外一个socket的功能 · RHostResolver:提供DNS解析功能Co
54、mms Server:允许开发者通过电缆或者红外使用串行口· RCommServ:提供一个到Comms Server的会话 · RComm:提供通过串行口通行的功能Message Server:保存消息数据并且提供到消息功能如SMS,MMS,OBEX和Mail的访问· CMsvSession:描述一个和消息服务器的会话 · CMsvEntry:描述消息stroe中的一个entry · CBaseMtm:提供访问和操作消息服务器entry的接口Server Plug-ins 客户端/服务器架构具有很好的可扩展性,许多服务
55、器都允许添加plug-in模块,为新的技术、协议和媒质提供功能。所添加的新功能可以通过一个generic api进行访问。如:· Message Server:MMS,SMS,POP3,SMTP · Socket Server:红外,蓝牙,CSD(Circuit Switched Data)Sessions 下图展示了不同的客户端/服务器会话场景:Client1:和服务器之间只有一个会话,在应用程序的control environment中与文件服务器的默认会话。Client2:和服务器之间有两个会话,除默认会话外还有一个显式的文件操作。Clie
56、nt3:和服务器之间有一个会话和两个字会话,与文件服务器有一个连接,对每个打开的文件分别由一个会话。 Requests 下图展示了一个客户端如何穿越线程边界与服务器进行通信,RSessionBase等类都是基类,需要继承。具体过程如下:· 调用一个客户端接口所提供的API,如RFs:rive(),来获取驱动器信息 · RSessionBase:SendReceive()被调用,参数为操作码和一个包含4个指向客户端内存指针的数组 · 内部的private函数RSessionBase:SendSync()被调用,访问内核 · 内核调
57、用服务器线程中的CSession2:ServiceL(), 封装了消息内容的RMessage2作为参数 · 调用RMessage2:WriteL()在用户端的空间中写入所需要的数据 · 调用RMessage2:Complete()来表示对客户端请求的完成Using Client APIs 客户端API继承自RSessionBase或者RSubSessionBase,必须以以下顺序使用:· 建立到相应的服务器的连接,一般通过函数Connect()或者Open()。 · 在建立连接后,可以使用所有的API,请求可以通过同步或者异步的
58、方式发送。 · 在使用完后必须关闭到服务器的连接,否则将发生资源泄漏 需要注意的是:可能会发生leave,资源必须使用CleanupClosePushL()放到cleanup stack上。 ClientAPI的使用案例:HBufC* CFileUtil:ReadL(const TDesC& aFileName) RFs fs; User:eaveIfError(fs.Connect(); CleanupClosePushL(fs);
59、60;RFile file; User:eaveIfError(file.Open(fs, aFileName, EFileRead); CleanupClosePushL(file); TInt fileSize; file.Size(fileSize); HBufC8* data = HBufC8:NewL(fileSize); file.Read(data); CleanupStack:opAndDestroy(2);
60、160; return data;资源文件资源文件 · 指定了应用程序的相关信息,包含要显示的控件定义(如菜单,对话框等),是所有应用程序所必须的。 · 资源文件的后缀名为<application name>.rss。最多可以包含4095个资源。 · 一个应用程序可以包含多个资源文件,并在运行时动态加载其他资源文件。 · Uikon预先定义了许多在资源文件中可以使用的结构体。 · 资源文件需要编译成二进制文件,在C+代码中需要include编译产生的.rsg文件。具体的文件及解释如下: / 4 letter ID 该字段
61、必须每个应用程序唯一NAME S60R / INCLUDES 包含已经定义的资源结构#include <eikon.rh>#include <avkon.rh>#include <avkon.rsg>#include <appinfo.rh>/hrh用于包含枚举常量,如菜单项;rls定义了在UI中使用的字符串#include "S60ResourceLab.hrh"#include "S60ResourceLab.rls"/允许应用程序指
62、定版本号,可选RESOURCE RSS_SIGNATURE /为该应用程序的默认文件指定一个名字RESOURCE TBUF r_default_document_name buf="HEWB" /指定了所要显示的菜单和soft keysRESOURCE EIK_APP_INFO menubar=r_s60resourcelab_menubar; cba=R_AVK
63、ON_SOFTKEYS_OPTIONS_BACK; /定义了需要显示的menu pane,txt字段为空(S80中才有位置显示菜单的title,S60没有)RESOURCE MENU_BAR r_s60resourcelab_menubar titles= MENU_TITLE menu_pane=r_s60resourcelab_menu; txt="&q
64、uot; RESOURCE MENU_PANE r_s60resourcelab_menu items= MENU_ITEM command=EAknCmdExit; txt="Exit" , ME
65、NU_ITEM command=ES60ResourceLabCmdAppTest; txt="Test" RESOURCE TBUF r_s60resourcelab_text_goodbye buf = qtn_s60resourcelab_text_goodbye; RESOURCE TBUF r_s60resourcelab_text_everyone
66、60; buf = qtn_s60resourcelab_text_everyone; Localisation Files#ifdef LANGUAGE_01 #include "HelloWorld01.rls"#elif defined LANGUAGE_02 #include "HelloWorld02.rls"#endifrls_string qtn_caption_string "S60 Resource Lab"rls_strin
67、g qtn_s60resourcelab_text_goodbye "Goodbye"Resource CompilationHBufC* textResource = StringLoader:LoadLC( R_COMMAND1_TEXT );iLabel->SetTextL(*textResource);CleanupStack:PopAndDestroy( textResource );应用程序框架Basic Application Structure 一般应用程序都分为UI和Engine两部分。· UI负责显示和接受用户命
68、令 · Engine负责处理数据,可以被其他应用程序重用Basic Application Classes 下图展示了一个最基本的应用程序类图,其中每部分的作用如下:· Application:返回UID3,创建Document类 · Document:主要创建Application UI,也可以从文件中读写状态数据 · App UI:主要的用户界面,本身不可见,但是拥有可见控件,主要处理菜单命令和按键事件 · View/Container: 包含用户可见的控件,一个应用程序中可能有多个view或container · Model:根据应用程序情况的不同,可能被Document,AppUI或者View所拥有Class Derivations 下图展示了一个CMyApp应用程序的类继承关系,总共有四层:· 最上层:CMyApp类,用户应用程序相关类 · Avkon层:CAkn类与S
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论