一、界面雏形:
二、需求:
1、 用Container与View组合的方式编写应用程序;
2、 输入框内只能输入数字(前两个输入框限3位数字,第三个输入框没有限制);
3、 Menu菜单下为加、减、乘、除的选项;
4、 输入不合法数据时必须有提示框弹出;
5、 前两个输入框为可读可写,第三个输入框为只读;
6、 注意字符转换问题。
三、实现:
(1)新建myContainer类,继承CCoeControl,MCoeControlObserver
class myContainer: public CCoeControl, MCoeControlObserver
{
public: // Constructors and destructor
void ConstructL(const TRect& aRect);
~myContainer();
public: // New functions
void Calculate(TInt aCommand);
public: // Functions from base classes
//CEikRichTextEditor* iTestWindow;
CEikLabel* iLabelFirst; //add by caizhiping
CEikLabel* iLabelSecond;
CEikLabel* iLabelResult;
CEikFloatingPointEditor* iNumFirst;
CEikFloatingPointEditor* iNumSecond;
CEikFloatingPointEditor* iNumResult;
private: // Functions from base classes
/**
* From CoeControl */
void SizeChanged();
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
void Draw(const TRect& aRect) const;
TKeyResponse OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType ) ;
/**
* From MCoeControlObserver
* Acts upon changes in the hosted control's state.
*
* @param aControl The control changing its state
* @param aEventType The type of control event
*/
void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType);
void HandleResourceChange( TInt aType );
/**
* own
*/
TInt IdOfFocusControl();
void SwitchFocus(TInt aFromIndex, CCoeControl* aToControl);
void MoveFocusTo(const TInt index);
private: //data
TReal iFirstNum;
TReal iSecondNum;
TReal iResultNum;
};
(2)修改view类,继承CAknView类
class CCalcAppView : public CAknView
{
public:
// Constructors and destructor
CCalcAppView();
void ConstructL();
~CCalcAppView();
public: // Functions from base classes
/**
* From CAknView returns Uid of View
* @return TUid uid of the view
*/
TUid Id() const;
/**
* From MEikMenuObserver delegate commands from the menu
* @param aCommand a command emitted by the menu
* @return void
*/
void HandleCommandL(TInt aCommand);
/**
* From CAknView reaction if size change
* @return void
*/
void HandleClientRectChange();
private:
/**
* From CAknView activate the view
* @param aPrevViewId
* @param aCustomMessageId
* @param aCustomMessage
* @return void
*/
void DoActivateL(const TVwsViewId& aPrevViewId,TUid aCustomMessageId,
const TDesC8& aCustomMessage);
/**
* From CAknView deactivate the view (free resources)
* @return void
*/
void DoDeactivate();
private: // Data
myContainer* iContainer;
};
(3)ui类,继承CAknViewAppUi类
class CCalcAppUi : public CAknViewAppUi//, MAknTabObserver
{
public:
// Constructors and destructor
/**
* ConstructL.
* 2nd phase constructor.
*/
void ConstructL();
/**
* CCalcAppUi.
* C++ default constructor. This needs to be public due to
* the way the framework constructs the AppUi
*/
CCalcAppUi();
/**
* ~CCalcAppUi.
* Virtual Destructor.
*/
virtual ~CCalcAppUi();
private:
// Functions from base classes
// From MEikMenuObserver
void DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane);
private:
/**
* From CEikAppUi, takes care of command handling.
* @param aCommand command to be handled
*/
void HandleCommandL(TInt aCommand);
/**
* From CEikAppUi, handles key events.
* @param aKeyEvent Event to handled.
* @param aType Type of the key event.
* @return Response code (EKeyWasConsumed, EKeyWasNotConsumed).
*/
virtual TKeyResponse HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
};
(4)资源类:.rls中定义字符串资源
.rss中关联菜单项与字符串资源
.hrh中定义菜单的各个command项
(5)symbian计算器实现中遇到的问题:
a. CEikFloatingPointEditor的构造是二段构造函数,需要手动调用其ConstructL函数,否则构造失败;
b.要得到CEikFloatingPointEditor的值,必须先调用PrepareForFocusLossL()函数,再取其值,如下(假设iNumFirst为CEikFloatingPointEditor的实例)
iNumFirst->PrepareForFocusLossL();
iFirstNum =iNumFirst->Value();
c.illegal use of abstract class问题:检查该类中方法的实现,保证其父类的所有虚方法在子类中都有override;
d.undefied identifier “_LIT”与undefined identifier “user::Panic”错误:添加头文件<e32base.h>、<e32std.h>和<e32cons.h>三个头文件;
(6)小结(关于symbian消息机制)
类似于Brew中IWindow的消息机制,假如UI不处理该消息,将会层层漏下,直到栈顶控件(本例中UI--àView--àmyContainer)的顺序,个人觉得尽量在上层控件处理消息(当然绝大多数app应该是这个模式,毕竟很多业务的处理与信息的反显是由上层控件完成,这样不可避免会访问上层控件的一些private成员,为了保证其封装特性,尽量在上层处理消息)。