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

📄 essentials.cpp

📁 《UIQ 3 The Complete Guide》书的源代码
💻 CPP
字号:
// Copyright (C) UIQ Technology AB, 2007
//
// This material is provided "as is" without any warranty to its performance or functionality. 
// In no event shall UIQ Technology be liable for any damages whatsoever arising out of the
// use or inabilty to use this material. 


#include <e32cons.h>
#include "essentials.h"

GLDEF_C TInt E32Main();
GLDEF_C CConsoleBase* console; 

_LIT(KTextConsoleTitle, "Console");
_LIT(KTextFailed, "Failed with leave code = %d");
_LIT(KTextPressAnyKey, " [Press any key]\n");


// **************************************************** 
// CleanupDeletePushL() example
// **************************************************** 

MPolygon::~MPolygon()
	{
	_LIT(KMPolyDestruct, "MPolygon::~MPolygon\n");
	console->Printf(KMPolyDestruct);
	}

CSquare::CSquare()
{}

CSquare::~CSquare() 
	{
	_LIT(KCSquareDestruct, "CSquare::~CSquare\n");
	console->Printf(KCSquareDestruct);
	}

/*static*/ CSquare* CSquare::NewL()
	{
	CSquare* me = new(ELeave) CSquare();
	return (me);
	}


TInt CSquare::CalculateNumberOfVerticesL()
	{
	return (4);
	}

enum TPolygonType
{ ESquare };


LOCAL_C MPolygon* InstantiatePolygonL(TPolygonType aPolygon)
	{
	if (ESquare==aPolygon)
		return (CSquare::NewL());
	else
		return (NULL);
	}

void CleanupDeletePushLExampleL()
	{
	__UHEAP_MARK;
	_LIT(KStarting, "CleanupDeletePushLExampleL()\n");
	console->Printf(KStarting);
	
	MPolygon* square = InstantiatePolygonL(ESquare);
  
	// Try replacing the following line of code with CleanupStack::PushL()
	// It will succeed, but when the CleanupStack::PopAndDestroy() call is made
	// a User::42 panic occurs as described in Chapter 4
	CleanupDeletePushL(square); // The correct way to push a M-class pointer to the cleanup stack
	// CleanupStack::PushL(square); // The incorrect way
  
	// ... leaving calls would go here
  
	ASSERT(4==square->CalculateNumberOfVerticesL());
	CleanupStack::PopAndDestroy(square);
	
	_LIT(KEnding, "CleanupDeletePushLExampleL() - end\n");
	console->Printf(KEnding);
	__UHEAP_MARKEND;
	}

// **************************************************** 
// Change notification example for active objects
// **************************************************** 
CNotifyChange::CNotifyChange() : CActive(EPriorityStandard)
{ CActiveScheduler::Add(this); }

void CNotifyChange::ConstructL(const TDesC& aPath)
	{// Open a fileserver session
	User::LeaveIfError(iFs.Connect());
	iPath = aPath.AllocL();
	}

CNotifyChange* CNotifyChange::NewL(const TDesC& aPath) 
	{
	CNotifyChange* me = new(ELeave) CNotifyChange();
	CleanupStack::PushL(me);
	me->ConstructL(aPath);
	CleanupStack::Pop(me);
	return (me);
	}

CNotifyChange::~CNotifyChange()
	{
	Cancel();
	delete iPath;
	iFs.Close();
	}

void CNotifyChange::StartFilesystemMonitor()
	{// Only allow one request to be submitted at a time
	 // The caller must call Cancel() before submitting another
	 // Panic them if they don't
	if (IsActive())
	  {
	  _LIT(KAOExamplePanic, "CNotifyChange");
	  User::Panic(KAOExamplePanic, KErrInUse);
	  }
	// Monitor for all changes
	iFs.NotifyChange(ENotifyAll, iStatus, *iPath);
	SetActive(); // Mark this object active
	}

// Event handler method
void CNotifyChange::RunL()
	{
	// If an error occurred handle it in RunError()
	User::LeaveIfError(iStatus.Int());
	
	// Resubmit the request so as not to miss any future changes
	iFs.NotifyChange(ENotifyAll, iStatus, *iPath);
	SetActive();
	
	// Process the event
	_LIT(KChangeLog, "Change number: %d\n");
	console->Printf(KChangeLog, ++iChanges); // Logs the fact that a change occurred	
	}

void CNotifyChange::DoCancel()
	{// Cancel the timer
	iFs.NotifyChangeCancel(iStatus);
	}

TInt CNotifyChange::RunError(TInt aError)
	{// Called if RunL() leaves, aError contains the leave code
	_LIT(KErrorLog, "CNotifyChange::RunError %d\n");
	console->Printf(KErrorLog, aError); // Logs the error
	return (KErrNone); // Error has been handled
	}

// This method is used to allow the active scheduler loop to run and process active objects
// that have received completion events.  We need it in this test code to allow
// the active scheduler a chance to run and process outstanding completion events.
// 
// You do NOT need to use this method if you are writing application code,
// because it is already event driven.  It is used here purely as way to keep the 
// example code simple, within a console example rather than the GUI framework. 

LOCAL_C void RunIfReady(CActive::TPriority aPriorityLevel)
	{
	TInt completion;
	TBool readyObjects;
	do
		{
		readyObjects = CActiveScheduler::RunIfReady(completion, aPriorityLevel);
		}
	while (readyObjects);
	}

LOCAL_C void ChangeNotificationExampleL()
	{
	__UHEAP_MARK;
	_LIT(KStarting, "ChangeNotificationExampleL()\n");
	console->Printf(KStarting);
	
	RFs fs;
	User::LeaveIfError(fs.Connect());
	CleanupClosePushL(fs);
	
	_LIT(KTestDir, "c:\\essentials\\");
	User::LeaveIfError(fs.MkDir(KTestDir));

	// Monitor for changes in the test directory
	CNotifyChange* changeNotifier = CNotifyChange::NewL(KTestDir);
	CleanupStack::PushL(changeNotifier);
	changeNotifier->StartFilesystemMonitor();
	
	RFile file;
	_LIT(KTestFile, "c:\\essentials\\testfile");
	// This will cause a change notification
	User::LeaveIfError(file.Create(fs, KTestFile, EFileRead|EFileWrite));
	file.Close();	
	RunIfReady(CActive::EPriorityStandard);
	
	// This will cause a change notification
	User::LeaveIfError(fs.Delete(KTestFile));
	RunIfReady(CActive::EPriorityStandard);
	
	// This will cause a change notification
	fs.RmDir(KTestDir);
	RunIfReady(CActive::EPriorityStandard);	
	
	CleanupStack::PopAndDestroy(2, &fs); // changeNotifier, fs
	
	_LIT(KEnding, "ChangeNotificationExampleL() - end\n");
	console->Printf(KEnding);
	__UHEAP_MARKEND;
	}

// **************************************************** 
// Long running task example
// **************************************************** 

_LIT(KLongRunningTaskExPanic, "Example Panic");

void TLongRunningCalculation::StartCalculation()
	{// Flag a programming error if it's already running
	__ASSERT_DEBUG(iState==EWaiting, User::Panic(KLongRunningTaskExPanic, KErrInUse));
	iState=EBeginState;
	}
	
void TLongRunningCalculation::DoTaskStep()
	{// Do a short task step
	switch (iState)
		{
		case (EWaiting):
			iState = EBeginState;
			console->Printf(_L("EWaiting -> EBeginState\n"));
			// Task initialisation would go here
			break;
		case (EBeginState):
			iState = EIntermediateState; 
			console->Printf(_L("EBeginState -> EIntermediateState\n"));
			//	Task code would go here
			break;
		case (EIntermediateState):
			iState = EFinalState; 
			console->Printf(_L("EIntermediateState -> EFinalState\n"));
			// Task termination would go here
			break;
		case (EFinalState):	
			iState = EWaiting; 
			console->Printf(_L("EFinalState -> EWaiting\n"));
			// Task is finished
			break;
		default:
			ASSERT(EFalse); // Panic!  Should never get here
		}
	}

TBool TLongRunningCalculation::ContinueTask()
	{
	return (iState!=EWaiting);
	}

CBackgroundTask* CBackgroundTask::NewLC()
	{
	CBackgroundTask* me = new (ELeave) CBackgroundTask();
	CleanupStack::PushL(me);
	return (me);
	}

CBackgroundTask::CBackgroundTask() : CActive(EPriorityIdle) // Low priority task
{ CActiveScheduler::Add(this); }


// Issues a request to initiate a lengthy task
void CBackgroundTask::PerformRecalculation(TRequestStatus& aStatus)
	{
	iCallerStatus = &aStatus;
	*iCallerStatus = KRequestPending;
	__ASSERT_DEBUG(!IsActive(), User::Panic(KLongRunningTaskExPanic, KErrInUse));
	iCalc.StartCalculation(); // Start the task
	SelfComplete(); // Self-completion to generate an event
	}

void CBackgroundTask::SelfComplete()
	{// Generates an event on itself by completing on iStatus
	TRequestStatus* status = &iStatus;
	User::RequestComplete(status, KErrNone);
	SetActive();
	}

// Performs the background task in increments
void CBackgroundTask::RunL()
	{// Resubmit request for next increment of the task or stop
	if(iCalc.ContinueTask())
		{
		iCalc.DoTaskStep();
		SelfComplete();
		}
	else
		User::RequestComplete(iCallerStatus, iStatus.Int());
	}

void CBackgroundTask::CancelTask()
	{
	Cancel();
	}

void CBackgroundTask::DoCancel()
	{// Give iCalc a chance to perform cleanup
	iCalc.CancelCalculation();
	if (iCallerStatus) // Notify the caller
		User::RequestComplete(iCallerStatus, KErrCancel);
	}

CExampleActive::CExampleActive(CBackgroundTask& aTask) 
:	CActive(EPriorityStandard),
	iTask(aTask)
	{	
	CActiveScheduler::Add(this);
	}

CExampleActive* CExampleActive::NewLC(CBackgroundTask& aTask)
	{
	CExampleActive* me = new (ELeave) CExampleActive(aTask);
	CleanupStack::PushL(me);
	me->ConstructL();
	return (me);
	}

void CExampleActive::ConstructL()
	{// Submit long running task instruction
	iTask.PerformRecalculation(iStatus);
	SetActive();
	}

void CExampleActive::RunL()
	{//	Example is complete
	// 	Nothing to do here
	}
	
void CExampleActive::DoCancel()
	{
	iTask.CancelTask();
	}


LOCAL_C void LongRunningTaskExampleL()
	{
	__UHEAP_MARK;
	_LIT(KStarting, "LongRunningTaskExampleL()\n");
	console->Printf(KStarting);
	
	CBackgroundTask* backgroundTask = CBackgroundTask::NewLC();
	// Construction an active object, which starts the task when it is instantiated
	CExampleActive* example = CExampleActive::NewLC(*backgroundTask);
	
	RunIfReady(CActive::EPriorityIdle);
	
	CleanupStack::PopAndDestroy(2, backgroundTask); // example, backgroundTask
	
	_LIT(KEnding, "LongRunningTaskExampleL() - ending\n");
	console->Printf(KEnding);
	__UHEAP_MARKEND;
	}

// **************************************************** 
// Entrypoint and main test controller function and helper code
// **************************************************** 

LOCAL_C void DoStartL()
	{
	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
	CleanupStack::PushL(scheduler);
	CActiveScheduler::Install(scheduler);
	
	CleanupDeletePushLExampleL();
	ChangeNotificationExampleL();
	LongRunningTaskExampleL();
	
	CleanupStack::PopAndDestroy(scheduler);
	}


GLDEF_C TInt E32Main()
	{
	__UHEAP_MARK;
	CTrapCleanup* cleanup = CTrapCleanup::New();

	TRAPD(createError, console = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen)));
	if (createError)
		return createError;

	// Run application code inside TRAP harness, wait for key press then terminate
	TRAPD(mainError, DoStartL());
	if (mainError)
		console->Printf(KTextFailed, mainError);
		
	console->Printf(KTextPressAnyKey);
	console->Getch();
	
	delete console;
	delete cleanup;
	__UHEAP_MARKEND;
	return KErrNone;
	}



⌨️ 快捷键说明

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