Symbian3/SDK/Source/GUID-A3BCC33F-D11B-4F98-BCC3-9A06381A02E7.dita
changeset 7 51a74ef9ed63
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-A3BCC33F-D11B-4F98-BCC3-9A06381A02E7.dita	Wed Mar 31 11:11:55 2010 +0100
@@ -0,0 +1,206 @@
+<?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-A3BCC33F-D11B-4F98-BCC3-9A06381A02E7" xml:lang="en"><title>Constructing
+the view controller in the view architecture</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>Each view controller acts like a small UI controller.</p>
+<p>The call on the first phase constructor of the view controller occurs
+in the<xref href="GUID-FD2CDEB8-0784-4BE5-A775-170F57D71BBC.dita"> UI controller</xref>.</p>
+<p>The methods you need to implement in your <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita"><apiname>CAknView</apiname></xref>-derived
+class are as follows:</p>
+<ul>
+<li><p>C++ default constructor, which cannot contain any code that
+might leave. A common implementation is:</p>
+<itemgroup>
+<codeblock id="GUID-CA1A42F0-2B6F-4520-B408-1B46037B6E29" xml:space="preserve">
+CMyViewAppView::CMyViewAppView()
+    {
+    }</codeblock>
+<p>The class declaration for this constructor in the class header file
+needs to be public to support the construction method required.</p>
+</itemgroup>
+</li>
+<li><p>two-phase constructor, a common implementation is:</p>
+<itemgroup>
+<codeblock id="GUID-A98C61E4-8C11-4F7D-9782-C440B8FAE374" xml:space="preserve">CMyViewAppView* CMyViewAppView::NewL( const TRect&amp; aRect )
+    {
+    CMyViewAppView* self = CMyViewAppView::NewLC( aRect );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+CMyViewAppView* CMyViewAppView::NewLC( const TRect&amp; aRect )
+    {
+    CMyViewAppView* self = new ( ELeave ) CMyViewAppView;
+    CleanupStack::PushL( self );
+    self-&gt;ConstructL( aRect );
+    return self;
+    }
+</codeblock>
+<p>The declarations for <parmname>CMyViewAppView::NewL()</parmname> and <parmname>CMyViewAppView::NewLC()</parmname> in
+the class header file needs to be public to support the construction method
+required. </p>
+<p>In this approach, <parmname>CMyViewAppView::NewL()</parmname> is called
+from the UI controller. It creates a view object by calling <parmname>CMyViewAppView::NewLC()</parmname>. <parmname>CMyViewAppView::NewLC()</parmname> calls new (<parmname>ELeave</parmname>) on the C++ default constructor <parmname>CMyViewAppView</parmname> to
+create the object (and leave if it cannot), <xref href="jar:GUID-35228542-8C95-4849-A73F-2B4F082F0C44.jar!/sdk/doc_source/reference/reference-cpp/Kernel_Architecture_2/CCleanupClass.html#%3a%3aCCleanup%3a%3aPushL%28CBase%20%2a%29" format="application/java-archive">pushes</xref> a pointer to the clean-up stack in case the second phase construction method
+leaves, and then calls the second phase construction method of the object.
+When it returns to <parmname>CMyViewAppView::NewL()</parmname>, the pointer
+pushed to the cleanup stack is <xref href="jar:GUID-35228542-8C95-4849-A73F-2B4F082F0C44.jar!/sdk/doc_source/reference/reference-cpp/Kernel_Architecture_2/CCleanupClass.html#%3a%3aCCleanup%3a%3aPop%28%29" format="application/java-archive">removed</xref>.</p>
+</itemgroup>
+</li>
+<li><p>Symbian 2nd phase constructor with code that might leave.
+A common implementation is:</p>
+<itemgroup>
+<codeblock id="GUID-F282B41C-0AF0-4B62-853A-812F34667C78" xml:space="preserve">void CMyViewAppView::ConstructL()
+    {
+    // construct r_name32 resources
+    BaseConstructL(r_name32 );
+    }
+</codeblock>
+<p><parmname>CMyViewAppView::ConstructL()</parmname> is a public class
+providing the second phase construction that accepts the rectangle the view
+is drawn to.</p>
+<p><xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-B9CF9FAC-AA26-3787-83E5-71030E221347"><apiname>CAknView::BaseConstructL()</apiname></xref> initializes this view
+with standard values. It accepts the symbolic ID name of a resource from the
+resource file.</p>
+</itemgroup>
+</li>
+<li><p>a method for returning the UID for the view. A common implementation
+is:</p>
+<itemgroup>
+<codeblock id="GUID-272134EE-D14C-4F97-A46D-0BEC71EF01ED" xml:space="preserve">
+TUid CMyViewAppView::Id() const
+    {
+    return KViewId;
+    }
+
+</codeblock>
+<p><parmname>CMyViewAppView::Id()</parmname> is the override of <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-82E37EFD-FCCF-3D3E-AA36-7E20A688C980"><apiname>CAknView::ID()</apiname></xref> to
+return the UID of the view</p>
+<p><parmname>KViewId</parmname> is defined somewhere in a header file,
+and is unique to this application</p>
+</itemgroup>
+</li>
+</ul>
+<section id="GUID-952D9762-EA63-489D-9698-FC504BD73001"><title>Scalability</title>
+<p>If you wish to support <xref href="GUID-B02C762B-C452-4184-ABEA-4753E6CD47D2.dita">scalability</xref> in
+your application, then you need to implement <xref href="GUID-1185F595-0488-3E93-8D60-6B3A1A3AC32E.dita#GUID-1185F595-0488-3E93-8D60-6B3A1A3AC32E/GUID-7B8E4FA3-29F4-39DF-BBB3-71E7AB2433C4"><apiname>CEikAppUi::HandleResourceChangeL()</apiname></xref> in
+the <xref href="GUID-FD2CDEB8-0784-4BE5-A775-170F57D71BBC.dita"> UI controller</xref>,
+and then a <parmname>HandleClientRectChange</parmname> method in the view
+controller.</p>
+<p>A common implementation is as follows:</p>
+<codeblock id="GUID-F5BC393D-EA47-45B2-8892-B71CE934F5B6" xml:space="preserve">
+void CMyViewAppView::HandleClientRectChange()
+    {
+    if ( iContainer )
+        {
+        iContainer-&gt;SetRect( ClientRect() );
+        }
+    }
+
+</codeblock>
+<p>, where</p>
+<p><parmname>CMyViewAppView::HandleClientRectChange()</parmname> calls <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita#GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160/GUID-AC806401-86C7-308A-9D18-39085CB8D877"><apiname>CCoeControl::SetRect(aRect)</apiname></xref> to
+set the window size according to the requirements of the mobile device.</p>
+</section>
+<section id="GUID-DC760F92-C154-4DAA-AAD1-A0C02766C6B0"><title>Activating and
+deactivating views</title>
+<p>In order for a view to be displayed, it needs to be activated by <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-F6105D54-1C2A-36C0-8522-50DAB45FEF67"><apiname>CAknView::DoActivateL()</apiname></xref>.
+The override of this method in the view controller must create a <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived
+view to display visual content to mobile device users. The <parmname>DoActivateL()</parmname> call
+must be prepared to handle the case where it is called while the view is already
+active.</p>
+<p>If the view is not published for external use, or does not handle message
+parameters, a simple check and return if the view is already active is sufficient.</p>
+<p>A common implementation is as follows:</p>
+<codeblock id="GUID-01819343-975C-499B-9DF6-14DA9BB5912E" xml:space="preserve">
+void CMyViewAppView::DoActivateL(
+   const TVwsViewId&amp; /*aPrevViewId*/,TUid /*aCustomMessageId*/,
+   const TDesC8&amp; /*aCustomMessage*/)
+    {
+    if (!iContainer)
+        {
+        iContainer = new (ELeave) CMyViewAppContainer;
+        iContainer-&gt;SetMopParent(this);
+        iContainer-&gt;ConstructL( ClientRect() );
+        AppUi()-&gt;AddToStackL( *this, iContainer );
+        } 
+
+    // Message handling would take place here.
+   }
+</codeblock>
+<p>, where</p>
+<ul>
+<li><p><parmname>CMyViewAppView::DoActivateL()</parmname> is the
+override for <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-F6105D54-1C2A-36C0-8522-50DAB45FEF67"><apiname>CAknView::DoActivateL()</apiname></xref> for the application.</p>
+</li>
+<li><p><parmname>if (!iContainer)</parmname> checks to see if the
+view already exists.</p></li>
+<li><p><parmname>iContainer = new (ELeave) CMyViewAppContainer;</parmname> calls
+the first phase constructor of the <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived
+class that provides the view.</p></li>
+<li><p><xref href="GUID-1E95CF3C-A54A-3073-A7A9-6DC56A6B89E2.dita"><apiname>iContainer-&gt;SetMopParent(this);</apiname></xref> sets the
+context for the view being created. In this case, it assigns the <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived
+view to the view controller.</p></li>
+<li><p><parmname>iContainer-&gt;ConstructL( ClientRect() )</parmname> calls
+the second phase constructor of the <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived
+class that provides the view.</p></li>
+<li><p><xref href="GUID-18937B25-9AFE-36E2-BA5F-A6716DCD6F39.dita"><apiname>AppUi()-&gt;AddToStackL( *this, iContainer );</apiname></xref> adds
+the <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived view to the control stack for <xref href="GUID-542550FA-F9F1-46D6-8182-6E7FAA013572.dita">key event handling.</xref></p>
+</li>
+</ul>
+<p>The view architecture supports an automatic recovery mechanism if <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-F6105D54-1C2A-36C0-8522-50DAB45FEF67"><apiname>CAknView::DoActivateL()</apiname></xref> leaves.
+The Symbian platform calls <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-7F1B73A0-098D-3FDB-AD2E-D4901700AF02"><apiname>CAknView::DoDeactivate()</apiname></xref> in
+the view that has left, reinstates the previous view of the application, and
+returns to the view that was just displayed. If the application had no previous
+view, it exits. If the application’s previous view was the same as the activating
+view (that is, the view is reactivated with a new message), the application
+attempts to recover to the default view.</p>
+<p>In most cases, this mechanism removes the need to put any recovery mechanism
+in the <parmname>DoActivateL()</parmname> methods. The one situation where
+you may consider something more complex is when the view can be reactivated
+(that is, activated with a new message while already active). In this case,
+the view may attempt a more complex strategy to preserve the existing state
+if a leave happens during the attempt to handle the new message.</p>
+<p>To destroy the <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived control in a view
+control, you must override <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-7F1B73A0-098D-3FDB-AD2E-D4901700AF02"><apiname>CAknView::DoDeactivate()</apiname></xref>. It
+is called when the application exits, or another view has been activated and
+the previous active window needs to be shut down. This order makes view switching
+fast. In <parmname>DoDeactivate</parmname> the view is removed from the stack
+and therefore the view’s container and its controls are destroyed. This function
+must not leave.</p>
+<p>A common implementation is as follows:</p>
+<codeblock id="GUID-01F7257D-47C2-4A42-9717-97D3913F3AB0" xml:space="preserve">
+void CMyViewAppView::DoDeactivate()
+    {
+    if ( iContainer )
+        {
+        AppUi()-&gt;RemoveFromViewStack( *this, iContainer );
+        }
+    
+    delete iContainer;
+    iContainer = NULL;
+    }</codeblock>
+<p>, where</p>
+<ul>
+<li><p><parmname>CMyViewAppView::DoDeactivateL()</parmname> is the
+override for <xref href="GUID-11967EBB-7439-3775-B287-7560ECA0AF1F.dita#GUID-11967EBB-7439-3775-B287-7560ECA0AF1F/GUID-F6E07F12-FAB3-3CB8-AE1F-3F4E7023089A"><apiname>CAknView::DoDeactivateL()</apiname></xref> for the application.</p>
+</li>
+<li><p><parmname>if (!iContainer)</parmname> checks to see if the
+view already exists.</p></li>
+<li><p><xref href="GUID-67932EAC-2A97-393F-9719-894D5764B315.dita"><apiname>AppUi()-&gt;RemoveFromViewStack( *this, iContainer
+);</apiname></xref> removes the <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>-derived view from
+the control stack.</p></li>
+<li><p><parmname>delete iContainer;</parmname> deletes the <parmname>CCoeControl</parmname>-derived
+view.</p></li>
+</ul>
+</section>
+</conbody></concept>
\ No newline at end of file