当前位置: BOLT界面引擎 > 知识库文章 > 输入事件分发和路由策略介绍

输入事件分发和路由策略介绍

作者:李亚星 2012-08-07

 

        

元对象的标准输入事件包括键盘事件和鼠标事件

 

         输入事件在对象树层面的分发策略

                   键盘事件:

1.         发往当前的焦点所在对象

2.         如果当前的按键是回车/Tab,并且焦点对象是EditObject或者RichEditObject,那么会主动查询是否需要,不需要的话直接略过

3.         如果当前无焦点对象,那么直接忽略该键盘消息

 

鼠标事件:

1.         如果有对象在capturemouse中,那么发往该对象;否则继续转2处理

2.         如果是滚轮事件,那么判断当前对象树的mousewheelstrategy策略

a)         如果是focus策略,那么发往焦点所在对象

b)         如果是over策略,那么作为普通鼠标消息转3处理

3.         普通鼠标事件,对象树进行按照既定策略进行命中测试,取到合适的对象进行处理;如果没有找到符合要求的对象,直接忽略该事件

 

 

对象在进行输入命中测试时候,遵循以下策略:

1.         该对象不能为实对象,也就是RealObjectWebBrowseObjectFlashObject不可被命中

2.         该对象的必须为可见,包括自身的visible和所有的父对象的childrenvisible都为true

3.         该对象必须为enable,包括自身的enable和所有父对象的childrenenable都为true

4.         该对象必须可接收输入事件,也即是至少满足下面三条中的一条

a)         挂接了至少一个键盘or鼠标事件

b)         指定了重定向,包括对象粒度or事件粒度

c)         强制指定了enableinput属性为true

5.         该对象的alpha值必须大于0

6.         命中测试坐标点,须落在该对象的有效区域(包括在所有的父对象的limitrect)之内

7.         对于ImageObject/FillObject,命中测试坐标点对应的位图或者填充色的alpha通道必须大于0

8.         满足上面的条件的对象,取zorder值最大的,对于zorder相同的对象,则随机取一个,结果不可预期

 

 

元对象的输入事件路由策略

 

一个元对象收到所在对象树分发的鼠标事件和键盘事件后,按照如下策略进行处理:

 

1.         交由前置消息过滤器处理,如果过滤器处理了,终止路由;否则继续2

目前还没有元对象使用该消息过滤器,不过不排除以后可能使用

 

2.         交由对象上挂接的相应事件处理函数,如果响应了该事件,并且响应函数的handled返回值设置为true,那么终止路由;否则继续3

比如OnChar响应函数,在里面返回0truetrue会标识该事件为已处理,默认是未处理;除非有特殊需求,否则都应该标识为未处理

 

3.         如果在事件处理函数里面调用了RoureToFather,那么交由父对象处理,父对象也会从按照1-5的流程处理,如果有任何一步标识被处理了,那么终止路由;否则继续4

比如在OnChar响应函数里面调用了RouteToFather,那么此处会把事件交由父对象处理(对象数的根对象除外),父对象会无差别的处理OnChar事件,仿佛是对象树上分发而来的一般。原则上来说,如果你一个元对象的OnChar事件响应了,你是无法区分该事件是由对象树直接分发给自己的,还是某个child调用了RouteToFather而来,还是某个其它对象使用了消息重定向而来的。

 

4.         如果该事件指定了重定向对象,那么交由目的对象处理,目的对象也会从按照1-5的流程处理,如果有任何一步标识被处理了,那么终止路由;否则继续5

该机制其实是RouteToFather的强化版,可以把该消息重定向到同一个对象树上面的任意一个对象,目的对象的处理方式和RouteToFather一样,详细参考3

 

5.         交由后置消息过滤器处理,一般都是需要自己处理输入的元对象使用,比如EditObjectRichEditObjectWindowlessFlashObject等,前面1-4终止路由,都会导致元对象内部无法做默认处理,可以用来拦截指定的输入事件

该处理对EditObjectRichEditObjectWindowlessFlashObject等需要自己处理键盘和鼠标消息的元对象来说,非常重要,比如键盘输入,最终传递到EditObject时候,会变成EditObject对象的输入;如果在前面某个步骤中拦截了输入事件,那么EditObject对象便不会显示输入的内容了,其它事件也一样,可以用拦截某些特性的按键或者鼠标事件。

 

 

 

迅雷公司 版权所有 Copyright 2003-2010 Thunder Inc.All Rights Reserved. 意见反馈:xl7doc@xunlei.com