Categories: Lang-CN | Symbian C++ | UI | S60 | Code Examples
This page was last modified 13:50, 6 July 2008.
自定义控件: 容器控件(三)
From Forum Nokia Wiki
| ID | CS000861 | 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, TResourceReader, CCoeControlArray |
概述
这个代码片段演示如何创建一个拥有自定义控件的容器控件。例子演示如何用一个矩形框聚焦第一个部件及如何改变焦点。
本例扩展已存代码片段自定义控件: 定义(一); 容器控件存储其控件到CCoeControlArray中。
头文件
class CMyContainerControl : public CCoeControl { public: static CMyContainerControl* NewL(const TRect& aRect); static CMyContainerControl* NewLC(const TRect& aRect); virtual ~CMyContainerControl(); private: // from CCoeControl void Draw(const TRect& aRect) const; void SizeChanged(); public: // own methods // NOTE: Transfer ownership to CMyContainerControl void AddControlL(CCoeControl* aControl,TInt aControlId); void UpdateControls(); private: // own methods CMyContainerControl(); void ConstructL(const TRect& aRect); };
源代码
CMyContainerControl* CMyContainerControl::NewL(const TRect& aRect) { CMyContainerControl* self = CMyContainerControl::NewLC(aRect); CleanupStack::Pop(self); return self; } CMyContainerControl* CMyContainerControl::NewLC(const TRect& aRect) { CMyContainerControl* self = new(ELeave) CMyContainerControl(); CleanupStack::PushL(self); self->ConstructL(aRect); return self; } CMyContainerControl::CMyContainerControl() { } CMyContainerControl::~CMyContainerControl() { } void CMyContainerControl::ConstructL(const TRect& aRect) { // No parent owner, so create an own window CreateWindowL(); // Initialize component array InitComponentArrayL(); SetRect(aRect); ActivateL(); } void CMyContainerControl::SizeChanged() { UpdateControls(); } void CMyContainerControl::UpdateControls() { TPoint position; // Goes through all components of this container control CCoeControlArray::TCursor cursor = Components().Begin(); CCoeControl* ctrl = NULL; while ((ctrl = cursor.Control<CCoeControl>()) != NULL) { // If control is not visible, do not set it's position if (!ctrl->IsVisible()) { cursor.Next(); continue; } // Set position ctrl->SetPosition(position); // Set size TSize size = ctrl->MinimumSize(); size.SetSize(Rect().Width(),size.iHeight); ctrl->SetSize(size); // Calculate position position.iY += size.iHeight; // Does control fit to view? if (position.iY >= Rect().iBr.iY) { ctrl->MakeVisible(EFalse); } else { ctrl->MakeVisible(ETrue); } cursor.Next(); } } void CMyContainerControl::Draw(const TRect& /*aRect*/) const { CWindowGc& gc = SystemGc(); gc.SetBrushColor(KRgbBlack); gc.Clear(Rect()); } void CMyContainerControl::AddControlL(CCoeControl* aControl,TInt aControlId) { // NOTE: Transfer ownership of CCoeControl to CMyContainerControl // Add control into container control Components().AppendLC(aControl,aControlId); CleanupStack::Pop(aControl); // Focus first component if (Components().Count()==1) { aControl->SetFocus(ETrue); } // Update control's position UpdateControls(); }
SizeChanged函数
当CMyContainerControl的大小改变时(例如: 当SetRect()被调用时),部件的位置必须再次计算。
void CMyContainerControl::SizeChanged() { // Sets new position of the components UpdateControls(); }
聚焦部件
对CMyControl部件做如下变更:
- CMyControl::Draw()必须调用DrawFocusFrame()以便绘制焦点矩形
- CMyControl::DrawFocusFrame()是一个新方法,在其中绘制焦点框
void CMyControl::Draw(const TRect& aRect) const { CWindowGc& gc = SystemGc(); gc.SetBrushColor(KRgbBlue); gc.Clear(Rect()); DrawFocusFrame(aRect); } void CMyControl::DrawFocusFrame(const TRect& aRect) const { // Nothing to draw if not focused if ( IsFocused() == EFalse ) return; // Prep for draw CWindowGc& gc = SystemGc(); gc.SetPenStyle( CGraphicsContext::ESolidPen ); gc.SetPenSize( TSize(KFocusFrameWidth,KFocusFrameWidth) ); gc.SetBrushStyle( CGraphicsContext::ENullBrush ); gc.SetPenColor( KRgbDarkGray ); // Draw the rounded rectangle gc.DrawRoundRect( aRect, TSize( KFrameRoundRadius, KFrameRoundRadius ) ); }
后置条件
CMyContainerControl容器在列表中有一些CMyControl自定义控件。
参见
自定义控件系列:
- 自定义控件: 定义(一) 定义自定义控件
- 自定义控件: 从资源构造(二) 从资源创建控件
- 自定义控件: 聚焦(四) 处理摁键事件和改变活动自定义控件焦点
- 自定义控件: 滚动条(五) 给自定义控件添加滚动条
- 自定义控件: 在Dialog中(六) 把自定义控件加到CAknDialog
- Image:CustomControl.zip 样例代码补丁

