Discussion Board

Results 1 to 8 of 8
  1. #1
    Registered User SQR's Avatar
    Join Date
    Mar 2009
    Posts
    65
    Здравствуйте. Прошу вашей помощи.
    Суть проблемы:
    Пишу приложение (без GUI), выводит на рабочий стол небольшое окошко, в котором должна отображаться картинка.
    Картинка - статичное gif изображение, конвертирую в битмап с помощью CImageDecoder:
    Code:
    void CMyServer::LoadImage()
        {
        iBitmap = new(ELeave) CFbsBitmap();
        CleanupStack::PushL(iBitmap);
        iDecoder = CImageDecoder::FileNewL(iFs,KFileName);
        iFrameInfo = iDecoder->FrameInfo(0);
        iRect = iFrameInfo.iFrameCoordsInPixels;
        iBitmap->Create(iRect.Size(),EColor16M);
        iDecoder->Convert(&iStatus,*iBitmap,0);
        iImageLoaded = ETrue;
        iIsDraw = ETrue;
        SetActive();
        }
    Код работает, картинка отображается нормально. Проблема возникла, когда я стал писать часть кода, отвечающего за отображение картинки в режиме ожидания. Эта часть описана в том же классе, что и CImageDecoder. Вот код -
    Code:
    void CMyServer::WaitWgEvent()
        {
        iIsDraw = EFalse;
        iGetEvent = ETrue;
        __LOGSTR("WaitWgEvent");
        iWs.EventReady(&iStatus);
        SetActive();
        }
    и
    Code:
    void CMyServer::GetWgEvent()
        {
       if(iStatus == KErrNone)
    	{
        TWsEvent e;
        iWs.GetEvent(e);
        __LOGSTR1("event: %d",e.Type());
    	}
        TInt WgId = iWs.GetFocusWindowGroup();
        CApaWindowGroupName* gn = CApaWindowGroupName::NewLC(iWs, WgId);
        __LOGSTR1("Uid: 0x%x",gn->AppUid());
        if(gn->AppUid() == TUid::Uid(0x101fd64c))
    	{
    	Draw(ETrue);
    	}else{
    	Draw(EFalse);
    	}
        }
    и
    Code:
    void CMyServer::RunL()
        {
        __LOGSTR("RunL");
        if(iIsDraw)
    	{
    	Draw(ETrue);
    	}
        if(iWaitEvent)
    	{
    	WaitWgEvent();
    	}
        if(iGetEvent)
    	{
    	GetWgEvent();
    	}
        }
    Собственно, проблема вот в чём. Обнаружилось падение приложения с WSERV 8, определил, что по каким-то неведомым мне причинам iStatus вовсе не равняется KErrNone, и поэтому часть кода не выполняется. Подскажите хоть в какую сторону копать, а то что-то совсем мысли кончились

  2. #2
    Nokia Developer Moderator truf's Avatar
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355
    Так чему равнялся iStatus?

  3. #3
    Registered User popov_andrew_e's Avatar
    Join Date
    Oct 2010
    Posts
    20
    Quote Originally Posted by SQR View Post
    Code:
    void CMyServer::WaitWgEvent()
        {
        iIsDraw = EFalse;
        iGetEvent = ETrue;
        __LOGSTR("WaitWgEvent");
        iWs.EventReady(&iStatus);
        SetActive();
        }
    нигде не указано событие, наступления которого вы ожидаете

  4. #4
    Registered User SQR's Avatar
    Join Date
    Mar 2009
    Posts
    65
    Quote Originally Posted by truf View Post
    Так чему равнялся iStatus?
    Code:
    void CMyServer::GetWgEvent()
        {
        __LOGSTR1("iStatus: %d",iStatus.Int());
       if(iStatus == KErrNone)
    	{
        TWsEvent e;
        iWs.GetEvent(e);
        __LOGSTR1("event: %d",e.Type());
    	}
    ....
    Лог:
    Code:
    10.12.2010	21.29.19	iStatus: -2147483647
    Quote Originally Posted by popov_andrew_e View Post
    нигде не указано событие, наступления которого вы ожидаете
    Как тогда работает код в другом проекте?
    Code:
    void CFgObserver::Fun()
        {
        iSession.EventReady(&iStatus);
        SetActive();
        }
    И всё прекрасно работает. А тут вот косяк

  5. #5
    Nokia Developer Moderator truf's Avatar
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355
    Показывайте код всего класса с хедером.

    Я не вижу, где у вас iWaitEvent становится ETrue
    Last edited by truf; 2010-12-11 at 10:16.

  6. #6
    Nokia Developer Moderator truf's Avatar
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355
    А в общем и так понятно,

    EventReady(TRequestStatus *)

    IMPORT_C void EventReady(TRequestStatus *aStat);
    Description

    Requests standard events from the window server.

    Standard events include all events except redraws and priority key events.

    The client application will typically handle the completed request using the RunL() function of an active object, and in this case the request status aStat should be the iStatus member of that CActive object.

    Notes:

    The active object runs when an event is waiting. You should call RWsSession::GetEvent(TWsEvent &) in the RunL() function to get the event.

    You should not call this function again until you've either called RWsSession::GetEvent(TWsEvent &) or RWsSession::EventReadyCancel().
    Когда у вас срабатывает RunL, вы сначала вызываете WaitWgEvent раньше GetWgEvent, а потом тут же GetWgEvent, хотя он должен вызываться в следующем RunL(). Местами их поменять надо. Сначала должен вызываться GetEvent, и только потом - EventReady.

  7. #7
    Registered User Kolayuk's Avatar
    Join Date
    Mar 2010
    Posts
    42
    Если окно не должно ловить события, можно воспользоваться RWsSptite из анимационных апи, он полностью синхронный. Т.е там не нужно постоянно получать эвенты от оконного сервера и обрабатывать. Плюс, только спрайты позволяют отобразить картинку с прозрачным фоном на S60 3rd - S60 3rd FP2 (на S60 5th появилась поддержка альфа-каналов в окнах, а в S^3 впрочем опять исчезла). Чтение картинки я бы тоже сихронизировал (не такая там и большая задержка). Прикрепляю пример работы со спрайтом, и сихронного чтения картинки

    Чтение картинок

    Code:
    		TBuf8<255> type;
    		GetFileType(path,type);
    		CImageDecoder* iImage=CImageDecoder::FileNewL(CCoeEnv::Static()->FsSession(),path,type,CImageDecoder::EOptionAlwaysThread);
    		BitMap = new (ELeave) CFbsBitmap;
    		TFrameInfo iFrameInfo = iImage->FrameInfo(0);
    		BitMap->Create(iFrameInfo.iOverallSizeInPixels, iFrameInfo.iFrameDisplayMode );
    		TRequestStatus ReqStat;
    		iImage->Convert(&ReqStat,*BitMap);
    		User::WaitForRequest(ReqStat);
    		delete iImage;
    
    void CMain::GetFileType(const TDesC& aFileName, TDes8& aFileType)
    {
    	TEntry FileEntry;
    	if(CCoeEnv::Static()->FsSession().Entry(aFileName,FileEntry) == KErrNone)
    	{
    		TBuf8<255> FileBuffer;
    		if(!FileEntry.IsDir())
    		{
    			TInt FileSize = FileEntry.iSize;
    			if(FileSize > 255){FileSize = 255;}
    			if(CCoeEnv::Static()->FsSession().ReadFileSection(aFileName,0,FileBuffer,FileSize) == KErrNone)
    			{
    				RApaLsSession RSession;
    				if(RSession.Connect() == KErrNone)
    				{	
    					TDataRecognitionResult FileDataType;
    					RSession.RecognizeData(aFileName,FileBuffer,*&FileDataType);
    					aFileType.Copy(FileDataType.iDataType.Des8());
    					RSession.Close();
    				}
    			}
    		}
    	}
    }

    Использование RWsSprite
    Code:
    #include "TopInfo.h"
    #include <const.h>
    #include <eikenv.h>
    #include <aknutils.h>
    #include <aknsutils.h>
    CTopInfo::CTopInfo()
    	{
    	}
    
    CTopInfo::~CTopInfo()
    	{
    	delete iText;
    	iFont=NULL;
    	delete iMaskGc;
    	delete iMask;
    	delete iBitGc;
    	delete iBitmap;
    	iSprite->Close();
    	iWinGroup->Close();
    	}
    
    CTopInfo* CTopInfo::NewLC()
    	{
    	CTopInfo* self = new (ELeave) CTopInfo();
    	CleanupStack::PushL(self);
    	self->ConstructL();
    	return self;
    	}
    
    CTopInfo* CTopInfo::NewL()
    	{
    	CTopInfo* self = CTopInfo::NewLC();
    	CleanupStack::Pop(); // self;
    	return self;
    	}
    
    void CTopInfo::ConstructL()
    	{
    	// get font name
    	TTypefaceSupport iTypefaceSupport;
    	TBuf<KMaxTypefaceNameLength> fontName;
    	fontName.FillZ(KMaxTypefaceNameLength);
    	CEikonEnv::Static()->ScreenDevice()->TypefaceSupport(iTypefaceSupport, 0);
    	fontName = iTypefaceSupport.iTypeface.iName;
    	// get font
    	TFontSpec FontSpec(fontName, KFontSize);	
    	FontSpec.iTypeface.SetIsProportional(ETrue);
    	CEikonEnv::Static()->ScreenDevice()->GetNearestFontInTwips(iFont,FontSpec);
    	
    	//iFont=CEikonEnv::Static()->NormalFont();
    	isVisible=EFalse;
    	//calculate size
    	TBuf<15> temp;
    	temp.Fill('P',15);
    	iSize=TSize(iFont->TextWidthInPixels(temp),iFont->HeightInPixels()*2+3);
    	iPos=TPoint(5,90);
    	// create image and it's mask
    	iBitmap=new(ELeave) CFbsBitmap();
    	iMask=new (ELeave) CFbsBitmap();
    		
    	iBitmap->Create(iSize,EColor16M);
    	iMask->Create(iSize,EColor16M);
    		
    	CFbsBitmapDevice* BitDevice=CFbsBitmapDevice::NewL(iBitmap);
    	CFbsBitmapDevice* MaskDevice=CFbsBitmapDevice::NewL(iMask);
    		
    	BitDevice->CreateContext(iBitGc);
    	MaskDevice->CreateContext(iMaskGc);
    		
    	iBitGc->UseFont(iFont);
    	iMaskGc->UseFont(iFont);
    	//create window group with high priority (always at front)
    	iWinGroup=new (ELeave) RWindowGroup(CEikonEnv::Static()->WsSession());
    	iWinGroup->Construct((TUint32)iWinGroup);
    	iWinGroup->EnableReceiptOfFocus(EFalse);
    	iWinGroup->SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront);
    	//create sprite
    	iSprite= new (ELeave) RWsSprite(CEikonEnv::Static()->WsSession());
    	iSprite->Construct(*iWinGroup,iPos,0);
    	iMember.iBitmap=NULL; // no image
    	iMember.iMaskBitmap=NULL;
    	iMember.iOffset=TPoint(0,0);
    	iMember.iInterval=TTimeIntervalMicroSeconds32(0);
    	iMember.iInvertMask=ETrue; // black - not transparadent, white - transparadent
    	iSprite->AppendMember(iMember);
    	iSprite->SetPosition(iPos);
    	iSprite->Activate();
    	CEikonEnv::Static()->WsSession().Flush();
    	iText=HBufC::New(1024);
    	Hide();
    	}
    void CTopInfo::Show()
    	{
    	isVisible=ETrue;
    	iMember.iBitmap=iBitmap; //bitmap isn't NULL -> sprite is shown
    	iMember.iMaskBitmap=iMask;
    	iSprite->UpdateMember(0,iMember);
    	iSprite->SetPosition(iPos);
    	CEikonEnv::Static()->WsSession().Flush();
    	}
    
    void CTopInfo::Hide()
    	{
    	isVisible=EFalse;
    	iMember.iBitmap=NULL; // bitmap is NULL -> sprite is hidden
    	iMember.iMaskBitmap=NULL;
    	iSprite->SetPosition(iPos);
    	iSprite->UpdateMember(0,iMember);
    	CEikonEnv::Static()->WsSession().Flush();
    	}
    void CTopInfo::Draw()
    	{	// drawing at bitmap and it's mask 
    	TRgb color;
    	MAknsSkinInstance* skin = AknsUtils::SkinInstance();
    	AknsUtils::GetCachedColor(skin,color,KAknsIIDQsnTextColors,EAknsCIQsnTextColorsCG6 );
    	// split text to lines
    	CDesCArray* arr = new (ELeave) CDesCArrayFlat(3);
    	TBuf<3> sep(_L(", "));
    	while (iText->Des().Find(sep)!=KErrNone)
    		{
    		TInt f=iText->Des().Find(sep);
    		if (f==KErrNotFound){break;}
    		arr->AppendL(iText->Des().Left(f));
    		iText->Des().Copy(iText->Des().Right(Abs(f-iText->Des().Length()+sep.Length())));
    		}	
    	arr->AppendL(iText->Des());
    	//draw
    	iBitGc->SetBrushColor(color);
    	iBitGc->SetBrushStyle(CFbsBitGc::ESolidBrush);
    	iBitGc->SetPenColor(color);
    	iBitGc->DrawRect(TRect(-1,-1,iSize.iWidth+1,iSize.iHeight+1));
    	iBitGc->SetBrushColor(color);
    	iBitGc->SetBrushStyle(CFbsBitGc::ENullBrush);
    	iBitGc->SetPenColor(color);
    	iBitGc->UseFont(iFont);
    	iBitGc->DrawText(arr->MdcaPoint(0),TRect(0,0,iFont->TextWidthInPixels(arr->MdcaPoint(0)),iFont->HeightInPixels()),iFont->AscentInPixels(),CFbsBitGc::ELeft,0);
    	iBitGc->DrawText(arr->MdcaPoint(1),TRect(0,3+iFont->HeightInPixels(),iFont->TextWidthInPixels(arr->MdcaPoint(1)),3+2*iFont->HeightInPixels()),iFont->AscentInPixels(),CFbsBitGc::ELeft,0);
    		
    	TRgb TransColor(0,0,0);
    	iMaskGc->SetBrushColor(KRgbWhite);
    	iMaskGc->SetBrushStyle(CFbsBitGc::ESolidBrush);
    	iMaskGc->SetPenColor(KRgbWhite);
    	iMaskGc->DrawRect(TRect(-1,-1,iSize.iWidth+1,iSize.iHeight+1));
    	iMaskGc->SetPenColor(TransColor);
    	iMaskGc->SetBrushColor(TransColor);
    	iMaskGc->SetBrushStyle(CFbsBitGc::ENullBrush);
    	iMaskGc->UseFont(iFont);
    	iMaskGc->DrawText(arr->MdcaPoint(0),TRect(0,0,iFont->TextWidthInPixels(arr->MdcaPoint(0)),iFont->HeightInPixels()),iFont->AscentInPixels(),CFbsBitGc::ELeft,0);
    	iMaskGc->DrawText(arr->MdcaPoint(1),TRect(0,3+iFont->HeightInPixels(),iFont->TextWidthInPixels(arr->MdcaPoint(1)),3+2*iFont->HeightInPixels()),iFont->AscentInPixels(),CFbsBitGc::ELeft,0);
    	CEikonEnv::Static()->InfoMsg(iText->Des());
    //update image (if needed)
    	if (isVisible)
    		{
    		iMember.iBitmap=iBitmap;
    		iMember.iMaskBitmap=iMask;
    		}
    	
    	iSprite->UpdateMember(0,iMember);
    	iSprite->SetPosition(iPos);
    	CEikonEnv::Static()->WsSession().Flush();
    	delete arr;
    	}
    void CTopInfo::Update(TPtr8 aText)
    	{
    	iText->Des().Copy(aText);
    	Draw();
    	}

  8. #8
    Registered User SQR's Avatar
    Join Date
    Mar 2009
    Posts
    65
    truf,
    Огромное спасибо за разьяснения!
    Kolayuk,
    Спасибо, но почему-то User::WaitForRequest(ReqStat) никогда не завершается.
    В итоге решил проблему с использованием CActiveSchedulerWait, теперь всё работает как нужно.
    За спрайты тоже спасибо, но пока их использовать наверное не буду, т.к. картинка непрозрачная.

Similar Threads

  1. RWsSession and EventReady
    By spanish_sweetie in forum Symbian C++
    Replies: 6
    Last Post: 2010-12-11, 11:55
  2. connect () failed with RWsSession
    By amipatel in forum Symbian User Interface
    Replies: 6
    Last Post: 2008-07-19, 10:11
  3. RWsSession lost events
    By vitor.hugo in forum Symbian C++
    Replies: 0
    Last Post: 2007-07-03, 11:44
  4. RWsSession variable differences
    By newnb in forum Symbian C++
    Replies: 1
    Last Post: 2006-12-19, 02:26
  5. how to use RWsSession::SimulateKeyEvent(key);
    By liafail in forum Symbian C++
    Replies: 3
    Last Post: 2006-11-30, 14:38

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved