Acquisizione dell'evento della tastiera Cmd-C (o Ctrl-C) dall'applicazione Flex modulare nel browser o AIR

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

  •  09-06-2019
  •  | 
  •  

Domanda

Sembra che sia impossibile acquisire l'evento della tastiera normalmente utilizzato per la copia quando si esegue un'applicazione Flex nel browser o come app AIR, presumibilmente perché il browser o il sistema operativo lo intercetta per primo.

C'è un modo per dire al browser o al sistema operativo di lasciar passare l'evento?

Ad esempio, su un AdvancedDataGrid ho impostato l'evento keyUp su handleCaseListKeyUp(event), che chiama la seguente funzione:

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

Durante l'esecuzione, non riesco mai a ottenere il rilascio del tasto "C" mentre premo anche il tasto comando (che viene visualizzato come KeyboardEvent.ctrlKey).Ottengo i seguenti risultati di traccia:

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

Come puoi vedere, l'unico evento che posso catturare è il rilascio del tasto comando, il rilascio del tasto "C" mentre si tiene premuto il tasto comando non viene nemmeno inviato.

Qualcuno ha implementato con successo la gestione standard della tastiera copia e incolla?

Sono destinato a utilizzare solo il tasto "C" da solo (come mostrato nell'esempio di codice) o a rendere disponibile un pulsante di copia?

Oppure devo creare manualmente il listener a un livello superiore e trasmettere l'evento alle viscere della mia applicazione modulare?

È stato utile?

Soluzione

Ho fatto un test in cui ho ascoltato gli eventi chiave sul palco e ho notato che (sul mio Mac) potevo catturare control-c, control-v, ecc.bene, ma tutto ciò che riguarda il comando (il tasto ) non è stato catturato finché non ho rilasciato il tasto comando, e quindi ctrlKey era falso (anche se la documentazione dice che ctrlKey dovrebbe essere vero per il tasto comando sul Mac), e il charCode era 0.Abbastanza inutile, insomma.

Altri suggerimenti

Un'altra cosa incredibilmente fastidiosa di cui ho appena realizzato è che ctrl-c non può essere catturato event.ctrlKey && event.keyCode = Keyboard.C (O ...event.charCode == 67), invece devi testare charCode O keyCodeessendo 3.In un certo senso ha senso charCode poiché ctrl-c è 3 nella tabella ASCII, ma non ha senso keyCode, che dovrebbe rappresentare il tasto sulla tastiera, non il carattere digitato.Lo stesso vale per tutte le altre combinazioni di tasti (perché ogni combinazione ctrl ha un equivalente ASCII).

Modificare Trovato un bug nel sistema di bug Flex a riguardo: https://bugs.adobe.com/jira/browse/FP-375

Ho trovato una soluzione alternativa a questo in base alla sequenza di acquisizione.Quando premi Cmd+A, ad esempio, la sequenza è:

  • tipo:CHIAVE_GIÙ, codice chiave 15
  • tipo:KEY_UP, codice chiave 15
  • tipo:CHIAVE_GIÙ, codice chiave 65

Quindi ogni volta che si abbassa e poi si abbassa il codice chiave 15 e l'acquisizione successiva è inattiva, si può presumere che l'utente abbia premuto la combinazione di tasti.La mia implementazione finisce così:

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

Per me, i seguenti lavori:

    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;
        }
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top