Функция получения текущего активного окна

Лучший способ помочь другим, поделиться своими находками.

Функция получения текущего активного окна

Сообщение Agasper 15 авг 2012, 16:49

Ввиду отсутствия стандартного решения проблемы, приведу свой код. В функцию надо передать массив окон, среди которых вы хотите найти верхнее.
Примечание: если вы собираетесь вызывать функцию каждый OnGUI() event, то рекомендую разбить ее на две части, и хранить Hashtable в переменной класса, чтобы каждый раз не терять время на выяснении кучи типов и полей.

Синтаксис:
Используется csharp
 /// <summary>
    /// Функция определяет самое верхнее окно из списка
    /// </summary>
    /// <returns>
    /// ID самого верхнего окна
    /// </returns>
    /// <param name='id_list'>
    /// Список ID окон
    /// </param>
    int GetTopmostId(List<int> id_list)
    {
        //Получаем тип GUI
        Type guiType = typeof(GUI);
        //Получаем тип списка окон
        Type windowListType = guiType.Assembly.GetType("UnityEngine.GUI+_WindowList");                                
        //Получаем поле instance списка, в котором хранится его экземпляр (это синглтон)
        FieldInfo windowListInstanceField = windowListType.GetField("instance", BindingFlags.NonPublic | BindingFlags.Static);
        //Получаем значение поля, теперь  нас есть экземпляр списка
        object windowListInstance = windowListInstanceField.GetValue(null);
        //Получаем поле спика с окнами
        FieldInfo windowsField = windowListType.GetField("windows", BindingFlags.NonPublic | BindingFlags.Instance);
        //Получаем сам список окон типа Hashtable
        Hashtable hashtable = windowsField.GetValue(windowListInstance) as Hashtable;
        //Осталось перебрать его и найти верхнее
        int min = -1;
        int window_id = -1;
        foreach(DictionaryEntry entry in hashtable)
        {
            int key = (int)entry.Key;
            if (id_list.Contains(key)) //сравнивать только если окно в нашем списке
            {
                //получаем значение поля глубина у окна
                int depth = (int)entry.Value.GetType().GetField("depth", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(entry.Value);
                if (min < 0 || depth < min)
                {
                    min = depth;
                    window_id = key;
                }
            }
        }
       
        return window_id;
   }
_www.agasper.net
CEO Solar Games Ltd.
Наши игры: _www.solar-games.net
Agasper
UNIт
 
Сообщения: 69
Зарегистрирован: 13 фев 2011, 20:20
Откуда: Ростов-на-Дону
  • Сайт

Re: Функция получения текущего активного окна

Сообщение Neodrop 15 авг 2012, 17:06

По идее, этот код не будет работать в рантайме, потому что вы используете Отражения не публичных полей, а это запрещено. Как минимум для мобилок и Web.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Функция получения текущего активного окна

Сообщение Agasper 15 авг 2012, 17:17

В собранном проекте на PC все отлично работает, для остальных сборок не проверял.
_www.agasper.net
CEO Solar Games Ltd.
Наши игры: _www.solar-games.net
Agasper
UNIт
 
Сообщения: 69
Зарегистрирован: 13 фев 2011, 20:20
Откуда: Ростов-на-Дону
  • Сайт

Re: Функция получения текущего активного окна

Сообщение pod4444 15 авг 2012, 17:51

рефлекшен должен быть самый последний инструмент из всех, просто потому что он рушит всю инкапсуляцию. зачем вообще придумали приватные члены? делали уж все пабликом.
проще сделать какой-нибудь класс в котором хранятся все нужные окна и активное из нужных.
Аватара пользователя
pod4444
Старожил
 
Сообщения: 721
Зарегистрирован: 20 янв 2012, 22:02
Откуда: Воронеж
Skype: pod4444
  • Сайт

Re: Функция получения текущего активного окна

Сообщение Agasper 15 авг 2012, 17:54

Придумайте другой способ получить текущее активное окно, и я перестану использовать рефлекшн.
_www.agasper.net
CEO Solar Games Ltd.
Наши игры: _www.solar-games.net
Agasper
UNIт
 
Сообщения: 69
Зарегистрирован: 13 фев 2011, 20:20
Откуда: Ростов-на-Дону
  • Сайт

Re: Функция получения текущего активного окна

Сообщение Neodrop 15 авг 2012, 20:11

Я же сказал, что не будет работать именно на мобилках и в WEB
А для standalone вполне может и прокатит.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Функция получения текущего активного окна

Сообщение pod4444 16 авг 2012, 09:15

challenge is accepted

Синтаксис:
Используется csharp
    public class WindowsTemp : MonoBehaviour
    {
        public Rect windowRect = new Rect(20, 20, 120, 50);
        public Rect windowRect2 = new Rect(20, 100, 120, 50);

        void OnGUI()
        {
            windowRect = UnityEngine.GUI.Window(0, windowRect, DoMyWindow, "My Window");
            windowRect2 = UnityEngine.GUI.Window(1, windowRect2, DoMyWindow, "My Window");
        }

        void DoMyWindow(int windowID)
        {
            WindowsController.ControllFocus(windowID);
            if (UnityEngine.GUI.Button(new Rect(10, 20, 100, 20), "Hello World"))
                print("Got a click");
        }
    }
 


Синтаксис:
Используется csharp
    public static class WindowsController
    {
        public static int idWindowFocus;

        public static void ControllFocus(int windowID)
        {
            if ((Event.current.button == 0) && (Event.current.type == EventType.MouseUp))
            {
                Debug.Log(windowID);
                idWindowFocus = windowID;
            }
        }
    }
Аватара пользователя
pod4444
Старожил
 
Сообщения: 721
Зарегистрирован: 20 янв 2012, 22:02
Откуда: Воронеж
Skype: pod4444
  • Сайт

Re: Функция получения текущего активного окна

Сообщение Agasper 16 авг 2012, 10:28

А теперь угадайте на каком слое окно сразу после появления. Пока пользователь не нажал по нему.
_www.agasper.net
CEO Solar Games Ltd.
Наши игры: _www.solar-games.net
Agasper
UNIт
 
Сообщения: 69
Зарегистрирован: 13 фев 2011, 20:20
Откуда: Ростов-на-Дону
  • Сайт

Re: Функция получения текущего активного окна

Сообщение pod4444 16 авг 2012, 18:03

а зачем угадывать?
Аватара пользователя
pod4444
Старожил
 
Сообщения: 721
Зарегистрирован: 20 янв 2012, 22:02
Откуда: Воронеж
Skype: pod4444
  • Сайт


Вернуться в Исходники (Копилка)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2