Захват события клавиатуры с помощью команды Cmd-C (или Ctrl-C) из приложения modular Flex в браузере или AIR

StackOverflow https://stackoverflow.com/questions/31849

  •  09-06-2019
  •  | 
  •  

Вопрос

Похоже, что невозможно зафиксировать событие клавиатуры, обычно используемое для копирования при запуске приложения Flex в браузере или в качестве приложения AIR, предположительно потому, что браузер или операционная система перехватывают его первыми.

Есть ли способ сообщить браузеру или операционной системе пропустить событие?

Например, в AdvancedDataGrid я установил событию keyUp значение handleCaseListKeyUp(событие), которое вызывает следующую функцию:

        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", одновременно нажимая клавишу command (которая отображается как KeyboardEvent.ctrlKey).Я получаю следующие результаты трассировки:

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

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

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

Я нашел одно обходное решение для этого, основанное на последовательности захвата.Например, когда вы нажимаете Cmd + A, последовательность выглядит следующим образом:

  • Тип:KEY_DOWN, код ключа 15
  • Тип:KEY_UP, код ключа 15
  • Тип:KEY_DOWN, код ключа 65

Таким образом, каждый раз, когда вы нажимаете код ключа 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!
            }
        }
    }

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

    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;
        }
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top