Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 61
Текст из файла (страница 61)
TheConstructL() method should also construct the application view.S60 implementation of ConstructL():void CHelloS60AppUi::ConstructL(){// Initialise app UI with standard value.BaseConstructL();iAppView = CHelloS60AppView::NewL( ClientRect() );// Create a file to write the text to...}UIQ implementation of ConstructL():void CHelloUIQAppUi::ConstructL(){// Calls ConstructL that initiates the standard values.CQikAppUi::ConstructL();// Create the view and add it to the frameworkCHelloUIQView* appView = CHelloUIQView::NewLC(*this);AddViewL(*appView);CleanupStack::Pop(appView);}In the UIQ implementation, AddViewL() registers the view with thesystem and adds it implicitly to the control stack, which enables the viewto receive key and pointer input. The first view that is added becomes thedefault view for the application.The ownership of the view is transferred to the application UI, andit is later unregistered and deleted automatically in the application UI’sdestructor.
It is interesting to note that the derived application UI classin S60 takes ownership of the view object and is responsible for deletingA GRAPHICAL HELLO WORLD323it, while the base class the UIQ implementation takes this responsibilityand the destructor for the application UI class does nothing at all. Thedestructor for the S60 application UI class is as follows:CHelloS60AppUi::∼CHelloS60AppUi(){if ( iAppView ){delete iAppView;iAppView = NULL;}}In S60, the application UI class also handles command events, whichmay originate from a range of sources such as menu bars, or the soft keys.This is done by implementing the HandleCommandL() function:void CHelloS60AppUi::HandleCommandL( TInt aCommand ){switch( aCommand ){case EEikCmdExit:case EAknSoftkeyExit:Exit();break;case ECommand1:{// Load a string from the resource file and display it...}break;case ECommand2:{...}break;default:Panic( EHelloS60Ui );break;}}Here a command is an instruction, identified by an integer value knownas a command ID.
Command IDs are enumerated constants defined inheader files, which are traditionally given the extension HRH, while theother commands (EEikCmdExit, EAknSoftkeyBack) are defined bythe system.In the S60 implementation, the UI framework calls HandleCommandL() when either of the menu options available from the left softkeyare selected (see Figure 11.4).In UIQ, commands are usually handled by application views.324THE APPLICATION FRAMEWORKFigure 11.4 S60 emulator with the HelloS60 command menu openThe Application ViewThe final step of creating an application is creating the applicationviews – the user’s entry points into the application.Anything that can draw to the screen is a control.
Controls can also(optionally) handle key and pointer events. Note that controls don’t haveto be able to draw. They can be permanently invisible but that’s quiteunusual: a permanently invisible control clearly can’t handle pointerevents, but it can handle keys, as we’ll see in Chapter 18.The application UI is not a control. It owns one or more controls,including such obviously visible controls as the toolbar; we’ll see a fewothers in the next few chapters.In a typical UIKON application, you write one control yourself andmake it the size of the client rectangle, the area of the screen remainingafter the toolbar and so on have been taken into account.
You then usethat control to display your application data, and to handle key andpointer events (which are not commands).A GRAPHICAL HELLO WORLD325The HelloS60 and HelloUIQ application views are controls whosepurpose is to draw the text ‘Hello world!’ on the screen in a reasonablypleasing manner. They do not handle key or pointer events.UIQ application viewIn UIQ, views are the primary means of displaying data and handlingcommands and other user input events.
Views can be configured andtheir initial commands and controls set in resource files using a number of resource structures, including QIK_VIEW_CONFIGURATION,QIK_VIEW and QIK_VIEW_PAGE. Each view has a class, derived fromthe framework class CQikViewBase, which handles construction andactivation of the view, command handling and use of the view’s controls.A view object is constructed in several stages to minimize the startuptime of the application.
The first stage constructs as little as possible.The static factory function, NewL(), follows the standard Symbian OStwo-phase construction rules. The function instantiates the object, whichcalls CQikViewBase’s first-phase constructor and then calls the secondphase ConstructL() method, which calls the second-phase constructorCQikViewBase::BaseConstructL() to register the view with theview server to allow navigation between applications.The next stage of construction occurs in the ViewConstructL()method which is called the first time the view needs to be activated.For applications which use multiple views, the ViewConstructL()method is valuable because it reduces application start-up time by onlyinitializing the views that are used immediately the application starts. Italso avoids wasting memory, particularly if some views are not used atall.ViewConstructL() fully constructs the view by reading its configuration resource structure and initializing its controls.
In HelloUIQ, it callsthe ViewConstructFromResourceL() method of CQikViewBase.In UIQ, all views are uniquely identified by a view ID (a TVwsViewIdobject), consisting of the UID of the application and an ID that uniquelyidentifies the view within the application. The view ID is returned byCQikViewBase::ViewId(), a pure virtual method which is calledfor each view by CQikAppUi::AddViewL(). All view classes mustimplement this method.In UIQ, a command can be located on a softkey, in a toolbaror in a menu, depending on the interaction style of the phone.
Toallow for this flexibility, commands are defined in a more abstractway, rather than being explicitly coded as particular GUI elementssuch as menu items. This is usually done in a resource file using theQIK_COMMAND_LIST structure. Commands are associated with viewsand are handled within view classes. This is done by re-implementingthe HandleCommandL(CQikCommand& aCommand) method definedby CQikViewBase:326THE APPLICATION FRAMEWORKvoid CHelloUIQView::HandleCommandL(CQikCommand& aCommand){switch(aCommand.Id()){// Just issue simple info messages to show that// the commands have been selectedcase EHelloUIQInfoPrint1Cmd:{// Shows an infoprintiEikonEnv->InfoMsg(R_INFOPRINT1_TEXT);break;}case EHelloUIQInfoPrint2Cmd:{...}case EHelloUIQInfoPrint3Cmd:{...}// Go back and exit command will be passed to the CQikViewBase// to handle.default:CQikViewBase::HandleCommandL(aCommand);break;})Note that UIQ applications do not provide an exit command.
Whenyou start an application, it remains running and persistent; you do notclose it but simply switch away from it to use other applications. However,it is useful to provide an exit command in debug builds, to test that theapplication exits cleanly without leaking memory.S60 application viewThe S60 application view derives from CCoeControl. The applicationview is fully constructed by the static factory function, NewL(), whichinstantiates the object and then calls the second-phase ConstructL()method to perform any initialization which may leave.void CHelloS60AppView::ConstructL( const TRect& aRect ){// Create a window for this application viewCreateWindowL();// Set the windows sizeSetRect( aRect );// Activate the window, which makes it ready to be drawnActivateL();}The ConstructL() method calls CreateWindowL() to create theview’s associated window, then SetRect() to set the area on the screenA GRAPHICAL HELLO WORLD327that the view will occupy and ActivateL() to indicate that the view isready to draw itself.The Resource FileAs regards code, we now have everything we need to start the applicationframework.
We do, however, need an application resource file andregistration files.In this section, we take a brief look at the resource file. This will giveus a pretty good idea of how resource files work – good enough to beable to read resource files and guess what they mean. For more details,have a look at Chapter 13.In the code we’ve examined so far, we have already seen referencesto things that must be implemented in the application’s resource file:• strings R_INFOPRINT1_TEXT, R_INFOPRINT2_TEXT, etc.• enumerated constants such as EHelloUIQInfoPrint1Cmd.The other things we haven’t seen in the code are the definitionsnecessary to construct some aspects of the application’s GUI, such as themenu and any shortcut keys. They are defined in the resource file as well.Let’s look through the resource file to see exactly what is defined andhow.
First, there’s some boilerplate material:HelloS60 resource file (HelloS60.rss):NAME HELL#include <eikon.rh>#include <avkon.rh>#include <avkon.rsg>#include <appinfo.rh>#include "HelloS60.rls"#include "HelloS60.hrh"HelloUIQ resource file (HelloUIQ.rss):NAME HELL#include <eikon.rh>#include <eikon.rsg>#include <qikon.rh>#include <qikon.hrh>#include <uikon.rh>#include <uikon.hrh>#include <QikCommand.rh>#include "HelloUIQ.rls"#include "HelloUIQ.hrh"Resource files must contain a NAME statement, which comes beforeany RESOURCE statements. It has to be distinct from the names usedby UIKON and one or two other system components.