细谈Symbian的按键处理

一。Symbian的按键事件捕获,可以通过以下两种方式:

1:UI中的HandleKeyEventL();

2:view中的OfferKeyEventL();

这两个函数都是通过重载基类中的相应函数来实现的。使用这两个函数的主要区别在于使用OfferKeyEventL前需把对应的view压入控件栈(AddToStackL ), 否则捕获不到该控件对应的按键输入,而HandleKeyEventL()则不需要压入控件栈,可以处理全局按键事件。这两个函数根据实际情况分别使用, 当多个view时最好用OfferKeyEventL(),这样便于各个View的自定义控件的控制,可在各个view中分别对按键输入做不同的相应。

另外,如果同时定义了这两个函数,关于他们的执行顺序,有按键事件时其先被传递到控件栈中的OfferKeyEventL,如果 OfferKeyEventL返回EKeyWasConsumed,则不再传到HandleKeyEventL中,否则传递到 HandleKeyEventL在做处理。

二。virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType); 有两个参数

1:const TKeyEvent& aKeyEvent     记录按键的具体信息,参看SDK中的定义如下

struct TKeyEvent
{
TUint iCode;//键盘码
TInt iScanCode;//扫描码
TUint iModifiers;//修饰键
TInt iRepeats;//是个标记,告诉你产生的这个按键事件是重复按键还是长按一个键时周期产生的按键事件。
};

2:TEventCode aType     记录键盘事件类型,参看SDK中的定义如下

enum TEventCode
{
EEventNull,
EEventKey,
EEventKeyUp,
EEventKeyDown,
……
}; //枚举比较多,未一一列出,详情请参考w32std.h头文件

EEventKeyDown //接收按键按下时的信息。
EEventKey //在按键按下后,到按键松开前,周期性的收集信息.键盘连击率,RWsSession::SetKeyboardRepeatRate方法设置时间间隔)。
EEventKeyUp //收集按键释放信息。

每次按键时,都会依次产生上面三个按键事件(组合键Shift、Alt、Ctrl等除外),根据不同的应用需求做处理,在很多基本的应用时,我们不 太关心键按下或松开的时刻,而只关心我们按的是什么键,比如在对话框里输入一些,我们只关心按的是a还是b,而什么时候按下a或b对我们来说并不重要,那 么我们在OfferKeyEventL()或HandleKeyEventL()中,只需对(aType == EEvenKey)时做处理。如下

TKeyResponse CXXXView::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if ((aType == EEventKey) && (aKeyEvent.iScanCode == '1'))
{
   //todo what you want
}
else
   return EKeyWasConsumed;

}

而另外一种情况,比如游戏,一个键的按下或释放的时刻就显得很重要了,这时需要对(aType == EEvenKeyDown)或(aType == EEvenKeyUp)时进行处理,比如我们可以在(aType == EEvenKeyDown)时移动一个物体,在(aType == EvenKeyUp)时停止移动。

iRepeats
    按键时先产生个aTyep=EEvenKeyDown的事件,紧接着产生aType=EEvenKey的事件,如果你按下一个键(比如*)的时间比较长,如果超过了系统默认时间间隔(系统有默认值,更改可用RWsSession::SetKeyboardRepeatRate() 来 设置时间间隔),那么经历那个系统默认时间间隔后,会再次产生aTyep=EEvenKey的事件,而这两次aTyep=EEvenKey事件的唯一区别 就是前一个的aKeyEvent.iRepeats=0,而之后的aKeyEvent.iRepeats=1。所以aTyep=EEvenKey(且 aKeyEvent.iRepeats=1)的事件每隔一定时间间隔就会自动产生,直到你松开按键。而后产生aTyep=EEvenKeyUp事件。
由此可以实现短按一个键和长按一个键的区别操作了,如UCWEB里向下滚动,长按下方向键会一行一行的滚动,短按则会由左到右的滚动。
   
iModifier
w32std.h里是这样定义iModifier的:TUint iModifiers;
enum TEventModifier
{
EModifierAutorepeatable=0x00000001,
EModifierKeypad=0x00000002,       
EModifierLeftAlt=0x00000004,      
EModifierRightAlt=0x00000008,     
……
EAllModifiers=0x0fffffff          
};
定义很多多,但很容易看出,iModifier就是指Shift、Alt、Ctrl等这种修饰键有没有被按下(E71等全键盘手机会用到)。比较很容易理 解,单按一个a和shift+a(输入大写A)结果是不一样的,总得有个参数标记一下,这个参数就是iModifier了。另外,从定义可以发现,他们都 是单字节位定义的,比如:
EModifierAutorepeatable=0x00000001           对应的二进制是 0001
EModifierKeypad=0x00000002                   对应的二进制是 0010
EModifierLeftAlt=0x00000004                  对应的二进制是 0100
    这样做是因为有时候我们可能按下不只一个的修饰键,比如两个(shift + alt),而把这样同时两个或者更多修饰键被按下的情况一一枚举出来是不科学和不实用的,使用这种单字节位定义的好处就是我们在判断某个修饰键有没有被按 下时,只需要按位与(&)一下就行了,比如,如果没有其他修饰键,一般按a时产生的iModifer是3(对应的二进制是0011),那么:
if (aKeyEvent.iModifier & EModifierAutorepeatable)和
if (aKeyEvent.iModifier & EModifierKeypad)时都为真,而
if (aKeyEvent.iModifier & EModifierLeftAlt)就为假,
    这样我们在处理按键事件时就能方便的判断出来那些修饰键被按下了。另外需要注意的就是,按下修饰键时只产生EEvenKeyDown和 EEvenKeyUp事件,而无EEvenKey。因为如果分长按和短按修饰符键的话,那么在输入大写或者组合键的时候就会产生很多个按键消息。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值