⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirscracceng.cpp

📁 symbian平台上如何在屏幕上快速的显示图片
💻 CPP
字号:
/*
* ============================================================================
*  Name     : CDirScrAccEng from DirScrAccEng.cpp
*  Part of  : DirScrAcc
*  Created  : 06/11/2003 by Forum Nokia
*  Description:
*     Engine for drawing using Direct Screen Access.
*  Version  :
*  Copyright: Nokia Corporation
* ============================================================================
*/

#include "DirScrAccEng.h"
#include "DirScrAccRenderer.h"

#include <eikenv.h>

// This number is for runnning in the device. Drawing would be too fast if the number were smaller.
// For the emulator this number is less relevant. Emulator knows only ticks that are 1/10 seconds. 
// Device ticks are 1/64 seconds.

const TInt KGenerationInterval = 10000;

_LIT(KDirScrAccTxt, "DirectScreenAccessDemo");

//
// class CDirScrAccEng
//
CDirScrAccEng::CDirScrAccEng(RWsSession& aClient, CWsScreenDevice& aScreenDevice, RWindow& aWindow, TBool aUseFrameBuffer)
: CTimer(CActive::EPriorityStandard),
	iClient(aClient),
	iScreenDevice(aScreenDevice),
	iWindow(aWindow),
    iDirectScreenAccess(0),
    iGc(0),
    iRegion(0),	
    iPosition(0,0),
    iDrawing(EFalse),
    iRenderer(0),	
    iScreenAddr(0),
    iOffScreenBmp(0),    
    iUseFrameBuffer(aUseFrameBuffer)
	{    
    iFlagRect.SetRect(iPosition, aWindow.Size());
    // calculate the (used) frame buffer size in bytes
    iFrameBufLen = iFlagRect.Width() * iFlagRect.Height() * 2;
	}

CDirScrAccEng* CDirScrAccEng::NewL(RWsSession& aClient, CWsScreenDevice& aScreenDevice, RWindow& aWindow, TBool aUseFrameBuffer)
    {
    CDirScrAccEng* self = new (ELeave) CDirScrAccEng(aClient, aScreenDevice, aWindow, aUseFrameBuffer);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(); // self;
    return self;
    }

CDirScrAccEng::~CDirScrAccEng()
	{
    if(IsActive())
	    Cancel();

	delete iDirectScreenAccess;	
    delete iRenderer;            
    delete iOffScreenBmp;    
	}

void CDirScrAccEng::ConstructL()
	{
	// contruct the timer
	CTimer::ConstructL();

	// Create the DSA object
	iDirectScreenAccess = CDirectScreenAccess::NewL(iClient, iScreenDevice, iWindow, *this);
	CActiveScheduler::Add(this);

    // create the offscreen bitmap
    iOffScreenBmp = new (ELeave) CFbsBitmap;
	iOffScreenBmp->Create(iScreenDevice.SizeInPixels(), EColor4K);

// for emulator, always use offscreen bitmap
#if defined(__WINS__)
    iUseFrameBuffer = EFalse;
#endif
    
    if(iUseFrameBuffer)        
        {
        // fetch screen buffer address
        TScreenInfoV01 screenInfo;
	    TPckg<TScreenInfoV01> sInfo(screenInfo);
	    UserSvr::ScreenInfo(sInfo);
         
        iScreenAddr = screenInfo.iScreenAddressValid ? (TUint8*)screenInfo.iScreenAddress : 0;
        User::LeaveIfNull(iScreenAddr);

        // skip the palette data in the beginning of frame buffer (16 entries in 12bit mode)
        iScreenAddr += 16 * 2;

        // initialise the raw redraw event (used when drawing directly to frame buffer)
        iRedraw.Set(TRawEvent::ERedraw);
        }

    // create our renderer
    iRenderer = CFlagRenderer::NewL(iFlagRect.Width(), iFlagRect.Height());
    
	}

// Start Drawing
void CDirScrAccEng::StartDrawingL()
	{
	if (iDrawing)
		User::Panic(KDirScrAccTxt, DirScrAccEngAlreadyStarted);
    
    // Initialise DSA

    // Trap the call to CDirectScreenAccess->StartL() to suppress system
    // error notes (e.g. active screen saver may cause problems)
	TRAPD(dsaErr, iDirectScreenAccess->StartL());
    if(dsaErr == KErrNone)
        {

	    // Get graphics context for it
	    iGc = iDirectScreenAccess->Gc();

	    // Get region that DSA can draw in
	    iRegion = iDirectScreenAccess->DrawingRegion();

	    // Set the display to clip to this region
	    iGc->SetClippingRegion(iRegion);

        iDrawing = ETrue;

        // request a timer event after a defined interval
        After(TTimeIntervalMicroSeconds32(KGenerationInterval));
        }
	}

// Stop Drawing
void CDirScrAccEng::StopDrawing()
	{
	if (!iDrawing)
		User::Panic(KDirScrAccTxt, DirScrAccEngAlreadyStopped);
	
	// Cancel timer and display
    // This is CActive::Cancel, which calls derived method DoCancel
	Cancel();
	iDrawing = EFalse;
	}
	
// Implement MDirectScreenAccess
void CDirScrAccEng::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
	{
	// Restart display
	// Note that this will result in the clipping region being updated
	// so that menus, overlaying dialogs, etc. will not be drawn over      
	StartDrawingL();    
	}

void CDirScrAccEng::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
	{
	// Cancel timer and display
	Cancel();
	iDrawing = EFalse;
	}

// Timer's RunL()
void CDirScrAccEng::RunL()
	{
	
    iRenderer->RenderNextFrameL((TUint8*)iOffScreenBmp->DataAddress());

    // blit the offscreen bitmap (if used) to screen
    if(!iUseFrameBuffer)
        {        
        iGc->BitBlt(iPosition, iOffScreenBmp, iFlagRect);
        // Force screen update: this is required for WINS, but may
	    // not be for all hardware. 
        // For Series 60 devices this is necessary, 
        // we can't access screen memory directly, 
        // rather we access a screen buffer.
        iDirectScreenAccess->ScreenDevice()->Update();
        }
    else
        {        
        // copy bitmap contents to frame buffer
        Mem::Copy(iScreenAddr, iOffScreenBmp->DataAddress(), iFrameBufLen);

        // Drawing to screen buffer (ScreenInfo) - force update
        // We do not use Graphics context, so we generate an event to get screen refreshed
        // As a side-effect, the backlight stays on        
        UserSvr::AddEvent(iRedraw);
        }        

	// Renew request
	After(TTimeIntervalMicroSeconds32(KGenerationInterval));

	}

// Timer's DoCancel()
void CDirScrAccEng::DoCancel()
	{
	// Cancel timer
	CTimer::DoCancel();

	// Cancel DSA
	iDirectScreenAccess->Cancel();    
	}

	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -