Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 60
Текст из файла (страница 60)
Inreality, it takes much longer to fully learn how a UIKON GUI programworks and in this chapter we only briefly comment on the C++ codeitself. There’s nothing particularly difficult about it, but it is easier to coverA GRAPHICAL HELLO WORLD317how UIKON uses C++ when we have seen more of how Symbian OSC++ works.The Project Specification FileAs mentioned in Chapter 1, all Symbian OS applications require a projectspecification file, with an MMP extension. The project specification filefor HelloS60 is as follows:TARGETTARGETTYPEUIDHelloS60.exeexe0x0100039CE 0xEA7408AFSOURCEPATHSOURCESOURCESOURCESOURCESOURCE..\srcHelloS60.cppHelloS60Application.cppHelloS60AppView.cppHelloS60AppUi.cppHelloS60Document.cppSOURCEPATH..\dataSTART RESOURCEHEADERTARGETPATHEND //RESOURCEHelloS60.rssSTART RESOURCETARGETPATHEND //RESOURCEHelloS60_reg.rss\private\10003a3f\appsUSERINCLUDE..\incSYSTEMINCLUDE\epoc32\includeLIBRARYLIBRARYLIBRARYLIBRARYLIBRARYLIBRARYLIBRARYLIBRARYeuser.libapparc.libcone.libeikcore.libavkon.libcommonengine.libefsrv.libestor.libresource\appsLANG SCVENDORIDSECUREIDCAPABILITY// End of File00xEA7408AFReadUserDataThe HelloUIQ project specification file is very similar, with smalldifferences in the name of the target file, the source files and the specificlibraries used – for example the UIQ application does not use S60’savkon.lib, but lists qikon.lib, the equivalent one in UIQ, instead.318THE APPLICATION FRAMEWORKThe TARGET, TARGETTYPE, SOURCE, SOURCEPATH, USERINCLUDE,SYSTEMINCLUDE and LIBRARY entries that are needed in a consoleapplication’s MMP file are described in Chapter 1.
The S60 applicationhas further requirements in the MMP file:• UID – specifies the application’s three unique IDs. UID1 is the samefor all binary files and is supplied automatically. UID2 indicatesthe kind of executable (0x0100039CE for an application) and UID3uniquely identifies our binary• START RESOURCE ... END blocks – detail the resources required bythe application (see Chapter 13 for more details)• TARGETPATH – specifies where project files should be released• LANG – specifies one or more languages by means of two-charactercodes. The codes can be anything you like, as long as each languagehas a unique code, but for specific languages you are recommendedto use the two-digit codes that are defined in the TLanguage enumeration in e32const.h, which is included in e32std.h.
Sincethe default language code is SC, the LANG entry could safely beomitted from the above listing. See Chapter 13 for more informationon multilingual applications• VENDORID – the vendor’s unique identifier (this is optional)• SECUREID – the application’s unique identifier; the HelloS60 application needs to use a platform security capability, so it requires aSECUREID (see Chapter 9)• CAPABILITY – HelloS60 requires ReadUserData capability to enablereading a message from a file.In a GUI application that only prints ‘Hello World!’ to the screen,without accessing the file system, there is no need for any capability – thisis the case in the HelloUIQ code.The Application Entry PointEvery Symbian OS application must implement two functions that arecalled by the framework as it starts the application.Note that the Carbide.c++ wizard puts the functions discussed inthis section into files specific to the GUI – for HelloS60, they are inHelloS60.cpp, whereas for HelloUIQ, they are in HelloUIQApplication.cpp.A GRAPHICAL HELLO WORLD319The first is a non-leaving function which creates a new instance ofthe application class.
This function is similar for both the HelloS60 andHelloUIQ applications. For the HelloS60 example, the code is:LOCAL_C CApaApplication* NewApplication(){return new CHelloS60Application;}The framework expects this factory function to have exactly thisprototype. It constructs and returns an instance of the application class,or returns NULL if it cannot be instantiated.The second function is the application’s entry point function, identicalfor both S60 and UIQ applications, called E32Main():GLDEF_C TInt E32Main(){return EikStart::RunApplication( NewApplication );}E32Main() calls EikStart::RunApplication(), passing as anargument a pointer to the factory function which creates an instance ofthe application class.The Application ClassThe application class represents the properties that are the same for everyinstance of the application.
This includes the information specified in theregistration file, for instance, the caption and the capabilities, and the UID.At a minimum, it must also implement two functions: AppDllUid() andCreateDocumentL().AppDllUid() returns the application’s UID. The implementations forHelloS60 and HelloUIQ are similar.S60 implementation of AppDllUid():TUid CHelloS60Application::AppDllUid() const{// Return the UID for the HelloS60 applicationreturn KUidHelloS60App;}UIQ implementation of AppDllUid():TUid CHelloUIQApplication::AppDllUid() const{// Return the UID for the HelloUIQ applicationreturn KUidHelloUIQApp;}320THE APPLICATION FRAMEWORKThe UID itself is usually defined in the HRH file or in a header file thatcontains the application’s global information.AppDllUid() is called by the framework just after calling NewApplication().
One of the reasons it needs the UID is to check whetherthere is a running instance of the application that it can switch to. Thevalue returned must be the same as the UID3 value specified in theMMP file. Once the UID has been verified, the framework calls theCreateDocumentL() method.CreateDocumentL() is a factory function for creating an objectof the document class.
Note that, although the application creates thedocument, the framework is responsible for destroying it.S60 implementation of CreateDocumentL():CApaDocument* CHelloS60Application::CreateDocumentL(){return (static_cast<CApaDocument*> (CHelloS60Document::NewL(*this)));}UIQ implementation of CreateDocumentL():CApaDocument* CHelloUIQApplication::CreateDocumentL(){return CHelloUIQDocument::NewL(*this);}The DocumentThe really interesting code starts with the document class. In a file-basedapplication, the document essentially represents the data in the file. Youcan do several things with that data, each of which makes differentdemands; printing it, for example, doesn’t require an application butediting it does.
We’ll see more of this in Chapter 17.If your application handles modifiable data, the application architecture requires your document to create an application user interface thatis used to edit the document.In a non-file-based application, you still have to code a function inthe document class to create an application user interface, since it is theapplication UI that does the real work.
Apart from creating the applicationUI, the document class for such an application is trivial; it implements theCreateAppUiL() function, inherited from the document’s base class,CEikDocument. This function instantiates an object of the applicationUI class.S60 implementation of CreateAppUiL():CEikAppUi* CHelloS60Document::CreateAppUiL()A GRAPHICAL HELLO WORLD321{return (static_cast <CEikAppUi*> (new (ELeave) CHelloS60AppUi));}UIQ implementation of CreateAppUiL():CEikAppUi* CHelloUIQDocument::CreateAppUiL(){return new (ELeave) CHelloUIQAppUi;}This function is called by the framework.
Note that CreateAppUiL()only carries out first-phase construction. In other words, it does not callthe application UI’s ConstructL() – the framework is responsible forcalling that. The framework also takes ownership of the application UIobject, so the destructor of the document class does not need to destroy it.The Application UIStarting the application UI is the final step in bringing up the applicationframework. The GUI action proper starts with the application UI, whichhas two main roles:• to get commands to the application• to distribute keystrokes to controls, including the application’s mainview, which is owned by the application UI.A command is simply an instruction without any parameters or anyinformation about where it came from, which the program must execute.The definition is deliberately vague, since commands can originatefrom a variety of places. In UIQ applications, commands usually originatefrom an application’s menu.
In other customized UIs, commands mayoriginate from other sources. In the S60 UI, for example, which showscommonly-used commands on a toolbar, commands may come from atoolbar button.It doesn’t matter where the command comes from: the application UIreceives it as a 32-bit command ID in HandleCommandL() and simplyexecutes the appropriate code to handle the command.Some commands can be executed immediately. For example, theClose command exits an application. (We don’t ask the user, we simplysave their data. If the user didn’t want to exit, all they need to do is startthe application again.) Other commands need further UI processing.
AFind command, for example, needs some text to find, and possibly someindication of where to look. Handling such commands involves dialogs,which are the subject of Chapter 16.322THE APPLICATION FRAMEWORKNot all input to applications comes from commands. If you type theletter X into a word processor while you’re editing, it doesn’t generatea command, but a key event. If you tap on an entry in an Agenda, itdoesn’t generate a command, but a pointer event.
Handling pointer andkey events is the business of the application view and other controls in theapplication. Chapter 15 deals with drawing to controls and Chapter 18covers key and pointer interaction.The application UI class is constructed and returned by the document’sCreateAppUiL() function, described above. Its second-phase construction method, ConstructL(), is called by the framework and shouldinclude a call to the second-phase constructor of the base class (CQikAppUi::ConstructL() for UIQ and CAknAppUi::ConstructL()for S60 – each of which ultimately calls CEikAppUi::BaseConstructL()). Among other things, the base-class constructor method readsthe application’s resource file and creates the visible GUI elements.