今天闲来无事写了一个活动对象的测试代码,谁知道一运行死活跑不起来.程序执行到SetActive()就自动退出.硬是把这个简单的例子搞了2个小时. 后来才知道原来Carbide.vs提供的Active框架没有重写NewL()或者NewLC()方法,而我直接调用new (ELeave) CActiveTest2NewClass;并没有初始化ConstructL()里面的数据.编译也不报错,Debug跟踪却是下面一行出问题.郁闷的要命.

       下面的代码就是今天的收获:

CActiveTest2AppUi from ActiveTest2Appui.h/*

============================================================================

 Name        : CActiveTest2AppUi from ActiveTest2Appui.h

 Author      :

 Version     :

 Copyright   : Your copyright notice

 Description : Declares UI class for application.

============================================================================

*/

#ifndef ACTIVETEST2APPUI_H

#define ACTIVETEST2APPUI_H

// INCLUDES

#include <aknappui.h>

// FORWARD DECLARATIONS

class CActiveTest2Container;

class CActiveTest2NewClass;

// CLASS DECLARATION

/**

* Application UI class.

* Provides support for the following features:

* - EIKON control architecture

*

*/

class CActiveTest2AppUi : public CAknAppUi

    {

    public: // // Constructors and destructor

        /**

        * EPOC default constructor.

        */     

        void ConstructL();

        /**

        * Destructor.

        */     

        ~CActiveTest2AppUi();

       

    public: // New functions

    public: // Functions from base classes

    private:

        // From MEikMenuObserver

        void DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane);

    private:

        /**

        * From CEikAppUi, takes care of command handling.

        * @param aCommand command to be handled

        */

        void HandleCommandL(TInt aCommand);

        /**

        * From CEikAppUi, handles key events.

        * @param aKeyEvent Event to handled.

        * @param aType Type of the key event.

        * @return Response code (EKeyWasConsumed, EKeyWasNotConsumed).

        */

        virtual TKeyResponse HandleKeyEventL(

            const TKeyEvent& aKeyEvent,TEventCode aType);

    private: //Data

        CActiveTest2Container* iAppContainer;

  CActiveTest2NewClass* iTest2NewClass;

    };

#endif

CActiveTest2AppUi from ActiveTest2Appui.cpp/*

============================================================================

 Name        : CActiveTest2AppUi from ActiveTest2Appui.cpp

 Author      :

 Version     :

 Copyright   : Your copyright notice

 Description : CActiveTest2AppUi implementation

============================================================================

*/

// INCLUDE FILES

#include "ActiveTest2Appui.h"

#include "ActiveTest2Container.h"

#include <ActiveTest2.rsg>

#include "ActiveTest2.hrh"

#include "ActiveTest2NewClass.h"

#include <avkon.hrh>

#include <aknnotewrappers.h>

// ================= MEMBER FUNCTIONS =======================

//

// ----------------------------------------------------------

// CActiveTest2AppUi::ConstructL()

//

// ----------------------------------------------------------

//

void CActiveTest2AppUi::ConstructL()

    {

    BaseConstructL();

    iTest2NewClass = CActiveTest2NewClass::NewL();

    iAppContainer = new (ELeave) CActiveTest2Container;

    iAppContainer->SetMopParent( this );

    iAppContainer->ConstructL( ClientRect() );

    AddToStackL( iAppContainer );

    }

// ----------------------------------------------------

// CActiveTest2AppUi::~CActiveTest2AppUi()

// Destructor

// Frees reserved resources

// ----------------------------------------------------

//

CActiveTest2AppUi::~CActiveTest2AppUi()

    {

    if (iAppContainer)

        {

        RemoveFromStack( iAppContainer );

        delete iAppContainer;

        }

 if(iTest2NewClass)

 {

  delete iTest2NewClass;

 }

   }

// ------------------------------------------------------------------------------

// CActiveTest2AppUi::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)

//  This function is called by the EIKON framework just before it displays

//  a menu pane. Its default implementation is empty, and by overriding it,

//  the application can set the state of menu items dynamically according

//  to the state of application data.

// ------------------------------------------------------------------------------

//

void CActiveTest2AppUi::DynInitMenuPaneL(

    TInt /*aResourceId*/,CEikMenuPane* /*aMenuPane*/)

    {

    }

// ----------------------------------------------------

// CActiveTest2AppUi::HandleKeyEventL(

//     const TKeyEvent& aKeyEvent,TEventCode /*aType*/)

// takes care of key event handling

// ----------------------------------------------------

//

TKeyResponse CActiveTest2AppUi::HandleKeyEventL(

    const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/)

    {

    return EKeyWasNotConsumed;

    }

// ----------------------------------------------------

// CActiveTest2AppUi::HandleCommandL(TInt aCommand)

// takes care of command handling

// ----------------------------------------------------

//

void CActiveTest2AppUi::HandleCommandL(TInt aCommand)

    {

    switch ( aCommand )

        {

        case EAknSoftkeyBack:

        case EEikCmdExit:

            {

            Exit();

            break;

            }

        case EActiveTest2CmdAppTest:

            {

   // Info message shown only in the emulator

   //iEikonEnv->InfoMsg(_L("test"));

   

   //Load localized message from the resource file

   //HBufC* message = CEikonEnv::Static()->AllocReadResourceLC(R_MESSAGE_TEXT);

   // Show information note dialog

   //CAknInformationNote* note = new (ELeave) CAknInformationNote;

   //note->ExecuteLD(message->Des());

   //CleanupStack::PopAndDestroy(message);

            iTest2NewClass->StartL(3000000);

            break;

            }

        // TODO: Add Your command handling code here

        default:

            break;     

        }

    }

 

ActiveTest2NewClass.h

/*

============================================================================

 Name        : ActiveTest2NewClass.h

 Author      :

 Version     :

 Copyright   : Your copyright notice

 Description : CActiveTest2NewClass declaration

============================================================================

*/

#ifndef ACTIVETEST2NEWCLASS_H

#define ACTIVETEST2NEWCLASS_H

#include <e32base.h> // For CActive, link against: euser.lib

#include <e32std.h>  // For RTimer, link against: euser.lib

class CActiveTest2NewClass : public CActive

{

public:

 // C++ constructor

 CActiveTest2NewClass();

 

 // Second-phase constructor

 void ConstructL();

 

 // Cancel and destroy

 ~CActiveTest2NewClass();

public: // New functions

 // Function for making the initial request

 void StartL(TTimeIntervalMicroSeconds32 aDelay);

 

//就是下面两个方法Carbide.vs没提供

 static CActiveTest2NewClass* NewLC();

 static CActiveTest2NewClass* NewL();

private: // From CActive

 // Handle completion

 void RunL();

 

 // How to cancel me

 void DoCancel();

 

 // Override to handle leaves from RunL(). Default implementation causes

 // the active scheduler to panic.

 //void RunError(TInt aError);

private:

 enum TActiveTest2NewClassState

 {

     EUninitialized, // Uninitialized

     EInitialized, // Initalized

     EError   // Error condition

 };

private:

 TInt    iState;  // State of the active object

 RTimer iTimer;  // Provides async timing service

 TInt iCount;

};

#endif

 

ActiveTest2NewClass.cpp

/*

============================================================================

 Name        : ActiveTest2NewClass.cpp

 Author      :

 Version     :

 Copyright   : Your copyright notice

 Description : CActiveTest2NewClass implementation

============================================================================

*/

#include "ActiveTest2NewClass.h"

#include <eikenv.h >

CActiveTest2NewClass::CActiveTest2NewClass() : CActive(EPriorityStandard) // Standard priority

{

}

void CActiveTest2NewClass::ConstructL()

{

 User::LeaveIfError(iTimer.CreateLocal()); // Initialize timer

 CActiveScheduler::Add(this);    // Add to scheduler

}

CActiveTest2NewClass* CActiveTest2NewClass::NewLC()

{

 CActiveTest2NewClass* self = new (ELeave) CActiveTest2NewClass;

 CleanupStack::PushL(self);

 self->ConstructL();

 return self;

}

CActiveTest2NewClass* CActiveTest2NewClass::NewL()

{

 CActiveTest2NewClass* self = NewLC();

 CleanupStack::Pop(self);

 return self;

}

CActiveTest2NewClass::~CActiveTest2NewClass()

{

 Cancel(); // Cancel any request, if outstanding

 // Delete instance variables if any

}

void CActiveTest2NewClass::DoCancel()

{

 iTimer.Cancel();

}

void CActiveTest2NewClass::StartL(TTimeIntervalMicroSeconds32 aDelay)

{

 Cancel();      // Cancel any request, just to be sure

 iState = EUninitialized;

 iTimer.After(iStatus, aDelay); // Set for later

 SetActive();     // Tell scheduler a request is active

}

void CActiveTest2NewClass::RunL()

{

 if (iState == EUninitialized) {

  // Do something the first time RunL() is called

  //iState = EInitialized;

  iCount++;

  _LIT(TempString,"the iCount's value is :");

  HBufC* iBuf = HBufC::NewLC(100);

  iBuf->Des().Copy(TempString);

  iBuf->Des().AppendNum(iCount);

  CEikonEnv::Static()->InfoMsg(*iBuf);

  CleanupStack::PopAndDestroy(iBuf);

 } else if (iState != EError) {

  // Do something

 }

 iTimer.After(iStatus, 3000000); // Set for 1 sec later

 SetActive();     // Tell scheduler a request is active

}

 

另外就是以下几点收获:

1:debug到某一行出错并不代表就是这行的错误,可能是它上面一行,要看debug窗口里面红色显示的内容.

2:在epoc32\wins\c\system\Bootdata下面建一个ErrRd文件(无扩展名),可以让程序在关闭退出的时候报一个错误码.例如我的这个错误报kern-exec 0.之后可以到