Nokia论坛技术资料Symbian解决方案-中文版(2)-转载

如何在不基于视图的应用程序中传递命令行参数

说明:
可以使用如下方法:
CEikAppUi::ProcessCommandParametersL()
具体使用方式可以参考SDK中的帮助
如何调度基于DLL或EXE的任务

说明:
使用RScheduler类调度基于DLL或EXE的任务需要如下处理:
在模拟器上调度基于DLL的任务,需要完成:

Code:
//MyDll.cpp
LOCAL_D TInt StartDLL(TAny* aParam)
    {
    CMyDll* self = new(ELeave) CMyDll;
    self->Test();
    return(KErrNone);
    }
TInt CMyDll::Test()
    {
    return KErrNone;
    }
EXPORT_C TThreadFunction ThreadFunction()
    {
    // Ordinal one export that returns the function
    // which extracts the pseudo-command line
    // under WINS, this is passed as thread data).
    return StartDLL;
    }
GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
    {
         return(KErrNone);
    }

传递到StartDLL中的参数按如下方法使用以便生成SCheduledTask对象

Code:
TFileName* fileName = reinterpret_cast<TFileName*>(aParam);
CcFileStore* store = CDirectFileStore::OpenLC(iFsSession, fileName, EFileRead);
RStoreReadStream instream;
instream.OpenLC(*store, store->Root());
// Get task count
TInt count = instream.ReadInt32L();
__ASSERT_ALWAYS(count > 0, Panic(ETaskExePanicNoScheduledTasks));
for (TInt i=0;i<count;i++)
    {
    CScheduledTask* task =
    CScheduledTask::NewLC(instream);
    }

在目标设备上调度基于EXE的任务,可以如下处理:

Code:
GLDEF_C TInt E32Main()
    {
    TBuf<256> cmd;
    RProcess().CommandLine(cmd);
    return Test(cmd);
    }
LOCAL_C TInt Test(TDesC& aTaskDataFile)
    {
    // Extract scheduled tasks as shown above.
    }
当focus返回程序时丢失按键声音的问题
说明:
详细描述

我们的程序会启动外部应用,但当程序返回时,本应有的键盘声音却丢失了。尽管启动的外部程序已綺关闭了。这里说的外部程序包括camera, video, messages, 及 agenda。只有当程序关闭再进入时才能听到按键声音。
概述
根据这个情况,应由CAknKeySoundSystem负责发声。它的BringToForeground()方法可以通知server客户端已回到前台中,这时context stack将用来处理声音。

这是在CAknAppUi中调用的:
Code:
void CAknAppUi::HandleForegroundEventL(TBool aForeground)
 {
  if (iKeySounds && aForeground)
     {
     iKeySounds->BringToForeground();
      }
  CEikAppUi::HandleForegroundEventL(aForeground);
 }
解决方案
当你使用Nokia论坛所提供的Utilizing External Application方法在应用程序间来回切换时,应该确定你调用了
CAknAppUi::HandleForegroundEventL(aForeground);
在你的重载中要完成HandleForegroundEventL()的调用,否则按键声音将丢失。
如:
Code:
void CMyViewAppUi::HandleForegroundEventL(TBool aForeground)
 {
CAknAppUi::HandleForegroundEventL(aForeground);
... // Application-specific code on Focus change
 }

设置全屏Symbian C++应用程序

说明:

详细描述

有几种不同的方式可以设置全屏程序

1、覆盖system panes

这个方法主要用在传统的view架构中,当view不是全屏时,可以通过调用CCoeControl::SetExtentToWholeScreen()方法来获取全屏。不过应该在MyView::ConstructL中调用ActivateL()之前调用。如下:

Code:

void CHelloWorldPlusAppView::ConstructL(const TRect& aRect) { // Create a window for this application view CreateWindowL(); // Set the window size SetRect(aRect); // This view is a full-screen view. SetExtentToWholeScreen(); // Activate the window, which makes it ready to be drawn ActivateL();}

当应用程序为skinned时是不推荐使用这个函数的(从Series60 2nd Edition向后,查看配置)。不管怎么说,全屏程序也不需要这个设置,因此这个应该不是问题:)

2、隐藏

status pane可通过在AppUi中设置进行隐藏:

Code:

#include <eikbtgpc.h> #include <avkon.rsg>StatusPane()->MakeVisible(EFalse);

Softkeys可以通过在AppUi进行如下设置来隐藏:

Cba()->MakeVisible(EFalse);

这将启动空softkeys,而确省的softkeys将不起任何作用。为了响应选项菜单和后退键,我们应该自己处理这些按键事件。可以通过处理HandleKeyEventL()方法来解决:

Code:

TKeyResponse CHelloWorldPlusAppUi::HandleKeyEventL( const TKeyEvent& aKeyEvent,TEventCode aType){ // Left or right softkey pressedif (aType==EEventKeyDown && (aKeyEvent.iScanCode == EStdKeyDevice0 || aKeyEvent.iScanCode == EStdKeyDevice1)) { Cba()->MakeVisible(ETrue);}else { Cba()->MakeVisible(EFalse); }} return EKeyWasNotConsumed;}

这样处理后,你将能看到全屏的程序

3、这里hoolee再提供一种方法就是

iContainer = CYourContainer::NewL(AppUi()->ApplicationRect(), *this);

这样你的控件将被全屏绘制:)

在16位descriptor和8位descriptor之间拷贝数据

说明:
详细描述

首先,我们应该包含utf.h头文件,并连接charconv.lib库

Code:
// Copy data from srcBuf16 to destBuf8 
CnvUtfConverter::ConvertFromUnicodeToUtf8(destBuf8, srcBuf16); 

// Copy data from srcBuf8 to destBuf16
CnvUtfConverter::ConvertToUnicodeFromUtf8(destBuf16,srcBuf8);

在在自己的进程中(没有UI)使用CFbsBitmap

说明:

详细描述

CFbsBitmap在一个自己完成的服务中给出KErrCouldNotConnect错误。

解决方案

CFbsBitmap需要连接到字体和位图服务上,在自己的进程中必须手工来完成这些操作。如你所说的自己的服务。

一个解决方法是连接到RWsSession,它负责联系到字体和位图服务。通常服务中并不需要也不能直接使用UI,所以RWsSession不是我们在这里所能使用的。

另一种方法连接字体和位图服务的方法是使用RFbsSession::Connect(),当关闭操作时,我们需要调用RFbsSession:Disconnect().

防止资源文件列表中出现保留的ID

说明:
一个MENU_ITEM的命令标识不能为0(因为这是专为EEikCmdCanceled所保留的)
而一个DIALOG的item其ID也不能为0(也是保留值)
通常这些我们设置枚举值时,一个最常见的错误就是设定开头值从0开始,这样错误很难发现。
一个对话框item的ID为0时将触发“Eikon-Dialog 3"错误,这里的3代表EEikDialogPanicFocusableLineWithIdZero错误。

处理打开HTTP会话时发生的异常

说明:
详细描述

如果Internet AP没有正确配置的话,则RHTTPSession::OpenL()会引发KErrNotFound错误。这可能是每个开发者在设备上运行该类使用HTTP AP所会遇到的一个问题。因为在模拟器上,OpenL()方法会使用默认的AP连接点配置。
解决的方法就是捕捉到错误并通知用户配置正确的Internet AP。

Code:
// Open RHTTPSession with default protocol ("HTTP/TCP")
TRAPD(err, iSession.OpenL());
if(err != KErrNone)
     {
    // Most common error; no access point configured, and
    // session creation leaves with KErrNotFound.
    _LIT(KErrMsg, "Cannot create session. Is internet access point configured?");
    _LIT(KExitingApp, "Exiting app.");
    CEikonEnv::Static()->InfoWinL(KErrMsg, KExitingApp);
    User::Leave(err);
    }

通过RConnection使用HTTP客户端API

说明:
如果你使用HTTP客户端API,那就无法选择特定的网络连接。因为缺省的解决方式是显示一个IAP对话框供用户选择。无论如何,我们可以使用一种更加友好的方式提供给用户。这就是通过RConnection来创建一个我们需要的连接。在这个连接上进行我们的HTTP会话。

Code:
User::LeaveIfError(iSocketServ.Connect());
User::LeaveIfError(iConnection.Open(iSocketServ));
iHttpSession.OpenL();

// Initiate connection
iConnection.Start(iStatus);

//...

RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo();
RStringPool pool = iHttpSession.StringPool();

// Attach to socket server
connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketServ, 
RHTTPSession::GetTable()), THTTPHdrVal(iSocketServ.Handle()));

// Attach to connection
TInt connPtr = REINTERPRET_CAST(TInt, &iConnection);
connInfo.SetPropertyL(pool.StringF(HTTP::EHttpSocketConnection, 
RHTTPSession::GetTable()), THTTPHdrVal(connPtr));

// Open transaction...
iHttpTrans = iHttpSession.OpenTransactionL(iUri, *this, 
pool.StringF(HTTP::EGET, RHTTPSession::GetTable()));
RHTTPHeaders hdr = iHttpTrans.Request().GetHeaderCollection();

//...

显示异常警告的訽因和错误码

说明:
如果你的程序生成一个异常警告,它将关闭程序,并显示一个提示框“Program closed:/n%S",这里%S就是你程序的名称。
如果要让模拟器或实际设备显示这个异常发生的訽因和错误代码。我们可以生成一个文件名为ErrRd的空文件(注意没有扩展名),将它放在C:\System\bootdata\中。
在设备上你可以使用一个文件管理器来生成这样的文件,如FExplorer
在模拟器上,你可以在你电脑上%EPOCROOT%\epoc32\wins[cw|b]\c\system\bootdata\下生成。
当该文件存在时,错误显示就会为“Program closed:/n%S/n%S %d”,这里第二个%S将被替换为错误訽因(如USER,KERN-EXEC等),而%d则为错误代码。
注意:这里的错误訽因和代码只显示在提示框中,而不会记录在这个errrd文件中。

如何得到程序路径

说明:
程序一般安装在手机内或存储卡内,下列代码允许程序动态生成其安装路径,当程序访问同目录下文件时可以使用。
这是通过CompleteWithAppPath(TDes& aFileName)完成的,所有的结果(包括盘符、路径和文件名,以及扩展名)都可在给定的描述符中返回。

Code:
#include <aknutils.h>    // for CompleteWithAppPath()
// aFileName parameter contains the name of the file to open,
// without any path information
void CSomeAppClass::OpenFileL(const TFileName& aFileName)
    {       
    TFileName fullPath(aFileName);
    // insert the full application path into the file name
    CompleteWithAppPath(fullPath); // from aknutils.h
    ... // (proceed to open the file)
    }

如,该应用程序安装在手机内存中,则下列代码:
_LIT(KDataFileName, “data.dat”);
OpenFileL(KDataFileName);
从C盘打开的文件可为:c:\system\apps\myapp\data.dat

如何在模拟器上调用RealPlayer播放流媒体

说明:
Series 60 SDK及其模拟器都没有包含RealPlayer,因此你无法调用RealPlayer来播放流媒体。
如果你知道RealPlayer的UID号,则在实际设备上可以通过
CAknView::ActivateViewL();来调用
你可以通过使用CDocumentHandler类来通知RealOnePlayer自动播放特定的.3gp媒体文件。不幸的是,模拟器上不支持这些。
(hoolee题外话:通过安装Helix的emulator版,也应该可以在模拟器上进行流播放的调用调试)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值