Symbian3/SDK/Source/GUID-0C814ED6-3F64-4E0E-9C47-654AEDADBA90.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Tue, 20 Jul 2010 12:00:49 +0100
changeset 13 48780e181b38
parent 8 ae94777fff8f
permissions -rw-r--r--
Week 28 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 1897 and Bug 1522.

<?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" scope="external">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" scope="external">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#Model-View-Control_Pattern" scope="external">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_d0e5245_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_d0e5351_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 format="html" href="http://developer.symbian.org/main/documentation/reference/s%5E2/doc_source/reference/tb91sf-PP/fontandbitmapserver/index.html" scope="external">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_d0e5549_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" scope="external">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_d0e5627_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_d0e5644_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#Naming_Conventions" scope="external">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)" scope="external"> 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" scope="external">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 format="html" href="http://carbidehelp.nokia.com/help/topic/com.nokia.carbide.cpp.codescanner/html/codescanner.htm" scope="external">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_d0e5924_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_d0e5948_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_d0e5971_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_d0e6015_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_d0e6077_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_d0e6093_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_d0e6099_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_d0e6110_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" scope="external">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" scope="external">File: HelloSymbianWorld Example Code.zip</xref> 
(code example associated with this article)</p></li>
</ul></section>
</conbody></concept>