symbian下实现自定义模态对话框

来源:互联网 发布:涤纶网络丝的规格 编辑:程序博客网 时间:2024/06/03 18:15

大家可能对自定义控件有所了解,其实自定义对话框和自定义控件类似。但是自定义模态对话的实现最关键的地方就是进行阻塞。比如:

CAknInformationNote* pNote = new(ELeave) CAknInformationNote;
TInt nRet = pNote->ExecuteLD(_L("Test"));

 

首先介绍一下,我自己实现的思路:

1、建立一个活动对象;

2、建立一个活动对象调度器,使用调度器来达到阻塞的目的;

3、在活动对象类中新建一个自定义控件;并将该控件加入到AppUi的Stack,以获得按键信息;

 

以下是相应的代码,如有更好的解决方案,请多多赐教。。

 

/*
============================================================================
 Name        : MdDialog.h
 Author      : 赵旭峰
 Version     : 1.0
 Time    : 2011/05/30
 Description : 自定义模态对话框
============================================================================
*/

#ifndef MDDIALOG_H_
#define MDDIALOG_H_

#include <e32base.h>
#include "MdCtrl.h"

class CMdDialog : public CActive, public MMdCtrl
{
public:
 static CMdDialog* NewL();
 static CMdDialog* NewLC();
 ~CMdDialog();
 
private:
 CMdDialog();
 void ConstructL();
 
public:
 void StartL();
 
public:
 static TInt DoModalLD();
 
public:
 /*
  * 功能: 通知退出
  * 参数: 
  * 返回: 
  */
 virtual void NotifyExit();
 
 // from CActive
private:
 virtual void RunL();
 virtual void DoCancel();
 virtual TInt RunError(TInt aError);
 
private:
 RTimer iTimer;  // 定时器
 CMdCtrl* iCtrl;  // 自定义控件
};

#endif /* MDDIALOG_H_ */

 

 

/*
============================================================================
 Name        : MdDialog.cpp
 Author      : 赵旭峰
 Version     : 1.0
 Time    : 2011/05/30
 Description : 自定义模态对话框
============================================================================
*/

#include "MdDialog.h"

CMdDialog* CMdDialog::NewL()
{
 CMdDialog* self = CMdDialog::NewLC();
 CleanupStack::Pop(self);
 return self;
}

CMdDialog* CMdDialog::NewLC()
{
 CMdDialog* self = new(ELeave) CMdDialog;
 CleanupStack::PushL(self);
 self->ConstructL();
 return self;
}

CMdDialog::CMdDialog():
CActive(EPriorityStandard)
{
}

CMdDialog::~CMdDialog()
{
 // 取消运行
 if(IsActive())
  Cancel();
 // 定时器
 iTimer.Close();
}

void CMdDialog::ConstructL()
{
 // 初始化计数器和定时器
 User::LeaveIfError(iTimer.CreateLocal());
}

void CMdDialog::StartL()
{
 // 设定定时器状态为0.1秒
 iTimer.After(iStatus, 1000*100);
 // 提交异步请求
 SetActive();
}

TInt CMdDialog::DoModalLD()
{
 // 创建活动对象调度器
 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
 CleanupStack::PushL(scheduler);
 
 // 创建活动对象
 CMdDialog* active = CMdDialog::NewL();
 scheduler->Add(active);
 active->StartL();
 
 // 启动活动对象调度器
 CActiveScheduler::Start();
 
 // 删除活动对象
 if (active)
 {
  delete active;
  active = NULL;
 }
 
 // 删除活动对象调度器
 CleanupStack::PopAndDestroy(scheduler);
 
 return 0;
}

/*
 * 功能: 通知退出
 * 参数: 
 * 返回: 
 */
void CMdDialog::NotifyExit()
{
 // 删除自定义控件
 if(iCtrl)
  delete iCtrl, iCtrl = NULL;
 // 停止活动对象调度器
 CActiveScheduler::Stop();
}

void CMdDialog::RunL()
{
 // 创建自定义控件
 iCtrl = CMdCtrl::NewL(this);
}

void CMdDialog::DoCancel()
{
 
}

TInt CMdDialog::RunError(TInt aError)
{
 
}

 

 

 

/*
============================================================================
 Name        : MdCtrl.h
 Author      : 赵旭峰
 Version     : 1.0
 Time    : 2011/05/30
 Description : 自定义控件
============================================================================
*/

#ifndef MDCTRL_H_
#define MDCTRL_H_

#include <coecntrl.h>  // CCoeControl

class MMdCtrl
{
public:
 /*
  * 功能: 通知退出
  * 参数: 
  * 返回: 
  */
 virtual void NotifyExit() = 0;
};

// CMdCtrl
// 命令控制按钮组
class CMdCtrl : public CCoeControl
{
public:
 static CMdCtrl* NewL(MMdCtrl* aObserver);
 static CMdCtrl* NewLC(MMdCtrl* aObserver);
 // 析构函数
 ~CMdCtrl();
 
private:
 CMdCtrl(MMdCtrl* aObserver);
 void ConstructL();
 
public:  // 来自CCoeControl
 // 指针事件
 virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
 // 按键事件
 virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent);
 // 大小改变
 virtual void SizeChanged();
 // 位置改变
 virtual void PositionChanged();
 // 绘制
 virtual void Draw(const TRect& aRect) const;
 
private: // 绘制
 
 /* 功能: 画背景
 * 参数:  aGc:窗口设备句柄; aRect:控件区域
 * 返回值: -
 * 注解:  -
 */
 void DrawBackground(CWindowGc& aGc, TRect& aRect) const;
 
 /* 功能: 画前景
 * 参数:  aGc:窗口设备句柄; aRect:控件区域
 * 返回值: -
 * 注解:  -
 */
 void DrawForeground(CWindowGc& aGc, TRect& aRect) const;
 
private:
 MMdCtrl* iObserver;
};

#endif /* MDCTRL_H_ */

 

 

/*
============================================================================
 Name        : MdCtrl.cpp
 Author      : 赵旭峰
 Version     : 1.0
 Time    : 2011/05/30
 Description : 自定义控件
============================================================================
*/

#include <eikenv.h>   // CEikonEnv
#include <coeaui.h>   // CCoeAppUi

#include "MdCtrl.h"


CMdCtrl* CMdCtrl::NewL(MMdCtrl* aObserver)
{
 CMdCtrl* self = CMdCtrl::NewLC(aObserver);
 CleanupStack::Pop();
 return self;
}

CMdCtrl* CMdCtrl::NewLC(MMdCtrl* aObserver)
{
 CMdCtrl* self = new(ELeave) CMdCtrl(aObserver);
 CleanupStack::PushL(self);
 self->ConstructL();
 return self;
}

// 二次构造
void CMdCtrl::ConstructL()
{
 // 创建窗口
 CreateWindowL();
 
 // 设置区域
 SetExtentToWholeScreen();
 
 // 加入堆栈
 CEikonEnv::Static()->AppUi()->AddToStackL(this);
 
 // 没有父窗口时,激活自己
 ActivateL(); 
}

// 构造函数
CMdCtrl::CMdCtrl(MMdCtrl* aObserver):
iObserver(aObserver)
{
}

// 析构函数
CMdCtrl::~CMdCtrl()
{
 // 移出堆栈
 CEikonEnv::Static()->AppUi()->RemoveFromStack(this);
}

// 指针事件
TKeyResponse CMdCtrl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
{
 // 响应按键
 switch(aKeyEvent.iCode)
  {
  case EKeyDevice0:
  case EKeyDevice1:
  case EKeyDevice3:
   if(iObserver) iObserver->NotifyExit();
   break;
  }
 
 // 处理所有按键消息
 return EKeyWasConsumed;
}

// 按键事件
void CMdCtrl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{

}
  
// 大小改变
void CMdCtrl::SizeChanged()
{
 DrawNow();
}

// 位置改变
void CMdCtrl::PositionChanged()
{
 DrawNow();
}

// 绘制
void CMdCtrl::Draw(const TRect& /*aRect*/) const
{
 CWindowGc& gc = SystemGc();
 TRect rect = Rect();
 
 // 设置画板区域
 gc.SetClippingRect(rect);
 // 画背景
 DrawBackground(gc, rect);
 // 画前景
 DrawForeground(gc, rect);
}

/* 功能: 画背景
* 参数:  aGc:窗口设备句柄; aRect:控件区域
* 返回值: -
* 注解:  -
*/
void CMdCtrl::DrawBackground(CWindowGc& aGc, TRect& aRect) const
{
 aGc.SetBrushColor(TRgb(255,0,0));
 aGc.SetPenColor(TRgb(0,255,0));
 aGc.SetBrushStyle(CWindowGc::ESolidBrush);
 aGc.DrawRect(aRect);
}

/* 功能: 画前景
* 参数:  aGc:窗口设备句柄; aRect:控件区域
* 返回值: -
* 注解:  -
*/
void CMdCtrl::DrawForeground(CWindowGc& aGc, TRect& aRect) const
{

}

 

 

使用方法很简单:

 

#include "MdDialog.h"

TInt nRet = CMdDialog::DoModalLD();

原创粉丝点击