从浏览器或AIR中的模块化Flex应用程序捕获Cmd-C(或Ctrl-C)键盘事件

时间:2008-08-28 08:34:09

标签: flex air

在浏览器中运行Flex应用程序或作为AIR应用程序时,似乎无法捕获通常用于复制的键盘事件,可能是因为浏览器或操作系统首先拦截它。

有没有办法告诉浏览器或操作系统让事件通过?

例如,在AdvancedDataGrid上,我已将keyUp事件设置为handleCaseListKeyUp(event),后者调用以下函数:

        private function handleCaseListKeyUp(event:KeyboardEvent):void
        {
            var char:String = String.fromCharCode(event.charCode).toUpperCase();

            if (event.ctrlKey && char == "C")
            {
                trace("Ctrl-C");
                copyCasesToClipboard();
                return;
            }

            if (!event.ctrlKey && char == "C")
            {
                trace("C");
                copyCasesToClipboard();
                return;
            }

            // Didn't match event to capture, just drop out.
            trace("charCode: " + event.charCode);
            trace("char: " + char);
            trace("keyCode: " + event.keyCode);
            trace("ctrlKey: " + event.ctrlKey);
            trace("altKey: " + event.altKey);
            trace("shiftKey: " + event.shiftKey);
        }

运行时,在按下命令键(显示为KeyboardEvent.ctrlKey)的同时,我永远无法释放“C”键。我得到以下跟踪结果:

charCode: 0
char: 
keyCode: 17
ctrlKey: false
altKey: false
shiftKey: false

正如您所看到的,我可以捕获的唯一事件是释放命令键,释放“C”键同时保持命令键甚至不发送。

有没有人成功实施标准复制和粘贴键盘处理?

我是否注定只使用它自己的“C”键(如代码示例所示)或制作复制按钮?

或者我是否需要在更高级别手动创建侦听器并将事件传递给我的模块化应用程序的内容?

4 个答案:

答案 0 :(得分:2)

我做了一个测试,我在舞台上听了关键事件,并注意到(在我的Mac上)我可以捕获control-c,control-v等等,但是任何涉及命令的事情(键)直到我发布命令键才被捕获,然后ctrlKey为假(即使文档说Mac上的命令键ctrlKey应为true),并且charCode为0.简直就是没用了。

答案 1 :(得分:0)

我刚刚意识到的另一个令人难以置信的烦恼是event.ctrlKey && event.keyCode = Keyboard.C(或...... event.charCode == 67)无法捕获ctrl-c,而是必须测试charCodekeyCode3。这对charCode有意义,因为ASCII表中的ctrl-c是3,但它对keyCode没有意义,它应该代表键盘上的键,而不是打字的角色。所有其他关键组合也是如此(因为每个ctrl组合都有一个ASCII等价物。)

编辑在Flex错误系统中发现了一个错误:https://bugs.adobe.com/jira/browse/FP-375

答案 2 :(得分:0)

对我而言,以下作品:

    private var _ctrlHoldFlag:Boolean = false; 

    // Do something if CTRL was held down and C was pressed
    // Otherwise release the ctrl flag if it was pressed
    public function onKey_Up(event:KeyboardEvent):void {  
        var keycode_c:uint = 67;

        if (_ctrlHoldFlag && event.keyCode == keycode_c)
        {
            //do whatever you need on CTRL-C
        }

        if (event.ctrlKey)
        {
            _ctrlHoldFlag = false;
        }
    }

    // Track ctrl key down press 
    public function onKey_Down(event:KeyboardEvent):void
    {
        if (event.ctrlKey)
        {
            _ctrlHoldFlag = true;
        }
    }

答案 3 :(得分:0)

我根据捕获序列找到了一个解决方法。例如,按Cmd + A时,序列为:

  • 类型:KEY_DOWN,keyCode 15
  • 类型:KEY_UP,keyCode 15
  • 类型:KEY_DOWN,keyCode 65

因此,每当您将keyCode 15向下然后向上并且下一次捕获失败时,您可以假设用户按下了组合键。我的实现最终是这样的:

    protected var lastKeys:Array;
    this.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler, false, 0, true);
    this.stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler, false, 0, true);

    private function getCmdKey(ev:KeyboardEvent):Boolean {
        this.lastKeys.push(ev);
        this.lastKeys = this.lastKeys.splice(Math.max(0, this.lastKeys.length-3), 3);

        if (this.lastKeys.length < 3) return false;

        if (ev.keyCode != 15 && ev.type == KeyboardEvent.KEY_UP) {
            var firstKey:KeyboardEvent = this.lastKeys[0] as KeyboardEvent;
            var secondKey:KeyboardEvent = this.lastKeys[1] as KeyboardEvent;

            if (firstKey.keyCode == 15 && firstKey.type == KeyboardEvent.KEY_DOWN &&
                secondKey.keyCode == 15 && secondKey.type == KeyboardEvent.KEY_UP) {
                    return true;
            }
        }

        return false;
    }

    private function keyHandler(ev:KeyboardEvent):void {
        var cmdKey:Boolean = this.getCmdKey(ev.clone() as KeyboardEvent);
        var ctrlKey:Boolean = ev.ctrlKey || cmdKey;

        if (ctrlKey) {
            if (ev.keyCode == 65) { 
                // ctrl + "a"-- select all!
            }
        }
    }