学习按键事件的总结_如何解决按键学习失败问题-程序员宅基地

技术标签: server  keyboard  character  dll  interface  symbian  



资料来自互联网


当用户按下一个键后,keyboard hardware就会生成一个中断,由keyboard driver捕捉,之后分解出这次按键事件的key code,然后driver将它发送到系统端的一个线程——被称为window server,而window server又会把它发向在window group中拥有焦点的那个应用程序中,这个步骤是使用一个control environment(CONE)来完成的,它是window server和user interface library之间的一个API函数。

从api函数中可以看出这个处理过程当windows server发送一个按键的事件便调用AppUI中的HandleWsEventL(),HandleWsEventL()方法首先调用CCoeControl::OfferKeyEventL()如果OfferKeyEvent()返回EKeyWasNotConsumed则继续调用AppUI中的HandleKeyEventL()。如果OffKeyEventL()处理了事件则返回EKeyWasConsumed。
如果想直接调用AppUI中的HandleKeyEventL()可以通过set ECoeStackFlagRefusesAllKeys 来省去调用OfferKeyEventL()。

 

每次按键都会产生3个事件类型1 EEventKeyDown,2 EEventKeyUp,3 EEventKeyDown;可以从OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)中的aType中得到事件类型。aKeyEvent是一个struct可以得到按键的更多性,eg:iCode指名按了哪个键(键名在e32keys.h中)iRepeats可以判断是重复按键还是长按键。如果想改变系统的按键重复率可以通过RWsSession 的SetKeyboardRepeatRate方法来设置。

S60手机默认情况下是不能接受连续按键的且只有先按下的键可以被接受(也就是按键阻塞,电源键和编辑键默认为非按键阻塞)。可以通过s60提供的CAKnAppUI中的SetKeyBlockMode()方法来取消按键阻塞。

iScanCode 和 iCode:


iCode 是每次完整的按键事件对应的一个唯一键盘码,所谓完整的按键事件就是EEvenKeyDown、EEvenKeyUp及EEvenKey 这三个事件,

iCode在EEvenKeyDown和EEvenKeyUp中均为0,只有在EEvenKey 中才对应相应的键盘码,这在SDK中有说:

The character code generated for an EEventKey, or 0 for a down or up event.

Key codes for special keys are defined in TKeyCode.

可见,在EEvenKeyDown和EEvenKeyUp中我们无法根据iCode进行相应处理,因为所有按键的iCode都是0,我们只能根据iScanCode来判断按下

的键位并处理。那么什么是iScanCode呢?

 

iScanCode在SDK中是这样描述的:

The scan code of the key that caused the event

怎么样,迷糊了吧,我们按下a这个键,不就是“a”这个键cause the event,而且The character code generated for the EEventKey 也是a 啊,

iScancode 和 iCode的区别在哪呢?别忘了,可能还有修饰键呢,如果我们只按下a,那么iScancode = 0x41 和 iCode = 0x61(对应ASCII中小写的

a),而如果我们按下shift + a,那么iScancode = 0x41 和 iCode = 0x41(对应ASCII中大写的A)。至于为啥小写a的iScancode 为啥是0x41而不是

0x61那就得问symbian了,人家就是这么定义的 -.-!!!

下面让我们看看两个完整的按键事件的实例:

a:

   184.190 --->code :0
   184.190 --->scan code :41
   184.190 --->iModifiers :0
   184.190 --->iRepeats :0

     EEvenKeyDown:a
   184.190 *********************************
   184.190 --->code :61
   184.190 --->scan code :41
   184.190 --->iModifiers :1
   184.190 --->iRepeats :0

     EEvenKey :a
   184.190 *********************************
   184.320 --->code :0
   184.320 --->scan code :41
   184.320 --->iModifiers :0
   184.320 --->iRepeats :0

     EEvenKeyUp:a
   184.320 *********************************

 

shift + a (实际上是左shift):

   233.020 --->code :0
   233.020 --->scan code :12
   233.020 --->iModifiers :500
   233.020 --->iRepeats :0
   233.020 leftshift was pressed

      EEvenKeyDown:shift
   233.020 *********************************
   233.210 --->code :0
   233.215 --->scan code :41
   233.215 --->iModifiers :500
   233.215 --->iRepeats :0
   233.215 leftshift was pressed

      EEvenKeyDown:a
   233.215 *********************************
   233.215 --->code :41
   233.215 --->scan code :41
   233.215 --->iModifiers :501
   233.215 --->iRepeats :0
   233.215 leftshift was pressed

      EEvenKey:shift + a
   233.215 *********************************
   233.340 --->code :0
   233.340 --->scan code :41
   233.340 --->iModifiers :500
   233.340 --->iRepeats :0
   233.340 leftshift was pressed

      EEvenKeyUp:a
   233.345 *********************************
   233.680 --->code :0
   233.680 --->scan code :12
   233.680 --->iModifiers :0
   233.680 --->iRepeats :0

     EEvenKeyUp:shift
   233.680 *********************************


了解了按键的处理流程之后,就可以在按键事件处理过程中的任何阶段拦截按键了。
见文:后台运行程序捕获按键

也可以在底层拦截按键,通过这种方式拦截按键之后,其它的任何按键处理都不会得到按键事件。可以通过S60Ex/Animation来测试。
见:

使用动画DLL捕获按键事件


内容如下:

动画DLL定义了一组多态DLL框架,用来处理动画。但是它也可以用来获得底层window server事件。


本文提供了一个方法,通过使用动画DLL捕捉底层事件。显示动画的示例在S60示例代码中有,但是未包含底层事件的处理。


所有的这些底层事件都可以通过MEventHandler::OfferRawEvent()接收和处理。这个方法需要在CAnim派生类中完成。函数将返回EFalse,此外

后台程序或前台程序需要使用RWindowGroup::CaptureKey()捕捉按键事件。

TBool CImage::OfferRawEvent( const TRawEvent& aRawEvent )
   {
   // To capture Zero key press
   if(aRawEvent.Type()==TRawEvent::EKeyDown && aRawEvent.ScanCode()=='0')
     {
     // Event handling code
     }
   return EFalse;
   }

当事件处理程序打开时,这些事件将送到MEventHandler::OfferRawEvent()方法中。可以通过调用 MAnimGeneralFunctions::GetRawEvents

(ETrue)函数完成。一个对象的类MAnimGeneralFunctions()没有生成。这个类由window server完成,并提供了通过CAnim::iFunctions指针访问所

有CAnim派生类的应用方法。因此为了接收到底层事件,需要增加下列代码到CAnim派生类的ConstructL()方法

void CImage::ConstructL( TAny* /*aArgs*/, TBool /*aHasFocus*/ )
   {   
    iFunctions->GetRawEvents(ETrue);   
   }

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/actual_/article/details/5188396

智能推荐

118个容易答辩通过的springboot计算机毕业设计程序,新手必备-程序员宅基地

文章浏览阅读169次。Springboot东莞汉庭酒店的酒店管理系统的设计与实现4ccnv。Springboot基于框架的服装电商平台的设计与实现c91g9。Springboot基于协同过滤算法的短视频推荐系统522j3。Springboot基于Vue框架的社区疫情监控系统ml3gs。Springboot基于Spring的手机销售网站8o5t9。Springboot基于vue框架的零售店记账系统01h6n。Springboot基于web的旅游社交分享系统95j7i。Springboot基于Vue的校园信息共享系统78v9t。

简易学生信息管理系统(Python版)_python学生信息管理系统-程序员宅基地

文章浏览阅读1.1k次,点赞3次,收藏14次。用户输入功能序号 user_num = eval(input('请输入功能序号:'))对不同序号的功能实现具体函数(3.1 定义函数、3.2 调用函数)按照用户输入的功能序号,执行不同的功能(函数)修改学生信息modify_info()查询学生信息search_info()显示功能界面info_print()显示学生信息print_all()添加学生信息add_info()删除学生信息del_info()显示所有学生信息和退出系统。_python学生信息管理系统

用jfreechart画折线图_jfreechart 双y轴水平分割线-程序员宅基地

文章浏览阅读9.6k次,点赞2次,收藏15次。JFreeChart 是开放源代码站点SourceForge.net 上的一个 JAVA 项目,它主要用来各种各样的图表,这些图表包括:饼图、柱状图 ( 普通柱状图以及堆栈柱状图 )、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等。应用jfreechart来画图需要两个jar包:jfreechart.jar和jcommon.jar,下载地址。下面是一个画折线图的例子:_jfreechart 双y轴水平分割线

[转载]python自动化将markdown文件转成html文件_python将md转化为html-程序员宅基地

文章浏览阅读593次。https://www.cnblogs.com/rond/p/5897625.html [python]自动化将markdown文件转成html文件一、背景我们项目开发人员写的文档都是markdown文件。对于其它组的同学要进行阅读不是很方便。每次编辑完markdown文件,我都是用软件将md文件转成html文件。刚开始转的时候,还没啥,转得次数多了,就觉得不能继续这样下去了。作为..._python将md转化为html

SQLlite在安卓中的基本详解和简单使用,真的太香了_sql lite 一条-程序员宅基地

文章浏览阅读3.4k次。super(context, name, null, version);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), ageINTEGER)");}@Overridepublic void onUpgrade(SQLite_sql lite 一条

origin8.0免安装版本总是出现图中错误(runtime error! abnormal program termination),导致就自动关闭,无法保存数据。发现沿着流动方向的热流密度变化不_origin 8.0免安装-程序员宅基地

文章浏览阅读612次,点赞6次,收藏11次。origin8.0免安装版本总是出现图中错误(runtime error!abnormal program termination),导致就自动关闭,无法保存数据。发现沿着流动方向的热流密度变化不是很明显。_origin 8.0免安装

随便推点

Java常用的几种JSON解析工具-程序员宅基地

文章浏览阅读8.3k次,点赞2次,收藏11次。Java常用的几种JSON解析工具_json解析工具

运行程序时出现这个错误Error occurred when finalizing GeneratorDataset iterator_w tensorflow/core/kernels/data/generator_dataset_o-程序员宅基地

文章浏览阅读4.1k次,点赞3次,收藏12次。tensorflow.python.framework.errors_impl.UnknownError: Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above. [Op:Conv2D]2021-09-24 15:31:45.989272: W tens_w tensorflow/core/kernels/data/generator_dataset_op.cc:103] error occurred w

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean wi-程序员宅基地

文章浏览阅读2.9w次,点赞2次,收藏3次。org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shiroFilter' defined in class path resource [spring-shiro.xml]: Cannot resolve reference to bean 'securityManage_caused by: org.springframework.beans.factory.unsatisfieddependencyexception:

Windows Server 2016 收不到UDP数据_收不到udp数据包,wireshark能-程序员宅基地

文章浏览阅读1k次。之前用得好好的UDP数据接收软件在这台新服务器上竟然收不到数据了,wireshark 能抓到数据确认数据已经到服务器:netstat -ano 确认程序也已经监听了对应的端口:这一度让我怀疑会不会是操作系统的原因,直到看到udp服务器不能接收到数据包??急!!!-CSDN论坛这个帖子的最后一个回复:赶紧把防火墙开了,然后可以了:哦,原来wireshark抓到的数据是通过防火墙之前的数据,总是记不住。..._收不到udp数据包,wireshark能

固定不动的层(兼容IE6)-程序员宅基地

文章浏览阅读1.0k次。原文: 点击打开链接利用模拟的position:fixed做的对联* { padding:0; margin:0;}body { height:100%; overflow:hidden; font-size:14px; line-height:2; position:relative;}html { height:100%; overflow:hidden;}.fi

Java小型图形界面设计(银行卡类)_bankcard类图-程序员宅基地

文章浏览阅读2.9k次,点赞5次,收藏40次。java小型图形界面设计,实现类方法与前端界面的融合,还有更多的内容欢迎期待!_bankcard类图

推荐文章

热门文章

相关标签