Flex Open Active Windowの背後にあるウィンドウを開きます
-
13-09-2020 - |
質問
Flex Airアプリでは、アクティブなものの後ろにウィンドウをどのように開くのですか?
私は後続を試してみて、それを働かせることはできないようです
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="onCreationComplete(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.Window;
private var window1:Window = new Window();
private var window2:Window = new Window();
private var timer:Timer = new Timer(3000,1);
private function onCreationComplete(event:FlexEvent):void
{
window1 = new Window();
window1.title = "Window 1";
window1.width = 200;
window1.height = 200;
window1.open(false);
window1.orderInBackOf(this);
window2 = new Window();
window2.title = "Window 2";
window2.width = 200;
window2.height = 200;
timer.addEventListener(TimerEvent.TIMER_COMPLETE, openWindow2, false, 0, true);
timer.start();
}
private function openWindow2(event:TimerEvent):void
{
window2.open(false);
window2.orderInBackOf(window1);
}
]]>
</fx:Script>
</s:WindowedApplication>
.
このコードでは、Window1がメインアプリケーションウィンドウの後ろに開くと予想し、3秒で、Window2はWindow1の後ろに開きます。しかし、これを実行した場合、Window1はメインウィンドウの上に開き、Window2はWindow1の上に開き、メインアプリはフォーカスを保持します。これはフレックスのバグのようです。もしそうならこの問題に対する回避策はありますか?
正しい解決策はありません
他のヒント
だからこの問題を解決するための良い方法はないようです。回避策は、AirEvent.Window_Completeのイベントリスナーを追加し、イベントハンドラのウィンドウを移動します。これは「正しい」回避策のようです、そしてそれは私の元の例のような単純なケースのために機能します。問題は、このアプローチが私のコードでは機能しなかったことです。
SDKからSpark.comPonents.Windowコードを見ると、ウィンドウを開くと(commitProperties())、event.enter_frameのイベントリスナーが追加されます。その後、イベントハンドラ、EnterFrameHandler()で、カウンタを保持し、2番目のフレームで、AirEvent.Window_Completeイベントを表示します。これにより、LiveDocが言うにもかかわらず、windowのステータスに関係なく、windowのステータスに関係なく、2番目のフレームで起動すると思います。
ウィンドウが初期レイアウトを完了したときにディスパッチされ、基礎となるNativeWindow を開きます。
私のウィンドウが2番目のフレームによって完全に作成されていなかったことを推測していたので、失敗しました。
だから私の回避策です:
まず、私のウィンドウで、開いている(OpenWindowActive)をオーバーライドします。 OpenWindowActiveがfalseの場合は、event.enter_frameにイベントリスナーを追加します。イベントハンドラでは、カウンタを保持し、フレーム数が特定の数字に達すると(現在は10)、現在のウィンドウをアクティブなものの後ろに移動します。これはこの問題を回避するための非常にハッキーな方法です。私は限界を増やしていて、今は約90%の時間に成功しました。私が100%に近づくまで限界を増やし続けることができましたが、私がウィンドウに変更を加えるたびにこの状態をチェックする必要があります。また、この状態は機械によって異なる可能性があります。
誰かが私の回避策がどれほど悪いか私の問題を解決する方法をはるかに良い方法で教えてくれるならば、私はそれを愛しています...しかしそれまでこれまでにこれを行う必要があります...
UseWeakReferenceパラメータをTRUEに設定している特定の理由はありますか?さもなければ、あなたはちょうどコールすることができるはずです:
timer.addEventListener(TimerEvent.TIMER_COMPLETE, openWindow2);
.
しかし、そのコード行のバグがあります。 TIMER_COMPLETEイベントは、タイマーがそのサイクルをすべて終了すると発生します。あなたはあなたのタイマーを無限に「火」に設定しました。だからそれはそれがサイクルを完成させることは決してないだろう。
そのコード行を次のものに変更する必要があり、予想される結果を得る必要があります。
timer.addEventListener(TimerEvent.TIMER, openWindow2);
.
あなたの2番目の質問に対処するために(Window1がアプリケーションの背後に表示されないのか)。 OrderInbackof関数の戻り値による判断:
Boolean — true if the window was succesfully sent behind;
false if the window is invisible or minimized.
.
ウィンドウが見えない場合、注文が失敗するようです。 CreationCompleteハンドラにコードを持つことで、アプリケーションウィンドウが自分自身を表示する機会がある前にこの機能を呼び出している場合があります。 OpenWindow2関数内でそのコードを移動してみてください。 yeilding:
private function openWindow2(event:TimerEvent):void
{
window1.orderInBackOf(this);
window2.open(false);
window2.orderInBackOf(window1);
}
.
これが何らかの方法で助けてくれることを願っています
- GMale
編集:最後のコメントごとに試してみてください、
private function openWindow2(event:TimerEvent):void
{
window1.depth = 5; //arbitrary number
window2.depth = 4;
window1.open(false); //assumes window1 isn't opened before
window2.open(false);
}
.