todos - Captura del evento de teclado Cmd-C(o Ctrl-C) desde la aplicación Flex modular en el navegador o en el AIR
todos los atajos del teclado (4)
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 de AIR, presumiblemente porque el navegador o sistema operativo lo está interceptando primero.
¿Hay alguna manera de decirle al navegador o al sistema operativo que deje pasar el evento?
Por ejemplo, en AdvancedDataGrid he establecido 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 se ejecuta, nunca puedo obtener la liberación de la tecla "C" mientras también presiono la tecla de comando (que aparece como KeyboardEvent.ctrlKey). Obtengo los siguientes resultados de rastreo:
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 mantiene presionada la tecla de comando ni siquiera se envía.
¿Alguien ha implementado con éxito el manejo estándar de copiar y pegar el teclado?
¿Estoy destinado a usar solo la tecla "C" por sí mismo (como se muestra en el ejemplo del código) o hacer que un botón de copia esté disponible?
¿O necesito crear el oyente manualmente en un nivel superior y pasar el evento a las entrañas de mi aplicación modular?
Hice una prueba donde escuché los eventos clave en el escenario y noté que (en mi Mac) podía capturar control-c, control-v, etc. bien, pero cualquier cosa que implique comando (la tecla was) no era capturado 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 código de caracteres era 0. Bastante inútil, en resumen.
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
), sino que debes probar para charCode
o keyCode
siendo 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 en el teclado, no el carácter escrito. Lo mismo ocurre con todas las otras combinaciones de teclas (porque cada combo ctrl tiene un equivalente ASCII).
Editar Encontrado un error en el sistema de error de Flex sobre esto: https://bugs.adobe.com/jira/browse/FP-375
He encontrado una solución a esto basada en la secuencia de captura. Cuando presiona Cmd + A, por ejemplo, la secuencia es:
- tipo: KEY_DOWN, keyCode 15
- tipo: KEY_UP, keyCode 15
- tipo: KEY_DOWN, keyCode 65
Por lo tanto, cada vez que se baja el KeyCode 15 y luego sube y la siguiente captura se realiza, puede suponer 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í, los siguientes trabajos:
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;
}
}