NativeWindow クラスのイベント

以下は NativeWindow クラスのイベントのリストです。

displayStateChange    NativeWindow オブジェクトの displayState 属性が変更された
displayStateChanging  NativeWindow オブジェクトの displayState 属性が変更される直前
move                  NativeWindow オブジェクトがデスクトップ上で移動した
moving                NativeWindow オブジェクトがデスクトップ上で移動する直前
resize                NativeWindow オブジェクトの大きさが変更された
resizing              NativeWindow オブジェクトの大きさが変更される直前
close                 NativeWindow オブジェクトが閉じられた
closing               NativeWindow オブジェクトが閉じられる直前
  

ひとめで2つずつペアになっているのが分かるかと思います。4種類のウインドウに対する操作に対して、完了の直前と完了後それぞれの状態を通知するイベントが定義されています。

ing で終わるイベントは警告のような位置づけで、これを受け取ることで処理が完了する前に状況を確認したり、場合によっては処理自体をキャンセルするといった使い方が想定されています。そのため ing 系のイベントはいずれもキャンセル可能です。

一方 ing のつかないイベントは完了を通知するイベントです。事後処理が必要な場合に使用します。

では個々のイベントを少し詳しく見てみたいと思います。

NativeWindowDisplayStateEvent

まずは displayState 属性の変更に関連するイベントです。displayStateChanging は NativeWindow オブジェクトの displayState が変更される直前、displayStateChange は displayState が変更された後に該当する NativeWindow によってディスパッチされます。

このときディスパッチされるイベントオブジェクトの型は flash.events.NativeWindowDisplayStateEvent です。この型のイベントは beforeDisplayState と afterDisplayState の属性を持っていて、それぞれ変更前の値と変更後の値を示します。

displayStateChanging イベントの場合はまだ変更が完了していないので、イベントを受け取った時点での displayState 属性の値は beforeDisplayState の方ということになります。一方 displayStateChange イベントの場合は変更が既に行われているので、その時点の displayState 属性の値は afterDisplayState の方ということになります。

では早速サンプルコードを動かしてみましょう。まず、システムクロームを表示するようにアプリケーション記述ファイル内の rootContent タグの systemChrome が standard になっていることを確認します。

<rootContent systemChrome="standard" transparent="false" visible="true">[SWF reference is generated]</rootContent>
 

下のサンプルコードでは applicationComplete イベントのタイミングでイベントリスナ (onDispStateEvent) を追加しています。onDispStateEvent 内では trace() を使ってイベント情報を出力するようにしていますので、デバッグモードで実行してください。Flex Builder のコンソールにメッセージが出力されます。デバッグは虫のアイコンをクリックすると開始されます。

<?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(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, onDispStateEvent);
      stage.window.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, onDispStateEvent);
    }
    private function onDispStateEvent(e:NativeWindowDisplayStateEvent):void {
      trace("type:", e.type, e.afterDisplayState);
    }
    private function onMinBtnClick(e:MouseEvent):void
    {
      stage.window.minimize();
    }
    private function onMaxBtnClick(e:MouseEvent):void
    {
      if (stage.window.displayState != NativeWindowDisplayState.MAXIMIZED)
      {
        stage.window.maximize();
        maxBtn.label = "v";
      }
      else
      {
        stage.window.restore();
        maxBtn.label = "\u25A2";
      }
    }
    private function onCloseBtnClick(e:MouseEvent):void
    {
      stage.window.close();
    }
  ]]>
  </mx:Script>
  <mx:HBox width="100%" backgroundColor="#ffffff">
    <mx:Button id="minBtn" label="_" click="onMinBtnClick(event)" />
    <mx:Button id="maxBtn" label='{"\u25A2"}' click="onMaxBtnClick(event)" />
    <mx:Button id="closeBtn" label="X" click="onCloseBtnClick(event)" />
  </mx:HBox>
  <mx:HBox width="100%" height="100%" backgroundColor="#ffffff"/>
</mx:ApolloApplication>
 

注意深くテストをした人は、システムクロームの最小化 / 最大化ボタンと、ウインドウ内の最小化 / 最大化ボタンとで押された後のイベントに違いがあるのに気づいたことと思います。

システムクロームのボタンからウインドウを最大化したり元に戻したりすると displayStateChanging と displayStateChange の両方のイベントが発生します。

一方、ウインドウ内のボタンを押した場合は displayStateChange イベントしか発生しません。(つまり ing イベントは発生しません)

これは、システムクロームから操作がされた場合、その操作によりリクエストされた処理が実際に行われる前に対応することが可能なようにという配慮によるものです。そのため、NativeWindow が displayStateChanging を自動的にディスパッチするのです。

一方、ウインドウ内のボタンから minimize() 等のメソッドを呼び出す場合は、呼び出す前に必要な対応を記述しておくことが可能なはずです。そのため minimize(), maximize(), restore() を呼んでも displayStateChanging は自動的にはディスパッチされません。

もし minimize() 等による displayState の変更に対しても displayStateChanging イベントが必要な場合には、以下のような記述を追加します。下は minimize() が呼ばれた場合です。

private function onMinBtnClick(e:MouseEvent):void
{
  stage.window.minimize();
  var dispStateEvent:NativeWindowDisplayStateEvent = 
    new NativeWindowDisplayStateEvent(
      NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, true, true, 
      stage.window.displayState, NativeWindowDisplayState.MINIMIZED);
    stage.window.dispatchEvent(dispStateEvent);
}
 

ApolloApplicaton のクロームではこれと同様な処理が追加されています。アプリケーション記述ファイルの rootContent タグの systemChrome を none にして ApolloApplication のクロームを表示すると displayStateChanging を確認することができます。

ちょっと長くなってしまいましたのでイベント話の続きはまた次回。

コメントする

2014年1月

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
レンタルサーバー

月別 アーカイブ

Powered by Movable Type 4.261