完整文档下载地址http://www.cppblog.com/Files/franksunny/RNotifier.7z
如何在S60非UI框架程序中弹提示信息
在非依赖于UI的S60程序中,也就是不建立在控件环境基础上的程序,比如控制台应用程序,独立的线程等。在这些程序中需要弹提示信息的时候,就不能直接用基于CCoeControl的任何UI类了,因为这些程序中没有供养CCoeControl生存的CCoeEnv环境,当然不嫌繁琐,在程序的main函数中像自己创建活动规划器一样去创建CCoeEnv环境也是一个可行的方法,但是这超出本文的涉及范围,本文提出的是不创建CCoeEnv环境情况下,通过RNotifier或RNotifier的派生类来实现弹提示信息。
RNotifier简单应用
其实RNotifier和RFs一样都是派生自RSessionBase,所以使用起来也是类似的,下面给出一个最简单的例子代码
RNotifier vNotifier;
User::LeaveIfError(vNotifier.Connect());
CleanupClosePushL(vNotifier);
//title and context
TBuf<256> title;
TBuf<256> context;
title.Copy(_L("info"));
context.Copy(_L("data"));
// Button text
_LIT(KYesButton, "Yes");
_LIT(KNoButton, "No");
// Display the dialog
TInt button;
TRequestStatus status;
vNotifier.Notify(title, context, KYesButton, KNoButton, button, status);
User::WaitForRequest(status);
// destroy notifier
CleanupStack::PopAndDestroy();
运行上述代码可以得到如下的对话框提示
RNotifier本身和RFs是基于Symbian OS的,而非专属于S60平台的,所以在UIQ等平台上继续可以使用RNotifier,这在跨平台开发上相当的便利,省去了移植的苦恼。
RNotify复杂应用
上面例子代码是最简单的一种RNotifier的应用,为了开发的方便和提高开发效率,S60封装了一套CAknGlobal*和RAknKeyLock等的类供第三方开发者使用,由于在UIQ平台上我没有涉及过,而且目前借助S60的开源代码,我就拿一个S60中的相关类CAknGlobalConfirmationQuery来说明下吧,在源代码sf\mw\classicui\uifw\AvKon\notifsrc路径下面有多个类似类的源代码。其实CAknGlobalConfirmationQuery除了二阶段构造外,最主要的就是ShowConfirmationQueryL、UpdateConfirmationQuery、CancelConfirmationQuery三个函数,这三个函数的代码罗列如下
/**
* Shows global Confirmation query synchronously
*
* @param aStatus TRequestStatus which will be completed when user
* selects one item from the list query.
* @param aPrompt Prompt text
* @param aSoftkeys Softkey resource
* @param aAnimation Animation resource
* @param aTone Tone id
* @param aDismissWithAllKeys If set ETrue the query gets dismissed with all
* keypresses
*/
EXPORT_C void CAknGlobalConfirmationQuery::ShowConfirmationQueryL(
TRequestStatus& aStatus,
const TDesC& aPrompt,
TInt aSoftkeys,
TInt aAnimation,
const TDesC& aImageFile,
TInt aImageId,
TInt aImageMaskId,
CAknQueryDialog::TTone aTone,
TBool aDismissWithAllKeys )
{
delete iBuffer;
iBuffer = NULL;
iBuffer = CBufFlat::NewL(KBufferGranularity);
RBufWriteStream bufStream;
bufStream.Open(*iBuffer);
CleanupClosePushL(bufStream);
bufStream.WriteInt32L(KAKNNOTIFIERSIGNATURE);
if ( aDismissWithAllKeys )
{
bufStream.WriteInt8L( ETrue );
}
else
{
bufStream.WriteInt8L( EFalse );
}
bufStream.WriteInt32L(aSoftkeys);
bufStream.WriteInt32L(aAnimation);
bufStream.WriteInt16L(aImageId);
bufStream.WriteInt16L(aImageMaskId);
bufStream.WriteInt16L(aTone);
bufStream.WriteInt16L(aPrompt.Length());
bufStream << aPrompt;
bufStream.WriteInt16L(aImageFile.Length());
if (aImageFile.Length())
{
bufStream << aImageFile;
}
bufStream.WriteInt32L(iSkinsMajorId);
bufStream.WriteInt32L(iSkinsMinorId);
if (iAknSDData)
{
bufStream.WriteInt8L(ETrue);
bufStream << *iAknSDData;
}
else
{
bufStream.WriteInt8L(EFalse);
}
iBufferPtr.Set(iBuffer->Ptr(0));
iNotify.StartNotifierAndGetResponse(aStatus, KAknGlobalConfirmationQueryUid,
iBufferPtr, iResultBuf);
CleanupStack::PopAndDestroy(); // bufStream
}
该函数用于显示对话框。其主要的实现就是调用RNotifier的StartNotifierAndGetResponse函数。
EXPORT_C void CAknGlobalConfirmationQuery::UpdateConfirmationQuery( TInt aSoftkeys )
{
iSoftkeys = aSoftkeys;
iCmd = EAknUpdateGlobalQuery;
TPckgBuf<SAknNotifierPackage<SAknGlobalMsgQueryParams> > pckg;
pckg().iParamData.iCmd = iCmd;
pckg().iParamData.iSoftkeys = iSoftkeys;
TPckgBuf<TInt> ret;
iNotify.UpdateNotifier( KAknGlobalConfirmationQueryUid, pckg, ret);
}
该函数用于对话框产生后更新对话框,其功能就是使用函数RNotifier::UpdateNotifier。
EXPORT_C void CAknGlobalConfirmationQuery::CancelConfirmationQuery()
{
if (iBuffer)
{
iNotify.CancelNotifier(KAknGlobalConfirmationQueryUid);
delete iBuffer;
iBuffer = 0;
}
}
该函数用于对话框产生后程序取消对话框,其功能就是使用函数RNotifier::CancelNotifier。
RNotifier的实现跟踪
通过以上两个代码,我们差不多对RNotifier类的使用了解了,但是这个RNotifier到底是如何实现弹出一个对话框呢?
其实RNotifier的真正实现是通过Symbian OS的C/S架构来实现的,这个在文章开篇提到RNotifier和RFs一样派生自RSessionBase就已经埋下了伏笔。
RNotifier的源代码实现位于sf\os\kernelhwsrv\kernel\eka\euser\us_ksvr.cpp,这个代码中还有RChunk、RDevice和RHandleBase等等基础类的实现代码。
RNotifier的服务器类CNotifierServer和服务器会话通道类CNotifierSession以及相关的其他类则位于sf\os\kernelhwsrv\kernel\eka\ewsrv\ws_main.cpp中。这些类的声明则位于sf\os\kernelhwsrv\kernel\eka\include\twintnotifier.h文件中。
再深入进去,就会了解到RConsole类,这个类的声明位于sf\os\kernelhwsrv\kernel\eka\include\e32twin.h中,代码实现位于sf\os\kernelhwsrv\kernel\eka\ewsrv\co_cli.cpp中。搞了半天又遇到一个C/S架构,这个Client的Server是CWsServer,其通道为CWsSession,在CWsSession内最主要的类是CWsWindow,这几个类的声明位于sf\os\kernelhwsrv\kernel\eka\include\ws_std.h,而这几个类的实现代码则又绕回到sf\os\kernelhwsrv\kernel\eka\ewsrv\ws_main.cp中去了。
好了,自己暂时只能走到这一步了,上面只是简单给出一些源代码的路径,有兴趣的同学可以去一探究竟,我才疏学浅就只能点到为止了。
欢迎对其有更深入挖掘的同学能够发布新的小结,到时记得分享到我的邮箱frank.sunny@163.com,当然假如我文中有什么错误也希望能够告知我一下,谢谢。
posted on 2010-12-17 21:26
frank.sunny 阅读(1968)
评论(0) 编辑 收藏 引用 所属分类:
symbian 开发