Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 94
Текст из файла (страница 94)
The entireapplication thread, with all its active objects, is suspended during thiswait. If you need animation to occur on a longer timescale, use an activeobject to handle the animation task.Using active objectsAnimation using active objects isn’t good enough for some purposes,because active objects are scheduled non-pre-emptively and, particularlyin application code, there is no guarantee about how long an activeobject event-handler function may take to run. Some animations have tokeep running or else they look silly. Examples include the flashing textcursor, or the analog or digital clocks on the bottom of your applicationbutton bar. A busy message that appears when a program is running aparticularly long event handler would (by definition) prevent any otheractive object from running.All such animations run as part of the window server in a windowserver animation DLL. They are required to be good citizens of the windowserver and to have very short-running active objects.
See Chapter 6 for adetailed description of active objects.Uikon Debug KeysAs we saw in Chapter 10, debug builds of the emulator allow you to usevarious key combinations to control and test your application’s use ofmemory. These keys are implemented as UIKON components. You canalso use the key combinations in Table 17.1 to control your program’s524GRAPHICS FOR DISPLAYTable 17.1 Key Combinations for Controlling DrawingKeyEffectCtrl+Alt+Shift+MCreates a ‘mover’ window that you can move allaround the screen, causing redraws underneath itCtrl+Alt+Shift+RCauses the entire application view to redrawCtrl+Alt+Shift+FCauses the window server client API to enableauto-flush, so that draw commands are sent to thewindow server as soon as they are issued, rather thanwaiting for the buffer to fill or for a program to issue aFlush()Try this and watch things slow down: it can be usefulfor naked-eye flicker testing.
It is also handy fordebugging redraws. You can step through drawing codeand see every command produce an instant result onthe emulator.Ctrl+Alt+Shift+GDisables auto-flushCtrl+Alt+Shift+KKills the application that currently has keyboard focus(this key is implemented by the window servercomponent)drawing behavior. Remember that these settings only apply to the currentapplication’s Uikon environment.Control ContextThe ActivateGc(), DeactivateGc() and ResetGc() functions ina control normally pass directly through to window server functions:gc.Activate(*iWin), gc.Deactivate(*iWin) and gc.Reset().These functions, and the way that CONE calls them when recursingthrough component controls, guarantee that your graphics context isproperly reset to default values before each control’s Draw() function iscalled.In some cases, you do not want your graphics context to reset to systemdefault values: instead, you want to set the default values to somethingdecided by the control.
For this purpose, you can use a control context,an interface that overrides the activate and reset behavior of the graphicscontext.A control that uses a control context stores a pointer to it in itsiContext data member. By testing the iContext value, a control candetermine whether or not to use the system graphics context for all itsdrawing operations. This explains the second case – first mentioned inSection 17.5, when discussing the activation of the graphics context – inSPECIAL EFFECTS525the action of a control’s ActivateGc(), which is listed again below,for convenience.EXPORT_C void CCoeControl::ActivateGc() const{CWindowGc& gc = iCoeEnv->SystemGc();if(iContext)iContext->ActivateContext(gc, *iWin);elsegc.Activate(*iWin);}See the SDK and examples for further details.ScrollingThe window server supports scrolling but, once again, this feature maynot be available in all user interface implementations.
If it is available,you can ask for a region of a window to be scrolled, up, down, left orright. This results in:• some image data being lost• the window server moving some image data in the requested direction• an area of the window becoming invalid.The (new) invalid area is exactly the same size as the amount of (old)image data that was lost.Scrolling is clearly always application-initiated.
After a scroll, youshould call DrawNow(): you do not need to invalidate the area that wasinvalidated by the scroll. You must ensure that the new drawing preciselyabuts onto the old data, without any visible joins.Transparent WindowsBefore Symbian OS v8.0, all windows were opaque.
In other words, thedraw color for each pixel on the screen came from a single window, thetop window in the z-order at that point on the screen.Symbian OS v8.0 added support for transparent windows. An application can say before it activates its window that it wants it to be transparent.It does this by associating a value in the range from 0 to 255 with eachpixel of a window.
This value is known as the alpha value and windowsare said to be ‘alpha blended’ together. When a window is drawn, thisvalue is used to merge the color from the top window with that of thewindow underneath it (and the window underneath that if it, too, istransparent). If the value is 255, then you see only the color from the topwindow; if it is 0, you see only the color from the window below.
For526GRAPHICS FOR DISPLAYintermediate values, the two colors are merged, with the weighting determined by the particular value. In order to make your window transparent,you must call one of these two functions:TInt RWindow::SetTransparencyBitmap(const CFbsBitmap&aTransparencyBitmap);TInt RWindow::SetTransparencyFactor(const TRgb& aTransparencyFactor);If you use SetTransparencyBitmap(), then the bitmap should bea gray-scale bitmap and the window server reads values from this bitmapto use as the alpha values.
The pixels of the bitmap are matched withthe pixels of the window in a one to one fashion. If the bitmap is smallerthan the window in one or both dimensions then it is tiled over thewindow’s area. With SetTransparencyFactor(), the single colorspecified (which again has to be a gray color) is used as the alpha valuefor each pixel of the window (so the level of transparency is constantacross the whole window).In Symbian OS v8.1, a second method of making windows transparentwas added.
This method can only work if the color mode of the screenis chosen to include alpha values. In this mode, for each pixel, an alphavalue is stored, in addition to the usual information about the red, greenand blue components. Currently the only display mode that supports thisis EColor16MA. To make a window transparent by this method, you needto call the following function before the window is activated:TInt RWindow::SetTransparencyAlphaChannel();To draw to a window with this sort of transparency, you need to setthe alpha values of the pen and brush colors that are used.
These controlhow much of the color that is already present in the relevant pixels showsthrough and how much of the color you are drawing that you see. Thecolor that is already there may come from the window (or windows)underneath or from previous draw commands to the same window.Only certain devices support transparent windows and the SetTransparency functions all return an error value of KErrNotSupported ifthis feature is not available. To support transparent windows, the windowserver has to be configured with the resources that it needs to processthem and this is decided when the phone boots up.17.8Window Server FeaturesFrom Symbian OS v7.0s onward, various features have been added to thewindow server that complicate exactly when a redraw occurs.
They canWINDOW SERVER FEATURES527also affect what gets drawn on the screen, but only for code that is notwell written.Flicker-Free RedrawingThe way redraws were performed was changed in Symbian OS v7.0s.Before this point all the drawing commands that make up a redraw wereapplied by the window server directly to the screen. Since then, if theflicker-free redrawing feature is turned on in the system, when the deviceis booted the window server creates a screen-sized bitmap called the offscreen bitmap. This bitmap is used to construct the result of the redrawand its content is then copied to the screen.When the client calls BeginRedraw(), the window server redirectsall the graphics contexts that are active on that window from the screen tothe off-screen bitmap.
It also draws the background color of the windowinto the off-screen bitmap for the area being redrawn. Then each drawcommand is drawn into the off-screen bitmap. When the client callsEndRedraw() the area being redrawn is copied from the bitmap to thescreen.Without the off-screen bitmap, flicker can occur in two ways. First,if some of the pixels are drawn twice in the redraw then it is possible(although unlikely for well-written code) that the user of the phone seesthose pixels change color twice. Secondly, if there are any sprites visibleover the part being drawn, then the sprite flickers with every drawingprimitive.
With flicker-free redrawing, all drawing operations update theoff-screen bitmap and the screen pixels are updated only once. Clearly,this eliminates the first source of flicker entirely and any sprite cannotflicker more than once. In fact, the sprite won’t flicker at all, as theoff-screen bitmap is copied to the screen in a special way that does notcause the sprite to flicker.If flicker-free redrawing is in operation, it is even more importantthat an application’s redraw draws to every pixel. Without flicker-freeredrawing, an undrawn pixel often continues to have the color that theapplication had previously drawn on the screen at that point.
Althoughthis is never guaranteed in a multitasking system, it does often happenin practice, especially when using DrawNow() to update part of yourapplication (that is, to invalidate the area and then redraw it straightaway). When using flicker-free redrawing, the off-screen bitmap starts offwith the background color of the window, not with its previously drawncontent, so you can never get away with this kind of mistake in yourdrawing code.Flicker-free redrawing is only in operation if it is configured in thewindow server at boot time.
It can be turned off for individual windowsby using the following function, passing the value EFalse:TInt RWindow::EnableOSB(TBool aStatus);528GRAPHICS FOR DISPLAYRedraw StoringWhen only a single window can contribute to the color of pixels atany point on the screen, then it is reasonably efficient to use a singleredraw to draw that part of the screen. With the advent of transparentwindows, several windows can contribute to the color of a particulargroup of pixels, so redraws to all of these windows would be needed. Itwas decided that this was not practical and redraw storing was invented.Although this was designed with transparent windows in mind, if turnedon it applies to all windows owned by all applications. This was firstadded in Symbian OS v8.0, with transparent windows, but there havebeen improvements to it in later releases.The first time an application draws its window, it is likely that it isa full redraw to the whole of the area of the window and the windowserver stores all the drawing commands that the application performs.