displayStateChanging イベントのキャンセル
前回書いたように、ing 系のイベントは必要に応じて処理自体をキャンセルするために使用できます。displayStateChanging イベントであれば displayState の変更をキャンセルするわけですから、最大化や最小化を行わないという指示を出すことになります。
AS3 では、イベントにより標準的に行われることになっている処理をキャンセルするには、イベントハンドラ内で preventDefault() を呼び出します。前回のサンプルをそのまま使うと、onDispStateEvent() メソッド内に preventDefault() を追加すればよいことになります。
onDispStateEvent() メソッドは displayStateChange と displayStateChanging イベントの両者で共用しているのでキャンセル不可のイベント (displayStateChange) も渡される可能性があります。そのため、キャンセル可能かを確認するロジックも追加しています。
private function onDispStateEvent(e:NativeWindowDisplayStateEvent):void { if (e.cancelable) { // キャンセル可能かをチェック e.preventDefault(); // 標準処理をキャンセル } trace("type:", e.type, e.afterDisplayState); }
実際にこのコードを実行してみると、システムクロームのボタンを押しても何も起こらないのに対して、アプリ内のボタンはそのまま有効なのが分かると思います。また、アプリ内のボタン押下時に明示的に displayStateChanging イベントのディスパッチを行うと、システムクロームのボタンと同様にキャンセル処理が有効になるのが確認できると思います。
NativeWindowBoundsEvent
NativeWindow の bounds 属性が変更されると NativeWindowBoundsEvent がディスパッチされます。bounds 属性が変更されるのはウインドウの位置か大きさが変わった場合です。
NativeWindowBoundsEvent は beforeBounds と afterBounds の属性を持っていて、それぞれ変更前の値と変更後の bounds 属性の値を示します。ing 系 (moving, resizing) のイベントでは beforeBounds がその時点での値、完了通知のイベント (move, resize) では afterBounds がその時点での値ということになります。
NativeWindowDisplayStateEvent のケースと同様に、move と resize イベントはそれぞれウインドウの位置もしくは大きさが変われば常にディスパッチされますが、moving と resizing はマウス操作で位置や大きさを変えた場合のみディスパッチされ、スクリプトから bounds 等の属性を変更した場合にはディスパッチされません。
これも NativeWindowDisplayStateEvent のケースと同様に、属性値の変更時に明示的に moving や resizing をディスパッチすることで、他のコンポーネントでもキャンセルを可能にすることができます。
ちなみに Stage クラスにも resize イベントがあります。こちらはステージの大きさが変更された後に描画開始できる状態になるとディスパッチされます。
以下は NativeWindowBoundsEvent の発生を確認するためのサンプルです。システムクロームを表示した状態で試してみてください。デバッグモードをお忘れなく。
<?xml version="1.0" encoding="utf-8"?> <mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="addListeners()"> <mx:Script> <![CDATA[ private function addListeners():void { stage.window.addEventListener(NativeWindowBoundsEvent.RESIZE, onBoundsEvent); stage.window.addEventListener(NativeWindowBoundsEvent.RESIZING, onBoundsEvent); stage.window.addEventListener(NativeWindowBoundsEvent.MOVE, onBoundsEvent); stage.window.addEventListener(NativeWindowBoundsEvent.MOVING, onBoundsEvent); } private function onBoundsEvent(e:NativeWindowBoundsEvent):void { trace("type:", e.type, e.afterBounds); } private function onBoxMouseDown(e:MouseEvent):void { stage.window.startResize(NativeWindowResize.BOTTOM_RIGHT); } private function onBarMouseDown(e:MouseEvent):void { stage.window.startMove( ); } ]]> </mx:Script> <mx:HBox mouseDown="onBarMouseDown(event)" width="100%" height="24" backgroundColor="#ffffff"/> <mx:HBox mouseDown="onBoxMouseDown(event)" width="100%" height="100%" backgroundColor="#ffffff"/> </mx:ApolloApplication>
close と closing イベント
最後に close と closing イベントです。これらのイベントは、ユーザがウインドウを閉じるボタンを押した時、閉じるまでに必要な処理があるケースなどに便利です。イベントの型は flash.events.Event です。
closing は閉じる直前に close は閉じた後に発生します。closing イベントをキャンセルすると、ウインドウを閉じるという処理自体をキャンセルできます。ただ closing イベントはシステムクロームの閉じるボタンを押した場合以外には自動的にディスパッチされないため、必要な場合には明示的にイベントを発生させる必要があります。この点は他の ing 系のイベントと同じです。
コメントする