ブラウザまたは AIR のモジュラー Flex アプリケーションから Cmd-C (または Ctrl-C) キーボード イベントをキャプチャする

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

  •  09-06-2019
  •  | 
  •  

質問

ブラウザまたは AIR アプリとして Flex アプリケーションを実行している場合、通常コピーに使用されるキーボード イベントをキャプチャすることは不可能のようです。おそらく、ブラウザまたは OS が最初にそれをインターセプトするためです。

ブラウザまたは OS にイベントを通過させる方法はありますか?

たとえば、AdvancedDataGrid では、keyUp イベントを handleCaseListKeyUp(event) に設定し、次の関数を呼び出します。

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

実行時に、コマンド キー (KeyboardEvent.ctrlKey として表示される) を押しながら「C」キーを離すことはできません。次のトレース結果が得られます。

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

ご覧のとおり、キャプチャできる唯一のイベントはコマンド キーを離したことです。コマンド キーを押したまま「C」キーを離しても送信されません。

標準のコピーアンドペーストキーボード処理をうまく実装した人はいますか?

(コード例に示すように) 「C」キーを単独で使用するだけでしょうか、それともコピー ボタンを使用できるようにするのでしょうか?

それとも、より高いレベルでリスナーを手動で作成し、イベントをモジュール型アプリケーションの内部に渡す必要がありますか?

役に立ちましたか?

解決

ステージ上のキーアップ イベントをリッスンするテストを行ったところ、(Mac 上で) control-c、control-v などをキャプチャできることに気付きました。問題ありませんが、コマンド ( キー) に関係するものは、コマンド キーを放すまでキャプチャされず、その後 ctrlKey が false になりました (ドキュメントには、Mac のコマンド キーに対して ctrlKey は true である必要があると記載されていますが)。 charCodeは0でした。要するに、かなり役に立たない。

他のヒント

私が今気づいたもう 1 つの信じられないほど面倒な点は、ctrl-c がキャプチャできないことです。 event.ctrlKey && event.keyCode = Keyboard.C (または ...event.charCode == 67)、代わりにテストする必要があります charCode または keyCodeいる 3. 。それはある意味理にかなっています charCode ctrl-c なので 3 ASCII テーブルにありますが、意味がありません。 keyCode, これは、入力された文字ではなく、キーボードのキーを表すことになっています。他のすべてのキーの組み合わせにも同じことが当てはまります (すべての Ctrl キーの組み合わせには同等の ASCII があるため)。

編集 これに関する Flex バグ システムでバグが見つかりました。 https://bugs.adobe.com/jira/browse/FP-375

キャプチャシーケンスに基づいて、これに対する回避策を1つ見つけました。たとえば、Cmd+A を押すと、シーケンスは次のようになります。

  • タイプ:KEY_DOWN、キーコード 15
  • タイプ:KEY_UP、キーコード 15
  • タイプ:KEY_DOWN、キーコード 65

したがって、keyCode 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