Symbian3/SDK/Source/GUID-0C814ED6-3F64-4E0E-9C47-654AEDADBA90.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 11 Jun 2010 12:39:03 +0100
changeset 8 ae94777fff8f
parent 7 51a74ef9ed63
child 13 48780e181b38
permissions -rw-r--r--
Week 23 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 2714, Bug 462.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-0C814ED6-3F64-4E0E-9C47-654AEDADBA90" xml:lang="en"><title>Going
Beyond Hello: A Tutorial for Symbian C++ Applications</title><shortdesc>This tutorial shows how you can extend that basic example to create
a small paint application, along the way learning more about the application
frameworks (e.g. defining menus, how to handle touch-screen events, drawing
to the screen etc.).</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>In the <xref href="GUID-301E5FAA-A1C3-4FD7-9D84-DAA61C66981B.dita">Symbian C++
Quick Start</xref> you learned how to create a basic example application using
Carbide.c++, and how to build and run it on the Windows emulator and on a
device.  </p>
<p><b>Comes with Code</b>: <xref href="http://developer.symbian.org/wiki/images/e/eb/HelloSymbianWorld_Example_Code.zip.dita">File:
HelloSymbianWorld Example Code.zip</xref></p>
<section id="GUID-14C6D367-D806-45F8-BC44-C5DBC78096D9">       <title> Application
Structure</title>       <p>Carbide.c++ offers two ways of exploring your project.
The traditional <b>Project Explorer</b> window, which can also be found in
Eclipse, lists the files belonging to the project in the same directory structure
as in the file system.  </p><p>The <b>Symbian Project Navigator</b> contains
the same contents, but displays them in a logical hierarchy according to <xref href="http://developer.symbian.org/wiki/index.php/Coding_Standards_and_Conventions.dita">Symbian
Conventions</xref>. </p><p> You might wonder why a basic "Hello World" application
contains so many files. The answer is straightforward - a much simpler Hello
World wouldn’t be a very good starting point for real-world applications.
 </p><p>Instead the wizard generates the project for a complete and readily
extensible application. The project separates code and data, and uses a form
of the <xref href="http://wiki.forum.nokia.com/index.php/Design_Patterns_in_Symbian.dita#http://wiki.forum.nokia.com/index.php/Design_Patterns_in_Symbian/Model-View-Control_Pattern">model
view controller pattern</xref> for structuring your code. The application
already reacts to system events and contains everything that is required for
localization. </p><p/><p><b>What are the directories of a project?</b><fig id="GUID-898488F8-5CF9-4A01-95F8-45E2C5D2E501">
<image href="GUID-FFC6F01E-15AB-43E6-90E8-0E42DA297AE9_d0e5124_href.png" placement="inline"/>
</fig></p><p/><b>\group</b><ul>
<li><p><b>bld.inf</b>: Component-definition file. This specifies the <codeph>mmp</codeph> files
that belong to your component, any shared header files that it exports, and
the default build targets (e.g. GCCE, WINSCW).</p><ul>
<li><p><codeph>Bld.inf</codeph> is used to generate the makefiles and <codeph>abld.bat</codeph> used
to build for the command-line (see <xref href="GUID-301E5FAA-A1C3-4FD7-9D84-DAA61C66981B.dita">Symbian
C++ Quick Start</xref>). </p></li>
<li><p>This file is the starting point when you want to import a Symbian C++
project into Carbide.c++, because it contains references to all executables
in your project (see the section on Importing Other Examples). </p></li>
</ul></li>
<li><p><b>HelloWorld.mmp</b>: Project-definition file. This specifies how
to build an executable (in this case <codeph>HelloWorld.exe</codeph>) in a
platform- and compiler-independent way. It contains information such as resource
files to be compiled, source files to include when compiling, and the libraries
to include when linking. </p></li>
<li><p><b>Icons_aif_scalable_dc.mk</b>: Makefile used to create the application's
icon from the <codeph>*.svg</codeph> file in the <codeph>/gfx</codeph> folder. </p></li>
</ul><p> </p><p><b>\src</b></p><ul>
<li><p> <b>HelloWorldApplication.cpp</b>: This file contains the entry point
for the EXE file (<codeph>E32Main()</codeph>) as well as the implementation
of the Application class (which provides some basic functionality for the
GUI framework). Normally this is "boilerplate" code and you do not need to
make any changes. </p></li>
<li><p><b>HelloWorldDocument.cpp</b>: This class is supposed to take care
of the persistent data model of your application and therefore provides some
functions to load and save <codeph>.ini</codeph> files. This mechanism is
disabled by default - for most applications you may treat this as "boilerplate"
code. </p></li>
<li><p><b>HelloWorldAppUi.cpp</b>: This is the main controller of your application.
It contains the logic for handling application-wide events (so you don’t have
to handle, for example, the exit event in every view). It owns all the views
that you use. </p></li>
<li><p><b>HelloWorldContainerView.cpp</b>: This is a kind of controller, which
is responsible for handling events and the UI elements of the currently visible
view. It’s not visible itself, but owns and manages the <i>Container</i> (below),
which corresponds to the view in the traditional model view controller pattern.</p></li>
<li><p><b>HelloWorldContainer.cpp</b>: Contains the UI elements that should
be displayed by the view. Therefore, the ContainerView and the Container usually
have a very strong relationship. </p></li>
</ul><p>During start-up, one class instance creates the next:</p><fig id="GUID-2A3EE3C2-3515-4217-BCB3-182A01936898">
<image href="GUID-AC3F5010-ECA6-4257-98B5-77FB26B4987F_d0e5230_href.png" placement="inline"/>
</fig><p/><p><b>\inc</b></p><ul>
<li><p><b>HelloWorldApplication.h</b>, <b>HelloWorldDocument.h</b>, <b>HelloWorldAppUi.h</b>, <b>HelloWorldContainerView.h</b>, <b>HelloWorldContainer.h</b>: Header files corresponding to each of the main source files above. </p></li>
<li><p><b>HelloWorld.hrh</b>: UIDs/identifiers for UI elements including views.
These are shared between the resource file definitions for UI elements and
the source code command handlers.</p></li>
<li><p><b>HelloWorld.pan</b>: Panic code and method definitions.</p></li>
</ul><p/><p><b>\data</b></p><ul>
<li><p><b>HelloWorld_reg.rss</b>: Contains registration information about
the application, such as its title.</p></li>
<li><p><b>HelloWorld.rss</b>: Main resource file. Contains additional information
about the application, as well as user interface and text resource definitions.
     </p></li>
<li><p><b>HelloWorld.loc</b>, <b>HelloWorld.l01</b>: Localization files. Strings
used by UI are defined in separate localization resource files. Each file
has the format <codeph>.lxx</codeph>, where <i>xx</i> is a language specific
numeric file extension - e.g. UK English is ‘01’, French ‘02’ and German ‘03’.
The <codeph>.loc</codeph> file is a kind of junction that <codeph>#includes</codeph> the
language specific files. The languages are compiled into separate resource
files (extension <codeph>.rxx</codeph>; the resource file for the current
language is loaded by the UI framework at runtime</p></li>
</ul><p/><p><b>\gfx</b></p><ul>
<li><p><b>list_icon.bmp</b>, <b>list_icon_mask.bmp</b>, <b>mark_icon.bmp</b>, <b>mark_icon_mask.bmp</b>:
Bitmap and bitmap masks. These are compiled into the MultiBitMap (<codeph>mbm</codeph>)
format for display in the application.</p></li>
<li><p> <b>qgn_menu_HelloWorld.svg</b>: SVG-T image that gets compiled into
the <codeph>HelloWorld_aif.mif</codeph> MultiImageFile (<codeph>mif</codeph>)
used for the application icon.</p></li>
</ul><p/><p><b>\sis</b></p><ul>
<li><p><b>HelloWorld.pkg</b>: Defines the contents that should be packaged
into the installable <codeph>.sis</codeph> file for the device. This includes
the executable as well as all resources required by the application (graphics
and so on).</p></li>
<li><p><b>HelloWorld.sis</b>: Compressed and self-contained installation file
for the device. Compiled based on the package file.     </p></li>
<li><p><b>HelloWorld.sisx</b>: <codeph>.sis</codeph> file which has been signed
with a certificate (in this case self-signed).</p></li>
</ul>     </section>
<section id="GUID-65BEDD17-334B-4C42-8D89-DAB355F97F51"><title> Extending
Hello World – Drawing</title><p>To make our application a little bit more
interactive, we are going to implement a simple paint tool, allowing the user
to draw lines by touching the screen.    </p><p>We could draw the lines directly
on the screen, but then everything would get lost when something caused our
application to redraw the screen – for example, a telephone call that came
through while our application was running. Therefore, we have to draw the
lines to a bitmap, which is simply copied to the screen whenever required.
  </p><p>Another solution (more difficult but also more flexible!) would be
to store all lines in a list and to iterate over the list each time the application
needs to draw the contents of the screen. </p></section>
<section id="GUID-217EFA6E-9B5F-4B65-8B99-E056CC26156D"><title> Using the
SDK Documentation</title><p>The class that can handle bitmap data is called <codeph>CFbsBitmap</codeph>.
Let’s take a look at the documentation for this class to find out more about
the required header files, libraries and available methods.    </p><p><xref href="http://developer.symbian.org/search/search_results.php?txtSearch=CFbsBitmap&amp;site=sdl_collection.dita">Search</xref> the
online documentation for the class you're interested in, in this case <codeph>CFbsBitmap</codeph>. <xref href="http://developer.symbian.org/main/documentation/reference/s%5E2/doc_source/reference/tb91sf-PP/fontandbitmapserver/index.html.dita">CFbsBitmap
in Os Font_and_Bitmap_Server</xref> should be (one of the) first topics you
find. </p><p/><note>If you're working offline you can also search for documentation
in the SDK. <b>Start</b> menu: <b>Start - S60 Developer Tools - 5th Edition
SDK, v<i>1.0</i> - SDK Documentation</b></note><p>Right at the top of the
reference page you will see that the header file we need to use is <codeph>FBS.H</codeph> and
the library we need to link against is called <codeph>fbscli.lib</codeph>. </p><fig id="GUID-23B3B7CF-E676-4FBC-8B26-E7B88764781C">
<image href="GUID-0B0EF90E-45A4-467F-8CD9-33FBC612B3BD_d0e5428_href.png" placement="inline"/>
</fig><p>This class is capable of storing a bitmap. It's also possible to
get direct access to the bitmap data. However for more convenient methods
of drawing we will work through a drawing device and context.    </p><p>To
find out more about bitmaps, contexts and drawing functions, <xref href="http://developer.symbian.org/search/search_results.php?txtSearch=bitmaps&amp;site=sdl_collection.dita">Search for ‘bitmaps’</xref> in the documentation, and go to the page <b>Bitmaps
in Using Bitmaps</b>, or <b>Using Bitmaps in Using Graphics Device Interfaces</b>.
   Symbian provides several different device and context classes. For our
application we’re going to use <codeph>CFbsBitmapDevice</codeph> (header file: <codeph>bitdev.h</codeph>,
library: <codeph>bitgdi.lib</codeph>) and <codeph>CFbsBitGc</codeph> (header
file: <codeph>bitstd.h</codeph>, library: <codeph>bitgdi.lib</codeph>). </p></section>
<section id="GUID-D9C51891-11DE-4042-AE32-CC7EA362C32A"><title> Adding Libraries
To a Project</title><p>In the previous step, we determined that we need two
libraries in order to use all three bitmap-related classes: <codeph>fbscli.lib</codeph> and <codeph>bitgdi.lib</codeph>.
To add them to our project, open the <codeph>HelloWorld.mmp</codeph> project
file (in the <codeph>/group/</codeph> folder if you’re using the <b>Project
Explorer</b> window). Switch to the <b>Libraries</b> tab.    At the top of
this page, you will see a list of included libraries. <codeph>fbscli.lib</codeph> is
already in the list, so we don’t need to add it. However <codeph>bitgdi.lib</codeph> is
missing. </p><note>There are more libraries in the list than are used by our
project (added by the wizard!). These cause no harm so we choose not to remove
them.</note><p>Click on the <b>Add</b> button. Search for <codeph>bitgdi.lib</codeph> in
the list and add it to the <b>Libraries</b> list. </p><fig id="GUID-7D1E15B4-5157-4F48-9084-6DDBD6EE0208">
<image href="GUID-E5FB2D04-D57E-4EEA-850F-40F813C75D8C_d0e5506_href.png" placement="inline"/>
</fig><p>When you’re finished, make sure that both libraries are in the <b>Libraries</b> list.
   </p><p>When you compile your application again, Carbide.c++ will detect
the changes in the .mmp file and ask you what to do. Click on <b>Compile and
Link</b> to update the project with the changes we have made to the <codeph>.mmp</codeph> file. <fig id="GUID-77F781CD-A2EF-4489-BAE2-EB283057670E">
<image href="GUID-10540A35-7E8E-40F0-BF93-CBC01884550C_d0e5523_href.png" placement="inline"/>
</fig></p></section>
<section id="GUID-F2A4FC0F-8C67-4151-8BD2-808FCEDD121F"><title> Creating Bitmaps</title><p>Now
the libraries have been added, we can use the bitmap classes in our project.
Open the file <codeph>HelloWorldContainer.h</codeph> and add the following
include statements: </p><codeblock xml:space="preserve">#include &lt;fbs.h&gt;
#include &lt;bitdev.h&gt;
#include &lt;bitstd.h&gt;
</codeblock><p>We also need to store the bitmap objects as instance (member)
variables. Add the following definitions to a private section of the <codeph>CHelloWorldContainer</codeph> class.
Be careful not to write anything into areas managed by the UI designer, because
your changes could be overwritten. These areas are marked by comments.   
 </p><codeblock xml:space="preserve">private:  
CFbsBitmap* iBitmap;  
CFbsBitmapDevice* iBmpDevice;  
CFbsBitGc* iBmpGc;   </codeblock><p>Symbian C++ uses some <xref href="http://developer.symbian.org/wiki/index.php/Coding_Standards_and_Conventions.dita#http://developer.symbian.org/wiki/index.php/Coding_Standards_and_Conventions/Naming_Conventions">naming conventions</xref>. Instance variables should have a lowercase <codeph>i</codeph> at
the beginning of the variable name (<codeph>iBitmap</codeph>). Arguments should
be marked by an a (<codeph>aBitmap</codeph>). Normal local variables that
you create inside a function do not need any prefix. That way, you instantly
know where the variable is coming from – this is very important when deleting
objects.    Next, we want to create the bitmap. Define and implement a new
method: </p><codeph>void CHelloWorldContainer::CreateBitmapsL()</codeph><p>Let’s
go line by line through the required code for this method:    First, we have
to make sure that any previous objects are deleted if they already exist.
This would be required (for example) if the running application needs to re-create
the bitmap because the screen layout changes. You don’t need to add an if
statement to check if the pointer is NULL beforehand – the C++ <codeph>delete</codeph> statement
only deletes the object if the pointer is not NULL. You do however need to
ensure that the objects are set to NULL after deletion to avoid possible "double
deletion" in the destructor. </p><codeblock xml:space="preserve">delete iBitmap; iBitmap = NULL;  
delete iBmpDevice; iBmpDevice = NULL;  
delete iBmpGc; iBmpGc = NULL;</codeblock><p>This following line of code should
look familiar – it simply creates an instance of the <codeph>CFbsBitmap</codeph> class:
     </p><p><codeph> iBitmap = new (ELeave) CFbsBitmap();</codeph>       </p><p>The
(<codeph>ELeave</codeph>) parameter is Symbian C++ specific. This causes a <xref href="http://developer.symbian.org/wiki/index.php/Leaves_%26_The_Cleanup_Stack_(Fundamentals_of_Symbian_C%2B%2B).dita"> leave</xref> (the
Symbian C++ equivalent of standard exceptions) if allocating the object fails
– for example, because there is not enough free memory. With the (<codeph>ELeave</codeph>),
you don’t have to manually check if the pointer is actually pointing to a
valid object after creating the object instance. You can find out more about
leaves in <xref href="http://developer.symbian.org/wiki/index.php/Fundamentals_of_Symbian_C%2B%2B.dita">Fundamentals
of C++</xref>.    </p><p>We do not handle the potential leave here; that’s
why the method name (<codeph>CreateBitmapL()</codeph>) has a trailing L to
show that it can also leave. More on this topic in a moment.    </p><p>Now,
it’s time to let the <codeph>CFbsBitmap</codeph> class allocate the memory
for the bitmap it is going to manage. The available drawing size for our container
can be queried by the method <codeph>Size()</codeph> from its base class. <codeph>EColor16MU</codeph> specifies
the color depth – in this case, it’s a true color display mode with 32 bits
per pixel; the top byte is unused. The color mode <codeph>EColor16MA</codeph> would
use the top byte for the alpha channel, several other modes are available
as well.   </p><p><codeph>iBitmap-&gt;Create(Size(), EColor16MU);</codeph>  
 </p><p>The next line creates a graphics device based on the bitmap. A graphics
device represents the medium being drawn to and is needed to create a graphics
context. The use of a <codeph>NewL()</codeph> method is common in Symbian
C++; it is a static factory function which returns a fully constructed object
of the desired type.   </p><p><codeph> iBmpDevice = CFbsBitmapDevice::NewL(iBitmap);</codeph> 
  </p><p>A graphics context provides a large number of drawing operations,
along with state settings defining how the drawing is performed. The bitmap
graphics context used here is a specialization of the generic graphics context
and adds some methods that can be used for bitmaps only – such as clearing
and copying rectangular areas.    </p><p><codeph>iBmpDevice-&gt;CreateContext(iBmpGc);</codeph> 
  </p><p>Whenever you create objects, it’s best to think about where and when
they are going to be deleted right away. Memory leaks are a serious issue
on a mobile device where no virtual memory is available and the main memory
is limited to 30-80 MB. Therefore, go to the destructor of <codeph>CHelloWorldContainer</codeph> and
add the required statements for deleting the three objects:      </p><p> <codeblock xml:space="preserve">delete iBmpGc;  
delete iBmpDevice;  
delete iBitmap;</codeblock>       </p><p>The next step addresses the remaining
question: where to call the <codeph>CreateBitmapsL()</codeph> method. Of course,
you could do this from the construction methods of the class. But what if,
while your application is running, the user physically turns the phone, causing
it to switch from portrait to landscape mode? Because the bitmap was created
with the portrait size in mind, the user would no longer be able to use the
full screen for drawing.    </p><p>Therefore, we have to react to events that
inform us when the screen size is changed. In those situations, <codeph>SizeChanged()</codeph> is
executed. When the container is first constructed, its size changes as well.
Because of this, we can simply call our <codeph>CreateBitmapsL()</codeph> method
from within <codeph>SizeChanged()</codeph>:       </p><p><codeblock xml:space="preserve">void CHelloWorldContainer::SizeChanged()  
	{  
	CCoeControl::SizeChanged();  
	LayoutControls();     
	// [[[ begin generated region: do not modify [Generated Contents]
	// ]]] end generated region [Generated Contents]
	if (!iBitmap || (iBitmap &amp;&amp; iBitmap-&gt;SizeInPixels() != Size()))
		{
		TRAPD(err, CreateBitmapsL());
		}
	}</codeblock>      </p><p>In the source code above, an additional check ensures
that the bitmap is only re-created if the size available for the container
is really different to the existing bitmap size – the <codeph>SizeChanged()</codeph> method
is also called, for example, when the option menu obscures part of our view.
This does not affect the available space for our drawing area and therefore
should not lead to re-creating the bitmap.    </p><p>But what is the <codeph>TRAPD()</codeph> statement
doing here? Let’s use this to take a closer look at the concept of leaves. </p><p/><p><b>Leaves</b></p><p>When
programming using Symbian C++, an L is appended to the name of methods that
can leave (usually because it contains other methods that can leave and does
not choose to "TRAP" them). Note: this is a helpful convention, but is not
checked or required by the compiler.    </p><p>Our <codeph>CreateBitmapsL()</codeph> method
contains two methods that can leave: the (<codeph>ELeave</codeph>) parameter
causes a leave if there is not enough memory to allocate the object. The <codeph>NewL()</codeph> method
from the graphics device also has a trailing <codeph>L</codeph> – meaning
that this method can also leave. We did not catch any (all) of those leaves
in the <codeph>CreateBitmapsL()</codeph> method so it was named with a trailing <codeph>L</codeph>.
   </p><p>Any leaves are passed up in the call stack until caught by a <codeph>TRAPD</codeph> macro.
The <codeph>SizeChanged()</codeph> method traps any leaves from <codeph>CreateBitmapsL()</codeph> and
consequently does <b>not</b> need to have a trailing <codeph>L</codeph>. 
  </p><p>The error code of the leave is stored in the err variable, which
is declared as a normal integer by this macro. It would be a good idea to
take a look at the contents of this variable and to handle errors instead
of ignoring them as we’re doing here. But for the sake of simplicity, we do
not handle any errors that might occur in this situation. </p><p/><p><b>Tip</b></p><p>A
good way to automatically check your code for potential problems is to use
the <i>CodeScanner</i> tool that comes with Carbide.c++. It is a static code-analysis
tool looking at Symbian coding rules and standards. Find out more at: <xref href="http://carbidehelp.nokia.com/help/topic/com.nokia.carbide.cpp.codescanner/html/codescanner.htm.dita">http://carbidehelp.nokia.com/help/topic/com.nokia.carbide.cpp.codescanner/html/codescanner.htm</xref></p></section>
<section id="GUID-7E4A9491-8F22-4D68-9890-95332D31412B"><title> Handling Touch
Events</title><p>Before we start handling the touch events, we need one more
instance variable in our code. To draw a line from one touch position to the
next, it’s necessary to save the first position. Therefore, add the following
private instance variable to <codeph>CHelloWorldContainer</codeph>: <codeblock xml:space="preserve">TPoint iLastPos;</codeblock></p><p><codeph>TPoint</codeph> is
a convenience class that stores two integers that can be used as co-ordinates.
Additionally, it provides some methods to modify the point. We do not need
to initialize the variable in the constructor of the <codeph>CHelloWorldContainer</codeph> class
– the container class is indirectly derived from the class <codeph>CBase</codeph>,
which automatically zero-initializes all member variables.    Touch events
are delivered to the container class, which is responsible for managing the
visible UI content in the main pane of your application. To handle the events
ourselves, we have to override the following method in <codeph>CHelloWorldContainer</codeph>: </p><p><codeph>void
CHelloWorldContainer::HandlePointerEventL(const TPointerEvent&amp; aPointerEvent)</codeph></p><p>Define
this method in the header file (can be private or protected) and add its implementation
in the <codeph>.cpp</codeph> file.    The information about the new event
is sent through the argument <codeph>aPointerEvent</codeph>. We are interested
in the up event for the first button (there is only one in current touch devices;
you can’t click with a right button as you would with a mouse). Whenever the
user releases the stylus or finger from the touch screen, we want to draw
a line to this position. Put the following code into this if statement: <codeblock xml:space="preserve">if (aPointerEvent.iType == TPointerEvent::EButton1Up)
  {
  }</codeblock></p><p>Drawing the line itself is rather simple. First, define
the color and style that should be used for drawing, then call the function
for drawing the line. Note that the settings concerning the color and style
stay active until they are changed again in this graphics context – you do
not need to set them every time when executing consecutive drawing operations. </p><codeblock xml:space="preserve">iBmpGc-&gt;SetPenColor(KRgbRed);  
iBmpGc-&gt;SetPenSize(TSize(2,2));  
iBmpGc-&gt;DrawLine(iLastPos, aPointerEvent.iPosition);</codeblock><p>Next, we
have to save the new position, because it will be required as the starting
point for the next line. </p><codeph>iLastPos = aPointerEvent.iPosition;</codeph><p>Finally,
issue a request to the framework to redraw the screen. Otherwise, the user
won’t see the new line! </p><codeph>DrawDeferred();</codeph><p>At the end
of the method, also call the <codeph>HandlePointerEventL()</codeph> method
of the base class (the container is derived from <codeph>CCoeControl</codeph>,
because it is a normal UI control by itself): </p><codeph>CCoeControl::HandlePointerEventL(aPointerEvent);</codeph><p>To
sum it up, this is the final code for the <codeph>HandlePointerEvent()</codeph> method: </p><codeblock xml:space="preserve">void CHelloWorldContainer::HandlePointerEventL(const TPointerEvent&amp; aPointerEvent)
    {
    if (aPointerEvent.iType == TPointerEvent::EButton1Up)
      {
      iBmpGc-&gt;SetPenColor(KRgbRed);
      iBmpGc-&gt;SetPenSize(TSize(2,2));
      iBmpGc-&gt;DrawLine(iLastPos, aPointerEvent.iPosition);
      iLastPos = aPointerEvent.iPosition;
      DrawDeferred();
      }
    CCoeControl::HandlePointerEventL(aPointerEvent);
    }</codeblock><p>We’ve already added all the code required for drawing
to the bitmap, but this bitmap still has to be transferred to the screen.
The <codeph>CHelloWorldContainer::Draw()</codeph> method is called when the
system wants the contents of the container to be redrawn. Therefore, we need
to add the following line of code to the end of the <codeph>Draw()</codeph> method,
which copies the bitmap to the top left of the graphics context of the screen: </p><codeph>gc.BitBlt(TPoint(0,
0), iBitmap);</codeph><p>Now compile the project. It should already work –
you can draw red lines by just clicking inside the main pane of the emulator! </p><fig id="GUID-CFD29EE4-464B-498C-80F5-493847DE0AEE">
<image href="GUID-700CD2E2-DBB7-40BD-BC6D-9BC79C5A0BBF_d0e5803_href.png" placement="inline"/>
</fig></section>
<section id="GUID-8DC096A0-807D-437C-9A96-ABAFE2AF7F26"><title>  Defining
a Menu </title><p>The application would be improved if the user could clear
the drawing during use, rather than having to restart it. This section shows
how you add and handle menu items to provide this functionality, and to exit
the application    Open the <codeph>HelloWorldContainer.uidesign</codeph> document.
You can find it in the root folder of your project in the <b>Project Explorer</b> or
in the <b>UI Designs</b> folder of the Symbian Project Navigator.    </p><p>Click
on the <b>Options</b> menu item below the UI design to reveal the menu. As
indicated, you simply need to click on the empty menu item and start typing. </p><fig id="GUID-96D944A2-87C5-4530-AB0C-580C3277285D">
<image href="GUID-20FEEF54-23CB-4D30-B846-11B4ACE8E772_d0e5827_href.png" placement="inline"/>
</fig><p>Add two menu items – <b>Clear</b> (for clearing the image) and <b>Exit</b> (for
closing the application).    </p><p>Then click once on the Exit menu item
to select it. Go to the <b>Behavior</b> group of the <b>Properties</b> window
and change the command ID to <codeph>EAknCmdExit</codeph> (this is available
in the drop-down list). This command will also be sent to your application
if the operating system wants to shut it down, for example, when the phone
does not have enough memory left. Therefore, it is necessary that every application
always responds to this event and instantly shuts the application down. It
is already handled by the basic application that the Carbide.c++ wizard generated
for you; you don’t need to implement the command handling for this event yourself. </p><fig id="GUID-8FD2973F-23FF-4734-AE16-CA39C02C7DE5">
<image href="GUID-D7F000F0-019A-486E-BB0C-C0065D08C5F6_d0e5850_href.png" placement="inline"/>
</fig><p>If you try your application now, you will see that the Exit menu
item already works. </p><p/><p><b>Tip</b></p><p> When testing the application,
always quit your application using the <b>Exit</b> command (rather than just
closing the emulator). The application environment will then automatically
check for memory leaks. If you just shut down the emulator you may not discover
the leak until much later, making it a lot more difficult to find the cause.</p></section>
<section id="GUID-0090F731-A243-44C7-96ED-1EC5DB172F8D"><title> Clearing the
Drawing </title><p>Whenever the <b>Clear</b> menu item is selected the view
class method <codeph>CHelloWorldContainerView::HandleCommandL()</codeph> is
called with the command ID of the menu item as a parameter.   </p><p> If we
want to handle the menu item, the UI designer can create the necessary code
for us. Right-click on the menu item and choose <b>Handle ‘selected’ Event</b>.
The UI designer will ask you to save the design – choose <b>Yes</b>. The code
will then be generated and you will jump into the code view to a new method
called <codeph>HandleClearMenuItemSelectedL()</codeph> – a more convenient
place to put your command-handling code than directly in a big <codeph>HandleCommandL()</codeph> method
that receives all commands. The auto-generated source code therefore calls
the new extra method from within <codeph>HandleCommandL()</codeph> (take a
look at that method to see what really happens). </p><fig id="GUID-8E944FEE-EFDF-4AFE-BEB8-F3B216B91A98">
<image href="GUID-881C353C-6482-4DFE-9D43-CFB80DEB77A5_d0e5894_href.png" placement="inline"/>
</fig><p>Now, we only need to tell the container that it should clear its
bitmap buffer. To do this, create a new public method in the container: </p><codeblock xml:space="preserve">void CHelloWorldContainer::ClearDrawing()
  {
  iBmpGc-&gt;Clear();
  DrawDeferred();
  }</codeblock><p>Now, call this method from the menu item handler method.
As explained in the section about the application architecture, the view class
(<codeph>CHelloWorldContainerView</codeph>) is the controller and owner for/of
the container class (<codeph>CHelloWorldContainer</codeph>). Therefore, this
class has a pointer to the container as an instance variable, which you can
use to clear the drawing. </p><codeblock xml:space="preserve">TBool CHelloWorldContainerView::HandleClearMenuItemSelectedL(TInt aCommand)
  {
  iHelloWorldContainer-&gt;ClearDrawing();
  return ETrue;
  }</codeblock><p>The menu command should now clear the image.    </p><p>Congratulations,
you have completed the tutorial and have created your own small mobile painting
application! </p></section>
<section id="GUID-2BD775FF-BD36-4550-A388-48A3B1832D9E"><title> Further Exercises</title><p>As
an exercise, it’s a good idea to extend the application by yourself – for
example, you could add some menu items that allow the end user to change the
color of the pen. </p><p/><p><b>Tip</b></p><p> It’s a good idea to learn
keyboard shortcuts as early as possible, because they can significantly increase
the efficiency of your work. For example, you can press <b>Ctrl + B</b> to
build the project, instead of using the icon or the menu commands. Also very
helpful: <b>Ctrl + Shift + F</b> automatically formats and indents your code.
You can get a full list of commands by pressing <b>Ctrl + 3</b>. A hot keys
list appears when you press <b>Ctrl + Shift + L</b>.</p><p/><p> <b>Importing
Other Examples</b></p><p>The S60 SDK itself installs many examples; additional
applications can be downloaded from the developer.symbian.org and Forum Nokia
(see the Related Info section  for more information).    To import ready-made
applications in Carbide.c++, go to <b>File | Import</b>. In the following
dialog, select <b>Symbian OS Bld.inf file</b> and click <b>Next</b>. </p><fig id="GUID-8E8F4507-70E7-496C-AE4D-16DAD8146ABA">
<image href="GUID-631E27DB-97A7-47E2-8FC1-856198435FFF_d0e5956_href.png" placement="inline"/>
</fig><p/><p>Now, click <b>Browse</b> and navigate to the <codeph>bld.inf</codeph> file
of the project you want to import. It’s usually stored in the <codeph>/group/</codeph> subfolder
of the project. </p><fig id="GUID-B682943D-10EE-4DC8-B510-7C2D54C536EE">
<image href="GUID-C588B869-6940-42B2-84F9-71467F6A4306_d0e5972_href.png" placement="inline"/>
</fig><p>In the following step, select which SDKs you would like to use. The
same considerations as those explained when creating your Hello World application
apply. </p><fig id="GUID-5A381CA4-CCE0-4359-8F02-697AEDA72BDE">
<image href="GUID-D492CF6C-F889-4299-AC75-951EF343AC9F_d0e5978_href.png" placement="inline"/>
</fig><p>You can usually accept the default values for the next step and let
the wizard import everything.    </p><p>In the last step, you have to define
the <b>Project Properties</b>. In most cases, you can leave the default values. </p><fig id="GUID-1AB6D789-9407-4AB0-8F52-B1138DE063BD">
<image href="GUID-F18A6C91-136D-450E-90F0-7C2B9263777C_d0e5989_href.png" placement="inline"/>
</fig><p>Afterwards, the project is imported and you can start working. The
project contents will not be copied to the current Carbide.c++ workspace,
so you will work directly on the original directory and the original files.
Copy the project to a different directory first if you want to keep the original
project or example in its original state – for example, into the workspace
directory.    </p><p><b>Troubleshooting</b>: If <keyword>importing</keyword> the
project fails, take special care of the last step of the import process: the
root directory should be set correctly to the root directory of the project
and not one level above it. Also, the project name should be the same as the
last part of the root directory. From time to time, the default values are
not configured properly, causing problems in the import process. </p><p/><p><b>Warning</b>  </p><p>Do
not use the standard (Eclipse) project import! The reason is that this import
method would also import all build configuration settings, including references
to installed SDKs and paths on the original system. Therefore, if you import
a project from somebody else but don’t have the SDK installed in exactly the
same directory, the build configurations will no longer work. The <codeph>bld.inf</codeph> import
method recreates the SDK bindings and only imports the real contents of the
project.</p></section>
<section id="GUID-191D5D9D-00FB-47F0-B88B-8B87588A20C8"><title> Summary</title><p>This
part of the tutorial has shown how we can extend the basic skeleton from the <xref href="GUID-301E5FAA-A1C3-4FD7-9D84-DAA61C66981B.dita">Symbian C++ Quick Start</xref> to
create a small paint application. The tutorial explains the application framework,
including how you define menus, how to handle touch-screen events, drawing
to the screen etc. </p></section>
<section id="GUID-8B6E602D-CA6B-41DD-B3DC-4C3BC9A04154"><title> Related Info</title><ul>
<li><p><xref href="GUID-301E5FAA-A1C3-4FD7-9D84-DAA61C66981B.dita">Symbian C++
Quick Start</xref></p></li>
<li><p><xref href="http://developer.symbian.org/wiki/index.php/Getting_Started_with_Debugging_on_the_Device.dita">Getting
Started with Debugging on the Device</xref></p></li>
<li><p><xref href="http://developer.symbian.org/wiki/images/e/eb/HelloSymbianWorld_Example_Code.zip.dita">File:
HelloSymbianWorld Example Code.zip</xref>  (code example associated with this
article)</p></li>
</ul></section>
</conbody></concept>