Downloadable code examples

HelloExeDll - EXEDLL example

Usual exe servers run on WINS can't have access to the system servers such as ECom, DBMS, Window server, etc. EXEDLL projects help to cope with this problem.

Generally, exe programs are used to implement servers or simple console programs. When you start an exe program on WINS, emulator launches in a very limited mode with the text console and almost no system services enabled. It might be sufficient for test programs, but makes it rather difficult to develop sophisticated exe servers.

To overcome the problem you can use the EXEDLL project target. It compiles into EXE for hardware environments and into DLL for WINS. It means that you can launch them from the fully loaded emulator. You can use the ExeLauncher for it.

Global Key Capture - capture key presses globally

You can capture key presses globally, when your application is not on screen or even from the invisible exe silently running in the background.

This demo is an ExeDll program that creates an invisible window and makes the Window server pass all the Left key presses to the program. You can run it on the emulator with the help of ExeLauncher

Global Long Key Capture - Capture long presses

RWindowGroup::CaptureKey function, demonstrated earlier does not allow for capturing long key presses. There is a similar function RWindowGroup::CaptureLongKey, however you cannot just use it instead the CaptureKey.

The trick is to call CaptureLongKey after the CaptureKey. The attached compilable example is an ExeDll that can be run on Emulator with the help of ExeLauncher

HelloWorld united. Single code base for S60 2nd and 3rd editions

The 3rd edition of Nokia's S60 platform is all cool and new, but there are a lot of older devices you would still like to support.

The introduction of platform security in the 3rd edition changed the internals of the system a lot. However, from the point of view of the regular application programmer, changes are not that big and are mostly related to the configuration-like issues. We have to rewrite the MMP file, declare couple of things differently, use different type of icons, etc. - a lot of small things that you just have to carefully do once. As the end result of these small differences you'll have two projects with a bit different structure, a bit different set of files and minor changes in the application code.

Universal HelloExeDll for S60 2nd and 3rd edition

ExeDlls are the targets for Symbian projects that make the projects compile into EXE for the hardware platform and into a special DLL, that can be launched as an EXE from the WINS emulator.

For S60 3rd edition EXEs can be started from the fully loaded emulator and some system interfaces have been changed. Universal HelloExeDll uses a bit of preprocessor magic and can be compiled both for S60 3rd and 2nd edition. On the 3rd edition the project will be built as an EXE; on the 2nd edition it will be built as a usual ExeDll - as an EXE for hardware and as a DLL for WINS.

Streaming Example

Compilable code example of using the Symbian Streaming API. Demonstrates how to store the whole object with the boolean, integer and descriptor data fields to and from stream.


// Let the data format be:
//
//
// Note, that when dealing with packaged data, we have to be careful about
// the concrete size in bytes. Descriptors will be saved using Symbian
// default format for descriptors. For TBool we use the default conversion
// to TInt
void CEmployee::ExternalizeL( RWriteStream &aStream ) const
{
// Write the used protocol version first
aStream << KEmployeeProtocolVersion;
aStream << static_cast ( iAge );
aStream << static_cast ( iFired );
aStream << static_cast ( iName->Length() );
aStream << *iName;
aStream << static_cast ( iSurname->Length() );
aStream << *iSurname;
}

Tip: protect both the RArray and its contents

Update: "new (ELeave) RStringArray" was missing the "ELeave" (thanks to Tote)

Lately I worked with the API that required passing the RPointerArray allocated on the heap so that ownership was passed to that API. It is quite a rare case, but demonstrates nicely how tricky the CleanupStack protection can sometimes be. Note the order of pushing to the cleanup stack. If CleanupClosePushL was called first and leave happened during the CleanupStack::PushL, memory leak would occur.


// Local Functions
typedef RPointerArray RStringArray;
...
HBufC* element1 = HBufC::NewLC( 10 );
HBufC* element2 = HBufC::NewLC( 20 );
RStringArray* array = new (ELeave) RStringArray;
// Protect the allocated heap mem
CleanupStack::PushL( array );
// Protect the kernel handle/array contents
CleanupClosePushL( *array );
array->AppendL( element1 );
array->AppendL( element2 );

CleanupStack::PopAndDestroy( array ); // Close the array
CleanupStack::PopAndDestroy( array ); // And free the heap mem
...

Preprocessing the incoming message

Start this code example (ready to install sis file included) and while the demo program is running all the incoming messages will be appended with the ".Changed" text.


For emulator trials, the demo program has an option to simulate the incoming message.

Creating contacts

Here is how you can programmatically create a new phonebook contact. This code example is the universal ExeDll – it can be compiled both for S60 2nd edition and for S60 3rd edition. Note that for 3rd edition the WriteUserData capability is needed to add the contact to the phonebook. If the program didn’t have this capability, the CPbkContactEngine::AddNewContactL would leave with KErrWrite.

Protecting the RPointerArray content against the leave – CleanupResetAndDestroyPushL

Every object allocated on the heap should be protected by pushing its pointer to the cleanup stack via CleanupStack::PushL. Kernel resources used by the R-objects like RPointerArray are protected via CleanupClosePushL.

Sometimes you’d like or have to protect all the RPointerArray content without pushing all the individual items to the cleanup stack. There are custom solutions for this purpose, but there is also a built-in facility – CleanupResetAndDestroyPushL. It is not well known and not widely used only because it is defined in a quite an unusual place - \epoc32\include\mmf\common\mmfcontrollerpluginresolver.h