Captura de evento de teclado Cmd-C (o Ctrl-C) desde la aplicación modular Flex en el navegador o AIR

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

  •  09-06-2019
  •  | 
  •  

Pregunta

Parece que es imposible capturar el evento de teclado que normalmente se usa para copiar cuando se ejecuta una aplicación Flex en el navegador o como una aplicación AIR, presumiblemente porque el navegador o el sistema operativo lo intercepta primero.

¿Hay alguna manera de decirle al navegador o al sistema operativo que deje pasar el evento?

Por ejemplo, en AdvancedDataGrid configuré el evento keyUp para manejarCaseListKeyUp (evento), que llama a la siguiente función:

        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);
        }

Cuando lo ejecuto, nunca puedo soltar la tecla "C" mientras presiono la tecla de comando (que aparece como KeyboardEvent.ctrlKey).Obtengo los siguientes resultados de seguimiento:

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

Como puede ver, el único evento que puedo capturar es la liberación de la tecla de comando, la liberación de la tecla "C" mientras se mantiene presionada la tecla de comando ni siquiera se envía.

¿Alguien ha implementado con éxito el manejo estándar del teclado para copiar y pegar?

¿Estoy destinado a usar la tecla "C" sola (como se muestra en el ejemplo de código) o a tener disponible un botón de copia?

¿O necesito crear el oyente manualmente en un nivel superior y pasar el evento a las entrañas de mi aplicación modular?

¿Fue útil?

Solución

Hice una prueba en la que escuché los eventos clave en el escenario y noté que (en mi Mac) podía capturar control-c, control-v, etc.está bien, pero todo lo relacionado con el comando (la tecla ) no se capturó hasta que solté la tecla de comando, y luego ctrlKey era falso (aunque los documentos dicen que ctrlKey debería ser verdadero para la tecla de comando en Mac), y el El código de caracteres era 0.Bastante inútil, en definitiva.

Otros consejos

Otra cosa increíblemente molesta de la que me acabo de dar cuenta es que Ctrl-c no puede ser capturado por event.ctrlKey && event.keyCode = Keyboard.C (o ...event.charCode == 67), en su lugar tienes que probar charCode o keyCodeser 3.Tiene sentido para charCode ya que Ctrl-c es 3 en la tabla ASCII, pero no tiene sentido para keyCode, que se supone que representa la tecla del teclado, no el carácter escrito.Lo mismo ocurre con todas las demás combinaciones de teclas (porque cada combinación Ctrl tiene un equivalente ASCII).

Editar Encontré un error en el sistema de errores Flex sobre esto: https://bugs.adobe.com/jira/browse/FP-375

Encontré una solución para esto basada en la secuencia de captura.Cuando presionas Cmd+A, por ejemplo, la secuencia es:

  • tipo:KEY_DOWN, código de clave 15
  • tipo:KEY_UP, código clave 15
  • tipo:KEY_DOWN, código clave 65

Entonces, cada vez que baja y luego sube el Código de tecla 15 y la siguiente captura es hacia abajo, puede asumir que el usuario presionó la combinación de teclas.Mi implementación termina así:

    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!
            }
        }
    }

Para mí, lo siguiente funciona:

    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;
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top