symbian 系统开发培训

上传人:沈*** 文档编号:140300058 上传时间:2022-08-23 格式:PPTX 页数:79 大小:1.14MB
返回 下载 相关 举报
symbian 系统开发培训_第1页
第1页 / 共79页
symbian 系统开发培训_第2页
第2页 / 共79页
symbian 系统开发培训_第3页
第3页 / 共79页
点击查看更多>>
资源描述
Symbian OS 开发培训开发培训Inspur Communication Information Systems Co.,Ltd I.Symbian OS 概述概述1998年6月,诺基亚(NOKIA)、摩托罗拉(MOTOROLA)、爱立信(ERICSSON)、三菱(MITSUBISHI)和Psion在英国伦敦共同投资成立Symbian公司。这个公司成立的目的是为了能够设计并开发出一种可以在手机及其他类似的移动通讯终端产品上运行的开放性操作系统,以此来推动高端智能移动电话及类似的终端产品尽快进入大众消费领域。之后有西门子(SIEMENS)、三星(SAMSUNG)、松下(Panasonic)、索尼爱立信(Sony Ericsson)等手机厂商相继入资,现如今,Symbian操作系统的智能手机已经占据了世界智能手机市场超过80%的份额。I.Symbian OS 概述概述Symbian是一个实时性、多任务的纯32位操作系统,具有功耗低、内存占用少等特点,非常适合手机等移动设备使用,经过不断完善,可以支持GPRS、蓝牙、SyncML、以及3G技术。Symbian是一个标准化的开放式平台,任何人都可以为支持Symbian的设备开发软件 。与微软产品不同的是,Symbian将移动设备的通用技术,也就是操作系统的内核,与图形用户界面技术分开,能很好的适应不同方式输入的平台,也可以使厂商可以为自己的产品制作更加友好的操作界面,符合个性化的潮流I.Symbian OS 概述概述目前Symbian OS手机有三种开发SDK:Nokia Series 80:主要机型有Nokia9200 系列Nokia Series 60:主要机型包括诺基亚7650、6600、西门子SX1 等UIQ2、UIQ3:Sony Ericsson P800,P900Sony Sony Ericsson P900II.开发平台搭建开发平台搭建安装ActivePerl(x86和x64分别对应32位和64位cpu)jre(java的应用平台)Symbian OS SDK(建议安装在 盘符根目录下)(C+)开发工具 手机软件开发过程:II.开发平台搭建开发平台搭建第一步:安装开发软件,搭建开发环境(下面主要介绍series 60 sdk,其余类似)第二步:在模拟器上开发调试(以VC环境开发为例)第三步:生成sis文件,在手机上安装运行几种开发环境:II.开发平台搭建开发平台搭建Visual C+6.0Borland C+Builder 6Carbide C+II.开发平台搭建开发平台搭建Symbian工程aifdatagroupincsrcsis工程基本目录结构:1.aif用来存放程序图标2.data用来存放运行所需要的资源文件.rss。3.group中比较重要的几个文件:bld.inf、*.mmp。4.inc 和src 存放工程头文件和源代 码文件。5.sis 用来存放 程序打包所需要的pkg文件,打包后生成的安装文件.sis也存放在此处。1.bld.inf声明build的相关信息 通常只包括这次build会引用到的mmp文件。2.例如:3.PRJ_MMPFILES hello.mmp 4.2.mmp文件保存工程 编译相关信息,主要内容如下5.TARGET hello.app /目标名称6.TARGETTYPE app /目标类型7.UID 0 x100039CE 0 x07B9DE87 /UID 唯一系统标示符8.TARGETPATH systemappshello /目标路径9.SOURCEPATH.src /源代码存放位置10.SOURCE helloApp.cpp /源代码列表 II.开发平台搭建开发平台搭建 SOURCEPATH.data /资源文件路径 RESOURCE hello.rss/资源文件 LANG SC /默认英语 USERINCLUDE.USERINCLUDE.inc /头文件路径 SYSTEMINCLUDE .epoc32include /系统包含文件目录 LIBRARY euser.lib apparc.lib cone.lib eikcore.lib LIBRARY eikcoctl.lib avkon.lib /库文件3.UID UID1-第一个UID(类型):UID1用来设定该应用程序是一个执行程序(executable file)还是一个数据文件(data file).UID value Numeric value(Hex)Meaning KExecutableImageUid 0 x1000007A.exe 可执行文件 KDaynamicLibraryUid 0 x10000079.dll.app.ldd,.pdd 文件 KDirectFileStoreLayoutUid 0 x10000037direct file store KPermanentFileStoreLayoutUid 0 x10000050permanent file store UID2-第二个UID(子类型):UID2-具体含义取决于UID1的值:如果UID1是KExecutableImageUid,UID2不使用,所以UID2的值可以随意取。如果UID1是KDynamicLibraryUid,UID2将会是:如果UID1是KDirectFileStoreLayoutUid或者KPermanentFileStoreLayoutUid,那么UID2将是:UID value Numeric value(Hex)Meaning KSharedLibraryUid 0 x1000008D .dll KUidApp 0 x100039CE .app KLogicalDeviceDriverUid 0 x100000AF a logical decive driver(.ldd)KPhysicalDeviceDriverUid 0 x100039D0 a physical device driver(.pdd)UID value Numeric value(Hex)Meaning KUidAppDllDoc 0 x10003A12 indicates this is a file store created by an .app to store user data(i.e,a document)KUidAppInfoFile 0 x10003A38 Indicates this is an AIF file(a type of file store)UID3-第三个第三个UID(子子类型子子类型):每个独立的应用程序有一个唯一的UID3值,它也被用作安全ID(secure ID),对于UIKON应用程序而言,用于关联数据文件和程序:1.对于dll和exe文件,它辩识特定的二进制(it identified the particular binary)。2.对于.app(UIKON应用程序),它辩识特定的应用程序(it identified the particular application program).3.对于由.apps创建的文件存储(file stores),它辩识和该文件相关的应用程序(it identifies the application program associated with this file).4.对于其他文件存储(file stores),它没有典型的用途(但是你可以自定义它的用途)Symbian 命名约定 Symbian大致分了四种类 C:C前缀表示类从CBase派生并应该基于堆构造。T:T前缀表示一个简单类,这种类不拥有任何额外的资源。如Tint、TReal等基本数据类型。R:R前缀表示一个资源类,它包含其它位置拥有资源的句柄。M:M前缀表示一个接口类,它定义了接口但需要派生类实现。结构(struct)类型作为T类对待,因为它也不拥有任何额外的资源,它的前缀通常是T(但也有一些以S开头)。enum TColorsERed,/尽量用E开头,尽量用枚举EGreen成员变量的名字以i开头,参数名以a开头 class TMyClass TInt iMyValue;void MyAddFunc(TInt aArg1,TInt aArg2);void MyAddFunc(TInt aArg1,TInt aArg2);void MyAddFuncL(TInt aArg1,TInt aArg2);-后缀L的约定是该 函数可 能产生异常退出;void MyAddFuncLC(TInt aArg1,TInt aArg2);-后缀LC的约定表示 成功完成之后,返回值会被压入清理栈中;(栈不保存);Symbian 编程规范和基本框架编程规范和基本框架Symbian 命名约定常量应加前缀K const CInt KMyconstant;宏全部为大写#define MY_HARDCODED_VALUE(25)Symbian四个主要的应用软件框架类 针对右图Graphics,UI程序应该具备的基本功能类:视图(View)、文档(Document)、应用程序(Application)、应用程序UI(Application UI)。所有的S60 UI应用程序都具有一些基本功能:提供一个用户界面,用于显示信息并允许用户进行交互。响应各种用户启动的事件,比如用户选择一个菜单项。响应系统启动的不同事件,比如导致屏幕重绘的window服务器事件。能够保存和恢复应用程序数据。可以唯一性的向框架标志自身。向框架提供有关应用程序的描述性信息,比如图标和标题等。Symbian 编程规范和基本框架编程规范和基本框架Symbian四个主要的应用软件框架类 一个程序只能有一个文档,可以有多个视图。l必须创建下面的每个方法,才能提供最小的S60应用程序:l 所有S60 UI都实现一个全局函数E32DLL(),当应用程序启动时,框架将首先调用该函数,该函数也称为DLL入口点入口点,应用程序必须存在该函数。框架调用NewApplication(),创建Application类,其类,其基类是CAknApplication.lApplication类类创建应用程序类的Document对象对象,并返回它的指针,以后框架使用该指针完成应用程序的创建。由框架调用AppDllUid()返回应用程序的UID。该函数必须返回在.mmp文件中指定的值。Document基类是CAknDocument.lDocument对象对象通过CreateAppUiL创建获取AppUi类的指针。AppUi类的基类是CAknAppUi 或者 CAknViewAppUi,它是用来处理应用程序事件,如操作菜单,操作视图,切换视图等等。lView 是控制类(c类),在屏幕上显示数据,用户与界面交互,传递命令给AppUi。Symbian 编程规范和基本框架编程规范和基本框架Symbian处理内存泄漏的手段 1.Trap和TrapD 处理异常 TInt err;Trap(err,CreateObject();/需要先定义err变量 TrapD(err,CreateObject();/不需要定义err变量 2.CleanupStack 它是处理内存泄漏的又一重要手段 CFoo*p=new(ELeave)CFoo();CleanupStack:PushL(p)p-SomeFunctionL();/可能异常退出,使得delete p 得不到调用 CleanupStack:Pop();delete p;Symbian二阶段构造 在Symbian中,如果在一个类的构造函数中需要执行某些比如申请内存等操作,那么有可能会Leave。如果Leave的话,这个时候这个类的析构 函数是不会被调用,因为还没有初始化完,也就没法把自己加入CleanupStack,那么那些申请了的内存可能会因为没有变量引用而造成内存泄漏。因此 在Symbian中类的构造函数中不能有可能会Leave的代码。Symbian 编程规范和基本框架编程规范和基本框架Symbian二阶段构造二阶段构造初始化一个类确实需要执行某些可能会Leave的函数,这就是Symbian中要求的两阶段初始化了。第一阶段,也就是在构造函数中执行一些不会 Leave的初始化工作。然后是第二阶段,把这个实例推进CleanupStack,再执行第二阶段的可能会Leave的代码。当然,在析构函数中,要能 够处理部分初始化的情况,也就是实例没有初始化成功,也能释放那些已经申请的内存或资源。CGraphicsAppView:CGraphicsAppView()CGraphicsAppView*CGraphicsAppView:NewL(const TRect&aRect)CGraphicsAppView*self=NewLC(aRect);CleanupStack:Pop(self);return self;CGraphicsAppView*CGraphicsAppView:NewLC(const TRect&aRect)CGraphicsAppView*self=new(ELeave)CGraphicsAppView;CleanupStack:PushL(self);self-ConstructL(aRect);return self;void CGraphicsAppView:ConstructL(const TRect&aRect)CreateWindowL();SetRect(aRect);Symbian 编程规范和基本框架编程规范和基本框架描述符描述符 描述符是用来存储文本和二进制的基本类u抽象类(Abstract):(TDes、TDesC、TDes8、TDesC8),描述符的基类,仅提供接口和基本功能,不能被实例化,一般只用作函数的参数。u文字常量(Literal):(TlitC、_LIT(),用于存储文字字符串(literal string),即C中字符串常量,通常使用_LIT()这种方式,也有_L(),_L8()这种方式。u栈类(Buffer):(TBuf、TBufC、TBuf8、TBufC8),数据存储于栈上,最基本的描述符变量类型,大小在编译时确定大小在编译时确定,包含描述符本身数据,使用最为普遍,具体方法如下u堆类(Heap):(HBufC、HBufC8),数据存储于堆上,大小在运行时确定 ,也就是用来处理动态申请的描述符类。在C/C+中用过动态内存的都知道,动态内存是啥回事,这里堆类描述符用的时候,也是差不多,由于堆描述符 没有构造函数,所以只能声明为指针类型,通过堆描述符类内静态函数NewL 方法申请内存,具体方法如下 HBufC*errorTitleCode=HBufC:NewLC(50);HbufC*unUseCode=NULL;u指针类(Pointer):(TPtr、TPtrC、TPtr8、TPtrC8),本身不包含描述符数据,但是包含长度数据,而且还包含一个指向位于描述符之外数据的指针。Symbian基本语法基本语法描述符关系简图描述符关系简图 Symbian基本语法基本语法描述符的使用描述符的使用u 文字描述符常量 _LIT(KMyFile,“c:SystemAppsMyAppMyFile.jpg”);它可以在任何使用TDesC&的地方使用。/常用的通知函数 NEikonEnvironment:MessageBox(_L(Error:init file not found!);/数字转字符串 TBuf16 buf;/TInt iNum=20;buf.Format(_L(%d),iNum );u 栈描述符 栈类描述符声明时必须指定描述符的最大长度,否则无法声明和定义,举例如下:/直接从字符串中构造 _LIT(Ktext,TestText);TBufC Buf(Ktext);/或从字符串赋值 TBufC Buf2;Buf2=Ktext;/从已有的对象中生成新的TBufC TBufC Buf3(Buf2);Symbian基本语法基本语法描述符的使用描述符的使用u 栈描述符 尽管这里的对象表示数据是不能被修改的(因为有个后缀C代表了常量的意思),但仍然有两种方式可以用来修改数据内容:这里的数据可以用赋值的方式替换掉;使用Des()函数构造出一个TPtr对象,这样就可以用它来修改数据。_LIT(Ktext,Test Text);_LIT(Ktext1,Test Text”);_LIT(KXtraText,New:);TBufC Buf1(Ktext);/Buf1长度为9 内容“Test Text”TBufC Buf2(Ktext1);/Buf2长度为10 内容“Test1 Text”/通过赋值的方式改变数据Buf2=Buf1;/Buf2长度变为9 内容“Test Text”/通过使用Des()生成指针改变TBufC的数据TPtr Pointer=Buf1.Des();/删除后四个字符Pointer.Delete(Pointer.Length()-4,4);/Buf1长度变为5 内容“Test”/增加新的数据Pointer.Append(KXtraText);/Buf1长度为9 内容为“Test New:”/也可以使用下列方式改变数据 TBufC Buf3(NewText);Pointer.Copy(Buf3);/Buf1长度为4,内容为New1/或直接从字符串里获得数据Pointer.Copy(NewText1);/Buf1长度为4,内容为New2Symbian基本语法基本语法描述符的使用描述符的使用u 栈描述符 可修改的描述符TBuf,TBuf8就不用通过那么复杂的方法来实现修改,它直接可以用Copy、Delete等方法,但是无论可修改的还是不可修改的,一旦指定最大的数据长度后,最大长度就不能进行修改了修改的只是数据内容,而数据内容修改的受限条件是不能超过声明或定义时的最大长度。u 堆描述符 堆描述符HBufC,HbufC8虽然都是不可修改类型的,但是它仍然具有构造和修改,与栈描述符不同的是:首先对内存需要显示释放,其次是堆描述符没有最大长度的限制,任何时候都可以用ReAlloc()函数重新申请分配。有两种方式来生成一个堆描述符示例:/第一种方式用New(),NewL(),或NewLC()HBufC*Buf=HBufC:NewL(15);/第二种方式是采用Alloc(),AllocL()或AllcLC()来处理 _LIT(KText,Test Text);TBufC CBuf=KText;HBufC*Buf1=CBuf.AllocL();CleanupStack:PushL(Buf1);堆描述符的修改方式:/1.赋值方式改变其数据的方法 _LIT(KText1,Text1);*Buf1=KText1;Symbian基本语法基本语法描述符的使用描述符的使用u堆描述符堆描述符堆描述符的修改方式:/2.通过可修改指针来改变数据的方式 TPtr Pointer=Buf1-Des();Pointer.Delete(Pointer.Length()-2,2);/删除数据 _LIT(KNew,New:);Pointer.Append(KNew);/添加数据重新申请内存 Buf1=Buf1-ReAllocL(KText().Length()+KNew().Length();CleanupStack:PushL(Buf1);释放内存 delete Buf;Buf=NULL;u指针描述符指针描述符不可修改的指针TPtrC 可用TBuf和TBufC构造出TPtrC对象 _LIT(KText,Test Code);TBufC Buf(KText);/或者为 TBuf Buf(KText);TPtrC Ptr(Buf);/使用构造函数初始化 TPtrC Ptr1;Ptr1.Set(Buf);/利用set函数初始化 Symbian基本语法基本语法描述符的使用描述符的使用u指针描述符指针描述符不可修改的指针TPtrC 用TText*构造TPtrC const TText*text=_S(Hello Worldn);TPtrC ptr(text);/或者 TPtrC Ptr2;Ptr2.Set(text);/如果要存储TText的一部分数据,我们使用下列方法 TPtrC ptr4(text,5);从另一个TPtrC中构造TPtrC const TText*text1=_S(Hello Worldn);TPtrC Ptr3(text1);/从一个TPtrC中获得另一个TPtrC TPtrC p1(Ptr3);/或 TPtrC p2;p2.Set(Ptr3);可修改的TPtr 同不可修改的指针描述符构造方法基本类似,区别在于,不可修改的指针描述符TPtrC的函数始终是不可修改的,因此没有Insert,Delete等函数,并且没有Des()函数,但有Alloc(),Compare(),Find(),Mid(),Size()等函数。Symbian基本语法基本语法动态数组动态数组 在传统c/c+中经常会使用数组来存储序列,它是具有相同数据类型的数据元素的集合,通过数组可以很方便的实现数据元素的访问等相关操作。动态数组是一个类的模板,可以接受各种各样的数据类型,Symbian OS主要提供了3类动态数组:RArray,RPointerArray,CArray活动对象活动对象 在symbian os 中活动对象是一种非抢先式多任务处理的机制,是symbian os 中一个十分重要的概念。可用于替代Symbian OS中的多线程。使用活动对象可获得的好处是:在同一个线程中运行的活动对象之间进行切换的代价要比线程上下文的切换代价低,这使得对于各种资源比较紧张的Symbian OS来说,使得活动对象更适合事件驱动多任务。概念:一个活动对象必须派生自基类CActive class CActive:public CBasepublic:enum Tpriority EPriorityIdle=-100;EPriorityLow=-20;EPriorityStandard=0;EPriorityUserInput=10;EPriorityHigh=20;Symbian基本语法基本语法活动对象活动对象 public:IMPORT_C CActive();IMPORT_C void Cancel();/删除未完成请求的函数 IMPORT_C void SetPriority(TInt aPriority);Inline TBool IsActive()const;protected:IMPORT_C CActive(TInt aPriority);IMPORT_C void SetActive();virtual void DoCancel()=0;/两个纯虚函数,继承类必须实现它们 virtual void RunL()=0;/处理函数 IMPORT_C virtual TInt RunError(TInt aError);public:TrequestStatus iStatus;/代表请求状态 .private:TBool iActive;.u构造时也会有一个优先级值来决定它们如何被调度 uCancel 和DoCancel用来取消发出的请求,Docancel是一个纯虚函数,需要由派生类实现。Cancel的功能就是调用DoCancel,如果用户取消当前请求调用Cancel而不是DoCancel,但在代码中要实现DocancelSymbian基本语法基本语法活动对象活动对象uIsActive确定活动对象是否处于活动状态uSetActive 激活活动对象,一般在调用请求后紧接着调用它。uRunL 异步事件处理函数,当一个请求完成时,活动对象调度器会调用这个函数,进行下一步处理uRunError 当RunL函数出现异常时会出现RunError函数,它也是纯虚函数,需要派生类实现。具体例子见文档。文件管理文件管理 symbian系统采用了C/S(客户端/服务器)的架构。对于文件操作,系统有一个文件系统管理的服务器。程序通过联结这个文件管理服务器来进行文件。在symbian os 中,Flash(闪存)通常被定义在c盘,symbian智能手机中还有一个ROM存储器通常被映射在z盘,用户的许多文件也存放在z盘。其他可移动存储(如存储卡)则映射在d,e等盘符。symbian开发环境下各盘符对应的映射关系:客户机c:盘 对应开发平台中sdk的 epoc32winsc目录 客户机d:盘 对应开发平台中sdk的epoc32winsd目录 客户机z:盘 对应开发平台中sdk的epoc32releasewinsurelz目录或者 epoc32releasewinsurelzu文件命名规则 一个完整的symbian os 文件应该包含以下四个部分 1.驱动器名,即盘符 2.路径,从根目录到或当前会话目录起到文件经过的所有目录路径 3.文件名,遵循c/c+命名规范 4.文件扩展名 例如:c:myfiledata.txt就是合法的文件名,一个完整的文件名不能超过255个字符。Symbian基本语法基本语法文件管理文件管理u文件访问流程 1.应用程序要进行文件读写之前,必须建立应用程序与文件服务器的连接,这种连接也称会话(session),Sysmbian os中提供RFs类来实现这个功能,该类提供了Connect()和Close()函数来建立和关闭连接。RFs fsSession;/建立RFs类的对象 User:LeaveIfError(fsSession.Connect();/建立连接,为防止出现异常放 User:LeaveIfError中 fsSession.Close();/用完关闭连接 2.文件服务器可以实现文件的读、写、删、建,通过 RFile的Open(RFs aFs,const TDesC&aName,TUnit aFileMode)打开文件。通过Write()和Read()可以实现文件的写和读。RFile的Create()用于建立新文件。删除文件可以使用RFs的Delete()。3.另一种比较重要的文件读写方式-流(Stream)文件输出流 RWriteStream 和文件输入流RReadStream 文件输出六主要使用RWriteStream 的派生类RFileWriteStream 将数据外化为流,它需要先打开一个文件,打开文件的两种方式:OpenL:当文件不存在会产生异常,所以必须保证文件存在 Replace:文件存在删除并重建新的,不存在就创建,因每次都创建文件,会带来额外开销。例子:RFileWriteStream writer;writer.PushL();/writer on cleanup stackUser:LeaveIfError(writer.Replace(iCoeEnv-FsSession(),*iFileName,EFileWrite);writer SetTypeL(FileStore-Layout();TStreamId id=iDb.CreateL(FileStore);FileStore-SetRootL(id);FileStore-CommitL();CleanupStack:PopAndDestroy(FileStore);iOpen=ETrue;iDb.Close();Symbian基本应用基本应用数据库管理数据库管理 (3)创建表格:通过文件流存储打开数据库:_LIT(KFileName,C:DataBase.db);CFileStore*FileStore=CPermanentFileStore:OpenLC(iFsSession,KFileName,EFileRead|EFileWrite);FileStore-SetTypeL(FileStore-Layout();iDb.OpenL(FileStore,FileStore-Root();添加字段:_LIT(KId,Id);_LIT(KText,Text);_LIT(KTableName,Table);TDbCol IdCol(KId,EDbColText);TDbCol TextCol(KText,EDbColText);CDbColSet*ColSet=CDbColSet:NewLC();ColSet-AddL(IdCol);ColSet-AddL(TextCol);创建表格:User:LeaveIfError(iDb.CreateTable(KTableName,*ColSet);释放不使用的内存:CleanupStack:PopAndDestroy(ColSet);CleanupStack:PopAndDestroy(FileStore);Symbian基本应用基本应用数据库管理数据库管理 (4)创建索引:TDbKeyCol IdKey(KId);CDbKey*key=CDbKey:NewLC();key-AddL(IdKey);User:LeaveIfError(iDb.CreateIndex(KTableName,KTableName,*key);CleanupStack:PopAndDestroy(key);首 先创建一个索引对象,将其添加到索引集合中,通过调用RDbStoreDatabase:CreateIndex(const TDesC&aName,const TDesC&aTable,const CDbKey&aKey)创建表格,最后清除不使用的内存。(5)插入记录:_LIT(KIdText,100001);首先打开数据库。打开表:RDbTable table;CleanupClosePushL(table);User:LeaveIfError(table.Open(iDb,aTableName,table.EUpdatable);获取字段集合:CDbColSet*ColSet=table.ColSetL();CleanupStack:PushL(ColSet);添加记录:table.Reset();table.InsertL();table.SetColL(ColSet-ColNo(KId),KIdText);table.PutL();CleanupStack:PopAndDestroy(2);/清除内存:注意:每插入一条记录,就必须调用table.InsertL(),设置完值后,必须调用table.PutL()提交。Symbian基本应用基本应用(6)查询记录:首先打开数据库和表。TPtrC ptrc;for(table.FirstL();table.AtRow();table.NextL()table.GetL();ptrc.Set(table.ColDes(colSet-ColNo(KId);table.FirstL()将焦点设置为第一条记录,table.AtRow()验证下一条记录是否存在,table.NextL()将焦点移动到下一条记录。每查询一条记录,必须调用table.GetL();使用TPtrC:Set()将查询结果写进描述符。(7)执行SQL语句:首先打开数据库。TBuf SQL;SQL.Append(_L(/Some SQL);RDbUpdate DbUpdate;TInt incStat=DbUpdate.Execute(iDb,SQL,EDbCompareNormal);incStat=DbUpdate.Next();while(incStat=1)incStat=DbUpdate.Next();DbUpdate.Close();Symbian基本应用基本应用 Symbian GUI编程编程60系列用户界面显示器规范如下:系列用户界面显示器规范如下:分辨率:分辨率:176像素像素(宽宽)208像素(高)像素(高)正方形像素正方形像素 物理尺寸:约物理尺寸:约35mm(宽宽),41mm(高高),对应约对应约0.2mm的象素点距。的象素点距。颜色数(颜色数(4096色或更多)色或更多)Symbian GUI编程编程Symbian GUI编程编程显示器按照一定的层次结构进行布局。布局由被称为窗口(显示器按照一定的层次结构进行布局。布局由被称为窗口(windows)和窗格)和窗格(panes)的组件构建。)的组件构建。屏幕(屏幕(Screen)是最顶层的显示组件,对应于物理屏幕的整个象素区域。)是最顶层的显示组件,对应于物理屏幕的整个象素区域。窗口(窗口(Window)屏幕(screen)是窗口的唯一父组件。一般情况下一个窗口会充满整个屏幕,但有时也存在一些小窗口(临时性的),它们只占据屏幕的一部分,环绕其周围的部分是可见的。每个应用程序都在自己的窗口中运行。应用程序也可以调用其它的临时窗口。窗格(窗格(Pane)窗格是窗口(window)的子组件。一个窗口可以包含多个窗格,而每个窗格又可以包含多个子窗格,如此等等。不含有子组件的底层组件被称为元素(element)。应用窗口应用窗口 应用窗口是覆盖整个屏幕的主窗口。通常它并不直接用于显示,而是作为各种窗格的父组件。一个典型的应用窗口由下几种窗格组成:一个典型的应用窗口由下几种窗格组成:-状态窗格-主窗格-控制窗格 Symbian GUI编程编程GUI应用程序的基本组成部分应用程序的基本组成部分Application负责启动方面的工作Document负责永久保持的工作AppUI负责接受并处理用户的命令AppView负责图形显示的工作Model可选:负责处理数据view架构架构view是一个执行特定任务的一屏是一个执行特定任务的一屏同一时刻,同一时刻,view管理系统只允许一个管理系统只允许一个view处于激活状态处于激活状态每个每个view都有一个都有一个ID每个每个view必须到必须到view server上去登记上去登记调用调用ActiveViewL()还能够激活其它应用程序的还能够激活其它应用程序的views在在view之间能够传递消息之间能够传递消息class CMyView:public CAknViewCCoeControl框架框架主要内容简单控件CCoeControl概述控件的初始化控件的重绘用户输入处理(按键事件)复合控件常用控件对话框表格资源菜单软键热键CCoeControl框架框架WINDOWS serverCCoeControl框架框架WINDOWS serverCoeControl可以作为视图的基类传统的EIKON视图架构containerdialog负责应用程序视图区域的显示工作一个应用程序的界面分为三部分标题栏软键区域应用程序视图区域(右图的黑框部分)使用CGraphicsContext进行画图在UI平台能力范围内工作(如:60系列)系统提供的常用控件有按钮编辑器文本标签列表框可以内嵌其它控件(又称定制控件,或者复合控件)CoeControl所有对屏幕的操作都是在控件上进行控件从CCoeControl继承而来控件是屏幕上的一个矩形区域控件占据窗口的全部或者部分应用程序的视图使用至少一个控件控件可以处理用户的输入事件键盘事件鼠标事件CoeControl是所有控件的基类被派生类直接调用的函数SetRect()CreateWindowL()被派生类重载的函数OfferKeyEventL()Draw()所拥有的函数可以分为以下三类初始化Drawing用户输入处理初始化初始化class CAbcContainer:public CCoeControl public:/Constructors and destructor void ConstructL(const TRect&aRect);CAbcContainer();private:/Functions from base classes void SizeChanged();void Draw(const TRect&aRect)const;void CAbcContainer:ConstructL(const TRect&aRect)CreateWindowL();SetRect(aRect);ActivateL();初始化初始化class CAbcContainer:public CCoeControl public:/Constructors and destructor void ConstructL(const TRect&aRect);CAbcContainer();private:/Functions from base classes void SizeChanged();void Draw(const TRect&aRect)const;void CAbcContainer:ConstructL(const TRect&aRect)CreateWindowL();SetRect(aRect);ActivateL();Drawingvirtual void Draw(const TRect&aRect)const;负责产生控件的图形化外观重要提示基类中的该函数为空,在派生类中如果不实现该函数的话控件将不可见该方法由应用程序框架调用,不要自己调用该函数方法是const,意味着你在Draw()中不能更改任何成员变量,或者调用任何不是const的函数。该函数不允许leave,因此你必须用TRAP封装可能leave的函数Draw()void CAbcContainer:Draw(const TRect&aRect)const CWindowGc&gc=SystemGc();gc.SetPenStyle(CGraphicsContext:ENullPen);gc.SetBrushColor(KRgbDarkBlue);gc.SetBrushStyle(CGraphicsContext:ESolidBrush);gc.DrawRect(aRect);/gc.Clear()图形设备接口图形设备接口GDI抽象类CGraphicsContext(图形上下文)定义了一致的接口派生类CWindowGc和CFbsBitGc具体实现了这些接口可以直接使用CFbsBitGc绘图,但不推荐:推荐的绘图方式推荐的绘图方式建议在程序中使用CWindowGc提供的接口图形上下文图形上下文 CWindowGc&SystemGc()const用来获取当前的图形上下文提供了许多有用的绘图函数画点、线、椭圆、矩形、位图等等改变画笔/画刷的颜色和风格改变字体设置裁剪区域,原点在某一时刻CWindowGc只能由一个窗口激活void Activate(RDrawableWindow&aWindow)void Deactivate()控件的重绘控件的重绘(redraw)更新在屏幕上的显示两种类型系统发起的window server我们“必须”重绘控件应用程序发起的内部状态改变我们“想要”重绘控件系统发起的重绘系统发起的重绘1.当window server检测到可能使一个区域无效的事件对话框/菜单不再需要时启动一个GUI程序时2.发送redraw消息给拥有窗口的应用程序3.应用程序通过CONE发送消息给相关的控件4.调用控件的Draw()函数应用发起的重绘应用发起的重绘通常是某个内部状态改变的结果实现方法有以下几种:Invalidate控件窗口的某部分,让window server发送一个redraw消息请求CONE立即重绘整个控件立即重绘控件的某个部分所有的实现方法最终都是调用Draw()函数redraw的类型的类型立即重绘整个控件CCoeControl:DrawNow()在程序初始化时采用一旦有机会就重绘整个窗口:void CCoeControl:DrawDeferred()const部分窗口:void RWindow:Invalidate(const TRect&)立即重绘已知无效的部分void CSemView:DrawSunNow()const Window().Invalidate(iSunArea);ActivateGc();Window().BeginRedraw(iSunArea);DrawSun();Window().EndRedraw();DeactivateGc();更多更多Draw()的信息的信息参数aRect指定重绘的区域相对于控件的原点(左上角)对于简单控件,通常重绘整个控件对于复合控件,只重绘部分控件防止屏幕闪烁只重绘位于无效区域的部分不要短时间内多次重绘某个区域尽量避免大面积的重绘处理按键事件处理按键事件控件能够检测并处理按键事件按键事件的处理是独立于资源文件定义的热键处理之外的UI框架已经实现了大部分的按键处理典型应用导航键选择键CONE控件堆栈控件堆栈按键事件由系统通告给对其感兴趣的控件在一个特殊的数据结构(CONE控件堆栈)中登记感兴趣的控件系统给控件发送OfferKeyEventL事件CONE控件堆栈中的控件被一一通告事件的发生,直至某个控件宣称接收了该事件控件按优先级被通告事件的发生控件必须告知系统是否接收了该事件如果没有任何控件宣称接收一个事件,则最后将由AppUi在它的CMyAppUi:HandleKeyEventL()中处理该事件AppUi对按键事件的处理对按键事件的处理在CONE控件堆栈中登记控件void CtestAppUi:ConstructL()BaseConstructL();iAppContainer=new(ELeave)CtestContainer;iAppContainer-SetMopParent(this);iAppContainer-ConstructL(ClientRect();AddToStackL(iAppContainer);iAppContainer2=new(ELeave)CtestContainer2;iAppContainer2-SetMopParent(this);iAppContainer2-ConstructL(ClientRect();AddToStackL(iAppContainer2);在析构的时候将控件从CONE控件堆栈中注销CtestAppUi:CtestAppUi()if(iAppContainer)RemoveFromStack(iAppContainer);delete iAppContainer;CCoeControl对按键事件的处理对按键事件的处理TKeyResponse OfferKeyEventL(const TKeyEvent&aEvent,TEventCode aType)TKeyResponse CMyGameView:OfferKeyEventL(const TKeyEvent&aKeyEvent,TEventCode aType)switch(aType)case EEventKey:if(aKeyEvent.iScanCode=EStdKeyNkp5|aKeyEvent.iScanCode=EStdKeyDevice3)iMyGameEngine-Fire();return EKeyWasConsumed;break;case EEventKeyDown:case EEventKeyUp:return EKeyWasNotConsumed;点击事件的处理点击事件的处理60系列并不支持笔写输入但模拟器支持笔的点击void HandlePointerEventL(const TPointerEvent&)复合控件复合控件compound control包含其它控件的控件有时也称container,容器为什么要用复合控件共享主控件的现有窗口重用控件系统控件(CEikLabel)自己的控件(CMyInfoControl)可以选择性地重绘子控件容器(主控件)的责任容器(主控件)的责任创建窗口只为主控件创建窗口子控件重用该窗口创建和删除子控件在主控件中定义成员变量在析构函数中删除子控件摆放子控件设置自己的大小摆放子控件CCoeControl&Windows创建一个新窗口CreateWindowL()为主控件所拥有为子控件所共享重用现有的窗口SetContainerWindowL(const CCoeControl&aContainer)子控件调用该函数减少与window server的c/s交互创建子控件创建子控件在容器的第二阶段构造函数中创建子控件,并让它们重用容器的窗口void CtestContainer:ConstructL(const TRect&aRect)CreateWindowL();/创建主窗口 iLabel=new(ELeave)CEikLabel;iLabel-SetContainerWindowL(*this);iLabel-SetTextL(_L(Example View);iToDoLabel=new(ELeave)CEikLabel;iToDoLabel-SetContainerWindowL(*this);iToDoLabel-SetTextL(_L(Add Your controlsn here);SetRect(aRect);ActivateL();通告给通告给CONE相应的信息相应的信息告诉CONE拥有的子控件的数目TInt CtestContainer:CountComponentControls()const缺省的实现返回0返回子控件的指针CCoeControl*CtestContainer:ComponentControl(TInt aIndex)const用来依次对所有的子控件执行操作第一个控件的index为0,顺序通常不是很重要如果忘记重载上述两个函数,则子控件依然存在,但无法显示,因为CONE不知道我们的容器有几个子控件复合控件的绘图复合控件的绘图重绘容器时也重绘了子控件首先调用容器的Draw()然后调用子控件的Draw()CONE利用CountComponentControls()和ComponentControl(TInt aIndex)依次调用自控件的Draw()防止闪烁如果子控件覆盖了整个容器的区域,则无须为容器提供Draw(),否则会重绘两次同一区域,产生闪烁只重绘没有被子控件覆盖的区域设置裁剪区域void SetClippingRect(const TRect&aRect)Tint SetClippingRegion(const TRegion&aClippingRegion)TRegionFix clippingRegion;clippingRegion.Clear();clippingRegion.AddRect(Rect();clippingRegion.SubRect(iSubControl1);/裁剪掉该子控件占用的区域clippingRegion.SubRect(iSubControl2);转发按键事件转发按键事件只有容器被压入CONE控件堆栈由AppUi来将其压栈必须转发按键事件给子控件具体实现TKeyResponse CMainControl:OfferKeyEvent(.)if(aType!=EEventKey)return;return iSubControl-OfferkeyEventL(.)Symbian 构建工程构建工程构建工程的工具:构建工程的工具:bldmake和和abld Symbian 构建工程构建工程 VC6 bldmake bldfiles abld build vc6 WINS(WINdows Single Process)bldmake bldfiles abld build wins udeb ARMI bldmake bldfiles abld build armi urel THUMB bldmake bldfiles abld build thumb urel 必须在myprojectgroup下面执行 Sy
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!