如何在不基于视图的应用程序中传递命令行参数
说明:
可以使用如下方法:
CEikAppUi::ProcessCommandParametersL()
具体使用方式可以参考SDK中的帮助
如何调度基于DLL或EXE的任务
说明:
使用RScheduler类调度基于DLL或EXE的任务需要如下处理:
在模拟器上调度基于DLL的任务,需要完成:
//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对象
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的任务,可以如下处理:
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. }
详细描述
我们的程序会启动外部应用,但当程序返回时,本应有的键盘声音却丢失了。尽管启动的外部程序已綺关闭了。这里说的外部程序包括camera, video, messages, 及 agenda。只有当程序关闭再进入时才能听到按键声音。
概述
根据这个情况,应由CAknKeySoundSystem负责发声。它的BringToForeground()方法可以通知server客户端已回到前台中,这时context stack将用来处理声音。
这是在CAknAppUi中调用的:
void CAknAppUi::HandleForegroundEventL(TBool aForeground) { if (iKeySounds && aForeground) { iKeySounds->BringToForeground(); } CEikAppUi::HandleForegroundEventL(aForeground); }
当你使用Nokia论坛所提供的Utilizing External Application方法在应用程序间来回切换时,应该确定你调用了
CAknAppUi::HandleForegroundEventL(aForeground);
在你的重载中要完成HandleForegroundEventL()的调用,否则按键声音将丢失。
如:
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库
// 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。
// 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会话。
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)完成的,所有的结果(包括盘符、路径和文件名,以及扩展名)都可在给定的描述符中返回。
#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版,也应该可以在模拟器上进行流播放的调用调试)