Categories: Lang-CN | Symbian C++ | UI | S60 | Code Examples
自定义控件: 定义(一)
From Forum Nokia Wiki
| ID | CS000859 | Creation date | March 25, 2008 |
| Platform | S60 3rd Edition, FP1 | Tested on devices | Nokia N95 |
| Category | Symbian C++ | Subcategory | UI |
| Keywords (APIs, classes, methods, functions): CCoeControl |
概述
Symbian OS提供了大量现成的控件,但是有时还不够用。你可以通过从CCoeControl基类派生构造你自己的UI控件。
本例演示如何定义你自己的有一个CEikLabel的简单自定义控件。 派生自CCoeControl 并实现下述基本方法:
- 构造
- 布局
- 大小
- 绘制控件
- 被包含的控件(若有的话)
MMP文件
下面的库文件是必须的:
LIBRARY euser.lib LIBRARY apparc.lib LIBRARY cone.lib LIBRARY eikcore.lib LIBRARY avkon.lib LIBRARY commonengine.lib LIBRARY eikcoctl.lib LIBRARY gdi.lib
头文件
#include <coecntrl.h> #include <eiklabel.h> class CMyControl : public CCoeControl { public: static CMyControl* NewL(const TRect& aRect,const CCoeControl* aParent=NULL); static CMyControl* NewLC(const TRect& aRect,const CCoeControl* aParent=NULL); virtual ~CMyControl(); public: // from CCoeControl TSize MinimumSize(); private: // from CCoeControl void Draw(const TRect& aRect) const; void SizeChanged(); private: // own methods CMyControl(); void ConstructL(const TRect& aRect,const CCoeControl* aParent = NULL); private: // data CEikLabel* iStatusText; };
源代码
CMyControl* CMyControl::NewL(const TRect& aRect,const CCoeControl* aParent) { CMyControl* self = CMyControl::NewLC(aRect,aParent); CleanupStack::Pop(self); return self; } CMyControl* CMyControl::NewLC(const TRect& aRect,const CCoeControl* aParent) { CMyControl* self = new(ELeave) CMyControl(); CleanupStack::PushL(self); self->ConstructL(aRect,aParent); return self; } CMyControl::CMyControl() { } CMyControl::~CMyControl() { // NOTE: Does not delete iStatusText because we do not own it } void CMyControl::ConstructL(const TRect& aRect,const CCoeControl* aParent) { // No owner, so create an own window if(aParent == NULL) { CreateWindowL(); } // Use Parent's window else { // This is component in a compound control SetContainerWindowL(*aParent); } // Initialize component array InitComponentArrayL(); // Create contained controls iStatusText = new (ELeave) CEikLabel; iStatusText->SetContainerWindowL(*this); iStatusText->SetTextL(_L("HelloWorld")); // Store component to component array Components().AppendLC(iStatusText); CleanupStack::Pop(iStatusText); SetRect(aRect); // or //SetExtentToWholeScreen(); //NOTE: Can not see CBA buttons // The application should call this function on // all controls that are not components in a compound control if(aParent == NULL) { ActivateL(); } } TSize CMyControl::MinimumSize() { // Get CEikLabel minium size and grow it // that is this control MinimumSize. // Custom control also needs a few other methods so it can be laid out // and drawn. For example, custom controls usually implement MinimumSize(), // SizeChanged() and Draw() methods. // When using control in container control, set the minium size very small TRect rect = iStatusText->MinimumSize(); rect.Grow(TSize(2,2)); return rect.Size(); // When using the control in a dialog, set the control size large //return Rect().Size(); } void CMyControl::SizeChanged() { // Responds to size changes to set the size and position of the contents // of this control. For a simple control this might include text or // graphics. For a compound control this sets the size and position of the // component. It has an empty default implementation and should be // implemented by the CCoeControl-derived class. // The function is called whenever SetExtent(), SetSize(), SetRect(), // SetCornerAndSize(), or SetExtentToWholeScreen() are called on // the control. if (iStatusText) { TRect labelRect(Rect()); labelRect.Shrink(TSize(5,2)); iStatusText->SetRect(labelRect); } } void CMyControl::Draw(const TRect& /*aRect*/) const { CWindowGc& gc = SystemGc(); gc.SetBrushColor(KRgbBlue); gc.Clear(Rect()); }
使用CCoeControl
自定义控件CMyControl被添加到了MultiViews例子(S60 3rd FP1)中,在.cpp中作如下修改:
void CMultiViewsView1::DoActivateL( const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/) { iControl = CMyControl::NewL(ClientRect()); } void CMultiViewsView1::DoDeactivate() { if (iControl) { AppUi()->RemoveFromStack(iControl); delete iControl; iControl = NULL; } } void CMultiViewsView1::HandleSizeChange( TInt aType ) { if( iControl ) { iControl->HandleResourceChange( aType ); if ( aType==KEikDynamicLayoutVariantSwitch ) { TRect rect; AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, rect); iControl->SetRect(rect); } } }
后置条件
CMyControl可以放在另一个CCoeControl里(复合控件),或作为单独的控件而没有父控件。
参见
自定义控件系列:
- 自定义控件: 从资源构造(二) 从资源创建控件
- 自定义控件: 容器控件(三) 创建容器控件
- 自定义控件: 聚焦(四) 处理摁键事件和改变活动自定义控件焦点
- 自定义控件: 滚动条(五) 给自定义控件添加滚动条
- 自定义控件: 在Dialog中(六) 把自定义控件加到CAknDialog
- Image:CustomControl.zip 样例代码补丁
其它有用文章:

