Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
This page was last modified 13:56, 6 July 2008.

自定义控件: 定义(一)

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里(复合控件),或作为单独的控件而没有父控件。

参见

自定义控件系列:

其它有用文章:

 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtopicQUqfnTopicZseriesE5f60Q
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX