ブラウザまたは AIR のモジュラー Flex アプリケーションから Cmd-C (または Ctrl-C) キーボード イベントをキャプチャする
質問
ブラウザまたは 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;
}
}