Symbian开发杂记

1, Nokia PC Suite
    A tool connect Nokia's device with Windows PC.

2, elftran
2.1 Change file's capatilities
    elftran -capabilities <capatilities> <file>


3, Std File IO
After call fopen/fclose/fwrite... functions, system allocate data in the thread-local storage for STDLIB's DLL, and  it is not automatically cleaned up when the application is destroyed, it must be cleaned up by calling CloseSTDLIB() declared in epoc32/include/libc/sys/reent.h, and defined in estlib.lib. otherwise, system will report memory leak. and On the Emulator, in debug builds, failure to do this will cause a panic from the __UHEAP_MARKEND macro.

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,但不能连接libc.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的库libcrt0.lib代替。


6,Posix库的问题
P.I.P.S. Is POSIX on Symbian OS.
Inder to use posix interfaces, we should install pips sdk for building, and install pips package on device for running.
The pips sdk can be found at "http://developer.symbian.com/wiki/display/pub/P.I.P.S.", and pips package are released 3 version :
        For S60 2nd: pips_nokia_1_1_SS.SIS
        For S60 2nd: pips_nokia_1_2_SS.SIS
        For S60 3rd: pips_nokia_1_3_SS.SIS
we can find them on www.google.com

Nokia OpenC/C++ delivering an extensive range of standard C and C++ APIs, please refer to "http://www.forum.nokia.com/Resources_and_Information/Explore/Runtime_Platforms/Open_C_and_C++/" to get more information



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;
    }
};


http://www.newlc.com/topic-16547


30, unpack sis package
http://wiki.forum.nokia.com/index.php/How_to_unpack_.sis_file

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值