2

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の上に開き、メインアプリがフォーカスを保持します。これはFlexのバグのようです。もしそうなら、この問題の回避策はありますか?

4

2 に答える 2

0

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);
        }

これが何らかの形で役立つことを願っています、

  • g男性

編集:私の最後のコメントごとにこれを試してみてください、

        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);                    
        }
于 2010-07-09T03:29:12.380 に答える
0

したがって、この問題を解決する良い方法はないようです。回避策として、AIREvent.WINDOW_COMPLETE のイベント リスナーを追加し、イベント ハンドラでウィンドウを移動します。これは「正しい」回避策のようで、元の例のような単純なケースで機能します。問題は、このアプローチが私のコードでは機能しなかったことです。

SDK の spark.components.Window コードを見ると、ウィンドウを開くときに (commitProperties() で) Event.ENTER_FRAME のイベント リスナーが追加されていることがわかります。次に、イベント ハンドラ enterFrameHandler() でカウンタを保持し、2 番目のフレームで AIREvent.WINDOW_COMPLETE イベントをディスパッチします。これにより、ライブドキュメントに次のように表示されていても、ウィンドウのステータスに関係なく、AIREvent.WINDOW_COMPLETE イベントが 2 番目のフレームで発生すると思われます。

Windowが初期レイアウトを完了し、基になる NativeWindow を開くときに送出されます。

ウィンドウが 2 番目のフレームで完全に作成されていないため、orderInBackOf が失敗したと思います。


だからここに私の回避策があります:

まず、ウィンドウで open(openWindowActive) をオーバーライドします。openWindowActive が false の場合、Event.ENTER_FRAME のイベント リスナーを追加します。イベント ハンドラーではカウンターを保持し、フレーム カウントが特定の数 (現在は 10) に達すると、現在のウィンドウをアクティブなウィンドウの後ろに移動します。これは、この問題を回避する非常にハックな方法です。私は制限を増やしてきましたが、今では約 90% の確率で成功しています。100% に近づくまで制限を増やし続けることもできますが、ウィンドウに変更を加えるたびにこの条件を確認する必要はありません。また、この条件はマシンによって異なる場合があります。

誰かが私の回避策がどれほど間違っているかを教えてくれ、私の問題を解決するためのはるかに良い方法を教えてくれたら嬉しいです...しかしそれまではこれをしなければなりません...

于 2010-07-10T01:25:52.703 に答える