深入SymbianOS
1. SymbianOS基于微内核模型,微内核模型被设计得尽可能小,通过服务器提供绝大多数的服务。
这里的服务器其实是一个独立的进程,服务器进程通过与客户端(通常是某个应用)建立通信提供服务。而这种通信通常由服务器提供的客户端方使用的类来封装实现的。
在许多情况下,服务器运行自己的进程,提供保护性和模块性。服务器和客户端总是运行在不同的线程上,很多异步函数也是在服务器中实现。
所有的服务器都是从CActive派生来的,它们都是活动对象.
在Symibian OS中所有的异步服务都是Server通过C/S架构来实现的。Client是利用Server提供的特定服务的程序,Server接受来至Client的请求消息并同步或异步的处理他们。C/S架构有如下的优点:
1,可扩展性
2,有效性:相同的Server可以服务多个Client。
3,安全性:Server和Client存在于单独的进程中,并且通过消息传递进行通信。具有错误行为Client不会使他的Server崩溃(但是,Server可以通过客户线程的句柄来是具有错误行为的Client产生严重错误)。
4,异步性:在服务器完成请求的时候使用AO机制来通知他的Client。通过AO来挂起线程而不是轮询请求的状态,SymbianOS减少了处理该请求的处理器周期,从而节约了电源,这对于移动设备来说是非常重要的。
2. 子会话.
每次打开会话时都需要消耗更多的内核资源.客户/服务器框架在现有会话功能上提供了子会话功能,这有效地解决了需要多个客户会话的功能。子会话比完全会话使用较小的开销,但在客户端的实现也更复杂。
子会话是一咱让客户与服务器进行通信,而不需要单个会话来表示每个客户端的,轻量级方法.
客户与服务器建立单个会话,然后为每个对象创建子会话,每个子会话和会话关联,借此进行实际的进程间通信.
子会话必须与父客户会话相关联,因此对于支持子会话的服务器,至少有两个客户端类:一个由RSessionBase派生的会话类,一个由RSubSessionBase派生的子会话类。典型的子会话类RFile,RSocket
3. 框架解析
AppUi的几个重要事件处理方法:
HandleWsEventL()用于处理窗口服务器传递的事件,它的作用使框架调用下面这些具体事件处理方法;
HandKeyEvent()用于处理用户按键事件(此函数在控件堆栈为空时调用,否则框架将会调用OfferKeyEventL函数);
HandleForegroundEventL()当应用程序切换到前台或从前台切换到后台时调用该函数,默认的实现可以处理键盘焦点的改变;
HandleSystemEventL()用于处理由窗口服务器生成的事件;
HandleApplicationSpecificEventL()用于处理自己定义的自定义事件。默认的实现可以处理颜色方案改变的通知;
HandleCommandL()用于处理用户选择的菜单项;
HandleSwitchOnEventL()用于处理像设备切换之类的特定切换事件;
HandleMessageReadyL()用于处理窗口服务器产生的消息事件。
在以上各函数处理事件中,除了第一个HandleWsEventL()函数外,其它函数默认都是纯虚函数,需要重载才能用。
设置全屏Symbian C++应用程序,有三种方法:
1、覆盖system panes
这个方法主要用在传统的view架构中,当view不是全屏时,可以通过调用CCoeControl::SetExtentToWholeScreen()方法来获取全屏,应该在MyView::ConstructL中调用ActivateL()之前调用。
当应用程序为skinned时是不推荐使用这个函数的(从Series60 2nd Edition向后,查看配置)。不管怎么说,全屏程序也不需要这个设置,因此这个应该不是问题:)
2、隐藏
MEikAppUiFactory* f = CEikonEnv::Static()->AppUiFactory();
iStatusPane = f->StatusPane();
iToolBar = f->ToolBar();
if( iToolBar )
iToolBar->MakeVisible( EFalse );
if( iStatusPane )
iStatusPane->MakeVisible( EFalse );
3、iContainer = CYourContainer::NewL(AppUi()->ApplicationRect(), *this);
这样控件将被全屏
http://www.cppblog.com/franksunny/archive/2007/09/21/32597.aspx
1.http://www.newlc.com/Symbian-OS-Error-Codes.html
2.avkon 0
传入listbox中的描述符的格式有错误。
3.eikon dialog 3
避免在资源文件枚举中使用保留的ID
From Forum Nokia Wiki
From Forum Nokia Technical Library
在定义MENU_ITEM的Command时不能使用0,0是保留给EEikCmdCanceled使用的。
DIALOG中的每项ID也不能是0,0被系统保留。
上面的枚举是很典型的,并且我们习惯定义枚举时从0开始,当用在资源文件中时很可能造成了很奇怪的错误,这种情况通常很难找到bug的原因。
对话框中的项ID如果使用了0会产生下面的Panic信息:“Eikon-Dialog 3”在这里3的意思是EEikDialogPanicFocusableLineWithIdZero。
4.setting item lis
http://wiki.forum.nokia.com/index.php/Setting_Item_List_panics
5. c:/resource/ErrRd
6. viewsrv 9
由于 在appui中重写了PrepareToExit(),但其中没有调用父类的PrepareToExit()
7.CTypefaceStore -14
CCoeEnv::Static()->ScreenDevice()->GetNearestFontInTwips和ReleaseFont必须成对出现.
8.Des16Align 18
when you pass strings to Format() you have to pass pointer to TdesC.
当函数返回 TPtrC(const unsigned short) 时,以TPtrC函数的返回值,不要使用const TDesC&
9.初学S60,常见问题记录
http://blog.163.com/henan_lujun/blog/static/19538333200943110110559/
10.ESock_Client 14 错误:为描述符无效的错误。
在模拟器一次发送30K时出现,真机没测试。
sock serv和客户程序是不同进程, 所以在给异步函数传递小描述符时, 客户程序函数还没有返回, 此时可能成功, 但是对大描述符, 失败的几率就很高。所以,给异步函数传参数时不要传局部变量。
11.系统控件new出来最后没有被删除,会报 CONE 8错误Environment found window server resources had not been freed。
12. EIKCTL 42
EIKCTL 42 panic (Invalid bitmap index in CColumnListBoxData::raw())
使用了系统的ListBox, 传入的格式化字符串不对,比如图片数组里只有两张图片,而传入了/t3 ,就会报这个错误.
这个表明绘制控件时出现无效的资源句柄,如bitmap等.
使用了系统的ListBox, 传入的格式化字符串不对,比如图片数组里只有两张图片,而传入了/t3 ,就会报这个错误.
这个表明绘制控件时出现无效的资源句柄,如bitmap等.
13.“存储已满”
可能是有大量内存泄露导致。比如在多次循环中都有泄露。
14. 新建一个ui工程,编译报This project does not support program "BUILD_HELP" for platform "WINSCW"。
这个问题在carbide从2.3升级到2.6后出现。
把 bld.inf 文件里面 gnumakefile ../help/build_help.mk 路径里面的正斜线改称反斜线。
16.编译v5真机时,提示 dll contains initialized writable data,
在mmp中添加 EPOCALLOWDLLDATA
17.内存泄露。
所有应用程序分配的资源必须在程序结束时清理干净。在模拟器上,使用 debug 编译生成,没有这么做会由 __UHEAP_MARKEND 宏产生一个严重错误。
因为 STDLIB's DLL 在线程本地存储(thread-local storage)中分配的数据(结构体 _reent)在环境被销毁时不会被自动清理,它必须由 STDLIB 的使用者进行清理(CloseSTDLIB())。
使用这个函数,应在工程中包含 reent.h 文件。
Because the data allocated in the thread-local storage for STDLIB's DLL (the _reent structure) is not automatically cleaned up when the environment is destroyed, it must be cleaned up by the user of STDLIB
The function to achieve this is CloseSTDLIB(). To use this function, file epoc32/include/libc/sys/reent.h should be included in the project. Call CloseSTDLIB() after the point at which it is known that code in STDLIB's DLL will no longer be called and its thread-local storage no longer needed.
#include <reent.h>
CloseSTDLIB();
1.socket模拟http请求cmwap下载一个4k的文件。
iSocket.RecvOneOrMore(iNetBuff,0,iStatus,iLen);
SetActive();
和异步回响之间返回推送页需要7-8秒,返回实际数据时需要4-5秒.
请求cmwap时设置EKeep_Alive,就可以在接收完推送页内容后继续发送请求而不用再连接socket。
若设置Close,则连续发送请求会返回 KErrEof
1.简单介绍下dll.
SymbianOS中的DLL主要有两类:共享库dll和多态dll.
共享库的扩展名是dll,它还要发布头文件.h和导入库.lib.
多态dll实现一个抽象接口.它可以具有.dll的扩展名,但通常会使用能够进一步表达dll本质的扩展名,如.app表示应用程序,.fep表示前端处理器,.mdl是一个识别器.
SymbianOS中,dll的大小会被进一步优化,以节省ROM,RAM空间.
如:不支持dll的按函数名查找,只使用按序号连接的方式;
在Windows平台,每个进程都有自己独立的DLL空间,不同进程装载同一个DLL,互相之间是独立的,只有在一个进程内,才是共享的。但是S60平台的设计是所有进程都共享同一个DLL空间.
2. "可修改全局数据" 指的是任何非常量的全局域变量或任何非常量的函数域静态变量,为了简略表示,Symbian通常将这类变量称为WSD,代表可写静态数据。
SymbianOS中的dll不支持可写的全局数据,或支持的不好.
原因(1)全局数据是使用地址,不是使用从指针得出的偏移量访问.可能会重定位.
(2)装载的同一个dll的不同的进程使用相同的地址访问dll的全局数据,可能会造成混乱.
(3)每个支持可写静态数据的dll都需要一个最小4k的chunk.
这些限制造成一些不方便,如singleton pattern.
3.在SymbianOS中的dll中可以使用的仅有的全局数据是:全局常量内建类型,或没有构造函数的类的全局常量数据.
以下的全局数据可以使用:const TInt K=6;const TUid KUid={0x0FFFFFFF};
以下的全局数据不可以使用:const TPoint KPoint(0,0);
在向ARM目标机器构建时可能会产生如下错误信息:
has initialised data 可能表示使用了静态类成员
has uninitialised data 可能表示使用了全局可修改变量或trivial类
可以到D:/Symbian/7.0s/Series60_v21_C/Epoc32/release/armi/urel/应用程序名.APP.map文件中查找。
__data_start__=. 和 __data_end__=. 之间的内容 has initialised data.
__bss_start__=. 和 __bss_end__=. 之间的内容 has uninitialised data.
4.SymbianOS提供了一种机制,线程局部存储(thread local storage,TLS),dll可以使用它基于每个线程管理可写的静态数据.该机制会在每个dll中为每个线程分配一个单独的可写的静态数据的机器字.对每个线程使用TLS进行全局静态数据访问是安全的,因为这避免了当DLL被载入到多个进程中时带来的复杂性.
TLS的关键是两个函数:
void Dll::SetTls(void*)
void* Dll::Tls()
出于扩展性考虑,通常会使用它存储 指向一个结构体或简单T类的指针, 而在其中封装所有的可写静态数据.
5.
http://blog.csdn.net/Beover1984/archive/2005/10/13/502785.aspx
http://developer.symbian.com/china/support/code_clinic/clinic_april2008/index.jsp
http://wzcd2004.blog.163.com/blog/static/27892442200926113544382/
6. C语言工程移植到Symbian OS上注意如下几点:
(1)、首先要考虑C语言和C++语言的混合编程问题,因为在UI层要以C++语言来设计,UI层中的代码无法被移植,必须结合平台上的UI设计方法来设计,而UI层中要实现的功能可以用C语言来实现,要考虑好哪些应该用C++来设计,哪些应该用C语言来设计,如果出现C语言中的代码调用C++中的代码(这种情况应该尽量避免),则该C语言的代码必须用C++来编译,用C++来编译的文件名最好以“CPP”为扩展名,在C++中引用C的代码是最好加上“extern “C” {}”.
2、在程序退出之前要调用CloseSTDLIB(),以释放所有缓冲,该函数在“reent.h”文件中;
3、在MMP文件中要加入“estlib.lib”,该LIB库是C标准语言的LIB库;
4、Symbian中的STDLIB并没有完全实现POSIX的全部标准,所以有些C库的函数要自己实现或用其它方法来替代;
5、在C语言工程中最好不要有可写的全局静态变量(Global Writeable Static Data),在有些手机版本中是不支持全局变量的,但可以有全局静态常量,对于全局指针常量注意要这样申明,例如:static const char* const,即要有两个“const”。如果有出现全局静态变量或静态常量,则在MMP文件中要加入“EPOCALLOWDLLDATA”标识,否则会出现编译错误。对于可写的全局静态变量有种处理方法是把所有全局变量放到一个STRUCT结构中,然后这个结构的指针用Dll::SetTls()和Dll::Tls()来存取,存在的问题是用C编译的代码中无法调用C++的这种方法,还有一种最笨的处理方法是把指针的值存入一个文件中;
6、在C++与C的交互接口中会存在如char*与TdesC之间的转换,可以这样转换,例如:
把TDesC转换成char*:
HBufC8* utf8TempText = HBufC8::NewLC(STRING_LENGTH);
TPtr8 utf8Text(utf8TempText->Des());
CnvUtfConverter::ConvertFromUnicodeToUtf8(utf8Text,TDesCString);
Char* cString = (char*)utf8Text.Ptr();
把char*转换成TPtr:
TPtr8 utf8Text((TText8*)cString,strlen(cString),strlen(cString));
HBufC* ucs2TempText = HBufC::NewLC(utf8Text.Length()*2);
TPtr ucs2Text(ucs2TempText->Des());
CnvUtfConverter::ConvertToUnicodeFromUtf8(ucs2Text,utf8Text);
1.当函数内返回的类型是一个TPtrC时,函数的返回类型也要写成TPtrC,不要使用const TDesC&。
1. %s,%S
格式化描述符时,使用%S,参数是描述符的地址.
buf.Format(_L("%S"),&aDesC);
buf.Format(_L("%s"),aDesC.Ptr());
TInt 用%d , TInt64是long long型的,用%LD
2.unicode,utf8
EscapeUtils
CnvUtfConverter
CCnvCharacterSetConverter
3.
转换成char串
char* p = (char *)buf8.Ptr();
从char串转换
char* cc = "aaaa";
TPtrC8 a;
a.Set( (const TUint8*)cc , strlen(cc) );
4.能得到类的构造参数,就可以转换了。
TChar ch=buf[0];
更多描述符转换
http://www.cppblog.com/franksunny/archive/2007/11/28/37469.aspx
5.
TBuf8 buf;
const char* str=(const char*)buf.Ptr();
结果,在str中因为缺少一个结束符,导致这样使用会出错。
要用内存拷贝来实现
const char* CStringUtil::TransformTDes8ToConstChar( const TDesC8 &src)
{
char *str = new char[src.Length() + 1];
memcpy(str, src.Ptr(), src.Length());
str[src.Length()] = 0;
return str;
}
在代码中使用printf,也可能会有内存泄露。
6. 有的是未验证过的,或使用量少的。
1.对TPtr或TPtrC的赋值不会重定向指针,要达到这个目的必须使用Set().
2.使用operate[]遍历代价是昂贵的,考虑使用c++指针算法和TDesC::Ptr()来代替。
3.HBufC也可以作为动态缓冲区来运用,但其不够灵活,在HBufC::ReAlloc调用以后,要重新将指向其的指针定位。SymbianC++封装的动态缓冲区类CBufFlat、CBufSeg和RBuf,这几个类可以解决以上问题。
1.SymbianOS是基于客户/服务架构的,高度异步的操作系统,它提供一些运行于独立进程的服务,具有高度的可靠性.
多数情况下,应用程序只使用到OS本身提供的某些系统功能.
服务器API提供的函数一般有同步和异步版本,为了避免一些耗时的操作阻塞应用程序的接口,一般使用异步版本.
2.异步函数将iStatus的值设为KRequestPending后立即返回,它们在后台的单独线程中执行,这样与调用程序并行执行,当异步函数执行完后,向调用程序发送一个事件,然后一般去执行回调函数,若调用程序未执行完毕,则回调函数要等调用程序执行完才被执行.
3.调用程序使用User::WaitForRequest()来等待调用线程拥有的请求信号量被通知,即阻塞调用程序,来等待异步函数完成。
4.为了方便允许应用程序发布多个异步请求,并且在任何当前请求完成时获得通知,SymbianOS提供了一个支持框架:通过实现两种类型的对象来完成协作式多任务
(1)用于等待循环的活动规划器--每个线程一个活动规划器(提供的静态函数总是引用当前活动规划器)
(2)用于每个任务的活动对象--该对象封装异步请求及对象的处理函数.
5.活动对象是调用异步函数的类,它封装了异步服务请求,通过回调来处理异步函数的完成.它是一种处理实现类似多线程工作方式的机制.
6.使用活动对象的线程包含多个活动对象和一个活动调度器CActiveScheduler。调度器实现一个事件循环,它等待线程的请求信号量。当接收到某个事件时,会调用该事件所属活动对象的RunL方法。在Gui应用程序中,使用活动对象的线程已经安装了一个活动调度器。
7.活动调度器的等待循环及其活动对象的RunL方法被调用,都在同一线程中发生,实现了所谓的非抢占式多任务处理。
8.游离的信号异常,即调度器得到信号量通知,却未找到一个符合要求的活动对象来处理事件。
9.函数Cancel()检查活动对象是否有未完成的请求,如果有,就调用覆盖的函数DoCancel(),如果没有,就不调用。当DoCancel()方法退出后,Cancel()方法会调用User::WaitForRequest()方法(把信号标记量减1),即销毁KErrCancel消息.
10.什么时候使用活动对象?
当需要使用到系统提供的异步服务 或需要当前回调函数执行完后才能执行另一个请求而使用时间等待异步时
这时需要使用活动对象来封装异步请求.
在多个异步函数中处理事件,或通过非抢占式方式实行多个线程,使用活动对象是最好的方式.
11.symbian里不是所有的异步函数都可以使用User::WaitForRequest转换为同步, 比如如果该函数的实现里又请求了异步函数, 它的实现在RunL里才提交对你的事件, 使用User::WaitForRequest阻碍了RunL的调用, 导致程序挂死, 无法正常运行.
可以使用CActiveScheduleWait来实现伪同步,该类内部共用了活动规划期的AO列表, 使用自己的事件循环队列, 唯一的问题是在退出时的表现不完美.
12.CActiveScheduler::Start();
.......
直接屏幕访问,DSA
1.Series60设备必须知道当前活动的应用程序的外部的状况,例如:需要得到电话或消息的通知。这需要额外的处理过程来管理设备屏幕,会导致重绘性能降低。
标准应用程序的重绘较少发生,然而对于图形密集型程序,如游戏,大量的重绘会出现更多的问题。
直接屏幕访问,Direct Screen Access,用于与窗口服务器一道工作,用来管理外部事件,并且在访问屏幕时提供更佳的性能。
从编程者角度看,唯一改变的就是图形上下文对象。
用Windows Sever在屏幕上绘图需要进行上下文切换,这会减慢了绘图速度。越过Windows Sever就
避免了上下文切换,这样就可以直接访问屏幕,即:直接绘图。
2.Symbian OS有三种直接绘图:
(1).创建并使用CFbsScreenDevice
CFbsScreenDevice 是一个图形设备,使用前需要为它创建一个CFbsBitGc图形描述表,它具有指向屏幕驱动器SCDV.DLL的地址。使用它绘图在屏幕上直接完成而不需要Windows Sever。Windows Sever不知道直接绘图绘图动作,别的窗口出现时直接绘图无法停止,从而有可能使屏幕杂乱。
(2).直接访问显存
获得显存地址,直接通过指针访问显存对屏幕进操作比CFbsScreenDevice方法快,但其性能会受设备驱动器
的影响。在某些设备中,屏幕会根据显存的变化自动更新,而另一些设备的绘图必须要去激活才行。
显存地址只对目标硬件有效,在模拟器中我们使用临时位图及其数据地址。
上面两种直接描画方法的一个共同的问题是窗口服务器不了解描画,因此它不能通知应用程序是否出现另一个窗口或者窗口组。 即使当应用程序失去焦点的时候得到一个事件,它们也不能停止直接描画,因为直接描画实在太快了,并且屏幕内容有可能被弄乱。 这可能发生在玩游戏的时候,突然有电话打进来的情况下。
(3).使用CdirectScreenAccess
CdirectScreenAccess是一种较为安全(会得到Windows Sever的通知)的直接访问屏幕的的方法,速度也较快。所以很多时候都推荐用CdirectScreenAccess。当另一个窗口出现在应用程序窗口上时,CDirectScreenAccess从窗口服务器取得一个事件来中断描画。 CDirectScreenAccess然后调用MDirectScreenAccess派生类的AbortNow方法,这个方法必须被应用程序重载以便中断描画。 为了防止屏幕被弄乱,窗口服务器直到中断描画事件被处理的时候才画重叠窗口。
3.为了保证平滑绘制,在绘制到直接屏幕访问所提供的图形上下文以前,也应使用双缓冲。
4.RDirectScreenAccess类代表直接屏幕访问服务器的客户端类
CDirectScreenAccess类通过为RDirectScreenAccess创建一个高优先级的活动对象“包装器”,隐藏了它的复杂性。
MDirectScreenAccess类是混合接口类,指定了用于停止和重启直接屏幕访问的函数。
下面的代码说明CDirectScreenAccess实例是如何构造的,以及直接描画支持是如何激活的。
iDrawer = CDirectScreenAccess::NewL(iEikonEnv->WsSession(), *iEikonEnv->ScreenDevice(), Window(), *this);
iEikonEnv->WsSession().Flush();
iDrawer->StartL();
iDrawer->ScreenDevice()->SetAutoUpdate(ETrue);
CDirectScreenAccess的NewL方法获得一个窗口服务器会话、CONE的图形设备、应用程序窗口和一个到MDirectedScreenAccess导出类的指针作为参数。 在CDirectScreenAccess::StartL被调用来激活直接描画支持之前,客户端窗口服务器缓冲应该溢出。 为了能自动更新屏幕,屏幕设备的SetAutoUpdate方法需要使用ETrue参数,否则gc draw指令不会在模拟器中立即显示,而是在下一次冲刷(Flush)视窗服务器时才显示。 当直接描画支持激活的时候,CDirectScreenAccess产生一个CFbsBitGc图形上下文,可以被应用程序用来在屏幕上绘画。
iDrawer->Gc()->BitBlt( TPoint(0,0), iBitmap );
1.最初设计SymbianOS时,异常还不是C++标准的一部分.
无论实际上是否有异常被抛出,异常处理都着实增加了编译出来的代码的大小,并增加了运行时存储器的开销.
由于这些原因,标准C++的异常处理并不适宜添加到SymbianOS中.
SymbianOS强调的是简洁的操作系统和客户代码,它的实现更轻量级,只适合于小型设备的约束.
在编译基于SymbianOS的代码时,编译器被显示地设定为禁止C++异常处理,所有使用try,catch,throw关键字的地方都被标记为错误.
2.每个TRAP都对可执行文件大小,及程序执行速度有影响,每次进入和退出TRAP宏都会导致内核执行调用,并且在运行时还要分配一个结构
体来保存异常退出发生时栈的内容.
这些因素使用得TRAP在为一种代价不菲的异常退出处理方案了,所以在代码中尽量少使用TRAP.
3.SymbianOS中的异常退出/陷阱方法与C++中的抛出/捕获处理相似:它使用的捕获装置TRAP类似于try,catch;异常退出时,调用
User::Leave()等,等同于throw.
4.严格的异常处理是SymbianOS保持稳定性的核心.
清除栈是这种方法的核心,它提供了一种方式来删除在其它情况下可能不再使用的数据.
二阶段构造保证构造方法不会异常退出.
5.传统上,函数通过返回状态码表明函数执行的结果.在SymbianOS中许多API使用该方法,但它不能满足稳定的用户体验,因为:返回码可能
不能包括所有的情况;调用函数可能不知道如何处理特殊的错误.
异常退出可引起函数的立即退出,它不能被忽略.进程沿着嵌套调用链向上持续进行,直到遇到陷阱.
异常退出即leave,是由于程序因在各种情况下调用了User::Leave()等函数而产生的。
6.TRAP宏。使用TRAP捕获会可能会Leave的函数。它接收leave码。Leave终止于TRAP。总是TRAP以L结尾的函数。
7.CleanupStack清除栈。如果函数发生异常退出,在该函数中压到清理栈上的每个指针,在该函数退出前,全部都被弹出并释放。清理栈在弹出栈顶元素之前,先要回收该元素所指向的内存空间,从而充分保证程序在执行过程中不会发生内存泄露。
清除栈解决的是自动变量指针分配内存后,程序异常退出,时的删除问题。
对于对象的一长串函数调用,清除栈工作的非常好。
8.二阶段构造的目的是:在构造一个局部堆变量时,防止在构造函数中成员分配失败后,导致本对象占用的空间没有机会删除。因为在堆上给这个对象分配空间,对象中的成员占用的空间也是在堆上。
9.CBase派生类不应作为自动变量在栈上分配。
1.继承于CBase的类的构造函数放在私有段中,而在传统的c++中它放在公有段中,这样做的原因是CBase类的对象必须放在堆上,避免在栈上生成它。
2.在析构函数中不要有带异常退出的代码。
比如,若在析构函数中使用
CleanupStack::PushL();
CleanupStack::PopAndDestroy();可能会报E32User-CBase 66错误。
1.控件环境CONE用于组成UI应用程序的部分程序框架,它提供了File服务器的永久句柄,用于帮助减少所需连接的File服务器会话数量.为了访问它,在View类的iCoeEnv成员上调用FsSession().
也可以通过在File服务器句柄上调用Connect()来连接到File服务器.
2. BaflUtils
Location: BAUTILS.H
Link against: bafl.lib
判断一个全路径文件是否存在 BaflUtils::FileExists()
得到系统驱动器 BaflUtils::GetSystemDrive()
3.
获取程序的安装路径:
TFileName aFullName = CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
TInt pos = aFullName.LocateReverse('//');
aFullName.SetLength(pos); //(pos+1 带'/')
获取程序的安装盘符:
把 LocateReverse 改为 Locate 就OK。
TInt pos = aFullName.Locate('//');
4.
http://hi.baidu.com/simbalg/blog/item/f5b74723dc44f74692580798.html
5. TFileMode 的含义。
6. RFs
也可以通过
TUint iAtt = 0;
TInt err = aRFs.Att(aPath, iAtt);
判断err是否== KErrNone判断文件是否存在.
Att函数可能应该访问普通目录不需要AllFiles权限。
7.安装完软件后,可能也不会出现 private/[uid]目录,因为打包时没有往其中打文件。需要主动创建private/[uid].
测试装在c盘也可以写e盘下的private/[uid]目录.
测试装在e盘也可以写c盘下的private/[uid]目录.
1.Symbian中颜色由TRgb类列表,TRgb是一个32位的值,分别使用8位表示Red,Green,Blue,另有8位备用。
Series60对于不同的制造商有高度的可定制性,可以更改用户界面的颜色方案,所以为了确保颜色与使用的调色板保持一致,需要使用宏AKN_LAF_COLOR()定义颜色,从调色板值列表中找出颜色值传入AKN_LAF_COLOR生成对应的TRgb颜色.
2.可用的颜色范围由两个因素决定:设备的物理显示能力(颜色数量)和 当前的显示模式TDisaplyMod(可用的色深)。
首先,显然显示模式下的数量不能超出设备的显示能力。
显示模式EColor4K 表示12位显示,212=4K种颜色
EClolor64K表示16位显示,216=64K种颜色
3.
1.窗口,window,是一种系统资源,由窗口服务器拥有.窗口提供了在屏幕上显示其控件的机制.
2.控件,control,是可以显示信息和接收用户输入的矩形屏幕区域,是用户界面中用户交互的基本元素.
控件继承自CCorControl
3.控件的分类
(1)预定义控件,自定义控件
(2)自主窗口控件,寄宿控件
自主窗口控件直接与窗口服务器管理的一个窗口关联,同时对维持整个窗口区负责.应用程序至少有一个自主窗口控件--应用程序视图.
寄宿控件只占据窗口的一部分,和其它控件共享窗口区域.它有一个父窗口,父窗口必须属于一个自主窗口控件.
(3)复合控件,简单控件
复合控件在其区域内包含并拥有其它控件;简单控件不包含其它控件.
4.寄宿控件总是一个复合控件的子控件;复合控件树的最终父控件必须是一个自主窗口控件,
5.使CCoeControl具有滚动条
若CCoeConrol里面添加了多个子控件,超过了一个屏幕显示的范围,CCoeConrol本身是不会滚动的,所以下面的控件就不能显示了,需要绑定一个CEikScrollBarFrame使之具有滚动条。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)