quick_recipes (779892), страница 15
Текст из файла (страница 15)
There would still be a delay before CIdle::RunL() is called, though, since it has to be called from the activescheduler’s main loop.SUMMARY75One thing to notice about CIdle is that it will not regenerate itsrequest if the TCallback method returns 0.3.18 SummaryNow you’ve seen the essentials of Symbian C++, you should be confidentwith the fundamental idioms and concepts. So it’s time to move on tothe good stuff. The next chapter will list some ‘recipes’ for common taskswhen working on Symbian OS.
If you need further information aboutanything you’ve read in this chapter, or want to find out more, pleasevisit this book’s wiki page (developer.symbian.com/quickrecipesbook)for links to additional documentation.4Symbian C++ RecipesThis chapter forms the major part of the book. It contains ten sections,each of which contain recipes to guide your development, step by step.The following subjects are described in the numbered sections below:4.1File Handling4.2Contacts and Calendar4.3Networking4.4Messaging4.5Graphics and Drawing4.63D Graphics Using OpenGL ES4.7Multimedia4.8Telephony4.9Connectivity4.10 Location-Based ServicesEach recipe lists some preliminary information, as follows:Amount of time required:The amount of time to read the recipe, reflect on the major pointsin the snippets of example code shown in the book, and examine the full code sample (which can be downloaded from developer.symbian.com/quickrecipesbook).Location of example code: (e.g., \Files)This is the location in the set of example codes in which you can find theexample code associated with the recipe.78SYMBIAN C++ RECIPESRequired library(s): (e.g., efsrv.lib)A code project must link to this Symbian library in order for the codeshown in the recipe to be successfully linked.
You can either add thelibrary to the MMP file, using the LIBRARY keyword, or add it using theMMP editor in the Carbide.c++ IDE. We always assume that your codeproject links to the Symbian OS user library (euser.lib) – since everyrecipe requires it – and do not list it below.Required header file(s): (e.g., f32file.h)The Symbian OS system header file required to access the APIs discussedin the recipe. Unless otherwise stated, the header file will be in the\epoc32\include directory of your SDK installation.Required platform security capability(s): (e.g., ReadUserData)Please see Chapter 3, Section 3.11, for more information about platformsecurity capabilities.Each recipe then presents the problem you are trying to solve, andprovides a solution and further discussion.
We have also highlightedsome potential issues and gotchas, and given you some advanced tipswhere appropriate.4.1 File HandlingAlmost all applications require access to the smartphone’s file system.Many applications need to store a user’s settings; for example, a gamemay need to store high-score data; a customizable dictionary applicationneeds to store word entries. This section contains file system-relatedrecipes, such as reading from and writing to the file.Symbian OS has a file server to handle all file-related aspects, such ascreating, renaming, deleting and accessing files, creating and removingdirectories, and receiving change notifications when the file system ismodified.
An application uses the client-side file server API to sendrequests to the file server. The recipes in this section discuss the file serverAPI in detail.Symbian OS uses a VFAT (Virtual File Allocation Table) file system.VFAT supports long filenames, up to 255 characters in length.
Thefilenames are not case-sensitive, which means ‘c:\data\test.dat’ isthe same as ‘C:\DATA\test.DAT’.Like many other VFAT operating systems, a filename in Symbian OSconsists of:• a drive letter• a path• a filename• an extension (optional).FILE HANDLING79On Symbian OS, a filename and its extension are separated by a periodcharacter (.). The drive letter and the path are separated by a backslashcharacter (\), and the path and the filename are also separated by abackslash character (\). However, when quoting path specifiers in aSymbian OS descriptor that describes a file path, you must use doublebackslashes (\\).A drive letter can be labeled from A: to Z:, where C: is always thephone’s internal memory and Z: is always the ROM drive.
Other drivesmay be used differently by manufacturers. For example, most S60 devicesuse the E: drive for the external memory card or hard drive. Most UIQdevices use the D: drive for the external media.4.1.1 Easy Recipes4.1.1.1Get a File Server SessionAmount of time required: 10 minutesLocation of example code: \FilesRequired library(s): efsrv.libRequired header file(s): f32file.hRequired platform security capability(s): NoneProblem: You want to get a handle to a file server session.Solution: The file server handles all aspects related to files. It runs in itsown process, EFILE.EXE. To call any API relating to file operations, youneed a handle to a file server session, and must use class RFs, which isdeclared in f32file.h. The library name is efsrv.lib.There are two common ways of getting a file server session:• Connect to the file server by calling RFs::Connect().RFs fileServer;User::LeaveIfError(fileServer.Connect());// Use the file server session here// ...fileServer.Close();• A GUI application can use a file server session owned by the CCoeEnvclass.
The following code shows how to get a file server session fromCCoeEnv:RFs& fileServer = iCoeEnv->FsSession();80SYMBIAN C++ RECIPESNote that the code has to be written in any class that definesiCoeEnv as its member variables. Examples of such classes are CEikApplication, CCoeAppUi and CCoeControl.If you are writing code that runs inside the application framework,within a class that does not have the iCoeEnv variable, you can useCCoeEnv::Static() to access CCoeEnv.
For example:RFs& fileServer = CCoeEnv::Static()->FsSession();4.1.1.2Write Binary Data to a FileAmount of time required: 15 minutesLocation of example code: \Files\BinaryFileRequired library(s): efsrv.libRequired header file(s): f32file.hRequired platform security capability(s): NoneProblem: You want to write binary data to a file.Solution: The basic operation to write binary data to a file uses the RFileclass, which is a class that handles low-level file operations.
The methodof RFile that is used to write binary data is RFile::Write(). Thereare several variants of Write() methods, which can be divided into twocategories:• Synchronous requests (i.e., blocking).• Asynchronous requests (i.e., complete some time later).For each category, there are variants that allow us to write binary datawith a specific length and/or from a specific position.The binary data in Symbian OS is normally stored in an 8-bit descriptor.Specifically, it is stored in one of the TDesC8-derived classes, that is,TBufC8, HBufC8 or RBuf8. Please refer to Chapter 3 for an introductionto descriptors.The following example shows how to write binary data in a descriptorto a file:void CBinaryFileAppUi::WriteDesCToFileL(RFs& aFs,const TDesC& aFileName, const TDesC8& aBuffer){RFile file;User::LeaveIfError(file.Replace(aFs, aFileName, EFileWrite));CleanupClosePushL(file);User::LeaveIfError(file.Write(aBuffer, aBuffer.Length()));CleanupStack::PopAndDestroy(&file);}FILE HANDLING81Discussion: The aFileName parameter is the filename where we wantto write the descriptor.
The filename is in the format ‘x:\directory\filename.extension’.What may go wrong when you do this: Some directories in SymbianOS require special capabilities for read/write access. For example, youneed TCB capability to write to the \resource directory. Please referto Chapter 3 for more information about data caging.The RFile::Replace() method overwrites an eventual existing file.If you don’t want to overwrite an existing file, use the RFile::Create()method instead. It returns an error code, KErrAlreadyExists (-11),if the file already exists, in which case you should use RFile::Open()to open the existing file and write into it.Notice that the file is pushed to the cleanup stack using CleanupClosePushL(). It means PopAndDestroy() will also close the file.
Itwill not destroy the file or its contents, as the name could imply!What may go wrong when you do this: Remember to always checkthe return value of any RFile methods, such as Replace() andWrite(). If you don’t check, your application may panic later.The complete list of Symbian OS error codes can be found at\epoc32\include\e32err.h.You can check the error using a standard if statement and thendisplay a dialog when an error happens.TInt err = file.Replace(aFs, aFileName, EFileWrite);if (KErrPathNotFound == err){// Do something when path is not found,// for example display dialog to the user.}Alternatively, you can use User::LeaveIfError(), as in theprevious snippet.The following code shows how to call the WriteDesCToFileL()function:// CONSTANTSconst TInt KMaxBuffer = 512;_LIT(KNewFileName,"c:\\data\\newfile.dat");...82SYMBIAN C++ RECIPESRFs& fileServer = iCoeEnv->FsSession();// Create a buffer to be written to the file.RBuf8 buffer;User::LeaveIfError(buffer.CreateMax(KMaxBuffer));CleanupClosePushL(buffer);// Fill the buffer with your data.// ...// Write buffer to the file.WriteDesCToFileL(fileServer, KNewFileName, buffer);// Delete the buffer.CleanupStack::PopAndDestroy(&buffer);The example above uses a public folder, c:\data, to store the data.Note that this folder is not protected using data caging (see Chapter 3).It means any other application can access it.