Согнуть открытое окно за активным окном - PullRequest
2 голосов
/ 09 июля 2010

В приложении 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. Если да, есть ли решение этой проблемы?

Ответы [ 2 ]

0 голосов
/ 10 июля 2010

Так что, похоже, нет хорошего способа решить эту проблему. Обходным решением будет добавить прослушиватель событий для AIREvent.WINDOW_COMPLETE и переместить окно в обработчик событий. Это похоже на «правильный» обходной путь, и он работает для простого случая, как мой оригинальный пример. Проблема в том, что этот подход не работал на моем коде.

Если вы посмотрите на код spark.components.Window из sdk, вы увидите, что при открытии окна добавляется прослушиватель событий для Event.ENTER_FRAME (в commitProperties ()). Затем в обработчике события enterFrameHandler () он сохраняет счетчик, а во втором кадре отправляет событие AIREvent.WINDOW_COMPLETE. Это заставляет меня думать, что событие AIREvent.WINDOW_COMPLETE будет запускаться во втором кадре независимо от состояния окна, даже если liveoc сообщает:

Отправляется, когда Window завершает свою первоначальную компоновку и открывает базовый NativeWindow .

Я предполагаю, что мое окно не было полностью создано вторым кадром, и поэтому orderInBackOf не удалось.


Так вот мой обходной путь:

Во-первых, в моем окне я перезаписываю open (openWindowActive). Если openWindowActive имеет значение false, я добавляю прослушиватель событий для Event.ENTER_FRAME. В обработчике событий я сохраняю счетчик и, когда счетчик кадров достигает определенного числа (прямо сейчас 10), я перемещаю текущее окно за активным. Это ОЧЕНЬ хакерский способ обойти эту проблему. Я увеличивал лимит, и теперь он успешен примерно в 90% случаев. Я мог бы продолжать увеличивать лимит, пока не достигну 100%, но я ненавижу проверять это условие каждый раз, когда я делаю какие-либо изменения в окне. Также это условие может быть различным в зависимости от машины.

Я ЛЮБЛЮ это, если кто-то скажет мне, насколько ошибочен мой обходной путь, и расскажет мне о гораздо более эффективном способе решения моей проблемы ... но до тех пор это придется делать ...

0 голосов
/ 09 июля 2010

Есть ли конкретная причина, по которой вы устанавливаете для параметра useWeakReference значение true? В противном случае вы можете просто позвонить:

timer.addEventListener(TimerEvent.TIMER_COMPLETE, openWindow2);

Однако в этой строке кода есть ошибка. Событие TIMER_COMPLETE наступает, когда таймер завершает все свои циклы. Вы установили таймер на «огонь» бесконечно. Так что он никогда не завершит свои циклы.

Вам нужно изменить эту строку кода следующим образом, и вы должны получить ожидаемые результаты:

timer.addEventListener(TimerEvent.TIMER, openWindow2);


<ч />
Чтобы ответить на ваш второй вопрос (почему 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);                    
        }
...