Модераторы: Rickert
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [OpenGL] Из FullScreen в Window Mode, Как поменять статус окна из FullScreen в 
:(
    Опции темы
MuForum
  Дата 13.11.2007, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



Доброе время суток!
Я начинаю программист, недавно перешел с 'C++' на 'C#', так что строго прошу не судить, а по возможности указать на ошибки.


Цитата

# Name: 'Mu Online'
# Operation System: 'Windows'
# Genre: 'Fantasy MMORPG' (Massively Multiplayer Online Role Playing Game)
# Developer: 'Webzen, Inc.'
# Publisher: 'Webzen, Inc.'
# Official Website: WebZen
# About: Некоторое время назад было трудно даже представить себе, что возможно создать настолько хорошо отрисованный трёхмерный мир, но гениальная реализация 'OpenGL Full 3D Engine', разработанная 'Webzen', позволяет сделать это реальностью.



# Задача:
  1.  Необходимо написать программу, которая будет перехватывать нажатия кнопок клавиатуры 'F11', 'F12' (Низкоуровневой) — Это осуществил.
  2.  При нажатие на кнопку 'F11', Необходимо менять статус чужого окна из 'FullScreen' в 'WindowMode' и наоборот — Это осуществил.
  3.  При нажатие на кнопку 'F12', необходимо скрывать(Hide)/показывть(Show) окно. — Тут проблема.
# Детально о проблеме:
  •  Если запустить изначально игру в режиме 'окно' (В дальнейшем 'WindowMode'), затем скрыть(В дальнейшем 'Hide') игру, то можно свободно работать с остальными приложениями. (То есть тут проблем не возникает), но если изначально запустить игру в режиме 'полный экран' (В дальнейшем 'FullScreen'), затем при помощи кнопки 'F11' поменять статус окна на 'WindowMode', затем скрыть(Hide), и попытаться нажать вне окна, то окно игры тутже разворачивается. (3 раза повторив — игра закрывается).

    P.S. -> Окно, над которым необходимо делать изменения(Не наше), то есть в коде той программы ничего не возможно изменять.
Код

        private static int hWnd, hWnd2;
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYUP = 0x0101;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
......
......
......
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if ((nCode >= 0) && (wParam == (IntPtr)WM_KEYUP))
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode == 0x7A) // if have pressed button "F11"
                {
                    if (FindWindow("MU", null) != 0)
                    {
                        hWnd = FindWindow(null, "Game");
                        SetWindowText(hWnd, "new game");
                        hWnd2 = FindWindow(null, "new game");
                    }
                    if (IsWindowVisible(hWnd2) != 0)
                    {
                        if (fullmode1 == false)
                        {
                            DEVMODE dm = new DEVMODE();
                            dm.dmBitsPerPel = Convert.ToSByte(CD);
                            dm.dmPelsWidth = CorX;
                            dm.dmPelsHeight = CorY;
                            dm.dmDisplayFrequency = RR;
                            dm.dmFields = (int)DM.DM_BITSPERPEL | (int)DM.DM_PELSWIDTH | (int)DM.DM_PELSHEIGHT | (int)DM.DM_DISPLAYFREQUENCY;
                            if (CDS.ChangeDisplaySettings(ref dm, CDS.CDS_TEST | CDS.CDS_FULLSCREEN) == CDS.DISP_CHANGE_SUCCESSFUL) CDS.ChangeDisplaySettings(ref dm, CDS.CDS_UPDATEREGISTRY);
                            MoveWindow(hWnd2, 0, 0, CorX, CorY, true);
                            SetForegroundWindow(hWnd2);
                            fullmode1 = true;
                            fullmode2 = false;
                        }
                        else
                        {
                            SetWindowLong(hWnd2, GWL.GWL_STYLE, WS.WS_OVERLAPPED | WS.WS_VISIBLE | WS.WS_CAPTION | WS.WS_THICKFRAME | WS.WS_SYSMENU);
                            MoveWindow(hWnd2, 0, 0, CorX + 5, CorY + 10, true);
                            SetWindowPos(hWnd2, HWND.HWND_TOPMOST, 0, 0, CorX + 5, CorY + 10, SWP.SWP_NOSIZE | SWP.SWP_SHOWWINDOW);
                            SetForegroundWindow(hWnd2);
                            fullmode1=false;
                            fullmode2=true;
                        }
                    }
                    return (IntPtr)1;
                }
                else if (vkCode == 0x7B) // if have pressed button "F12"
                {
                    if (fullmode2 == true)
                    {
                        if (IsWindowVisible(hWnd2) != 0)
                        {
                            SetWindowPos(hWnd2, HWND.HWND_BOTTOM, 0, 0, CorX + 5, CorY + 10, SWP.SWP_NOSIZE | SWP.SWP_NOMOVE | SWP.SWP_NOZORDER | SWP.SWP_NOACTIVATE | SWP.SWP_HIDEWINDOW | SWP.SWP_NOCOPYBITS | SWP.SWP_NOSENDCHANGING);
                        }
                        else
                        {
                            SetWindowPos(hWnd2, HWND.HWND_TOPMOST, 0, 0, CorX + 5, CorY + 10, SWP.SWP_NOSIZE | SWP.SWP_NOMOVE | SWP.SWP_SHOWWINDOW);
                            SetForegroundWindow(hWnd2);
                        }
                    }
                    return (IntPtr)1;
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
......
......
......
        // ------------------------------------------------------------

        [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
        private static extern int SetWindowLong32(IntPtr hWnd, GWL nIndex, [MarshalAs(UnmanagedType.FunctionPtr)] WndProcDelegate windowCallback);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
        private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, GWL nIndex, [MarshalAs(UnmanagedType.FunctionPtr)] WndProcDelegate windowCallback);
        
        public static IntPtr SetWindowLongPtr(IntPtr hWnd, GWL nIndex, WndProcDelegate windowCallback)
        {
            if (IntPtr.Size == 8)
                return SetWindowLongPtr64(hWnd, nIndex, windowCallback);
            else
                return new IntPtr(SetWindowLong32(hWnd, nIndex, windowCallback));
        }

        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        private static extern int GetWindowLong32(IntPtr hWnd, GWL nIndex);

        [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
        private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, GWL nIndex);

        public static IntPtr GetWindowLongPtr(IntPtr hWnd, GWL nIndex)
        {
            if (IntPtr.Size == 8)
                return GetWindowLongPtr64(hWnd, nIndex);
            else
                return new IntPtr(GetWindowLong32(hWnd, nIndex));
        }
        
        // ------------------------------------------------------------

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string strclassName, string strWindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        public static extern void SetWindowText(IntPtr h, String s);

        [DllImport("user32.dll")]
        private static extern int IsWindowVisible(IntPtr hwnd);

        [DllImport("user32.dll")]
        private static extern int SetForegroundWindow(IntPtr hwnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SetWindowLong(IntPtr hWnd, GWL uFlags1, WS uFlags2);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern int SetWindowPos(IntPtr hWnd, HWND Flags, int X, int Y, int cx, int cy, SWP uFlags);

        // ---------- Start: Hook function. ----------

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        // ---------- End: Hook function. ----------

        [StructLayout(LayoutKind.Sequential)]
        public struct DEVMODE
        {
            public const int CCHDEVICENAME = 32;
            public const int CCHFORMNAME = 32;
            public short dmBitsPerPel;
            public short dmCollate;
            public short dmColor;
            public short dmCopies;
            public short dmDefaultSource;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
            public string dmDeviceName;
            public int dmDisplayFlags;
            public int dmDisplayFrequency;
            public int dmDitherType;
            public short dmDriverExtra;
            public short dmDriverVersion;
            public short dmDuplex;
            public int dmFields;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
            public string dmFormName;
            public int dmICMIntent;
            public int dmICMMethod;
            public short dmLogPixels;
            public int dmMediaType;
            public short dmOrientation;
            public int dmPanningHeight;
            public int dmPanningWidth;
            public short dmPaperLength;
            public short dmPaperSize;
            public short dmPaperWidth;
            public int dmPelsHeight;
            public int dmPelsWidth;
            public int dmPositionX;
            public int dmPositionY;
            public short dmPrintQuality;
            public int dmReserved1;
            public int dmReserved2;
            public short dmScale;
            public short dmSize;
            public short dmSpecVersion;
            public short dmTTOption;
            public short dmYResolution;
        }

        public enum GWL : int
        {
            GWL_WNDPROC = (-4),
            GWL_HINSTANCE = (-6),
            GWL_HWNDPARENT = (-8),
            GWL_STYLE = (-16),
            GWL_EXSTYLE = (-20),
            GWL_USERDATA = (-21),
            GWL_ID = (-12)
        }

        public enum SWP : uint
        {
            SWP_NOSIZE = 0x0001, // Сообщает, что нужно игнорировать параметры задания размеров окну.
            SWP_NOMOVE = 0x0002, // Сообщает, что нужно игнорировать параметры задания позиции окну.
            SWP_NOZORDER = 0x0004, // Сохраняет текущее положение в Z-последовательности (игнорирует сообщение hWndInsertAfter parameter).
            SWP_NOREDRAW = 0x0008, // Не перерисовывает окно.
            SWP_NOACTIVATE = 0x0010, // Не активизирует окно.
            SWP_FRAMECHANGED = 0x0020,
            SWP_SHOWWINDOW = 0x0040, // Отображает окно.
            SWP_HIDEWINDOW = 0x0080, // Скрывает окно.
            SWP_NOCOPYBITS = 0x0100, // Если этот спецификатор не будет установлен, тогда содержимое клиентской области окна будет скопировано и вставлено во вновь отобразившееся окно после его перемещения.
            SWP_NOOWNERZORDER = 0x0200, //Сообщает, что не следует изменять позицию окна владельца в Z-последовательности.
            SWP_NOSENDCHANGING = 0x0400, // Мешает окну получить сообщение WM_WINDOWPOSCHANGING.
            SWP_DRAWFRAME = SWP_FRAMECHANGED, // Прорисовка фрейма вокруг окна.
            SWP_NOREPOSITION = SWP_NOOWNERZORDER, // Такой же как и SWP_NOOWNERZORDER.
            SWP_DEFERERASE = 0x2000,
            SWP_ASYNCWINDOWPOS = 0x4000
        }
        
        public enum HWND : int
        {
            HWND_TOP = 0,
            HWND_BOTTOM = 1,
            HWND_TOPMOST = (-1),
            HWND_NOTOPMOST = (-2)
        }

        //Window Styles used when creating a window
        public enum WS : uint
        {
            WS_OVERLAPPED = 0x00000000,
            WS_POPUP = 0x80000000,
            WS_CHILD = 0x40000000,
            WS_MINIMIZE = 0x20000000,
            WS_VISIBLE = 0x10000000,
            WS_DISABLED = 0x08000000,
            WS_CLIPSIBLINGS = 0x04000000,
            WS_CLIPCHILDREN = 0x02000000,
            WS_MAXIMIZE = 0x01000000,
            WS_CAPTION = 0x00C00000,    /* WS_BORDER | WS_DLGFRAME  */
            WS_BORDER = 0x00800000,
            WS_DLGFRAME = 0x00400000,
            WS_VSCROLL = 0x00200000,
            WS_HSCROLL = 0x00100000,
            WS_SYSMENU = 0x00080000,
            WS_THICKFRAME = 0x00040000,
            WS_GROUP = 0x00020000,
            WS_TABSTOP = 0x00010000,
            WS_MINIMIZEBOX = 0x00020000,
            WS_MAXIMIZEBOX = 0x00010000,
            WS_TILED = WS_OVERLAPPED,
            WS_ICONIC = WS_MINIMIZE,
            WS_SIZEBOX = WS_THICKFRAME,
            WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
            WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
            WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
            WS_CHILDWINDOW = WS_CHILD
        }

        class CDS
        {
            [DllImport("user32.dll")]
            public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);

            [DllImport("user32.dll")]
            public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);

            public const int ENUM_CURRENT_SETTINGS = -1;
            public const int CDS_UPDATEREGISTRY = 0x00000001;
            public const int CDS_TEST = 0x00000002;
            public const int CDS_FULLSCREEN = 0x00000004;
            public const int CDS_GLOBAL = 0x00000008;
            public const int CDS_SET_PRIMARY = 0x00000010;
            public const int CDS_RESET = 0x40000000;
            public const int CDS_SETRECT = 0x20000000;
            public const int CDS_NORESET = 0x10000000;

            public const int DISP_CHANGE_SUCCESSFUL = 0;
            public const int DISP_CHANGE_RESTART = 1;
            public const int DISP_CHANGE_FAILED = (-1);
            public const int DISP_CHANGE_BADMODE = (-2);
            public const int DISP_CHANGE_NOTUPDATED = (-3);
            public const int DISP_CHANGE_BADFLAGS = (-4);
            public const int DISP_CHANGE_BADPARAM = (-5);
        }

        public enum DDSCL : int
        {
            DDSCL_ALLOWMODEX = 64,
            DDSCL_ALLOWREBOOT = 2,
            DDSCL_CREATEDEVICEWINDOW = 512,
            DDSCL_EXCLUSIVE = 16,
            DDSCL_FULLSCREEN = 1,
            DDSCL_MULTITHREADED = 1024,
            DDSCL_NORMAL = 8,
            DDSCL_NOWINDOWCHANGES = 4,
            DDSCL_SETDEVICEWINDOW = 256,
            DDSCL_SETFOCUSWINDOW = 128
        }

        public enum DM
        {
            DM_BITSPERPEL = 0x00040000,
            DM_PELSWIDTH = 0x00080000,
            DM_PELSHEIGHT = 0x00100000,
            DM_DISPLAYFLAGS = 0x00200000,
            DM_DISPLAYFREQUENCY = 0x00400000
        }
......
......
......



# Так же пробовал вот таким образом сворачивать:
Код

...
                    if (fullmode2 == true)
                    {
                        const int WM_SYSCOMMAND = 0x0112;
                        const int SC_MINIMIZE = 0xF020;
                        const int SC_RESTORE = 0xF120;
                        if (IsWindowVisible(hWnd2) != 0)
                        {
                            SendMessage(hWnd2, WM_SYSCOMMAND, SC_MINIMIZE, 0);
                        }
                        else
                        {
                            SendMessage(hWnd2, WM_SYSCOMMAND, SC_RESTORE, 0);
                            SetForegroundWindow(hWnd2);
                        }
...

- Но при нажатие на 'F12', окно сворачивается и тутже само разворачивается =( 



# Дополнительные ссылка на Интернет ресурсы:Добавлено @ 22:20
# for all - Так пытался найти ответ на свою проблему в Интернете, на всевозможных Форумах - Результат ноль =(

- Так же пробовал вот такие варианты:

Код

#define WM_TOGGLEFULLSCREEN (WM_USER+1)    
......
void ToggleFullscreen (GL_Window* window) // Toggle Fullscreen/Windowed
{
  PostMessage (hWnd2, WM_TOGGLEFULLSCREEN, 0, 0); // Send A WM_TOGGLEFULLSCREEN Message
}


P.S. -> При вызове этой функции, окно игры на секунды две как бы подвисает и закрывается. Информацию вычитал с этой темы: cvs.codeyard.net


# Предположение: В полне мне кажется возможно, что игра запускается сразу уже с режимом 'full screen exclusive mode', и из-за этого уже не получается преобразовывать окно из FullScreen в WindowMode.
Код

4 > Можно в Open GL yстановить full screen exclusive mode?

    glutInit(&argc, argv);
    glutInitWindowSize(640, 480);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutGameModeString("640x480:24");
    glutEnterGameMode();

// Maxim Krassa


P.S. -> Пример был взят с этого Интернет ресурса: faqs.org.ru


# Также копался в 'DEVMODE' -  Думал может что-либо новенькое найду, но результат отрицательный. Нашел достаточно хороший гайд на эту тему: vsokovikov.narod.ru


# Работа с 'ChangeDisplaySettings' & 'EnumDisplaySettings': ничего толком не дала. Вот тоже достаточно хороший гайд на эту тему: delphimaster.ru

Это сообщение отредактировал(а) MuForum - 13.11.2007, 22:49


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
Rickert
Дата 14.11.2007, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



Задержку после нажатия ставил? А то получается, что заодно твоё нажатие, комп принемает десяток сообщений о нажатии.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
MuForum
Дата 14.11.2007, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: нет
Всего: 4



#2, Rickert - Честно говоря не понял, что ты хотел сказать.

P.S. -> Если можешь объясни более развёрнуто, что ты предлагаешь.
+ Если есть возможности реализации примера - будет ещё лучше.


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
Rickert
Дата 14.11.2007, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: 6
Всего: 52



Когда ты нажимаешь один раз клавишу, программа ловит порядка 20 сообщений о нажатии, следовательно функции по нажатию выполняются порядка 20 раз.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.0476 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.