Macromedia Director非公式テクニカルノート MIAWのmodalをtrueにしてもステージが前面に切り替わる
Platform: Windows 1. 現象 2. 原因 3. 対処法 MasterApp Xtraを使った場合 使用するメソッドは、'mappKeepOnTop'と'mappDontKeepOnTop'、'mappGetActiveWindow'の計3つです。 まず、'mappKeepOnTop'は、指定したウィンドウをすべてのウィンドウのつねに最前面に表示します。Win32のみの機能ですので、ご注意ください。他のアプリケーションのウィンドウも含まれます。'mappDontKeepOnTop'は、'mappKeepOnTop'でつねに最前面に表示する設定にしたウィンドウを通常の状態に戻します。引数や戻り値の設定は、両者共通です。 メソッドの使用方法 sResult = mappDontKeepOnTop(ウィンドウID番号) 引数 戻り値 つぎに、'mappGetActiveWindow'は、Directorアプリケーションまたはプロジェクタのウィンドウの中で、最前面に開いているウィンドウのID番号を返します。 メソッドの使用方法 引数 戻り値 --[ウィンドウを開いたときつねに最前面に表示する] 'on openWindow'と'on closeWindow'ハンドラまでのスクリプトの処理は、前述したシンタックスについての説明でご理解いただけると思います。なぜ'on deactivateWindow'ハンドラを加えたかといいますと、2つのハンドラだけではステージのタイトルバーをクリックしたときに問題が生じるためです。なお、MIAWを閉じるとき、'forget window'を使いますと、'closeWindow'や'deactivateWindow'のイベントは発生せず、ハンドラが実行されません。また、MIAW自身から'forget window'を実行すると、Winodowsのプロジェクタは落ちてしまうことがあります([FN0108018]「MIAWを閉じるとプロジェクタが落ちる」参照)。 ステージが前面に切り替わって表示されるという現象は、前述した2つのハンドラで回避できます。ところが、ステージのタイトルバーをクリックすると、MIAWは前面に表示されているものの、ウィンドウのフォーカスだけはステージに切り替わってしまいます。そのため、ステージがアクティブになり、マウスイベントを受け取ってしまいます。これでは、モーダルの設定とはいえません。 そこで、'on deactivateWindow'ハンドラを記述し、アクティブウィンドウがMIAWからステージに切り替わったら、再度MIAWにフォーカスを戻そうということです。MIAWのウィンドウIDはすでに取得済みです。そして、MasterApp Xtraには、指定したウィンドウをアクティブにする'mappSetActiveWindow'というメソッドがあります。 もっとも、'deactivateWindow'イベントを受け取ると同時にこの処理を行ったのでは、タイミングが早過ぎるようです。一瞬間を空けて処理を行うために、ここでは親スクリプトとタイムアウトオブジェクトを使うことにしました。その親スクリプト名が「KeepOnTop」です。親スクリプトについて詳しくは、『Lingo辞書』または市販の解説書(たとえば大重美幸『Lingoスーパーマニュアル−Director 8対応−』オーム社)をご参照ください。 'mappSetActiveWindow'メソッドについて、簡単に説明しておきます。 メソッドの使用方法 引数 戻り値 --[KeepOnTop] まず、'on new'ハンドラでタイムアウトオブジェクトを作成します(タイムアウトオブジェクトについて、詳しくは『Lingo辞書』の'timeout()'関数および'new()'関数をご参照ください)。タイムアウトオブジェクト名はユニークな名前なら何でもよいので、親スクリプトのアドレス参照をストリングにして使っています。一瞬の間を空けるために、タイムアウト時間は1ミリ秒としました。タイムアウトハンドラが#xReactiveate、ターゲットオブジェクトはこの親スクリプトで生成した子オブジェクト('me')です。これで、子オブジェクト生成後1ミリ秒経過すると、このオブジェクトの'on xReactivate'ハンドラが呼び出されます。 on xReactivateハンドラは、一回だけの処理です。ですから、その第1ステートメントで、タイムアウトオブジェクトを削除します。ドキュメントに明示されていないようですが、タイムアウトハンドラは、その第2引数としてタイムアウトオブジェクトを受け取ります。 第3ステートメントは、MIAWをアクティブにする処理です。これは、第2ステートメントの'if...then'構文で、MIAWのウィンドウIDを格納しているグローバル変数gnWinIDが'void'でない場合に実行されます。変数値が'void'に設定されるのは、すでにご説明したムービースクリプトの'on closeWindow'ハンドラが実行されたときです。 ウィンドウが閉じても、それだけではまだMIAWがメモリに残るため、'on deactivate'ハンドラは引き続き実行されます。そのため、そのままでは非表示のMIAWがアクティブになり、ステージにフォーカスがもどりません。そこで、ウィンドウを閉じたとき('on closeWindow')には、グローバル変数を'void'に設定して、アクティブウィンドウの切り替えをしないようにしたのです。 Buddy APIを使った場合 使用するメソッドは、'baSetWindowState'と'baWinHandle'、'baActivateWindow'、それから'baFindWindow'の計4つです。 まず、'baSetWindowState'メソッドは、指定したウィンドウの状態を設定します。つねに最前面に表示の設定とその解除は、引数の変更によって指定することができます。 メソッドの使用方法 引数 状態: ウィンドウの状態をストリングで指定します。設定できる状態には各種ありますが、今回はつねに前面に表示させる"StayOnTop"と、その解除の"DontStayOnTop"を使用します。他の設定につきましては、エクストラのヘルプをご参照ください。 戻り値 つぎに、'baWinHandle'メソッドは、Directorのメインウィンドウのハンドル番号を返します。 メソッドの使用方法 引数 戻り値 'baActiveateWindow'メソッドは、指定したウィンドウをアクティブにします。 メソッドの使用方法 引数 戻り値 'baFindWindow'メソッドは、タイトルまたはクラスを指定してウィンドウを探すことができます。 メソッドの使用方法 引数 タイトル: ウィンドウのタイトル名を、ストリングで指定します。 引数のどちらかを無指定とする場合には、'empty'("")を指定します。 戻り値 --[ウィンドウを開いたときつねに最前面に表示する] --[KeepOnTop] スクリプトの構造は、MasterApp Xtraのサンプルと同様です。ただ、Buddy APIは、MIAWを閉じただけでは、つぎのウィンドウ(ステージ)に直ちにフォーカスが戻らず、非アクティブ表示されるようです。そのため、on xReactivateハンドラで、MIAWが閉じられた(グローバル変数gMyWindowが'void'の)場合には、つぎのウィンドウをアクティブに設定するようにしました。 'timeOut'オブジェクトをステージに対して生成したのは、このオブジェクトが(ステージを含めた)ウィンドウごとに設定されるものだからです。MIAWを閉じる('close window')と同時に'forget window'した場合に、'timeOut'オブジェクトはMIAWとともに消滅します。そうしますと、子オブジェクトへの参照もなくなり、スクリプトが実行されることなく、子オブジェクトも消滅することになります。'timeOut'オブジェクトを'forget window'後も残しておくためには、ステージに対して生成する必要がある訳です。上記のサンプルは、MIAWを閉じたときステージをアクティブにしています。'baFindWindow'メソッドを使って、ウィンドウタイトルからステージのハンドル番号を取得します。ステージのウィンドウタイトルは、デフォルトではプロジェクタのファイル名になります。ただし、拡張子は必要ありませんので、'itmeDelimiter'を"."に設定して、ファイル名のみを取り出しています。 _____ 作成者: 野中文雄 Copyright © 2001-2003 Fumio Nonaka. All rights reserved. |
|||