Tuesday, May 02, 2006

Descriptors...

Section #1: Arrays

1. Dynamic Arrays


General fixed length array using a flat buffer
CArrayFixFlat<TElement>* fixflat;

// Construct array of TElement objects where the iData
// data member of each element contains "X0", "X1", etc
// Uses the AppendL() function to add the members
// and the [] operator to access elements.

fixflat = new (ELeave) CArrayFixFlat<TElement>(3);

TElement theElement;

_LIT(KFormat1,"X%u");
for (value = 0; value < 3; value++) {
theElement.iData.Format(KFormat1,value);
fixflat->AppendL(theElement);
}


NOTE: We didn't specify the size anywhere


// Show each element
for (forix = 0; forix < fixflat->Count(); forix++)
console->Printf(KCommonFormat4,&(*fixflat)[forix].iData);

// Insert Elements
fixflat->InsertL(0,theElement);

// Delete Elements
fixflat->Delete(1); // delete the 2nd
fixflat->Delete(2,2); // delete what are now the 3rd and 4th

fixflat->Compress(); // compress the array

// reset the array (i.e. empty it)
fixflat->Reset();


// Expand by constructing a new element at position 1.
// Extend the array.
//
// Note the use of the TElement default constructor
// in both cases

fixflat->ExpandL(1);
fixflat->ExtendL();


// Resize the array so that it only contains one element
fixflat->ResizeL(1);

// Resize so that it contains 3 elements. The two new elements are bit-wise copies
// of a TElement object constructed using its default constructor.
fixflat->ResizeL(3);

// Resize so that it contains 5 elements.
// The two new elements are bit-wise copies of the TElement object passed through
// the reference.

_LIT(KMsgXXX,"XXX");
theElement.iData = KMsgXXX;
fixflat->ResizeL(5,theElement);


// Reserve sufficient space to append another five elements.
// This function may leave if there is insufficient memory.
// NOTE: this does NOT increase the number of elements in the array.

fixflat->SetReserveL(5);

// We can now append five elements and be sure that no leave will occur.




ARRAYS OF POINTERS (to CBase derived objects)


CArrayPtrFlat<CElement>* ptrflat;
CElement* ptr;

// Construct an array of CElement objects each containing the text "First" "second" etc
// Uses the AppendL() function to add the members and the [] operator to access elements.

// Construction & initialization
ptrflat = new (ELeave) CArrayPtrFlat(16);

ptr = new (ELeave) CElement;
_LIT(KMsgFirstElement,"First Element");
ptr->SetTextL(KMsgFirstElement);
ptrflat->AppendL(ptr);


ptr = new (ELeave) CElement;
_LIT(KMsgSecondElement,"Second Element");
ptr->SetTextL(KMsgSecondElement);
ptrflat->AppendL(ptr);

// Insert an element at the beginning of the array.

ptr = new (ELeave) CElement;
_LIT(KMsgInsertedBeg,"Inserted @ beginning Element");
ptr->SetTextL(KMsgInsertedBeg);
ptrflat->InsertL(0,ptr);

// Show number of elements
console->Printf(KCommonFormat5,ptrflat->Count());

// Show each element
for (forix = 0; forix < ptrflat->Count(); forix++)
console->Printf(KCommonFormat4,((*ptrflat)[forix])->iBuf);

// Delete the last two elements from the array BUT
// first we must get a reference to those elements
// (pointers to CElement objects) otherwise
// the CElement objects are orphaned.

//
// Here, we destroy those CElement objects.
//
// There are two alternative ways of indexing into
// the array, using either At() or the [] operator

// NOTE that the code below could be compressed to:
//
// delete (*ptrflat)[ptrflat->Count()-1];
// delete (*ptrflat)[ptrflat->Count()-2];
// ptrflat->Delete(ptrflat->Count()-2,2);


// Make a change to the object pointed to by the first element in the array
_LIT(KMsgNewTextFirst,"New text for the first CElement");
_LIT(KMsgNewTextSecond,"New text for the second CElement");
(*ptrflat)[0]->SetTextL(KMsgNewTextFirst);
ptrflat->At(1)->SetTextL(KMsgNewTextSecond);

// Destroy all of the CElement objects and reset the array.
ptrflat->ResetAndDestroy();

// Delete the array
delete ptrflat;





2. Fixed Arrays

Section #2: Buffers And Strings

Multiple Views

One of the most fundamental kind of apps is the one which supports multiple views. Here we discuss the multipleviews example which comes as a part of Series60 Examples.

The general idea is explained in the previous post. Here is the gist of it. For supporting multiple views, the view class must derive from CAknView as it contains methods for switching as well as activating/decativing other views. However to draw to a view as well as have a view contain other controls, the view needs to be an instance of CCoeControl. These 2 approaches cannot be mixed aka we cannot have a view inheriting from both CCoeControl as well as CAknView as this leads to a diamond kinda hierarchy. So we have the concept of a view and a container.

A container is simply a holder for other controls which also knows how to draw itself. Note that this container is just like a view for normal(Single View) applications. Every view is inherited from CAknView while every container is derived from CCoeControl. A view holds a container.

Here is an overview of the classes used with intersting bits as comments...

1. The main class -- Multiviews.cpp

Class creates an instance of CMultiviewsApplication and returns it by casting to CApaApplication.


2. Document Class -- MultiViewsDocument.cpp

Derives from CAknDocument, which derives from UIKON root document class CEikDocument which itself derives from CApaDocument. Ditto as application.

3. UI Class -- MultiViewsUI

Derives from CAknViewAppUI, instead of CAknAppUI. Actually CAknAppUI is used in single paned applications while CAknViewAppUI, which inherits from CAknAppUI, is used for multiple views. The view class maintains a reference to views. In ConstructL(), the views are created, added to base class using AddViewL() and a default view is set via SetDefaultViewL().

4. View Classes -- CMultiViewsView*

Derives from CAknView

5. Container Classes -- CMultiViewsContainer*

Derives from CCoeControl...

=====================

TitBits:
An interesting titbit is the hierarchy of classes. An application class derives from CAknApplication, which further derives from CEikApplication. CEikApplication is the root application class for all UIKON applications. It provides interface to resource file and document. CEikApplication class is derived from CApaApplication which defines basic behavious for all applications. This model is followed verbatim for Documents also. The hierarchy for UI and Views is a bit different.

An interesting titbit about the 2 phase constructions:-
a) Ctor is the first phase of construction. IT CANNOT LEAVE
b) ConstructL() is the second phase. IT CAN LEAVE.

Another one...
We don't need to include complete headers. A forward reference is sufficient incase we need only one class.

Yet Another...
NewL DOES NOT PUTS the object on CLEANUP STACK
NewLC PUTS object on CLEANUP STACK
Also the ConstructL() func called in the second phase construction is private..

===============================

Adding one more view to the application


  1. Create new container header and src

  2. Create new view header and src

  3. Include view construction & initialization code in UI

  4. Fill in menu event handler

Friday, April 28, 2006

The Control and the view

I was struggling with thisproblem for last couple of days. The problem is that I want an application which supports multiple views and one of these views has a listbox. A control having a listbox will inherit from CCoeControl and override interesting operations whereas a control which is a view will inherit from CAknView, which contains methods for switching views etc.

The most obvois way out, aka making this view inherit from both CCoeControl and CAknView does not works. So I was struck with this problem for about a week.

I just finished checking out the multiviews exmaple and there I found a solution to this problem. The idea is to follow the view and container model. The view will inherit from CAknView while the container will inherit from CCoeControl.

WORKING
The UI will maintain a reference to the views. The views WILL INCLUDE the container. The container will inform view of the appropriate actions, the view will update the UI of the same, which will propogate these events to DOC.

BUGS
Was missing a call to AddToStackL() in the UI and the listbox wasn't processing arrow keys. However it was still processing clicks.

Friday, March 31, 2006

List Box Construction

Here is how we construct a list box


TInt flags( CEikListBox::EPopout | CEikListBox::ELeftDownInViewRect );
iListBox = new( ELeave ) CEikColumnListBox;
iListBox->ConstructL( this, flags );

iListBox->SetListBoxObserver( iHandler );
iListBox->SetBorder( TGulBorder::EShallowRaised );
iListBox->CreateScrollBarFrameL( ETrue );
iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(
CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );

// Creates list items
CDesCArray* textArray = iCoeEnv->ReadDesCArrayResourceL( resourceId );
iListBox->Model()->SetItemTextArray( textArray );
iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray );

// Sets pixel values of width.
TRect rect(TPoint(KAknExQueryListBoxRectPointX,
KAknExQueryListBoxRectPointY),
TSize(KAknExQueryListBoxRectWidth,
KAknExQueryListBoxRectHeight) );

CColumnListBoxData* columnData = iListBox->ItemDrawer()->ColumnData();
columnData->SetColumnWidthPixelL( KAknExQueryNameColumnIndex,
rect.Width() );
columnData->SetColumnWidthPixelL( KAknExQueryNameGapColumnIndex,
rect.Width() );

// Gets current number of list box items.
TInt numberOfItems( iListBox->Model()->NumberOfItems() );
// Gets new height of list box.
TInt height( iListBox->CalcHeightBasedOnNumOfItems( numberOfItems ) );
// If new height is less than defined height of list box
// sets new height to list box height.
if ( height < rect.Height() )
{
rect.SetHeight( height );
}

iListBox->SetRect( rect ); // Sets rectangle of list box.
ActivateL();

Simple Debugging Hints

1. iEikonEnv->InfoMsg(_L("Confirmation Query"));

Tuesday, March 28, 2006

Query Example

This example details various types of query dialogs. I will do following assignments on basis of this example.

1. Single view with a list control which is populated from file on the FS
2. Multiple view app from the scratch. Will keep adding views until it resemples the actual app.

The second part is in progress. I have an app with 2 views. The second view has a data query and the filled data appears on a label on 2nd view. It isn't the most optimized thingy but it works.

Here are some of the observations..

1. iCoeEnv->ReadResource() isn't working but I know how to make it.
2. If a .rsg file cannot be opened, it may be because the file has not been created in the first place because of errors in the file.
3. Compile error incase header uses a component without including the component's header. Error shows in corresponding .cpp file though.
4. "Illegal use of incomplete struct/union/class" error occurs if corresponding header isn't included.
5. "Undefined Symbol" error of some old function can be resolved by cleaning and rebuilding.
6. Buffers are used as literals. They are interchangeable.

Friday, December 09, 2005

Apps Running!!

Am able to sync the example apps to my Nokia 6600 using my BT Dongle. YAY!!
Life is going to be pretty hectic and interesting!!

Sunday, October 23, 2005

Using MS Visual Studio..

The problem with visual studio is that it isn't completely integrated with Symbian Kit. So here is a quick hack..


a) Go to the appropriate dir and type bldmake bldfiles This creates a file abld.bat from mmp file.

b) Type abld makefile vc6 . This will create the VC6 project of the same in the BUILD/ dir.

b) Load the appropriate project from BUILD/ directory

Thursday, June 09, 2005

Symbian IPC #2

In this article, we will focus on Symbian IPC again. The examples we'll focus on will be from the Fibonacci series. These examples illustrate the basic idea of an application engine and active objects.