免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 608 | 回复: 0
打印 上一主题 下一主题

Symbian学习笔记17 之 CCoeControl控件 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-29 12:35 |只看该作者 |倒序浏览

CCoeControl是所有控件的基类,它封装了一个控件的基本属性和功能。编写简单控件涉及到的函数主要有以下三类:初始化、绘图及用户输入处理。下面是一个简单控件的声明。

class CSimpleControl : public CCoeControl

{

public:

void ConstuctL(const TRect& aRect);

~CSimpleControl();

private:

void Draw(const TRect& aRect) const;

TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);

};

初始化:控件的初始化包括三个主要内容:创建控件窗口,设置控件大小及激活控件。控件的默认大小为0 x 0,因此必须设置大小,否则将不可见。因此这三个步骤必不可少。初始化一般在第二阶段构造函数ConstructL()完成。

void CSimpleControl::ContructL(const TRect& aRect)

{

CreateWindowL();

SetRect(aRect);

ActivateL();

}

绘图:直接决定控件外观的函数是Draw()函数。

void CSimpleControl::Draw(const TRect& aRect) const

{

CWindowGc& gc = SystemGc();

gc.SetPenStyle(CGraphicsContext::ENullPen);

gc.SetPenColor(KRgbRed);

gc.SetBrushColor(KRgbDarkBlue);

gc.SetBrushStyle(CGraphicsContext::ESolidBrush);

gc.DrawRect(aRect);

}

在这段代码中,首先调用SystemGc()获取图形上下文,SystemGc()是CCoeControl的一个成员函数;然后设置相应的图形上下文项;最后调用绘图函数DrawRect()画一个矩形。

所有的绘图都是通过图形上下文(graphics context,GC)来完成的。在Symbian OS中,定义了一个抽象类CGraphicsContext来统一图形上下文的接口,为设备无关的绘图提供了丰富的API。派生类CWindowGc和CFbsBitGc则具体实现了这些API。我们可以直接使用CFbsBitGc来绘图,但不推荐使用这种方式。在实际编程时,应用程序应该使用CWindowGc通过窗口服务器来进行绘图。CWindowGc的绘图请求在窗口服务器的客户端缓冲区上进行缓存,这样可以一次性向窗口服务器提交多个绘图请求以提高绘图效率。CONE为每个GUI应用程序提供一个CWindowGc实例作为控件的缺省图形上下文,它由CConEnv创建,并且可以 使用CCoeControl::SystemGc()来进行访问。

 

图形上下文保存有下列对绘图函数有着重要影响的上下文项。

1. 画笔: pen定义绘图模式(颜色、样式和大小),它用来绘制线、轮廓以及文本。

2. 刷子:brush定义了填充模式、背景色或样式。

3. 字体:font定义了用来绘制文本的字体。图形上下文没有默认的字体,因此在使用相关文本函数前,必须调用UseFont()设置字体。另外,在使用完字体后必须调用DiscardFont()来删除字体,以免内存泄漏。

4. 当前位置:当前位置由MoveTo()和各种DrawXxxTo()成员函数来设置(绝对位置),并由MoveBy()和DrawXxxBy()移动(相对位置)。

5. 原点:origin定义了相对与设备原点的偏移,绘图时使用该偏移,可以使用SetOrigin()来设置原点。默认的原点为(0,0)。

6. 剪辑区域:clipping region定义图形操作中想要剪辑的区域。可以指定一个简单的矩形或任意复杂的区域。设置剪辑区域之后,只有落在剪辑区域内的绘图操作才被显示出来。可以使用SetClippingRect()函数来设置矩形剪辑区域,使用CancelClippingRect()来取消它;使用SetClippingRegion()函数来设置任意复杂的剪辑区域,使用CancelClippingRegion()来取消它;

使用Reset()可以将所有的上下文项设置为默认值。系统调用Draw()函数之前会自动调用Reset()函数,因此通常不需要在控件中显式调用该函数。

在设置好图形上下文后,可以调用各种绘图函数在控件上进行绘图。几乎所有的绘图函数都被设计为能够成功执行,因而一般不返回任何值。这使得多个绘图函数能够被打包为一条消息发送到服务器执行。如果绘图函数有返回值的话,这将是不可能的。

(1) 点和线.这些函数使用当前画笔。

virtual void Plot(const TPoint& aPoint);

virtual void DrawLine(const TPoint& aPnt1, const TPoint& aPnt2);

virtual void DrawLineTo(const TPoint& aPoint);

virtual void DrawLineBy(const TPoint& aVector);

virtual void DrawArc(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd);

virtual void DrawPolyLine(const CArrayFix<TPoint>* aPointList);

virtual void DrawPolyLine(const TPoint* aPointList, TInt aNumPoints);

(2) 实心轮廓图形.这些函数使用画笔和画刷,画笔用来绘制轮廓,刷子用来填充轮廓内部。

virtual void DrawPie(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd);

virtual void DrawEllipse(const TRect& aRect);

virtual void DrawRect(const TRect& aRect);

virtual void DrawRoundRect(const TRect& aRect, const TSize& aEllipse);

virtual TInt DrawPolygon(const CArrayFix<TPoint>* aPointList, TFillRule aFillRule = EAlternate);

virtual TInt DrawPolygon(const TPoint* aPointList, TInt aNumPoints, TFillRule aFillRule = EAlternate);

(3) 位图.能够以1:1的比例或者拉伸到所指定矩形区域的大小来绘制位图。

virtual void DrawBitmap(const TPoint& aTopLeft, const CFbsBitmap* aSource);

virtual void DrawBitmap(const TRect& aDestRect, const CFbsBitmap* aSource);

virtual void DrawBitmap(const TRect& aDestRect, const CFbsBitmap* aSource,const TRect& aSourceRect);

(4) 文本.使用当前字体。

virtual void DrawText(const TDesc& aString, const TPoint& aPosition);

virtual void DrawText(const TDesc& aString, const TRect& aBox, TInt aBaselineOffset, TTextAlign aHoriz = ELeft, TInt aLeftMrg = 0);

绘图和重绘:

在GUI程序中,所有的绘图都在控件上完成,绘图是由控件的Draw()函数来完成的,其声明如下virtual void Draw(const TRect& aRect) const;

基类CCoeControl的Draw()为空,因此在编写控件时必须实现该函数,否则控件将不可见。Draw()是由应用程序框架来调用,一般不应在应用程序中直接调用Draw()。控件不只是在初始化绘制它们的外观,而且在它发生变化时或者系统要求重绘(redraw)时进行重绘。按照重绘的触发源来划分,控件的重绘分为两种:系统发起的重绘和应用程序发起的重绘。系统发起的重绘处理从窗口服务器开始,它检测并判断何时需要重绘哪部分窗口。实际上,它维护窗口上的一个无效区域,并向拥有窗口的应用程序发送一个重绘事件,要求它重绘无效区域。应用程序发起的重绘处理由应用程序触发,它可以根据需要采用如下方法来实现(这些函数最终都是通过调用Draw()来实现的):void CCoeControl::DrawNow();立即重绘整个控件;void CCoeControl::DrawDeferred()const;一旦有机会就重绘整个控件;void RWindow::Invalidate(const TRect&);一旦有机会就重绘由参数指定的矩形区域。然而通过将重绘活动限制在矩形中,几乎不会节省很多开销,因此,编写大多数控件时,一般忽略传递限制矩形参数。

用户输入处理:

Symbian OS中处理用户输入的两个基本函数是OfferKeyEventL()和HandlePointerEventL()。由于Series60平台不支持笔写输入,所以主要使用OfferKeyEventL()。下面是一个简单控件处理按键事件的代码:

TKeyResponse CSimpleControl::OfferKeyEventL(const TKenEvent& aKeyEvent, TEventCode aType)

{

switch(aType)

{

case: EEventKey:

   if (aKeyEvent.iScanCode == EStdKeyNkp5 || aKeyEvent.iScanCode == EStdKeyEnter)

    iMyGameEngine->Fire();

   break;

case: EEventKeyDown:

   //....

case: EEventKeyUp:

   //....

}

return EKeyWasNotConsumed;

}


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP