Захват события клавиатуры Cmd-C (или Ctrl-C) из модульного приложения 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);
        }

При запуске я никогда не могу отпустить клавишу «C», одновременно нажимая и командную клавишу (которая отображается как KeyboardEvent.ctrlKey). Я получаю следующие результаты трассировки:

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

Как видите, единственное событие, которое я могу зафиксировать, - это отпускание клавиши управления, отпускание клавиши «C» при удерживании клавиши команды даже не отправляется.

Кто-нибудь успешно реализовал стандартную обработку клавиатуры для копирования и вставки?

Суждено ли мне просто использовать клавишу «C» самостоятельно (как показано в примере кода) или сделать доступной кнопку копирования?

Или мне нужно создать прослушиватель вручную на более высоком уровне и передать событие в внутренности моего модульного приложения?


person ianmjones    schedule 28.08.2008    source источник


Ответы (4)


Я провел тест, в котором я прослушивал события нажатия клавиш на сцене и заметил, что (на моем Mac) я мог легко захватить control-c, control-v и т. Д., Но ничего, связанного с командой (клавиша ), не было захватывались, пока я не отпустил командную клавишу, а затем ctrlKey был ложным (хотя в документации сказано, что ctrlKey должно быть истинным для командной клавиши на Mac), а charCode был равен 0. Короче говоря, довольно бесполезно.

person Theo    schedule 28.08.2008

Еще одна невероятно неприятная вещь, которую я только что понял, это то, что ctrl-c не может быть захвачен event.ctrlKey && event.keyCode = Keyboard.C (или ..._ 2_), вместо этого вам нужно проверить, является ли charCode или keyCode 3. Это имеет смысл для charCode, поскольку ctrl-c 3 в таблице ASCII, но не имеет смысла для keyCode, который должен представлять клавишу на клавиатуре, а не вводимый символ. То же самое касается всех других комбинаций клавиш (потому что каждая комбинация Ctrl имеет эквивалент ASCII).

Изменить Обнаружил ошибку в системе ошибок Flex по этому поводу: https://bugs.adobe.com/jira/browse/FP-375

person Theo    schedule 07.09.2008

Я нашел способ обхода этого, основанный на последовательности захвата. Например, когда вы нажимаете 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!
            }
        }
    }
person Pedro Andrade    schedule 22.04.2011
comment
просто хотел прокомментировать и сказать, что вы можете импортировать flash.ui.Keyboard и использовать Keyboard.CONTROL, Keyboard.A и т. д. вместо того, чтобы знать коды клавиш :-) - person Seaux; 09.01.2012

Для меня работает следующее:

    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;
        }
    }
person Community    schedule 09.01.2009