鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 手机系统开发 > Symbian > >

Symbian 编程札记

来源:互联网 作者:佚名 时间:2015-09-25 05:49
1, 栈问题 栈空间不足或者栈被破坏,不仅能导致程序崩溃,还能造成系统自动重启.解决方案 1) 在.mmp中用 EPROCSTACKSIZE 增大栈空间。但是需注意,EPROCSTACKSIZE的有效范围是8k到80k,默认值8k,如果申明的栈空间超过这个范围,应用程序是无法运行的,连main
1, 栈问题
栈空间不足或者栈被破坏,不仅能导致程序崩溃,还能造成系统自动重启.解决方案
1) 在.mmp中用 EPROCSTACKSIZE 增大栈空间。但是需注意,EPROCSTACKSIZE的有效范围是8k到80k,默认值8k,如果申明的栈空间超过这个范围,应用程序是无法运行的,连main函数就进不了。
2) 正确使用栈,特别是CleanupStack. 比如如下错误就可能导致系统自动重启:
RSocketSrv socket.
socket.Connect();
CleanupClosePushL(socket);

....

CleanupStack::PopAndDestroy(2, &socket);

2,堆问题
如果应用程序new/malloc失败,多半都是堆空间不足造成的。解决方案是在.mmp中用 EPROCHEAPSIZE 申明堆空间大小(设定最小和最大值),默认大小是:最小4k,最大1M


3,Console问题
Symbian程序在设备上运行时,可以将调试信息输出到Console,只需要调用CConsole::Printf或者C的printf即可。实现该输出功能的程序,需要连接estlib.lib和euser.lib,但不能连接elibc.lib,否则,Console将无法显示。

4,C/C++混合编程
.cpp中定义的函数可以给.c使用,申明导出函数的.h文件,以及定义导出函数的.cpp文件中,函数的申明和实现必须包含在EXTERC中,如果只在.h中用了EXTERC而不在.cpp中用,那么连接的时候,将提示找不到函数定义。例如:
//exportfunc.h
#ifndef __EXPORT_FUNC_H__
#define __EXPORT_FUNC_H__

#ifdef __cplusplus
extern "C"
{
#endif

import void func();

#ifdef __cplusplus
}
#endif

#endif



//exportfunc.cpp
#ifdef __cplusplus
extern "C"
{
#endif

void func()
{
//implement code block
}

#ifdef __cplusplus
}
#endif


5,标准C/C++格式的主函数
Symbian程序主函数有其特殊的形式,但也可以申明成标准C/C++格式的主函数,如,下面标准C/C++主函数的其中一种格式:
int main(int argc, char *argv[])
{
//Statements block

return 0;
}
但连接该程序时,需要用到库ecrt0.lib。特别需要说明的时,在Symbian 9.2中的ecrt0.lib是有问题的,连接时,提示exit函数未定义,可以用PIPS的库libecrt0.lib代替。


6,Posix库的问题
Symbian 3rd开始支持部分Posix接口,支持Posix接口的库叫PIPS。


7,基本数据类型的转换(待续...)
TBuf
TDesC
char

8, 清除栈
清除栈不能滥用。一般来说,若当前函数异常返回后,已分配的内存无法被释放,这样的内存地址才需要加入清除栈,如在函数内部分配,释放的指针。
以LC结尾的系统函数,在返回前,它将返回值加入了清除栈,所以要记得将其从清除栈中弹出。
在非主线程以外的其他线程中使用清除栈,需要先用CtrapCleanup::NewL初始化清除栈,并在线程退出前释放。

9, 重载CAknDialog/CEikDialog的PreLayoutDynInitL时,需要首先调用ActivateL(), 否则,会造成系统崩溃。

10, 获得CAknAppUi/CEikAppUi的指针
在CAknView子类中直接用AppUi();
在CCoeContro子类中,用iEikonEnv->EikAppUi();

11, 可以同过重载Dialog的PreLayoutDynInitL或PostLayoutDynInitL实现动态创建控件/设置控件的内容,但通常都在函数PostLayoutDynInitL中实现,因为若在PreLayoutDynInitL实现的话,会导致Dialog在弹出时出现闪烁的现象。

12, 怎样给Dialog中的CEikEdwin添加Vertical Scrollbar
1) 在资源文件中,将CEikEdwinInclusiveSizeFixed添加到EDWIN的flags中,以便ScrollBar显示在CEidEdwin的内部;否则,显示在CEikEdwin外部,可能落在可视区域之外而在屏幕上无法看见。
2) 在Dialog中的PreLayoutDynInitL用static_cast(CEikEdwin*)(ControlOrNull(edwin_id)获取CEikEdwin的句柄,然后调用CreateScrollBarFrameL()(注: 创建ScrollBar)和ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::Eon)(注:显示ScrollBar)

13,在Dialog中显示Listbox
RESOURCE DIALOG r_tmp_dialog
{
buttons = R_AVKON_SOFTKEYS_OK_CANCEL;
flags = EEikDialogFlagWait | EEikDialogFillAppClientRect;
items =
{
DLG_LINE
{
type = EAknCtSingleGraphicListBox;
id = ETmpListBox; //The id of listbox
control = LISTBOX
{
flags = EAknListBoxMenuList;
}
}
}
}


14, 在View中创建Container时,一定要将对Container调用SetMopParent, 将其MopParent 设置成该View, 否则,container中的control可能会显示不正确,比如listbox的scrollbar, 在设备上可能显示不出来。

15, Listbox 在添加了item之后一定要调用HandleItemAdditionL, 删除文件之后一定要调用HandleItemRemovalL, 否则,listbox可能显示不正常,比如scrollbar显示不出来或无法隐藏等。

16, 改变CEikEditor的text颜色
CCharFormatLayer* formatLayer = CEikonEnv::NewDefaultCharFormatLayerL();
TFontSpec fontspec = LatinBold16()->FontSpecInTwips();
TCharFormat charFormat( fontspec.iTypeface.iName, fontspec.iHeight );
TCharFormatMask charFormatMask;

charFormat.iFontPresentation.iTextColor = KRgbBlack;
charFormatMask.SetAttrib(EAttColor);
   
charFormatMask.SetAttrib(EAttFontTypeface);
charFormatMask.SetAttrib(EAttFontHeight);

formatLayer->Sense(charFormat, charFormatMask);
formatLayer->SetL(charFormat, charFormatMask);
iEdwin->SetCharFormatLayer(formatLayer);


17, 将TTime以系统定义的格式输出
TBuf<64> string;
TTime time;
time.HomeTime();
time.FormatL(string, _L("%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%:3%+B"));


18, 手机按键声音
#include <aknsoundsystem.h>
#include <avkon.rsg>

a) Disable Key Sound
//load key sound map from resources and push it to the context stack
KeySounds()->->PushContextL( R_AVKON_SILENT_SKEY_LIST );

//tell server to use this context stack for processing sounds
KeySounds()->BringToForeground();
//lock this context to the foreground, other BringToForeground() calls
//will be ignored until ReleaseContext() is called
KeySounds()->LockContext();

b) Enable Key Sound
//release the locked context
KeySounds()->ReleaseContext();

//pop the pushed context from the context stack
KeySounds()->PopContext();

19, Load png
For OS 6.1 (SDK 1.X), see CMdaImageFileToBitmapUtility class;
For OS 7.0/8.0 (SDK 2.x) see CImageDecoder class.

20, 在Draw函数之外使用CWindowGc, 必须先调用ActivateGc(), 使用完毕后,调用DeactivateGc(), eg:
ActivateGc();
CWindowGc & gc = SystemGc();
gc.SetBrushStyle( CGraphicsContext::ENullBrush );
gc.Clear( Rect() );
DeactivateGc();

21, 修改窗口中控件的颜色
比如:文字颜色,背景色,Label边框色、文字颜色、背景色等。
CCoeControl::OverrideColor(EColorxxx, KRgbBlack);

22, CTrapClean & CScheduler
1) 默认情况下,系统会为.app和.exe建立cleanup stack。 但是,如果是子进程,或者线程,需要自己建立,并在退出前释放:如下:
CTrapCleanup *trapHandler = NULL;
if (User::TrapHandler() == NULL)
{
trapHandler = CTrapCleanup::New();
}
//Others codes
delete trapHandler;
如果cleanup stack已经存在,就不要再建立,否则,可能会出问题。
2)默认情况下,系统会为GUI程序建立Active Scheduler。 但是对于其他程序,如命令行程序, 线程,则需要自己建立,并在退出前释放:
ActiveScheduler *scheduler = NULL;
if (CActiveScheduler::Current() == NULL)
{
scheduler = new CActiveScheduler;
if (scheduler != NULL)
{
CActiveScheduler::Install(scheduler);
}
}

//Other codes;

if (scheduler)
{
ActiveScheduler::Install(NULL);
delete scheduler;
scheduler = NULL;
}

如果系统没有建立Active Scheduler, 且程序中又使用到了Active Object, 并不是一定会出问题。 但是若出问题,一般在在跟异步函数或活动对象相关的地方,比如在调用WaitForRequest时,或在调用异步函数时。

23,RChunk
多进程可以使用RChunk共享数据(注意用Semophore或Mutex等保护共享数据区)。S60 2nd不能有static型数据,也可以借助RChunk代替static数据。

24, 可以在TRAP中是用返回值
TRAPD(errCode, retVal = FunctionL());
但是,只有当errCode是KErrNone时,retVal才有意义。但是,不要对LC函数是用返回值,否则可能会出问题:
TRAP(errCode, retVal = FunctionLC()); //Will lead out some problems
但是可以用:
TRAP(errCode, FunctionLC()); //OK

25, Client-Server间可以传递指针,但是只能是描述符(descriptor)的指针,不能是普通的、自定义数据类型的指针。如果需要传递非描述符指针,需要用TPckg打包成描述符指针。
class TTmpDataType
{
......
};

typedef TPckg<TTmpDataType> TTmpDataPckg;
TTmpDataType iDataSend;
TTmpDataPckg iPckgSend(iDataSend);

//Client end;
Tany *p[KMaxMessageArguments];
p[0] = &iPckgSend;
SendReceive(iStatus, p);

//Server end;
TTmpDataType iDataRecv;
TTmpDataPckg iPckgRecv(iDataRecv);
iMessage.ReadL(iMessage.Ptr0(), &iPckgRecv); //iMessage is received message of RMessage

26, 在S60 3rd之前,库中不能有static型的数据,但是在dll中可以用Dll类实现与static数据类似的功能。
EXPORT_LIB int Open(...)
{
XXX_HANDLE * h = new XXX;
Dll::SetTsl(h); //Set the pointer to thread local storage, h is pointer to an allocated area to be used as thread local storeage.
}

EXPORT_LIB int Handle(...)
{
XXX_HANDLE * h;
h = Dll::Tsl();
h->YYYY(....);
}

EXPORT_LIB void Close(...)
{
Dll::SetTsl(NULL);
}


27, BaflUtils, 是RFs有用的工具集, 如判断file、directory是否存在,将路径名分割成目录名、文件名、盘符等。


28, System changes and network changes
1) RChangeNotifier is system change notifier, you will be notified the is system status changes, such as power supply, memory, time etc. all types of changes are defined in TChanges.

2) Network changes notifier is implemented as RConnection::AllInterfaceNotifier. When the connection goes up or down, that type of notifier wil be obtained. When the notifier is obtained, you can use RConnection::EnumerateConnections to get the number of current connections, if the number is 0, we can get the connection goes down; otherwise, the connection goes up.


29, Handle key event in view
Events framework of symbian are:

Window server send key or pointer events or some other special events to Symbian application, it calls one of a number of functions, according to the type of event. The application handles key event by calling CAknAppUi::HandleWsEventL,

For key events, CAknAppUi::HandleWsEventL calls CCoeControl::OfferKeyEventL() for each control on the control stack, beginning with the control at the top (position 0) until a control consumes it. If no control on the stack consumes the key event, the app UI's HandleKeyEventL() is called. Note that CCoeControl::OfferKeyEventL() is not called for controls whose ECoeStackFlagRefusesAllKeys flag is set.


1) Override member functions HandleKeyEventL and InputCapabilities in CAknAppUi/CAknViewAppUi derived class1
TCoeInputCapabilities CMyAppUi::InputCapabilities() const
{
return (TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ENavigation);
}

TKeyResponse CMyAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) {
TInt retVal = EKeyWasNotConsumed;
if (iView) //iViews is member of CAknView
{
CMyiew *pView = static_cast<CMyView *>(iView)
retVal = pView->HandleKeyEventL(aKeyEvent, aType); // HandleKeyEventL is member function of CMyiew which is derived from CAknView, but it is not member of CAknView
}

return retVal;
}


2) Handle key event in view
class CMyView : public CAknView
{

..........

TKeyResponse HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
TInt retVal = EKeyWasNotConsumed;

if (aType != EKeyEventDown)
{
return retVal
}

switch(aKeyEvent.iCode)
{
case:
..............
}

return retVal;
}
};
上一篇:Symbian OS 错误代码
下一篇:没有了
网友评论
<