quick_recipes (779892), страница 34
Текст из файла (страница 34)
Email andMMS messages, in contrast, must be downloaded from the server usingthe Copy() function (this is similar to Recipe 4.4.5.7, except that youmust copy from the remote service to a local folder).Once a new entry has been created in either of these ways, ourapplication is notified through HandleSessionEventL(). In fact, newentries of all types (not just messages) will cause the callback to becalled, so we need to check whether the new entries are of a type thatwe are interested in. To help with this, we are given the TMsvId of theparent entry and a CMsvEntrySelection containing the IDs of thenew messages.
Our application handles entries of all types which havebeen created in the global inbox (which means they must be messageentries). You may want to add more checks to your own application,such as checking for a specific type of message (using the iType memberof TMsvEntry), or only checking for complete messages – the latter isimportant in the cases of email and MMS, and in fact in these casesit may be better to check the EMsvEntriesChanged case instead,as seen in the Summary Screen application example in Symbian OSCommunications Programming, 2nd Edition.As an example, our application provides a basic HandleNewIncomingMessagesL() function which just clears the TMsvEntryNew() attribute for all of the messages.
The CMsvEntry::ChangeAttributesL() function is a convenient way to set and clear a number of TMsvEntry attributes for a number of messages at once. Youmight refresh any cached lists of messages, update the user view of theinbox, display the new messages, forward the messages – whatever isappropriate for your application.void CSmsManager::HandleSessionEventL(TMsvSessionEvent aEvent, TAny*aArg1, TAny* aArg2, TAny* /*aArg3*/){switch (aEvent){...case (EMsvEntriesCreated):// what kind of entries are they?{if (iState == EWaitingForNewMessages){TMsvId* parentId = static_cast<TMsvId*>(aArg2);if (*parentId == KMsvGlobalInBoxIndexEntryId){CMsvEntrySelection* newMessageSelection =static_cast<CMsvEntrySelection*>(aArg1);CleanupStack::PushL(newMessageSelection);HandleNewIncomingMessagesL(*newMessageSelection);CleanupStack::PopAndDestroy(newMessageSelection);}}break;194SYMBIAN C++ RECIPES}...}}void CSmsManager::HandleNewIncomingMessagesL(CMsvEntrySelection&aSelection){iEntry->ChangeAttributesL(aSelection, 0, KMsvNewAttribute);// other handling, as appropriate for your application}Taking things further: You may wish to receive SMS messages destinedspecifically for your application, indicated by a specific text prefix; forinstance, a traffic report where the first words are ‘Traffic update’.
Itis desirable to intercept these messages before they are written to themessage store in the normal way, so that other applications, such as thephone’s messaging application, are not notified of your message. This isparticularly useful if the message is not a ‘standard’ class 1 SMS message,and you do not want the user to be notified that there is a new message,or attempt to read it.
To do this, rather than receiving a notification andthen checking whether the message was intended for your application, itis preferable to listen on a specific socket. Refer to the example titled EasyAPI for sending and receiving SMS datagrams on the Symbian DeveloperNetwork at developer.symbian.com/main/tools/utilities.4.4.6 Resources• Symbian OS Communications Programming, 2nd Edition: developer.symbian.com/commsbook.4.5 Graphics and DrawingOn Symbian OS, applications do not draw directly to the window, butuse a graphics context (GC) for drawing to the window. An area insidethe physical screen (the device’s display) first needs to be defined, anydrawing occurs inside that defined window area, thus preventing anapplication from drawing outside its window area.In principle, all normal graphics drawing in Symbian OS takes placein an RWindow-derived window, owned by the window server (WSERV).WSERV uses the font and bitmap server (FBSERV) for effective handlingof fonts and bitmaps.
It also manages other aspects of the user interaction(such as key input handling, pointer events, and so on). FBSERV ishighly optimized for speed and memory consumption and all fontsand bitmaps are loaded only once into memory, and then referencecounted to determine when they can be unloaded. The optimization canGRAPHICS AND DRAWING195occasionally cause problems. For example, if an application loads a fontand forgets to release it after use, it could lead to situations where the fontfile is left open. If the user tries to remove the font file from the file system,the installer returns an ‘In use’ error and removal is prevented.
Anotherpotential error situation comes with scalable graphics images. These areloaded into the memory once, and all future access is handled by usingthe cached image. If the content of the MIF file is altered, it might not bereflected when loading images, until the cached image is released fromthe memory, and the updated file reloaded.If you need to update the screen a number of times per second, forexample when writing a game, drawing through WSERV may be too slow.As an alternative, you can also draw graphics using direct screen access(DSA), which greatly reduces the overhead of communicating with thewindow server, and increases the drawing speed.When you create an application using the Symbian OS application framework, drawable windows are created by constructing CCoeControl-derived container classes for UIs, and the drawing is handled using CWindowGc in the CCoeControl’s Draw() function.
Incase you need to get access to the container’s window, you could geta handle to it by using the Window() function defined for CCoeControl, the area set for the container can be fetched with the Rect()function call and its position in the display is returned by the PositionRelativeToScreen() function. With CCoeControl, there is no needto activate/deactivate the graphics context (and trying to do so might leadto a panic) or to implement active objects for monitoring redraw events,since all of this is already handled by the Symbian OS applicationframework and the CCoeControl class.An important issue to understand with Symbian OS – and drawing init – is that Symbian OS is event-driven, and also all drawing is implemented as event-driven drawing.
This means that each redraw is startedwith an event, usually a WSERV-generated redraw event. WSERV implements a queue for storing redraw events in case they can’t be delivered,and this queue holds a maximum of only one redraw event per window.If your application is unable to receive and handle redrawing because itis handling an event of higher priority, subsequent redraw events can belost. However, as soon as the application can handle events again, it willprocess exactly one redraw event from the WSERV.This is important to understand, since if the application is busy handlingsome other events, it will not be able to receive redraw events until it hasfinished. This means that no updates to the window will occur until theapplication has completed processing for the other event.
Most often thishappens when using tight for or while loops or, for example, whenimplementing delays with calls to User::After(). It also can happenwhen using User::WaitForRequest() to wait active object requeststo complete. In the worst case scenario the window server will panic the196SYMBIAN C++ RECIPEShanging thread with ViewSrv 11 panic. This is why we have warned younot to use User::Wait. . .() throughout, whenever it has been shownin sample code (it is shown only to make the code snippet simpler).In case the drawing also has to be handled with these tight-loopingfunctions, the loops should be implemented as active objects where eachRunL call does one round of the loop and then sleeps for a while.
Thesleeping could, for example, be implemented as an RTimer/CPeriodictype of timer (with idle priority). This method would also allow thedrawing loops to be cancelled (since key events can be received and amenu can be shown), and it allows applications to receive redraw eventsfrom the WSERV. For more information about active objects, please referto Chapter 3.Drawing events are also buffered in the client side. In practice thismeans that lines inside the Draw() function are not executed one-by-onein the WSERV, but instead line commands are collected into a buffer,which will be executed when it is big enough or when it is flushed. For thisreason, having for/while loops or User::After() in the Draw()function and trying to do drawing into the same area while changingthe drawing content will not work well in practice. Instead, this kind ofdrawing should be timed or looped outside the Draw() function usingactive objects, drawing one state at a time, and waiting between draws.The most important feature of the Draw() function is that it is nonleaving and constant.
This means that no code inside the Draw()function may have the potential to leave – in case the leaving codecannot be avoided, it must be TRAPed. Since this function is constant, itcannot modify values so, for example, you can’t change state variablesbelonging to the class inside the Draw() function. Instead, you needto change the values outside and then call the DrawNow() function toinform WSERV to draw the required content to the container’s screen.All example code for drawing in normal application frameworks in thissection assumes that drawing is handled inside CCoeControl’s Draw()function, where the graphics context (GC) is retrieved as follows:void CMyContainer::Draw(const TRect& aRect,) const{CWindowGc& gc = SystemGc();}The example code in the recipes below shows just the snippetsmost relevant to the discussion in question.
Further information aboutgraphics and drawing on Symbian OS can be found in the SymbianDeveloper Library documentation, available in each SDK and online. Seethe Graphics section of the Symbian OS Guide for an overview of usingWSERV and FBSERV, and the C++ Component Reference section fordetails of each API. You will also find a set of recipes for using OpenGLES, for 3D graphics, later in Section 4.6.GRAPHICS AND DRAWING1974.5.1 Easy Recipes4.5.1.1Draw Lines and ShapesAmount of time required: 15 minutesLocation of example code: \Graphics_BasicsRequired library(s): gdi.lib, ws32.libRequired header file(s): gdi.h, w32std.hRequired platform security capability(s): NoneProblem: You want to draw lines and shapes to the screen.Solution: When drawing lines, either by using the line-drawing functionsor by using the shape-drawing functions, the lines and borders are drawnusing the currently set pen.
The most important settings for the pen arepen color and style.You can set the pen color by using the SetPenColor() function,and the pen style can be changed with SetPenStyle(). If you needlines with more than one pixel width, you can also change the pen sizewith the SetPenSize() function.The default value for the pen color is black and for the style is solid.The possible styles for the pen are as follows:• ENullPen (pen does not draw anything – i.e., is transparent).• ESolidPen (drawn with solid color).• EDottedPen (drawn as dotted line).• EDashedPen (drawn as dashed line).• EDotDashPen (drawn as alternating dashes and dots).• EDotDotDashPen (drawn as alternating single dashes and pairs ofdots).To draw a straight line you can call DrawLineXyz() functions,for example drawing a line from TPoint(10,10) to TPoint(50,60)could be done like this:gc.SetPenColor(KRgbRed);gc.SetPenStyle(CGraphicsContext::EDottedPen);gc.DrawLine(TPoint(10,10), TPoint (50,60));And to draw a rectangular area between these two points could bedone like this:gc.DrawRect(TRect(10,10,50,60));198SYMBIAN C++ RECIPESFor other line- and shape-drawing functionality, check the Graphics_Basics example code and also the Symbian Developer Library documentation for the CWindowGc class.4.5.1.2Draw Background Color or Fill a ShapeAmount of time required: 15 minutesLocation of example code: \Graphics_BasicsRequired library(s): gdi.lib, ws32.libRequired header file(s): gdi.h, w32std.hRequired platform security capability(s): NoneProblem: You want to draw a background color or fill the shapes youhave drawn.Solution: Brushes are used to fill the drawing area.