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

从缺省堆中分配内存单元实现日程表监测

概述:
当日程表被其他程序添加、删除或修改后,某第三方程序可能需要知道这些变化。他们可能也想知道具体哪项日程当前被执行了。

下面的解决方案描述了如何通过在S60第二版中写下一个日程表监测DLL来完成上述需求,具体可查看关于Calendar Interim API的文档。


解决方案:
1)首先生成一个独立的日程表监测DLL,如通过CAgendaObs::NewL()方法从CAgnObserver派生的一个CAgendaObs对象。
下面的小实例演示了这样的情况:

Code:
CAgnObserver* CAgendaObs::CloneL()

    {

    if(!iClone)     // initial value (TBool) EFalse

        {

        // Log: Creating clone

        CAgendaObs* result = NewL();

        result->iClone = ETrue;

        return result;

        }    

    }

void CAgendaObs::StartObserving()

    {

    if(iClone)

        {

        //Log: Start observing

        }

    }

void CAgendaObs::StopObserving()

    {

    if(iClone)

        {

        // Log: Stop observing

        }

    }

void CAgendaObs::Send(TInt aFunction, CAgnEntry *aEntry)

    {

    if(iClone)

        {

        switch(aFunction)

            {

            case ENotifyAddEntry:

                // Entry added

                break;

            case ENotifyDeleteEntry:

                // Entry deleted

                break;

            case ENotifyUpdateEntry:

                // Entry updated

                break;

            case ENotifyAddTodoList:

                // ToDo entry added

                break;

            case ENotifyDeleteTodoList:

                // ToDo entry deleted

                break;

            case ENotifyUpdateTodoList:

                // ToDo entry updated

                break;

            default:

                // Unexpected command

                break;

            }

       }

    }

void CAgendaObs::Send(TInt aFunction, CAgnTodoList *aTodoList)

    {

    if(iClone)

        {

        switch(aFunction)

            {

            case ENotifyAddEntry:

                // Entry added

                break;

            case ENotifyDeleteEntry:

                // Entry deleted

                break;

            case ENotifyUpdateEntry:

                // Entry updated

                break;

            case ENotifyAddTodoList:

                // ToDo entry added

                break;

            case ENotifyDeleteTodoList:

                // ToDo entry deleted

                break;

            case ENotifyUpdateTodoList:

                // ToDo entry updated

                break;

            default:

                // Unexpected command

                break;

            }

        }

    }

void CAgendaObs::ExternalizeL(RWriteStream &aStream) const

    {

    //write your code here

    if(iClone)

        {

        // Log: ExternalizeL called

        }    

    //closing

    CAgnObserver::WriteEndMarkerL(aStream);

    }

void CAgendaObs::InternalizeL(RReadStream &aStream)

    {

    //write your code here

    if(iClone)

        {

        // Log: InternalizeL called

        }

    //closing

    CAgnObserver::ReadEndMarkerL(aStream);

    } 

// The NewL of the DLL, to be exported

EXPORT_C CAgendaObs* CAgendaObs::NewL()

    {

    CAgendaObs* self = new (ELeave) CAgendaObs();

    CleanupStack::PushL(self);

    self->ConstructL();

    CleanupStack::Pop(self);

    return self;

    }

2) In another application register the observer using the following code:

Code:
#ifdef __WINS__

_LIT(KObserverFile,"agendaobs.dll");

#else

_LIT(KObserverFile,"c:\\system\\libs\\agendaobs.dll");

#endif

_LIT(KAgendaFile,"c:\\system\\data\\calendar");

// In ConstructL:

    RAgendaServ *iServer = RAgendaServ::NewL();

    iServer->Connect();

    CAgendaObs* iObserver = CAgendaObs::NewL();

    CAgnEntryModel *iModel = CAgnEntryModel::NewL(this);

    iModel->SetServer(iServer);

    iModel->OpenL(KAgendaFile);

// Call this method to register the observer DLL

void CSomeAppUi::Register()

    {

    if(iModel)

        {

        iModel->RegisterObserverL(TFileName(KObserverFile), iObserver);

        }

    }

// Before exiting, unregister the DLL

void CAgendaAppAppUi::Unregister()

{

    if(iModel)

        {

        iModel->UnregisterObserverL(TFileName(KObserverFile));

        }

}

注意,在MMP文件中,监测DLL要使用0x10000135作为UID2才行。

使用CHWRMVibra类来启动/停止/查询设备震动的状态

详细描述:
CHWRMVibra类是在S60第三版才开始发布的,它提供了控制设备震动模块的能力。
我们需要的链接库为:WRMVibraClient.lib
链接头文件为:hwrmvibra.h

下列代码演示了如何获得震动状态:

Code:
iVibrate = CHWRMVibra::NewL(); 

CHWRMVibra::TVibraStatus iStatus = iVibrate->VibraStatus();


返回的值有:

Code:
EVibraStatusUnknown 

EVibraStatusNotAllowed

EVibraStatusStopped

EVibraStatusOn


下列代码演示了如何获取情景模式下的震动部分设置“

Code:
CHWRMVibra::TVibraModeState iState = iVibrate->VibraSettings();

返回值为:

Code:
EVibraModeUnknown  

EVibraModeON 

EVibraModeOFF

下列代码演示了如何启动震动,这时震动的设置必须是EVibraModeON。

Code:
iVibrate->StartVibraL(0,50);

第一个参数表示是持续的时间(微秒),如果是0值表明震动将持续到StopVibraL()被调用为止。

第二个参数表明强度值,它的范围是-100至100之间。

下面的代码演示了如何停止震动

Code:
iVibrate->StopVibraL();

如何获取设备当前情景模式

详细描述:
我们可以通过使用Profiles Engine Wrapper API来获取当前情景模式。

首先需要包含这两个头文件:

Code:
mproengengine.h
proengfactory.h

然后是链接库:

Code:
ProfileEngine.lib

再看下列演示代码:

Code:
MProEngEngine* engine = ProEngFactory::NewEngineLC();

TInt activeId( engine->ActiveProfileId() );

通过调用ActiveProfileId()我们可以获取如下返回值:

Code:
0 - General

1 - Silent

2 - Meeting

3 - Outdoor 

4 - Pager 

5 – Offline

如何在Avkon tabs中使用SVG图标

概述:
我们可以在Avkon tab group的每个tab中显示我们自己的SVG图标。这一情况下对SVG文件有一些限制,现在描述如下。

解决方案:
CAknTabGroup::AddTabL()可用来生成一个带自定义SVG图标的tab,只有图标的mask层(如alpha或transparency)呗使用来生成该图表,其他数据被忽略了。

举例来说,现在有一个白色SVG带有如下图案:白色背景上一个黑色椭圆。

Code:
<ellipse fill="#FFFFFF" stroke="#000000" stroke-width="5" cx="25" cy="25" rx="20" ry="20"/>

为了让椭圆显示在tab上,填充参数必须修改如下:

Code:
<ellipse fill="none" stroke="#000000" stroke-width="5" cx="25" cy="25" rx="20" ry="20"/>.

只有这样修改后,图片的mask才会出现黑色背景和白色椭圆,当该SVG被使用在tab icon上时,就会现实出黑色的椭圆,而其他图片的其他地方都是做透明处理了。

注意,当mask被用来生成icon时,无法在TAB上绘制有色的SVG。

如何同时建立GMS和GPRS连接

概述:
S60第三方程序可能需要在保持GSM通话时提供访问GPRS的能力。

解决方案:
S60设备按基于GSM通话时保持GPRS的能力,分为三个类型。

Class A
可以同时建立GPRS服务和GSM服务(语音,SMS),并同时使用这两者。
这样的设备现在包括S60第三版机型(Nokia N73/N80/N91/N93, Nokia E60/E61/E70等)

Class B
可以同时建立GPRS服务和GSM服务(语音,SMS),但只能一次使用一种服务。当进行GSM服务时(通话,短信),则GPRS服务将被暂停,直到GSM服务结束才自动继续下去。
大部分S60第二版机型都在此类中(Nokia N70, Nokia N90, Nokia 6680等)

Class C
只能建立GPRS服务或GMS服务(通话,短信)其中一种,如果要切换服务必须手动控制。

注意:
目前没有一个直接可操控的API来询问当前设置支持GPRS类的能力,大部分S60第三版机器3G(WCDMA)电话都归属于A类,有一个API可用来检查当前电话是否支持WCDMA,代码为:

Code:
    TBool isSupported = CFeatureDiscovery::IsFeatureSupportedL(KFeatureIdProtocolWcdma);

    if (isSupported)

        {

        // activate the service

        }

绘制动画图片

概述:
应用程序可以通过ICL(Image Converter Library)使用CImageDecoder类在自定义的UI控件中绘制动画图片,比如GIF动画图片。

解决方案:
ICL允许使用CImageDecoder::Convert()将动画图片(多帧)转换为CFbsBitmap位图机型显示,我们可以通过使用CImageDecoder::FrameCount()获得图片文件的帧数,通过CImageDecoder::FrameInfo(TInt aFrameNumber = 0)返回每帧的信息、

对每帧来说都要调用CImageDecoder::Convert(),这个转换是异步的。每次完成后,完成后将返回一个CFbsBitmap实例。

帧之间的时间间隔可以通过TFrameInfo类获得,通过这些信息,我们可以依次播放CFbsBitmap以产生动画效果。

注意:在S60 2nd中可以使用CPAlbImageViewerBasic来播放动画,但在第三版中已经去除了。

当程序通过HTTP进行下载时无法接通来电

详细描述:
当我们使用HTTP Client API通过GPRS下载内容时会造成来电无法接通。当我们在下载一个大文件室需要考虑到这样的问题,如果有可能的话应该将大文件分割为许多小模块进行下载,因为HTTP的

传输能力很低(HTTP头很大),这时开发者需要平衡传输效率和来电接通的问题。

打开WAP Push信息

创建日期:
在访问Smart Message(BIO)数据时有几种不同的方式,大多数信息类型中,信息内容是存放在附件中,我们可以通过新的附件管理示例(CMsvStore)来访问。


某些情况下,内容是存放在CMsvStore流中的,可以通过public stream UID来读取

(定义在pushentry.h)

Code:
/** UID for the WAP Push MTM. */

const TUid KUidMtmWapPush = {0x10009158};

/** UID for WAP Push SI messages. */

const TUid KUidWapPushMsgSI = {0x10009159};

/** UID for WAP Push SL messages. */

const TUid KUidWapPushMsgSL = {0x1000915A};

/** UID for WAP Push multipart messages. */

const TUid KUidWapPushMsgMultiPart = {0x1000915B};

/** UID for WAP Push unknown-type messages. */

const TUid KUidWapPushMsgUnknown = {0x1000915C};

从缺省堆中分配内存单元

描述:
一般来说内存单元是从当前线程堆中分配的,但有时无法这样做,特别当要分配的内存单元很大时。
我们可以生成一个新的堆,从它那里获取我们需要的内存单元,示例如下:

Code:
//Try to create a heap in a local chunk. 
//The minimum length of the heap is 10M and the maximum length is 20M

RHeap *pChunkHeap = UserHeap::ChunkHeap(NULL, 10000*1024, 20000*1024); 

if (RHeap)
{

    void *mallocBuffer = NULL;

    TInt size = 8000*1024;  //Try to allocate a 8M memory cell

    mallocBuffer = pChunkHeap->Alloc(size);

    if (mallocBuffer )
    {
         //... Use this memory cell ...
    }

}

当N93翻转屏幕时动态更新的CBA在多视图程序中无法显示的问题

描述:

如何产生:
肖像模式->View1->风景模式(设备翻转)->切换到View->肖像模式(设备翻转)->View2中的CBA动态更新
但无法显示

Code:
TKeyResponse Ctest1Container2::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
     if(aKeyEvent.iCode == EKeyOK)
     {
                  if(iCba == R_AVKON_SOFTKEYS_OPTIONS_BACK)
                  {

                            CEikButtonGroupContainer* cba = CEikButtonGroupContainer::Current();

                            cba->SetCommandSetL(R_AVKON_SOFTKEYS_CANCEL);

                            cba->MakeVisible(EFalse);  //Add this line to the source code

                            cba->DrawNow();

                            cba->MakeVisible(ETrue);   //Add this line to the source code

                            //CEikonEnv::Static()->InfoWinL(_L("info"), _L("hi"));

   

                             iCba = R_AVKON_SOFTKEYS_CANCEL;

                  }
                  else
                  {

                           CEikButtonGroupContainer* cba = CEikButtonGroupContainer::Current();

                           cba->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_BACK);             

                           cba->MakeVisible(EFalse); //Add this line to the source code

                           cba->DrawNow();

                           cba->MakeVisible(ETrue); //Add this line to the source code

                           //CEikonEnv::Static()->InfoWinL(_L("info"), _L("hi"));

  

                           iCba = R_AVKON_SOFTKEYS_OPTIONS_BACK;

                  }
                  return EKeyWasConsumed;
      }
      return EKeyWasNotConsumed;
}
当N93从肖像模式调整到风景模式时如何保持当前程序在前台工作
描述:

一般来说如果将N93的摄像头进行翻转操作,则当前程序会切换到后台,而摄像机程序会出现在前台。
但有时为了防止这样的情况发生,我们可以通过如下方式来操作:
Code:
MCoeForegroundObserver::HandleLosingForeground()
{
  const TUid KNativeCameraAppUID = { 0x101ffa86}; //The UID of the native camera application

  TUid id( KNativeCameraAppUID);

  TApaTaskList taskList( CEikonEnv::Static()->WsSession() );

  TApaTask task = taskList.FindApp( id ); 

  if ( task.Exists() )  //If the native camera application is running
  {

          RWsSession WsSession = CCoeEnv::Static()->WsSession();

          TWsEvent event;

          TInt ForegroundWinGroup = WsSession.GetFocusWindowGroup();

          if (task.WgId()==ForegroundWinGroup)   //If the native camera application is on the foreground
          {

               const TUid KCurrentAppUID = { 0x20004A79 }; //The UID of current runing application

               TUid thisid( KCurrentAppUID );

               TApaTaskList taskList1( CEikonEnv::Static()->WsSession() );

               TApaTask task1 = taskList1.FindApp( thisid );

               if ( task1.Exists() )
               {
                      task1.BringToForeground();
               }
          }
    }
}

浏览器控件API无法显示Flash内容

描述:
第三方程序使用Browder Control API,可以显示HTML内容,但如果页面包含有Flash动画,则无法被正确显示,如何配置才能显示出Flash内容呢?

解答:
当前Adobe的Flash播放插件只为Nokia应用程序设计(通过VendorID检测),对其他程序来说,调用插件将返回NULL。无论你使用Netscapge Plug-in API或Browser Control API时,都会出现这样的情况。

使用document handler拷贝或移动未被识别文件时发生的问题

创建日期:
当你使用CDocumentHandler::CopyL()或MoveL()或SilentMoveL()时,被操作文件MIME类型不在下表中的话,那目标文件夹将会是一个临时目录

Code:
• image/vnd.nokia.ota-bitmap

• image/x-ota-bitmap

• application/vnd.nokia.ringing-tone

• audio/*

• image/*

• video/*

• application/vnd.rn-realmedia

• application/sdp

当CDocumentHandler实例被删除后,那拷贝或移动的文件也将在临时目录中被删除,这可能会导致无意删除行为,特别是在移动文件时。


解决方案:
当使用CDocumentHandler进行拷贝或移动文件操作时,非上述列表类型文件是不推荐使用该方法的。
PathInfo类有个方法叫OthersPath()可用来返回一般内容的路径。

S60 3rd Edition和S60 3rd Edition, FP1中不同的浏览器UID

在启动S60第三版中启动web浏览器打开特定URL的方法无法在S60第三版, FP1设备上完成(如Nokia N95)

这是因为S60第三版设备(如N73)有两个浏览器:“服务”和“网络”

“服务”的UID为0x10008D39而“网络”的UID为 0x1020724D

在第三版FP1设备(如N95)上,只有一个浏览器,UID为0x10008D39

为了能在FP1设备上工作,你必须将0x1020724D转换为0x10008D39

Code:
const TUid KOSSBrowserUidValue = {0x10008D39};
如何确保scroll bar背景被正确绘制
详细描述:
==概述==
当你绘制一个控件(如list box, grid, editor等)时会需要使用scroll bar,但这时其背景可能会保持白色。这种情况一般发生在Container没有传递一个正确的对象(context-specific skin parameters)到它的子控件中造成的。完成container类的CCoeControl::MopSupplyObject()方法会帮助子控件拥有正确的皮肤绘制,并且保证控件和他们父类之间的对象链表设置正确。

更多信息可以参考SDK文档中的MObjectProvider和CCoeControl::SetMopParent()部分

==解决方案==
要正确绘制scroll bar的背景,需要如下:


'''首先'''在从CCoeControl派生的view class的构造函数中加入如下代码:
Code:
    CAknsBasicBackgroundControlContext* 

        iSkinContext = CAknsBasicBackgroundControlContext::NewL(

            KAknsIIDQsnBgAreaMainAppsGrid,

            iAvkonAppUi->ApplicationRect(),

            EFalse );
注意:当使用'KAknsIIDQsnBgAreaMainAppsGrid(skinID)时,为application提供全屏rect.

'''然后'''实现MopSupplyObject()如下:
Code:
    TTypeUid::Ptr CMyCustomGridAppView::MopSupplyObject( TTypeUid aId )

        {

        if( aId.iUid == MAknsControlContext::ETypeId && iSkinContext != NULL )

            {

            return MAknsControlContext::SupplyMopObject( aId, iSkinContext );

            }     

        return CCoeControl::MopSupplyObject( aId );

        }

如何定制一个list box

详细描述:
==概述==
开发者可能需要根据自己的需求定制一个list box,这个提供一个示例,从一个double style list box中去除dotted column line.


==解决方案==
我们需要重载list box的item drawer方法,下面这个示例定义了一个double number style list box.

Code:
class CDSListItemDrawer : public CFormattedCellListBoxItemDrawer

    {

public:

    CDSListItemDrawer( MTextListBoxModel* aTextListBoxModel, 

                       const CFont* aFont, 

                       CFormattedCellListBoxData* aFormattedCellData );                      

    void  DrawItemText( TInt aItemIndex, const TRect &aActualItemRect, 

                        TBool aItemIsCurrent, TBool aViewIsEmphasized, 

                        TBool aItemIsSelected) const;                       

    void SetColour( const TRgb& aTextForeground, 

                    const TRgb& aTextBackground,

                    const TRgb& aHighlightForeground, 

                    const TRgb& aHighlightBackground );

private: // data

    TRgb                        iTextForegroundColour;

    TRgb                        iTextBackgroundColour;

    TRgb                        iHighlightForegroundColour;

    TRgb                        iHighlightBackgroundColour;

    const CFont*                iPersistentFont;

    CFormattedCellListBoxData*  iCellData;

    TInt                        iScrollOffset;

    };

/*******************************************************************/

// A list box class whose only responsibility is to look after a CDSListItemDrawer.

class CDSListBox : public CAknDoubleNumberStyleListBox

    {

public:

    CDSListBox( const CFont* aFont, 

                CFormattedCellListBoxData* aFormattedCellListBoxData );

                

    void SetScrollFrame();

    void FindCellSize();    

protected:

    virtual void CreateItemDrawerL();

    virtual CListBoxView* MakeViewClassInstanceL();    

private:

    const CFont*                iFont;

    CFormattedCellListBoxData*  iFormattedCellListBoxData;

    };    

/****************************************************************/

The .cpp source file should have the following implementation.

CDSListItemDrawer::CDSListItemDrawer( MTextListBoxModel* aTextListBoxModel, 

                                      const CFont* aFont, 

                                      CFormattedCellListBoxData* aFormatedCellData )

: CFormattedCellListBoxItemDrawer( aTextListBoxModel, aFont, aFormatedCellData ), 

  iPersistentFont( aFont )

    {

    }

void CDSListItemDrawer::DrawItemText( TInt aItemIndex, 

                                      const TRect &aItemTextRect, 

                                      TBool aItemIsCurrent, 

                                      TBool aViewIsEmphasized, 

                                      TBool aItemIsSelected) const

    {

    Gc()->SetBrushStyle( CGraphicsContext::ESolidBrush );

    Gc()->SetBrushColor( KRgbWhite );

    Gc()->Clear( aItemTextRect );

    TPtrC itemText = iModel->ItemText( aItemIndex );

    TInt textLength = itemText.Length();

    TInt tabPosition1 = itemText.Locate( '\t' );

    TInt tabPosition2 = itemText.Mid(tabPosition1+1).Locate( '\t' );

    const CFont* font = Font( aItemIndex );

    Gc()->SetPenStyle( CGraphicsContext::ESolidPen );

    Gc()->SetBrushStyle( CGraphicsContext::ESolidBrush );    

    TRgb textColour;

    TRgb bgColour;

    if ( aItemIsCurrent )

        {

        textColour = iHighlightForegroundColour;

        bgColour = iHighlightBackgroundColour;

        }

    else

        {

        textColour = iTextForegroundColour;

        bgColour = iTextBackgroundColour;

        }        

    Gc()->UseFont( iPersistentFont );

    // Set the item's background.

    Gc()->SetBrushStyle( CGraphicsContext::ESolidBrush );

    Gc()->SetBrushColor( bgColour );

    Gc()->SetPenColor( textColour );  

    TRect textRect( TPoint( aItemTextRect.iTl.iX, (aItemTextRect.iTl.iY-10) ), 

                    aItemTextRect.iBr );

    textRect.iBr.iY -= aItemTextRect.Height() / 2;

    if ( !font )

       {

       font = CEikonEnv::Static()->LegendFont();

       }    

    Gc()->UseFont(font);    

    TInt baseline = ( textRect.iBr.iY 

                    - textRect.iTl.iY 

                    - font->HeightInPixels() ) / 2 + font->AscentInPixels();    

    Gc()->DrawText( itemText.Mid( 0,tabPosition1 ),

                    textRect, baseline-20, CGraphicsContext::ELeft);    

    Gc()->DrawText( itemText.Mid( tabPosition1+1, tabPosition2 - tabPosition1 ),

                    textRect, baseline, CGraphicsContext::ELeft, 0);                    

    font = CCoeEnv::Static()->NormalFont();    

    Gc()->UseFont(font);    

    textRect.Move( 0, aItemTextRect.Height() / 2 );

    baseline = ( textRect.iBr.iY 

               - textRect.iTl.iY 

               - font->HeightInPixels() ) / 2 + font->AscentInPixels();              

    Gc()->DrawText( itemText.Mid( tabPosition2,textLength-tabPosition2 ),

                    textRect, baseline, CGraphicsContext::ELeft, 1);

    }

void CDSListItemDrawer::SetColour( const TRgb& aTextForeground, 

                                   const TRgb& aTextBackground,

                                   const TRgb& aHighlightForeground,

                                   const TRgb& aHighlightBackground)

    {

    iTextForegroundColour = aTextForeground;

    iTextBackgroundColour = aTextBackground;

    iHighlightForegroundColour = aHighlightForeground;

    iHighlightBackgroundColour = aHighlightBackground;

    iBackColor = iTextBackgroundColour;

    }

CDSListBox::CDSListBox( const CFont* aFont, 

                        CFormattedCellListBoxData* aFormattedCellListBoxData )

    {

    iFont = aFont;

    iFormattedCellListBoxData=aFormattedCellListBoxData;

    }

void CDSListBox::CreateItemDrawerL()

    {

    iItemDrawer = new (ELeave) CDSListItemDrawer( 

        Model(),

        iFont,

        iFormattedCellListBoxData );

    }

CListBoxView* CDSListBox::MakeViewClassInstanceL()

    {

    return new (ELeave) CListBoxView();

    }

void CDSListBox::SetScrollFrame()

    {

    }

void CDSListBox::FindCellSize()

    {

    }

/******************************************************************/

The calling function from a CCoeControl should contain:

    SetExtentToWholeScreen();     // Drawing it to the whole screen

    iTextForegroundColour = KRgbGreen;

    iTextBackgroundColour = KRgbRed;

    iHighlightForegroundColour = KRgbWhite;

    iHighlightBackgroundColour = KRgbBlue;

    iListItems = new (ELeave) CDesC16ArrayFlat( 2 );    

    const CFont *font; 

    _LIT( KTextFont, "LatinBold13" );

    CFont* myFont;

    CFormattedCellListBoxData* myFormattedCellListBoxData;

    CGraphicsDevice* screenDevice = CEikonEnv::Static()->ScreenDevice();

    TFontSpec textFontSpec( KTextFont, 200 );

    screenDevice->GetNearestFontInTwips( myFont,textFontSpec );

    myFormattedCellListBoxData = CFormattedCellListBoxData::NewL();

    iListBox1 = new (ELeave) CDSListBox( myFont, myFormattedCellListBoxData );

    iListBox1->ConstructL( this, 0 );

    iListBox1->SetRect( TRect( 0, 0, 3000, 3000 ) );    

    CDSListItemDrawer* drawer = (CDSListItemDrawer*) iListBox1->View()->ItemDrawer();        

    drawer->SetColour( iTextForegroundColour, 

                       iTextBackgroundColour,

                       iHighlightForegroundColour,

                       iHighlightBackgroundColour );    

    CColumnListBoxData* columnData=CColumnListBoxData::NewL();

    columnData->SetControl( iListBox1 );

    TInt columnSize;

    columnData->ColumnWidthPixel( columnSize );

    _LIT( KListItemFormat, "%d\t%S\t%S" );

     _LIT( KName1, "Name11" );

    _LIT( KContactNo,"123" );

    _LIT( KName2,"Name22" );

    _LIT( KContactNo2,"789" );

    TBuf<40> item;

    MDesCArray* itemList = iListBox1->Model()->ItemTextArray();           

    CDesCArray* itemArray = (CDesCArray*) itemList;

    TBuf<30> NameBuf;

    TBuf<30> ConBuf;    

    // add first item in the array

    NameBuf.Copy( KName1 );

    ConBuf.Copy( KContactNo );

    TInt id = 1;

    item.Format( KListItemFormat, id, &NameBuf, &ConBuf );

    itemArray->AppendL( item );    

    // add second item in the array

    NameBuf.Zero();

    ConBuf.Zero();

    NameBuf.Copy( KName2 );

    ConBuf.Copy( KContactNo2 );

    item.Format( KListItemFormat, id, &NameBuf, &ConBuf );

    itemArray->AppendL( item );

    NameBuf.Zero();

    ConBuf.Zero();

    iListBox1->SetRect( TRect( TPoint( 0,0 ), 

                        TPoint( 20000, 20000 )) );            

    iListBox1->ActivateL();            

    iListBox1->HandleItemAdditionL();    

    DrawNow();

注意:这里仅仅是示例,没有包括完整代码。为了正确绘制,相应元素如text, icons, highlight等都需要计算正确,这些需要花一番工夫。

通过CVideoRecorderUtility录制更大尺寸视频

详细描述:
如果想要录制尺寸超过QCIF(176x144)的视频,那就要使用MPEG-4格式("video/mp4v-es")。

Code:
    _LIT8(KMimeTypeMPEG4VSPL3, "video/mp4v-es; profile-level-id=3");  
    // MPEG-4 Visual Simple Profile Level 3

    _LIT8(KMimeTypeMPEG4VSPL4, "video/mp4v-es; profile-level-id=4");  
    // MPEG-4 Visual Simple Profile Level 4

我们可以在支持MPEG-4 VSP Level4(Visual Simple Profile Level 4)的设备上捕捉到30fps的VGA(640x480)视频,大部分S60第三版手机至少都支持VSP Level 3,即CIF(352x288)30fps的视频。

如:

Code:
    iRecorder->OpenFileL( iFilename, 

                          iCameraHandle, 

                          iControllerUid,

                          iFormatUid, 

                          KMimeTypeMPEG4VSPL4, 

                          KMMFFourCCCodeAAC );


在MvruoOpenComplete回调函数中,capture size, frame rate以及bit rate应该在CVideoRecorderUtility::Prepare()前设置好,如下示例:

Code:
void CMyVideoRecorder::MvruoOpenComplete( TInt aError )

        {

        if( aError == KErrNone )

            {

            // instead of using TRAP_IGNORE, proper error checking should be done

            TRAP_IGNORE( iRecorder->SetVideoFrameSizeL( iResolution ));

            TRAP_IGNORE( iRecorder->SetVideoFrameRateL( iFps ));

            TRAP_IGNORE( iRecorder->SetVideoBitRateL( KMMFVariableVideoBitRate ));

            ...

            iRecorder->Prepare();

我们可以通过CCamera获得当前设备所支持最大的视频capture size和frame rate

Code:
    TInt sizeIndex = 0, rateIndex = 0;  

    iCamera->EnumerateVideoFrameSizes( iResolution, sizeIndex, CCamera::EFormatYUV420Planar );

    iCamera->EnumerateVideoFrameRates( iFps, rateIndex, CCamera::EFormatYUV420Planar, sizeIndex );
显示多行信息的询问对话框
详细描述:

下列代码演示了如何使用一个可以显示多行信息的询问对话框:
Code:
_LIT(KTxtApplicationName, "Application Title");

    HBufC* sMessage =

    StringLoader::LoadLC( R_MESSAGE );

    HBufC* sTitle = HBufC::NewLC( KTxtApplicationName().Length() );

    sTitle->Des().Append( KTxtApplicationName );     

    CAknMessageQueryDialog* dialog = new ( ELeave ) CAknMessageQueryDialog();

    CleanupStack::PushL( dialog );

    dialog->PrepareLC( R_AVKON_MESSAGE_QUERY_DIALOG ); 

    dialog->QueryHeading()->SetTextL( *sTitle );

    dialog->SetMessageTextL( *sMessage );

    dialog->RunLD();

    CleanupStack::Pop(); // dialog

    CleanupStack::PopAndDestroy(2); // sTitle, sMessage

要显示在对话框中的信息是从资源文件加载的,我们在.rss文件中需要有如下定义:
Code:
    #define qtn_message “First Line \nSecond Line”    

    RESOURCE TBUF r_message

       {

       buf = qtn_message;

       }

如何获取当前函数的名称

详细描述:
有时候debug时为了记录相关信息,我们需要知道当前函数的名称,这时可以通过__func__来获取。

Code:
    void LogFunctionName(const char* name)
    {
        RDebug::Printf("current function: %s\n", name);
    }

现在,我们可以通过如下语句打印出函数名:

Code:
    LogFunctionName(__func__);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值