Capture d'un événement clavier Cmd-C (ou Ctrl-C) à partir d'une application Flex modulaire dans un navigateur ou AIR

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

  •  09-06-2019
  •  | 
  •  

Question

Il semble qu'il soit impossible de capturer l'événement clavier normalement utilisé pour la copie lors de l'exécution d'une application Flex dans le navigateur ou en tant qu'application AIR, probablement parce que le navigateur ou le système d'exploitation l'intercepte en premier.

Existe-t-il un moyen d'indiquer au navigateur ou au système d'exploitation de laisser passer l'événement ?

Par exemple, sur un AdvancedDataGrid, j'ai défini l'événement keyUp sur handleCaseListKeyUp(event), qui appelle la fonction suivante :

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

Lors de l'exécution, je ne parviens jamais à relâcher la touche "C" tout en appuyant également sur la touche de commande (qui apparaît sous la forme KeyboardEvent.ctrlKey).J'obtiens les résultats de trace suivants :

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

Comme vous pouvez le voir, le seul événement que je peux capturer est le relâchement de la touche de commande, le relâchement de la touche "C" tout en maintenant la touche de commande enfoncée n'est même pas envoyé.

Quelqu'un a-t-il implémenté avec succès la gestion standard du clavier copier-coller ?

Suis-je destiné à utiliser simplement la touche « C » seule (comme indiqué dans l'exemple de code) ou à rendre disponible un bouton de copie ?

Ou dois-je créer manuellement l'écouteur à un niveau supérieur et transmettre l'événement dans les tripes de mon application modulaire ?

Était-ce utile?

La solution

J'ai fait un test où j'écoutais les événements clés sur scène et j'ai remarqué que (sur mon Mac) je pouvais capturer control-c, control-v, etc.très bien, mais tout ce qui implique une commande (la touche ) n'a pas été capturé jusqu'à ce que je relâche la touche de commande, puis ctrlKey était faux (même si la documentation dit que ctrlKey devrait être vrai pour la touche de commande sur Mac), et le charCode était 0.Plutôt inutile, en somme.

Autres conseils

Une autre chose incroyablement ennuyeuse que je viens de réaliser est que ctrl-c ne peut pas être capturé par event.ctrlKey && event.keyCode = Keyboard.C (ou ...event.charCode == 67), vous devez plutôt tester charCode ou keyCodeêtre 3.Cela a du sens pour charCode puisque ctrl-c est 3 dans la table ASCII, mais cela n'a aucun sens pour keyCode, qui est censé représenter la touche du clavier, pas le caractère tapé.Il en va de même pour toutes les autres combinaisons de touches (car chaque combinaison ctrl a un équivalent ASCII).

Modifier J'ai trouvé un bug dans le système de bugs Flex à ce sujet : https://bugs.adobe.com/jira/browse/FP-375

J'ai trouvé une solution de contournement à celle-ci basée sur la séquence de capture.Lorsque vous appuyez sur Cmd+A, par exemple, la séquence est :

  • taper:KEY_DOWN, code clé 15
  • taper:KEY_UP, code clé 15
  • taper:KEY_DOWN, code clé 65

Ainsi, chaque fois que vous obtenez le keyCode 15 vers le bas, puis vers le haut et que la capture suivante est en panne, vous pouvez supposer que l'utilisateur a appuyé sur la combinaison de touches.Ma mise en œuvre se termine comme ceci :

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

Pour moi, les travaux suivants :

    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;
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top