完整文檔下載地址http://m.shnenglu.com/Files/franksunny/RNotifier.7z
如何在S60非UI框架程序中彈提示信息
在非依賴于UI的S60程序中,也就是不建立在控件環(huán)境基礎上的程序,比如控制臺應用程序,獨立的線程等。在這些程序中需要彈提示信息的時候,就不能直接用基于CCoeControl的任何UI類了,因為這些程序中沒有供養(yǎng)CCoeControl生存的CCoeEnv環(huán)境,當然不嫌繁瑣,在程序的main函數(shù)中像自己創(chuàng)建活動規(guī)劃器一樣去創(chuàng)建CCoeEnv環(huán)境也是一個可行的方法,但是這超出本文的涉及范圍,本文提出的是不創(chuàng)建CCoeEnv環(huán)境情況下,通過RNotifier或RNotifier的派生類來實現(xiàn)彈提示信息。
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等平臺上繼續(xù)可以使用RNotifier,這在跨平臺開發(fā)上相當?shù)谋憷?,省去了移植的苦惱?/span>
RNotify復雜應用
上面例子代碼是最簡單的一種RNotifier的應用,為了開發(fā)的方便和提高開發(fā)效率,S60封裝了一套CAknGlobal*和RAknKeyLock等的類供第三方開發(fā)者使用,由于在UIQ平臺上我沒有涉及過,而且目前借助S60的開源代碼,我就拿一個S60中的相關(guān)類CAknGlobalConfirmationQuery來說明下吧,在源代碼sf\mw\classicui\uifw\AvKon\notifsrc路徑下面有多個類似類的源代碼。其實CAknGlobalConfirmationQuery除了二階段構(gòu)造外,最主要的就是ShowConfirmationQueryL、UpdateConfirmationQuery、CancelConfirmationQuery三個函數(shù),這三個函數(shù)的代碼羅列如下
/**
* 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
}
該函數(shù)用于顯示對話框。其主要的實現(xiàn)就是調(diào)用RNotifier的StartNotifierAndGetResponse函數(shù)。
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);
}
該函數(shù)用于對話框產(chǎn)生后更新對話框,其功能就是使用函數(shù)RNotifier::UpdateNotifier。
EXPORT_C void CAknGlobalConfirmationQuery::CancelConfirmationQuery()
{
if (iBuffer)
{
iNotify.CancelNotifier(KAknGlobalConfirmationQueryUid);
delete iBuffer;
iBuffer = 0;
}
}
該函數(shù)用于對話框產(chǎn)生后程序取消對話框,其功能就是使用函數(shù)RNotifier::CancelNotifier。
RNotifier的實現(xiàn)跟蹤
通過以上兩個代碼,我們差不多對RNotifier類的使用了解了,但是這個RNotifier到底是如何實現(xiàn)彈出一個對話框呢?
其實RNotifier的真正實現(xiàn)是通過Symbian OS的C/S架構(gòu)來實現(xiàn)的,這個在文章開篇提到RNotifier和RFs一樣派生自RSessionBase就已經(jīng)埋下了伏筆。
RNotifier的源代碼實現(xiàn)位于sf\os\kernelhwsrv\kernel\eka\euser\us_ksvr.cpp,這個代碼中還有RChunk、RDevice和RHandleBase等等基礎類的實現(xiàn)代碼。
RNotifier的服務器類CNotifierServer和服務器會話通道類CNotifierSession以及相關(guān)的其他類則位于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中,代碼實現(xiàn)位于sf\os\kernelhwsrv\kernel\eka\ewsrv\co_cli.cpp中。搞了半天又遇到一個C/S架構(gòu),這個Client的Server是CWsServer,其通道為CWsSession,在CWsSession內(nèi)最主要的類是CWsWindow,這幾個類的聲明位于sf\os\kernelhwsrv\kernel\eka\include\ws_std.h,而這幾個類的實現(xiàn)代碼則又繞回到sf\os\kernelhwsrv\kernel\eka\ewsrv\ws_main.cp中去了。
好了,自己暫時只能走到這一步了,上面只是簡單給出一些源代碼的路徑,有興趣的同學可以去一探究竟,我才疏學淺就只能點到為止了。
歡迎對其有更深入挖掘的同學能夠發(fā)布新的小結(jié),到時記得分享到我的郵箱frank.sunny@163.com,當然假如我文中有什么錯誤也希望能夠告知我一下,謝謝。
posted on 2010-12-17 21:26
frank.sunny 閱讀(2009)
評論(0) 編輯 收藏 引用 所屬分類:
symbian 開發(fā)