Мне кажется, что эта глава интересна и волнительна. OpenGL выглядит более круто, если она выполняется в полноэкранном режиме. Для отображения во весь экран требуется больше возни с Windows API. Займемся этим.
Первое, что сделаем — используем переменную fullscreen
. Она задает режим, в котором программа будет выполняться. Если true
, то в полноэкранном режиме, если нет, то в окне.
Этот "полноэкранный" режим — простое окно без заголовка и границ, размером с рабочий стол. Смена разрешения рабочего стола может дать осложнение.
Предположим, что пользователь использует рабочий стол с разрешением 1024x768, а нам нужен экран размера 640x480. Окно откроется без проблем, однако остаток рабочего стола будет виден. Так что нам придется подстроить разрешение рабочего стола под размер окна.
Windows имеет список всех разрешений, которые могут поддерживаться видеокартой. Не забывайте: не все видеокарты поддерживают одинаковые разрешения. Что-нибудь типа 720x540 будет работать только на некоторых картах. Так что самым простым способом убедиться, что нужное разрешение достижимо — спросить об этом Windows. Если подходящий режим найден, то в него можно переключиться.
Список можно прочитать с помощью EnumDisplaySettings
. Первым аргументом мы интересоваться не будем. Второй — номер записи в списке. Мы хотим просмотреть каждое доступное разрешение, так что их следует перебрать один за другим. Третий аргумент — указатель на структуру, содержащую информацию о списке.
Мы запрашивает определенные ширину/ высоту/ глубину. Если есть режим с соответствующими атрибутами, строим цикл repeat/ until. Если подходящий режим не найден после перебора 255 записей списка, бросаем работу и выдаем сообщение об ошибке.
Если выбранный режим найден, то в него надо переключиться с помощью ChangeDisplaySettings
. Также спрячем курсор мыши, поскольку в OpenGL программах он нам не понадобится.
i := -1; repeat inc(i); EnumDisplaySettings(nil,i,@dmScreenSettings); if i > 255 then Throw('No suitable window mode found!'); until (dmScreenSettings.dmPelsWidth = width) and (dmScreenSettings.dmPelsHeight = height) and (dmScreenSettings.dmBitsPerPel = bits); ChangeDisplaySettings(@dmScreenSettings,0);
Другой способ состоит просто в указании Windows того, чего нам нужно.
dmScreenSettings.dmSize := sizeof(dmScreenSettings); // Size of The Devmode Structure dmScreenSettings.dmPelsWidth := width; // Selected Screen Width dmScreenSettings.dmPelsHeight := height; // Selected Screen Height dmScreenSettings.dmBitsPerPel := bits; // Selected Bits Per Pixel dmScreenSettings.dmFields := DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT; if ChangeDisplaySettings(@dmScreenSettings,CDS_FULLSCREEN) <> DISP_CHANGE_SUCCESSFUL then begin ThrowError('Screen resolution is not supported by your gfx card!'); WindowCreate := 0; Exit; end;
После завершения программы следует восстановить рабочий стол в его прежнее разрешение. Не забывайте об этом, иначе пользователь получит по завершении программы ваше разрешение экрана!
К счастью для нас, эта проблема имеет простое решение. Если вызвать ChangeDisplaySettings
с аргументом "0", то мы переключимся в обычный режим, установки которого хранятся в реестре. Не совсем по-джентельменски, зато работает. Ну, и снова покажем курсор мыши.
procedure KillOGLWindow; begin wglMakeCurrent( dcWindow, 0 ); // Kill Device Context wglDeleteContext( rcWindow ); // Kill Render Context ReleaseDC( hWindow, dcWindow ); // Release Window DestroyWindow( hWindow ); // Kill Window itself end;
Остался только вопрос о том, как установить полноэкранный режим в нашей программе. Можно либо задать его вручную путем fullscreen := true;
либо дать пользователю выбор. Это можно осуществить посредством обычного окна сообщения "Yes/ No".
if MessageBox(0,'Fullscreen Mode?', 'Question!',MB_YESNO or MB_ICONQUESTION) = IDNO then fullscreen := false else fullscreen := true;
Вот и все. Много Windows из ничего. Полный исходный код здесь.
FPC | 3.2.2 | release |
Lazarus | 3.2 | release |
MSE | 5.10.0 | release |
fpGUI | 1.4.1 | release |