Flex的组合键监听功能实现

来源:互联网 发布:群发短信软件app 编辑:程序博客网 时间:2024/04/27 21:23

最近在用Flex做一个绘图软件,需要实现复制/黏贴/删除图形的功能,一般用户习惯于使用Ctrl+C/Ctrl+V来复制黏贴,使用Delete键来删除,删除功能容易做,监听Stage的键盘按下事件就可以了,但监听Ctrl+C/V 对Flex来说成为了问题,因为Flex的监听机制,一旦按下了Ctrl键就监听不到其他键按下的事件了,即按下了Ctrl后Flex无法检测到其他键按下。要想实现Ctrl+C/V组合键,只能通过JS来监听了。


这涉及到2个问题:

1.Flex和JS的通信。

2.html页面的焦点。因为焦点在swf上时js无法监听到任何事件,所以当我们需要监听复制/黏贴事件时,需要把页面焦点设置为window。

代码如下:

Flex部分代码(类名KeyboardManager.as):

initialize()函数的参数stage是Applicatoin的舞台,KeyboradManager.as类初始化时调用这个函数。

ExternalInterface.addCallback("name", func);语句的意思是,当js使用Applicatoin.name语句时,Flex端就调用函数func。说简单些就是为js的注册一个回调函数func。

private var keysDown:Object = new Object();      // 已按下的键的队列public function initialize( stage:Stage ) : void {ExternalInterface.addCallback("keyDown",onKeyDown);  ExternalInterface.addCallback("keyUp",onKeyUp);stage.addEventListener(KeyboardEvent.KEY_DOWN, swfKeyDown);}public function onKeyDown( keyCode:uint ) : void {        keysDown[keyCode] = true;            checkKeyRole(keyCode); }         public function onKeyUp( keyCode:uint ) : void {       if (keyCode in keysDown) {            delete keysDown[keyCode];       }}public function swfKeyDown( e:KeyboardEvent ) : void {            var focus:Object = mx.core.Application.application.focusManager.getFocus();                        if( e.keyCode == Keyboard.CONTROL ){                //当焦点在输入框时用户可能需要复制/黏贴文本,所以不向js发送获取焦点请求。js获取焦点后会拦截键盘输入使windows的复制黏贴功能失效。                if( !(focus is TextInput) ){                    ExternalInterface.call("setFocus");                }                                        onKeyDown(e.keyCode);            }else if( e.keyCode == Keyboard.DELETE ){                onKeyDown(e.keyCode);            } }/** * 检测按下的键是否有快捷键功能 */private function checkKeyRole(keyCode:uint) : void {            switch(keyCode){                case Keyboard.C:                    if(isDown(Keyboard.CONTROL)){                        //TODO:复制图形                    }                    break;                case Keyboard.V:                    if(isDown(Keyboard.CONTROL)){                       //TODO:黏贴图形                    }                    break;                case Keyboard.DELETE:                    //TODO:删除图形                    break;                            }}/* * 判断某颗键有没有按下 */public function isDown(keyCode:uint):Boolean {            return Boolean(keyCode in keysDown);}

js代码:

document.onkeydown = func,即为html页面添加键盘监听事件

${application}.name(arg),即调用Flex端注册的回调函数${application}是Flex编译生成的swf的名字。

document.onkeydown = onKeyDown;document.onkeyup = onKeyUp;            function onKeyDown(){var code = window.event.keyCode;${application}.keyDown(code);}function onKeyUp(){var code = window.event.keyCode;${application}.keyUp(code);}function setFocus(){window.focus();}


我们从swfKeyDown函数开始跟踪一下组合键监听的思路。

1.当用户有键盘动作时,首先被swfKeyDown函数捕获到(因为此时页面的焦点必然在swf上)。

2.swfKeyDown捕获到键盘事件后判断按下的是什么键,如果是delete键,则不需要使用js监听组合键,直接调用onKeyDown函数做相应处理。

3.如果按下的Ctrl键,判断此时swf系统的焦点,如果焦点在TextInput组件上,则用户肯定是要复制文字,我们不做处理。当系统焦点没有在TextInput组件上而用户按下了Ctrl 键,那他必然需要复制图形,这时候我们调用js的函数setFoces()将焦点置回html页面,这时候js的键盘监听生效了。

4.swfKeyDown函数调用onKeyDown函数,swfKeyDown将Ctrl键放入键队列keysDown.

5.当用户再次按下C/V键时,被js的onKeyDown函数捕获,然后调用Flex端的onKeyDown函数

6.onKeyDown调用checkKeyRole函数,带有参数 keyCode

7.checkKeyRole根据keyCode判断此时用户按下的键是C/V,然后调用isKeyDown()判断Ctrl键是否被按下

8.若isKeyDown返回true,则做复制/黏贴图形的操作;若isKeyDown返回false,则不做任何操作。