Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 62
Текст из файла (страница 62)
Any capitalized328THE APPLICATION FRAMEWORKfour-letter name will do, but it is common to use an abbreviation of theresource file name.The #include statements load definitions of structures and constantsthat are used within the resource file. The final #include refers to theapplication’s HRH files. This contains the enumerated constants for theapplication’s commands. We need those commands in the C++ file so wecan tell which command has been issued; we also need them here so thatwe can associate the commands with the right menus and shortcut keys.After the NAME and #include lines, every UIKON resource file beginswith three unnamed resources as follows:S60 unnamed resources:RESOURCE RSS_SIGNATURE { }RESOURCE TBUF r_default_document_name{buf="HEWB";}RESOURCE EIK_APP_INFO{menubar = r_menubar;cba = R_AVKON_SOFTKEYS_OPTIONS_EXIT;}UIQ unnamed resources:RESOURCE RSS_SIGNATURE { }RESOURCE TBUF { buf = "HelloUIQ"; }RESOURCE EIK_APP_INFO { }The RSS_SIGNATURE structure allows us to specify version information and the TBUF specifies a friendly name for the application’sresource file.Of more interest is the EIK_APP_INFO resource.
In the S60 file, itidentifies the symbolic resource IDs of the HelloS60 menu and softkeys,defined as a Control Button Array (CBA).The Registration FileThe application needs to be registered with the system before it is actuallyvisible to the user. It is then listed by the application launcher in its list andicon views. The registration file is essential for registering the application;however for a full registration the following files (see Figure 11.5) arerequired:• one registration (_reg), file• at least one localization (_loc) file, one for each language• at least one multibitmap file (.mbm) containing several bitmaps.A GRAPHICAL HELLO WORLD329Registration fileAppName_reg.rscLocalizable filesAppName_loc.rsc(default)AppName_loc.r01AppName_loc.r02Icon filesAppNameIconsDefault.mbmAppName IconsShared.mbmFigure 11.5 Registration filesHelloUIQ_reg.rss:#include <AppInfo.rh>UID2 KUidAppRegistrationResourceFileUID3 0xE65A7653 // application UIDRESOURCE APP_REGISTRATION_INFO{app_file = "HelloUIQ"; // filename of application binary// (minus extension)// Specify the location of the localisable icon/caption// definition filelocalisable_resource_file = "\\Resource\\Apps\\HelloUIQ_loc";}HelloS60_reg.rss:#include "HelloS60.hrh"#include "HelloS60.rls"#include <appinfo.rh>#include <HelloS60.rsg>UID2 KUidAppRegistrationResourceFileUID3 _UID3RESOURCE APP_REGISTRATION_INFO{app_file="HelloS60";localisable_resource_file = qtn_loc_resource_file_1;localisable_resource_id = R_LOCALISABLE_APP_INFO;embeddability = KAppNotEmbeddable;newfile = KAppDoesNotSupportNewFile;}The AppInfo.rh file needs to be included as it contains the structuredefinition of the resource file.
The UID2 should always be KUidAppRegistrationResourceFile and UID3 must correspond to the uniqueapplication UID.330THE APPLICATION FRAMEWORKThe APP_REGISTRATION_INFO structure is the resource structurethat defines how the application looks and behaves and describes itsservices. For both applications, we create a link between the registrationfile and the application executable, using the app_file structure; wealso create links to the localizable application information files using thelocalisable_resource_file structure. This is described further inChapter 13.SummaryIn this chapter, we’ve looked at:• the Symbian OS Application framework• an overview of the S60 and UIQ application frameworks; how S60and UIQ applications are put together and how they interact withUIKON framework provided by Symbian• the basic code you need to start writing graphical applications forSymbian OS.12A Simple Graphical ApplicationAfter a series of chapters describing individual aspects of Symbian OS,it is time to pull a few threads together.
In Chapter 11, we described aminimal GUI application that simply showed how the UI framework andthe application UI fit together. Now we look at a complete, simple, butnon-trivial example application that forms a basis for the examples usedin several of the following chapters.In this chapter, we cover some aspects of application design andintroduce the idea of how to program a user interface that does notassume a particular screen size. This latter point is important if you wantto target your application at multiple user interfaces, as it helps speed upyour porting efforts. In addition, we show how an application can usethe principles described in Chapter 7 to save and restore its persistentdata.Before looking at the application’s structure and behavior in moredetail, we start with a general introduction to the Noughts and Crosses(otherwise known as Tic-Tac-Toe) application.
Figure 12.1 shows theapplication running on a phone using the S60 user interface.This application runs a game of noughts and crosses in which twoplayers take turns to make their moves. The object of the game is to placethree noughts (or crosses) in any row, column or diagonal before youropponent manages to do so.We’ve implemented the game in a way that minimizes the differencesneeded to run on phones using the S60 and UIQ user interfaces.
Depending on the nature of the phone it is running on, you can make a moveeither by using a combination of the cursor and pushbutton keys or bytapping on the screen.332A SIMPLE GRAPHICAL APPLICATIONFigure 12.1 The Noughts and Crosses applicationWe’ve also kept the logic relating to the game itself very simple sothat the bulk of the code illustrates issues of a general nature, relevant tomost applications.
In particular, we’ve designed the layout of the displayin a way that can easily be adapted to show a rectangular grid with anynumber of tiles and to display on phones with a variety of screen formats.The grid layout is defined by a set of constants in oandxdefs.h:static const TInt KTilesPerRow= 3;static const TInt KTilesPerCol= 3;static const TInt KNumberOfTiles = (KTilesPerRow*KTilesPerCol);All the application’s layout and drawing code is based on these values.By changing them, the layout can be adapted for games using differentlysized and shaped boards.The same header file also defines values that are specific to theNoughts and Crosses game, including the constant KTilesPerSide(which, unlike the earlier values, assumes that the board layout is square)and the states that can be associated with each tile:static const TInt KTilesPerSide = 3;enum TTileState{ETileBlank = 0,ETileNought = 1,ETileCross = 4};IMPLEMENTING THE GAME ON S60333The state values are chosen so that ETileCross is greater than theproduct of ETileNought with either KTilesPerRow or KTilesPerCol, which helps with the calculation of a winner.This file also defines the height of the application’s status window,used to show whose turn it is to play:static const TInt KStatusWinHeight = 20; // in pixelsIn Chapter 11 you saw that the simplest Symbian OS graphical application needs instances of four classes: the application, the document, theapplication UI and a view.
For this game, we’ve added two more classes:a controller and a model, or engine. Since the game control logic is sosimple, we could have implemented it entirely within the application UIclass, rather than defining separate controller and engine classes. However, we’ve chosen to add these classes from the start, in preparation forthe more complex form of the game that is developed in Chapter 20.The overall structure of the game is shown in Figure 12.2.ApplicationDocumentAppUlControllerViewEngineFigure 12.2 Structure of the Noughts and Crosses applicationWe cover the S60 version of the game first and then look at the changesthat are needed to create the UIQ version.12.1 Implementing the Game on S60The Application ClassThe S60 class definition for the Noughts and Crosses application classis listed below.
As you can see, it is very similar to the correspondingclass in Chapter 11’s basic application: it implements AppDllUid(), toreport the application’s UID to the application framework, and CreateDocumentL().334A SIMPLE GRAPHICAL APPLICATIONclass COandXApplication : public CAknApplication{public:// From CApaApplicationTUid AppDllUid() const;protected:// From CEikApplicationCApaDocument* CreateDocumentL();};This is fairly typical for applications. It is rare for an application classto override any of the other application class member functions.The Document ClassThe class definition for the Noughts and Crosses document class, listedbelow, provides the implementation of CreateAppUiL(), which isalways required. In addition, it implements persistent storage of thegame’s state in the StoreL() and RestoreL() functions, using theprinciples described in Chapter 7.class COandXDocument : public CAknDocument{public:static COandXDocument* NewL(CEikApplication& aApp);virtual ∼COandXDocument();// From CEikDocumentCEikAppUi* CreateAppUiL();void StoreL(CStreamStore& aStore, CStreamDictionary& aStreamDic) const;void RestoreL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic);CFileStore* OpenFileL(TBool aDoOpen, const TDesC& aFilename, RFs& aFs);private:COandXDocument(CEikApplication& aApp);private:COandXAppUi* iAppUi;};The implementations of StoreL() and RestoreL() delegate tothe application UI class the actual task of storing and restoring theapplication’s data, but they retain the responsibility for associatingthe application’s UID with the ID of the stream in which the data isstored.void COandXDocument::StoreL(CStreamStore& aStore,CStreamDictionary& aStreamDic) const{TStreamId id = iAppUi->StoreL(aStore);IMPLEMENTING THE GAME ON S60335aStreamDic.AssignL(KUidOandXApp, id);}void COandXDocument::RestoreL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic){TStreamId id = aStreamDic.At(KUidOandXApp);iAppUi->RestoreL(aStore, id);}The application framework provides support for an application to saveits document data in an application-specific direct file store and, in UIQ,it is sufficient just to implement the two functions listed above.In contrast, S60 applications are assumed not to be document-basedand the default behavior is that the application framework never callsthese two functions.