franksunny的个人技术空间
获得人生中的成功需要的专注与坚持不懈多过天才与机会。 ——C.W. Wendte

 完整文档下载地址http://www.cppblog.com/Files/franksunny/RNotifier.7z

如何在S60UI框架程序中弹提示信息

 

在非依赖于UIS60程序中,也就是不建立在控件环境基础上的程序,比如控制台应用程序,独立的线程等。在这些程序中需要弹提示信息的时候,就不能直接用基于CCoeControl的任何UI类了,因为这些程序中没有供养CCoeControl生存的CCoeEnv环境,当然不嫌繁琐,在程序的main函数中像自己创建活动规划器一样去创建CCoeEnv环境也是一个可行的方法,但是这超出本文的涉及范围,本文提出的是不创建CCoeEnv环境情况下,通过RNotifierRNotifier的派生类来实现弹提示信息。

RNotifier简单应用

其实RNotifierRFs一样都是派生自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除了二阶段构造外,最主要的就是ShowConfirmationQueryLUpdateConfirmationQueryCancelConfirmationQuery三个函数,这三个函数的代码罗列如下

        /**

        * 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

}

该函数用于显示对话框。其主要的实现就是调用RNotifierStartNotifierAndGetResponse函数。

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 OSC/S架构来实现的,这个在文章开篇提到RNotifierRFs一样派生自RSessionBase就已经埋下了伏笔。

RNotifier的源代码实现位于sf\os\kernelhwsrv\kernel\eka\euser\us_ksvr.cpp,这个代码中还有RChunkRDeviceRHandleBase等等基础类的实现代码。

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架构,这个ClientServerCWsServer,其通道为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 开发

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



常用链接

留言簿(13)

随笔分类

个人其它博客

基础知识链接

最新评论

阅读排行榜

评论排行榜