Author:孙东风 2007-04-08
①MVC架构
我们知道,在软件编写过程中一直提倡"数据"和"界面"的高度分离,Symbian中也是这么做的。
首先,基于"传统EIKON框架"的应用程序会产生App、Document、AppUi、Container四个类,其中App是应用程序的"启动类",Document基础上没什么用处,而Symbian中大量的处理工作都放在了AppUi和Container类中。AppUi就象是一个交通枢纽负责南来北往的数据,一般来说,在Symbian的程序中都会新建一个Engine的"引擎类"来负责程序的逻辑处理,而AppUi就是负责把"引擎类"中数据的处理结果、数据的变化及时更新到Container中。
下面是我写的一个Symbian游戏引擎中AppUi二阶段构造函数中的代码:
void CMegajoyAppUi::ConstructL() { BaseConstructL();
iAppContainer = new (ELeave) CMegajoyContainer; iAppContainer->SetMopParent( this ); iAppContainer->ConstructL( ClientRect() ); AddToStackL( iAppContainer );
iMainEngine = new (ELeave) CMegajoyMain(this);
iLancher = CIdle::NewL( CActive::EPriorityIdle );
iLancher->Start(TCallBack(Start,this));
}
|
从中可以看到,上面AppUi的二阶段构造函数中同时产生了iAppContainer和iMainEngine实例,并且我们把一个AppUi的this指针传递给了"引擎类"。我们知道,做为一种GUI程序,无非就是用户界面的交互(包括键盘、鼠标等)和引擎处理数据。而Symbian中提供给用户界面交互接口的正是AppUi类,它里面的HandleCommandL()负责处理用户的菜单操作,HandleKeyEventL()负责处理用户的键盘操作,DoExit()负责用户的退出操作等。那么,一切数据的处理和界面的显示都经过AppUi这个中枢就显得很有必要了!
试想一下,用户按下某个键,这个键从传递到AppUi的HandleKeyEventL()函数里(当然也有可能是其上某个控件的消息响应函数中,这里忽略控件栈的讨论),而AppUi调用iMainEngine来处理这个按键数据,从而进行必要的逻辑转变,比如从一个界面跳转到另一个界面,那么iMainEngine里就会把一个全局的界面ID从一种状态转换到另一种状态,但是这种状态的切换会伴随着界面的变化,界面上也需要体现出这种变化,而界面的绘制是在iAppContainer中完成的,iAppContainer又是在AppUi中构造并初始化的。
就是说我们的iAppContainer和iMainEngine需要一种类似通信的机制,让iAppContainer能及时的知道iMainEngine中某个全局变量状态的变化并及时做出界面上的更新。
问题到了这里已经很明显,iAppContainer和iMainEngine都在AppUi类里,而这两个实例对象之间需要一种类似通信的机制。
解决这种两个对象实例之间通信问题的非我们的"Observer模式"莫属!下面我们就来看看Symbian中的"Observer模式"。
②Observer模式
Observer模式提供一种类与类之间传递消息的机制,当某个事件发生或状态改变时,拥有观察者的类可以向另一个类发送某个消息,这样另一个类可以根据变化做出相应的处理。呵呵,是不是觉得简直是为了我们Symbian量身定做的一个模式?
在我们的Symbian架构中iMainEngine中会有事件发生(因为AppUi类把事件传递给它了)或状态改变(例如全局界面ID的变化),那么我们的iMainEngine中就需要有一个"观察者"的实例以便向iAppContainer发送消息,iAppContainer可以根据变化做出相应的处理。
这样我们就可以定义一个消息接口的类,这个类是抽象的,内部的函数也都是纯虚函数(只提供接口),下面是我写的Symbian游戏引擎中观察者接口(或者说消息接口)的定义:
class MMegajoyAction{ public: // Graphic functions virtual void FlipBackBuffer(void)=0; virtual void BitBlt(TInt iBltType, CExtendedBitmap &iBitmap, const TPoint &aPosition)=0; virtual void DoExit(void)=0; virtual TBool ReadIniFile(TUid iInfo, void *ptr, TUint &size)=0; virtual TBool CheckIniFile(TUid iInfo)=0; virtual void WriteIniFile(TUid iInfo, void *ptr, TUint size)=0; virtual void RemoveIniData(TUid iInfo)=0; }; |
因为iMainEngine和iAppContainer都在AppUi中,那么AppUi就成为它们之间消息中转的最佳选择了,让AppUi类实现这个接口MMegajoyAction,并传递AppUi的this指针到iMainEngine,而iMainEngine中也有个MMegajoyAction的实例对象MMegajoyAction *Actions;从而当iMainEngine中有事件发生(因为AppUi类把事件传递给它了)或状态改变(例如全局界面ID的变化)时直接调用Actions传递消息到AppUi,AppUi中通过实现的具体接口再调用iAppContainer中的方法,实现了iMainEngine和iAppContainer之间的通信机制。
如下是我写的Symbian游戏引擎中AppUi对观察者接口的实现
void CMegajoyAppUi::FlipBackBuffer(void){ iAppContainer->FlipBackBuffer(); }
void CMegajoyAppUi::BitBlt(TInt iBltType, CExtendedBitmap &iBitmap, const TPoint &aPosition){ switch(iBltType){ case BLTTYPE_NORMAL: iAppContainer->BlitToBackBuffer(iBitmap, aPosition); break; case BLTTYPE_MASKED: iAppContainer->BlitToBackBufferMasked(iBitmap, aPosition); break; } }
void CMegajoyAppUi::DoExit(void){ Exit(); }
TBool CMegajoyAppUi::ReadIniFile(TUid iInfo, void *ptr, TUint &size){ TInt r; TBool result = EFalse; RFs fs; fs.Connect(); CleanupClosePushL( fs ); RDictionaryReadStream rdsIniFile; CDictionaryStore *cdIniFile = Application()->OpenIniFileLC(fs); if (cdIniFile->IsPresentL(iInfo)){ rdsIniFile.OpenLC(*cdIniFile, iInfo); TPtr8 buf((TUint8*)ptr, size); TRAP(r, rdsIniFile.ReadL(buf)); CleanupStack::PopAndDestroy(); // rdsIniFile result = ETrue; } CleanupStack::PopAndDestroy( 2 ); // fs, cdIniFile return result; }
TBool CMegajoyAppUi::CheckIniFile(TUid iInfo){ TBool result = EFalse; RFs fs; fs.Connect(); CleanupClosePushL( fs ); RDictionaryReadStream rdsIniFile; CDictionaryStore *cdIniFile = Application()->OpenIniFileLC(fs); result = cdIniFile->IsPresentL(iInfo); CleanupStack::PopAndDestroy( 2 ); // fs, cdIniFile return result; }
void CMegajoyAppUi::WriteIniFile(TUid iInfo, void *ptr, TUint size){ TInt r; RFs fs; fs.Connect(); CleanupClosePushL( fs ); RDictionaryWriteStream rdsIniFile; CDictionaryStore *cdIniFile = Application()->OpenIniFileLC(fs); rdsIniFile.AssignLC(*cdIniFile, iInfo); TPtr8 buf((TUint8*)ptr, size, size); TRAP(r, rdsIniFile.WriteL(buf)); rdsIniFile.CommitL(); CleanupStack::PopAndDestroy(); cdIniFile->CommitL(); CleanupStack::PopAndDestroy( 2 ); }
void CMegajoyAppUi::RemoveIniData(TUid iInfo){ RFs fs; fs.Connect(); CleanupClosePushL( fs ); RDictionaryWriteStream rdsIniFile; CDictionaryStore *cdIniFile = Application()->OpenIniFileLC(fs); cdIniFile->Remove(iInfo); cdIniFile->CommitL(); CleanupStack::PopAndDestroy( 2 ); }
|
可见,接口的实现也分为两部分
virtual void FlipBackBuffer(void)=0;
virtual void BitBlt(TInt iBltType, CExtendedBitmap &iBitmap, const TPoint &aPosition)=0;
这两个接口属于界面的更新,AppUi直接调用iAppContainer中的函数进行消息的传递,而其它几个数据保存、读取、删除的操作都是在AppUi本地完成。
而下面的用户接口消息(按键、菜单等操作)则直接传递消息给iMainEngine进行处理:
TKeyResponse CMegajoyAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) { if(iMainEngine) return iMainEngine->DoKeyEvent(aKeyEvent, aType); return EKeyWasNotConsumed; } void CMegajoyAppUi::HandleCommandL(TInt aCommand) { switch ( aCommand ) { case EAknSoftkeyOk: iMainEngine->ExternalEvent(EVT_SELECT); break; case EAknSoftkeyBack: iMainEngine->ExternalEvent(EVT_ESCAPE); break; case EEikCmdExit: iMainEngine->ForceQuit(); Exit(); break; default: break; } }
|
分享到:
相关推荐
【标题】"S60 V3塞班软件合集软件.rar"所指的是一份针对塞班S60 V3平台的软件集合压缩包。这个标题告诉我们,这个压缩文件里面包含了一系列适用于诺基亚等手机品牌的塞班S60第三版(Series 60 3rd Edition)操作系统...
诺基亚塞班智能手机sisx,java软件.rar这个压缩包文件包含了专为诺基亚塞班(Symbian)系统设计的应用程序集合。诺基亚塞班操作系统是曾经广泛使用的智能手机平台,尤其在2000年代中期至晚期,它在移动设备市场占据着...
Symbian S60 V3软件Symbian S60 V3软件Symbian S60 V3软件Symbian S60 V3软件Symbian S60 V3软件Symbian S60 V3软件Symbian S60 V3软件Symbian S60 V3软件打包下载 我佛痴悲 石祖江Symbian S60 V3软件打包下载 我佛...
塞班(Symbian)是一种经典的智能手机操作系统,曾经在2000年代至2010年代初广泛应用于诺基亚等品牌的手机中。它以其强大的功能和开放性吸引了大量的开发者为其开发应用程序。在塞班系统上,为了确保软件的安全性和...
Symbian塞班软件破解入门资料,新手值得一看~
Symbian S60 V3软件打包下载Symbian S60 V3软件打包下载Symbian S60 V3软件打包下载Symbian S60 V3软件打包下载Symbian S60 V3软件打包下载Symbian S60 V3软件打包下载Symbian S60 V3软件打包下载Symbian S60 V3软件...
【Symbian塞班软件开发工程师培训班实施方案】 随着信息技术的快速发展,Symbian操作系统作为曾经在智能手机领域的主导者,曾引领了移动开发的热潮。本文将深入探讨Symbian平台的开发现状、ASD(Accredited Symbian...
在移动操作系统的历史中,塞班(Symbian)曾是智能手机领域的主导者,尤其在2000年至2010年间,它为诺基亚等品牌提供了强大的操作系统支持。然而,随着Android和iOS的崛起,塞班的市场份额逐渐下滑,官方对开发者的...
"Symbian塞班软件开发工程师培训班实施方案" 本文档主要介绍了Symbian塞班软件开发工程师培训班实施方案的整个项目计划,包括市场需求、人才缺口、薪资待遇、认证考试等方面的分析和讨论。 1. 市场需求方面,随着...
《Symbian OS:线程编程中文版》是针对Symbian操作系统进行深入探讨的一份技术文档,尤其聚焦于线程编程这一核心概念。Symbian OS曾是智能手机领域广泛使用的实时操作系统,尤其是在诺基亚等早期智能手机中占据主导...
诺基亚非智能手机,只能使用jar软件,但是在导入手机证书后就可以使用签名软件(软件设置里--“总是允许”可以选择),使用这时先安装JAVA环境,然后用JAR处理器对jar软件进行处理(不处理,可能会无法生成JAD文件)...
须安装py平台,想提取源代码可以用sis编辑器解包。。
SYMBIAN OS C++ 高效编程教程
塞班S60软件汉化工具Zlrsc-V3.5是专为塞班系统(Symbian S60)设计的一款本地化工具,旨在帮助用户将非中文版的应用程序转化为中文界面,使得广大中国用户能够更加方便地使用这些软件。Zlrsc是一款功能强大的汉化...
在标题中提到的“塞班s60v1和v2软件游戏sis解压工具”是指针对这类sis文件的专业解压工具,它们允许用户在电脑上预处理sis文件,以便更方便地将内容转移到手机上。这种工具的主要作用是对sis文件进行拆分和提取,...
塞班手机万用加密软件 ET私密锁是一款强力软件私密加密工具,软件使用前加密,不管是你的名片夹,通讯记录,短信,照片,音乐,多媒体资料,文件管理,程序管理,记事本,备忘录,包括第三方软件,游戏,充分做到物...
《Symbian OS C++ 高效编程》与《Symbian OS Explained》是两本专注于Symbian操作系统开发的书籍,它们为开发者提供了深入理解Symbian OS架构、API以及C++高效编程技巧的重要资源。源码的提供使得读者能够通过实际...
Symbian塞班操作系统作为曾经占据主导地位的手机操作系统,尽管已被Android和iOS等现代平台所取代,但在过去的岁月里,它在手机市场的影响力不容忽视。本文主要讨论的是针对Symbian平台的软件开发工程师的培训方案,...