quick_recipes (779892), страница 37

Файл №779892 quick_recipes (Symbian Books) 37 страницаquick_recipes (779892) страница 372018-01-10СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 37)

If, for example, you have aneditor inside your own control, then you need to forward all necessarykey events in your container control’s OfferKeyEventL() function.208SYMBIAN C++ RECIPES4.5.3 Advanced Recipes4.5.3.1Use Off-Screen Images for DrawingAmount of time required: 15 minutesLocation of example code: \Graphics_ImagesRequired library(s): efsrv.lib, bitgdi.lib, ws32.libRequired header file(s): f32file.h, bitstd.h, bitdev.h,w32std.hRequired platform security capability(s): NoneProblem: You want to implement double-buffering to ensure flicker-freegraphics.Solution: Double-buffering is an established technique for drawing flickerfree graphics. It is an essential idiom used for rendering fluid motionin anything from drag and drop puzzle games to high-speed shoot‘em ups.Double-buffering makes use of an offscreen bitmap.

The first thing todo is construct a bitmap, and then create a graphics context from whichwe can use the actual drawing functions. To get a graphics context,we need to have a screen device made. The code for this part is asfollows:iBitmap = new(ELeave)CFbsBitmap();iBitmap->Create(ImgSize, EColor16M);iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);User::LeaveIfError(iBitmapDevice->CreateContext(iGraphicsContext));After these four lines are executed, we can use the function providedby iGraphicsContext (which is CFbsBitmapDevice) to draw intothe iBitmap (which is CFbsBitmap), and then just call DrawNow().WSERV will generate a redraw event and the container’s Draw() functionis called, in which you can use graphics context as usual to draw theiBitmap image onto the screen.Discussion: The most usual cause of graphics flickering is drawing thesame pixels multiple times over one draw event.

The easiest way to avoidflickering is to make the draw function code in such a way that all pixelsare drawn a minimum time over one draw event – basically what thismeans is not calling Clear(), DrawRect(), etc. for areas that will bedrawn later on in the same draw event.As can be seen in the example code in AnimationContainer.cpp,off-screen bitmaps can be used to draw GIF animation frames into animage that can be shown on the screen.GRAPHICS AND DRAWING209Tip: To avoid distortion in the image as well as to make the actualscreen drawing code faster, you should construct the off-screen imageto be the same size as the actual physical screen size in pixels.4.5.3.2Load GIF Animation ImagesAmount of time required: 25 minutesLocation of example code: \Graphics_ImagesRequired library(s): bitgdi.lib, ws32.lib, imageconversion.lib, apgrfx.lib, apmime.libRequired header file(s): bitstd.h, w32std.h, imagedata.h,imageconversion.h, apgcli.h, apmrec.hRequired platform security capability(s): NoneProblem: You want to load and draw all frames from a GIF image.Solution: You can use the CImageDecoder class also for loading GIFfiles, and other images that have multiple frames in them.

Sometimes itmight even be better for the application architecture to load MBM/MIFfiles with active object loops to enable event receiving while loadingmultiple frames.To load GIF images, you first need to construct a CImageDecoderinstance, as you did in Recipe 4.5.2.1. You should then check the amountof frames on it:iImageDecoder =CImageDecoder::FileNewL(iFsSession,aFileName,KtxTypeImageGif_8);iCurrCount = iImageDecoder->FrameCount();And then start looping the frame reading:void CAniFrame_Reader::NextImageL(void){if(iCurrCount > 0 && !IsActive()){iCurrImg++;// add 1 to the index, so we can read the next frameif(iCurrImg >= iCurrCount || iCurrImg < 0){// in case the index is non-valid, we set it to zero// should only happen after reading the last frameiCurrImg = 0;}delete iFrameImg;iFrameImg = NULL;iFrameImg = new(ELeave) CFbsBitmap();iFrameImg->Create(iImageDecoder->FrameInfo(iCurrImg).iOverallSizeInPixels,210SYMBIAN C++ RECIPESiImageDecoder->FrameInfo(iCurrImg).iFrameDisplayMode);delete iFrameMsk;iFrameMsk = NULL;iFrameMsk = new(ELeave) CFbsBitmap();iFrameMsk->Create(iImageDecoder->FrameInfo(iCurrImg).iOverallSizeInPixels, EGray2);iImageDecoder->Convert(&iStatus, *iFrameImg,*iFrameMsk,iCurrImg);SetActive();}}Since the Convert() function is asynchronous, RunL() will becalled when it has finished decoding the current frame.

With GIF imageframes, some frames are not full frames, but actually only have the pixelsthat have changed since the previous frame. Also, the frame might needto be drawn in another position than the full image rectangle. To makesure of what is drawn and where, you need to check the informationstored in the frame information object for the currently loaded frame:void CAniFrame_Reader::RunL(){if(iFrameMsk && iFrameImg){if(iFrameMsk->Handle() && iFrameImg->Handle()){TBool reDraw(EFalse);TRect drawArea(TPoint(0,0),iFrameImg->SizeInPixels());if(TFrameInfo::ERestoreToBackground &iImageDecoder->FrameInfo(iCurrImg).iFlags){reDraw = ETrue;}else{drawArea = iImageDecoder->FrameInfo(iCurrImg).iFrameCoordsInPixels;}iCallBack.AppendFrameL(*iFrameImg,*iFrameMsk,DrawArea,ReDraw);}}}With this example, the code for the frame and the instructions onwhere to draw it are directed to another level which, for example, can beimplemented with off-screen bitmap drawing:void CAnimationContainer::AppendFrameL(CFbsBitmap& aImage, CFbsBitmap&aMask, TRect aArea, TBool aReDraw){GRAPHICS AND DRAWING211if(iGraphicsContext){TSize imgSize(aImage.SizeInPixels());if(aReDraw){iGraphicsContext->DrawBitmap(TRect(0,0, imgSize.iWidth,imgSize.iHeight), &aImage);}else{iGraphicsContext->DrawBitmapMasked(aArea, &aImage,TRect(0, 0, imgSize.iWidth, imgSize.iHeight),&aMask, EFalse);}}DrawNow();}As you can see from the code samples, if the frame information flags aredefining that the background should be restored (with a ERestoreToBackground flag), the mask is not used, but the image is drawn withoutit.

This usually happens at least with the first frame, so the animation canstart from fresh.Tip: The example code uses a defined interval for timing the animation. You could also read the timing information from the frameinformation and get the frames timed exactly as they were designed tobe handled.What may go wrong when you do this: With this example old framesare not saved, to optimize the speed storage, so you don’t need tokeep loading them when looping the animation. But you need toremember that the maximum default heap is 1 MB, and if you exceedyour application’s maximum heap, you will get ‘Out of memory error’.For example, 20 frames on 320 × 240 sized images with 24 bits/pixelwill take a little over 4.6 MB of memory.4.5.3.3Draw Skins as Backgrounds (S60 Only)Amount of time required: 20 minutesLocation of example code: \Graphics_ImagesLibaries: aknskins.lib, aknskinsrv.lib,aknswallpaperutils.lib212SYMBIAN C++ RECIPESRequired header file(s): aknsbasicbackgroundcontrolcontext.h, aknsskininstance.h, aknsdrawutils.hRequired platform security capability(s): NoneProblem: You want to have the background drawn with the currentlyselected skin.Solution: The skin is drawn to a container by calling CAknsBasicBackgroundControlContext, so first you need to construct one:iBgContext =CAknsBasicBackgroundControlContext::NewL(KAknsIIDQsnBgAreaMain,TRect(0, 0, 1, 1), ETrue);The first argument defines which skin item is used, the second onedefines the area to be used and the third defines whether the parentcontrols (i.e., the control you wish to draw the skin to); the relativeposition to the screen should also be taken into account.As you can see, the rectangle for the object is not set here.

This is tomake sure it is always set correctly and as you can see from the example,the object is constructed before the rectangle area for the container isset. This means that as soon as the rectangle area for the container is setthe SizeChanged() function will be called, and in this function youshould always set the correct position and area:if ( iBgContext ){iBgContext->SetRect(Rect());if ( &Window() ){iBgContext->SetParentPos( PositionRelativeToScreen() );}}After this, you are ready to draw the skin into your container’s background:void CMySplashContainer::Draw(const TRect& /*aRect*/) const{CWindowGc& gc = SystemGc();MAknsSkinInstance* skin = AknsUtils::SkinInstance();AknsDrawUtils::Background(skin, iBgContext, this, gc, Rect());}Note that to make the skins actually work, you also need to implementthe MopSupplyObject() function in your container:TTypeUid::Ptr CMySplashContainer::MopSupplyObject(TTypeUid aId){GRAPHICS AND DRAWING213if (iBgContext){return MAknsControlContext::SupplyMopObject(aId, iBgContext );}return CCoeControl::MopSupplyObject(aId);}What may go wrong when you do this: The first argument forthe CAknsBasicBackgroundControlContext defines which skinitem is used.

Thus if you select the wrong background, your skin mightnot look ideal for the situation. In case you have problems with it,check the AknsConstants.h header file for different options.4.5.3.4Draw Outside the Symbian OS Application FrameworkAmount of time required: 40 minutesLocation of example code: \Graphics_NonAFWRequired library(s): ws32.lib, gdi.lib, apgrfx.libRequired header file(s): w32std.h, gdi.h, apgwgnam.hRequired platform security capability(s): NoneProblem: You want to draw without the application framework.Solution: When constructing GUI applications without using the standardapplication framework, the first task is to construct the screen device,which presents the device’s physical display.

Характеристики

Тип файла
PDF-файл
Размер
1,59 Mb
Материал
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6367
Авторов
на СтудИзбе
310
Средний доход
с одного платного файла
Обучение Подробнее