您的位置:首页 > Web前端

Symbian按键处理函数:OfferKeyEventL()详解

2012-10-01 16:52 483 查看
irtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);

这个函数专门用于处理键盘事件,如果对程序的交互和运行需要通过键盘控制,那么视图类就应该去实现这个方法。如果类实现这个方法,特别需要注意的是,若对 象没有对键盘事件作出响应那么应该返回EKeyWasNotConsumed ,反之,若对象对该键盘事件做出了响应那么就要返回EKeyWasConsumed。当键盘事件发生时,控制框架调用每一个在控件栈中对象的 OfferKeyEventL()函数,直到他们中其中的一个可以处理这个键盘事件并返回EKeyWasConsumed。

参数:

const TKeyEvent& aKeyEvent :键盘事件。TKeyEvent 类描述了键盘事件的细节,他包括四个属性,分别是iCode, iModifiers, iRepeats, iScanCode 。当处理一个TKeyEvent的时候,TStdScanCode型的iScanCode通常被TKeyCode型的iCode取代。

TEventCode aType :键盘事件类型,包括:EEventKey, EEventKeyUp or EEventKeyDown

返回值指明对象是否处理了这个键盘事件。

任意一个键盘的按键事件都将导致三个独立的事件:EEventKeyDown, EEventKey和EEventKeyUp,事实上他们触发的顺序也是这个样子的。为可以获得可以被OfferKeyEventL()函数处理的键盘事 件,应用程序必须调用CCoeAppUi::AddToStackL()方法,把控件压入到栈中。这只是对控件起作用,而不是组成控件的控件组件。复合控 件如果有需要的话也可以把键盘事件传递给他们的组件控件,但是组件控件本身并不可以在控制栈上。

如果一个类覆盖了 CCoeControl::OfferKeyEventL() 方法那么他同时也要覆盖InputCapabilities() 虚函数,返回一个TCoeInputCapabilities 对象,这个对象的属性符合OfferKeyEventL()函数的行为。通常没有必要在内部调用InputCapabilities() 方法,而这个方法也一般被UI控制框架调用。

SDK讲述:
OfferKeyEventL()

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


Description
Handles key events.

If a control wishes to process key events, it should implement this function. The implementation must ensure that the function returns EKeyWasNotConsumed if it does not do anything in response to a key event, otherwise, other controls or dialogs may be prevented
from receiving the key event. If it is able to process the event it should return EKeyWasConsumed.

When a key event occurs, the control framework calls this function for each control on the control stack, until one of them can process the key event (and returns EKeyWasConsumed).

Each keyboard key press results in three separate events: EEventKeyDown, EEventKey, and EEventKeyUp, in that order.

To receive key events, which can be processed by this function, the application should call to add the control to the stack. This only applies, however, to controls which are not components of a compound control. Compound controls should pass key events
to their components as necessary: the components themselves do not go on the stack.

Classes that override should also override the virtual function, returning a object whose attributes correspond to the behaviour of the function. Note that it is not necessary to call on any component controls from inside a class' function. This is done
automatically by the UI Control Framework.

If overriding , the implementation must include a base call to CCoeControl's .

Parameters
const &aKeyEvent

The key event.

aType

The type of key event: EEventKey, EEventKeyUp or EEventKeyDown.

Return value

Indicates whether or not the key event was used by this control.

OfferKeyEventL()函数的运用

S60平台只有一种控制游戏的方法就是键盘控制.虽然Symbian也支持手写输入,但是很不方便,实际应用中通常都是使用键盘来控制.但是各种手机,他的键盘设计又各不相同,所以,最理想化的就是让用户自己定义控制键.

     键盘事件处理起来很简单,(简单毛啊)AppUI使用HandleKeyEventL方法接收键盘事件.AppUI通过调用OfferKeyEventL将键盘事件传递给活动的View.

     如果使用了AddToStackL,则键盘事件将会自动的从AppUI传递到View并且添加到控制栈中.键盘事件将不在AppUI里进行操作处理,除非键盘事件是全局性的.

     TKeyEvent和TEventCode作为OfferKeyEventL的参数传递,他包含了:键盘事件类型,键盘扫描码,键盘字符码.每一次点击按键都会依次发生如下三个事件:EEventKeyDown (接收按键按下时的信息),EEventKey(在按键按下后,到按键松开前,周期性的收集信息.键盘连击率,RWsSession::GetKeyboardRepeatRate方法设置时间间隔.),EEventKeyUp(收集按键释放信息).

     在实际运用中,如果一个按键被按下,并且持续一段时间,你应该做一个标记,例如持续移动一个物体.当按键被放开时,重新标记.

     另外,EEventKey可以作为一个时间器来使用.在按键按下后,你可以使用他来多次执行同一个动作.使用RWsSession::SetKeyboardRepeatRate来设定动作重复的时间间隔.

     每一个键的TKeyEvent包含两段独立的代码,扫描码和特征码.扫描码:TKeyEvent::iScanCode选择处理键盘事件,主要负责接收按键的顺序.而TKeyEvent::iCode主要是负责处理一些相应的事件.

     在Symbian里面,同时按下两个以上的键是无效的,只有先被按下的那个会被相应,(Power键除外)这就是键盘锁机制.我们通过CAknAppUi提供的SetKeyBlockMode方法来解决这一问题.键盘锁在很多操作系统中使用,所以这种修改是不推荐的.示例代码:
以下内容为程序代码:

void CMyGameAppUi::ConstructL()

    {

       // Disable key blocking

       SetKeyBlockMode(ENoKeyBlock);

    }

Typically the OfferKeyEventL method in the game"s view would look like this:

TKeyResponse CMyGameView::OfferKeyEventL(const TKeyEvent&  

       aKeyEvent,TEventCode aType)

    {

    switch(aType)

       {

       case EEventKey:

          if(aKeyEvent.iScanCode == EStdKeyNkp5 ||

                aKeyEvent.iScanCode == EStdKeyDevice3)

             {

             // EEventKey is called multiple times periodically as

             // long as the key is pressed down, so the ship will be

             // firing periodically too.

             iMyGameEngine->Fire();

             return EKeyWasConsumed;

             }

          break;

       case EEventKeyDown:

          switch(aKeyEvent.iScanCode)

             {

             // Key pressed down; start moving the ship to left or

             // right, and keep it moving as long as the key is

             // pressed.

             case EStdKeyNkp4:

             case EStdKeyLeftArrow:

                iMyGameEngine->SetShipMovingTo( ELeft ;

                return EKeyWasConsumed;

             case EStdKeyNkp6:

             case EStdKeyRightArrow:

                iMyGameEngine->SetShipMovingTo( ERight ;

                return EKeyWasConsumed;

             }

          break;

       case EEventKeyUp:

          switch(aKeyEvent.iScanCode)

             {

             // Key released; stop moving the ship

             case EStdKeyNkp4:

             case EStdKeyLeftArrow:

             case EStdKeyNkp6:

             case EStdKeyRightArrow:

                iMyGameEngine->SetShipMovingTo( ENowhere ;

                return EKeyWasConsumed;

             }

          break;

       }

    return EKeyWasNotConsumed;

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息