Опубликован: 28.04.2009 | Доступ: свободный | Студентов: 1838 / 107 | Оценка: 4.36 / 4.40 | Длительность: 16:40:00
Специальности: Программист
Лекция 3:

Усложненные технологии визуализации

3.2.3. Диалоговое окно выбора видеорежима

Диалоговое окно выбора видеорежима из примера Ch03\Ex05 хотя и выполняет свою задачу, однако имеет при этом ряд существенных недостатков, затрудняющих его применение в реальных приложениях:

  1. При каждом запуске приложения приходится заново выбирать видеорежим, что довольно быстро начинает раздражать. Поэтому было бы логичным реализовать сохранение параметров выбранного видеорежима в конфигурационный файл.
  2. Все параметры видеорежимов "свалены в одну кучу ", отчего очень быстро начинает "рябить в глазах ". Коммерческие приложения обычно разбивают информацию о видеорежимах на три списка: в первом списке пользователь выбирает разрешение экрана, во втором – глубину цвета (формат пикселей), а в третьем – частоту обновления экрана.
  3. Для пользователя актуальны только те видеорежимы, соотношение сторон которых совпадает с соотношением сторон монитора. С другой стороны, для оценки в уме соотношения сторон видеорежима вроде 1792Ч1344 требуются незаурядные математические способности, поэтому было бы логичным предусмотреть типовые фильтры 4:3, 5:4 и 16:9, отбрасывающие видеорежимы с соотношением сторон отличным заданного8В принципе, можно было бы запрашивать у пользователя соотношение сторон монитора, после чего масштабировать изображение исходя из параметров разрешения экрана и соотношения сторон монитора (такой подход применяется, к примеру, в игре Half-Life 2) .
  4. Не помешало бы на всякий случай предоставить пользователю возможность выбора визуализации в оконном режиме, который иногда оказывается весьма полезным (например, при одновременной работе с несколькими приложениями).

Ну что ж, настало время разработать новую версию диалогового окна, свободную от этих недостатков (рисунок 3.9). Запустите Visual Studio 2005 и создайте приложение Windows Application. Мы начнем с создания класса, инкапсулирующего работу с файлами конфигурации приложения. Наш файл конфигурации будет содержать 7 полей:

Таблица 3.3. Поля файла конфигурации
Поле Тип данных Описание Значение по умолчанию
Width int размер заднего буфера вдоль оси X 0
Height int размер заднего буфера вдоль оси Y 0
Format SurfaceFormat формат пикселей заднего буфера SurfaceFormat.Unknown
RefreshRate int частота обновления экрана 0
FullScreen bool работает ли приложение в полноэкранном режиме ( false – нет, true – да) true
Init bool равен true, если информация о конфигурации приложения была загружена из файла false
ShowSettingForm bool надо ли отображать при запуске приложения диалоговое окно выбора видеорежима true

Так как наш файл конфигурации не будет представлять собой нечего экстравагантного, все операции по созданию класса вполне можно выполнить в дизайнере Visual Studio. Для этого в окне Solution Explorer раскройте узел Properties, и сделайте двойной щелчок левой кнопкой мыши на узле Setting.settings, после чего слева откроется дизайнер файла конфигурации приложения9Дизайнер файла конфигурации приложения доступен также посредством вкладки Settings окна Properties . Добавьте в настройки приложения новые поля согласно таблице 3.3 и рисунок 3.10.

 Новая версия диалогового окна выбора видеорежима

Рис. 3.9. Новая версия диалогового окна выбора видеорежима
 Настройка параметров конфигурации приложения

увеличить изображение
Рис. 3.10. Настройка параметров конфигурации приложения

Теперь приступим к созданию диалогового окна настройки параметров приложения. Добавьте приложение в новую форму, разместите на ней элементы управления аналогично рисунку 3.9 и задайте их свойства согласно таблице 3.4.

Таблица 3.4. Свойства формы диалогового окна и элементов управления
Класс Свойство Значение
Form (диалоговое окно) Name SettingsForm
Text Параметры
FormatBorderStyle FixedDialog
MinimizeBox false
MaximizeBox false
CheckBox Name inWindowCheckBox
Text Визуализировать в окне
GroupBox Text Видеорежим
Label Text Соотношение сторон
ComboBox (фильтр отображаемых видеорежимов по соотношению сторон) Name aspectRatioComboBox
DropDownStyle DropDownList
Label Text Разрешение
ComboBox (список разрешений экрана) Name resolutionComboBox
DropDownStyle DropDownList
Label Text Глубина цвета:
ComboBox (список форматов пикселей) Name colorDepthComboBox
DropDownStyle DropDownList
Label Text Частота обновления
ComboBox (список частот обновления экрана) Name refreshRateComboBox
DropDownStyle DropDownList
Button Name okButton
Text Ok
Button Text Cancel
DialogResult Cancel

Как видно, диалоговое окно содержит списки соотношений сторон экрана, разрешений, глубины цвета (формата пикселей) и частот обновления экрана. Информация в этих списках должна отображаться в дружелюбной форме, ведь неподготовленный пользователь вряд ли сможет без подсказки понять разницу между форматами Bgr32 и Bgr565. Кроме того, информация в списках должна быть отсортирована по некоторому критерию: например, видеорежимы должны перечислять в порядке увеличения разрешения экрана. Чтобы реализовать эти требования придется создать четыре структуры (по одной на каждый список), инкапсулирующие элементы списков. Для этого необходимо добавить в файл диалогового окна код из листинга 3.11.

// Инкапсулирует элемент списка соотношений сторон
public struct AspectItem 
{
// Коэффициент отношения сторон
public float aspect;
public AspectItem(float aspect) 
{
this.aspect = aspect; 
}
// Проверяет указанный элемент списка разрешений 
(ResolutionItem) на соответствие текущему 
// соотношению сторон. В случае равенства метод 
возвращает true, иначе - false public bool
Compare(float aspect) 
{
// Нулевое соотношение сторон является зарезервированным 
значением ( "любое соотношение
// сторон "), поэтому возвращаем true if 
(this.aspect == 0) return true;
// Сравниваем коэффициенты отношения сторон, 
закладывая небольшой  "запас " в
один процент. 
// Дело в том, что некоторые режимы имеют не совсем 
 "академически " правильное
соотношение 
// сторон. Например, соотношение сторон разрешения 
1360 x 768 равно 85/48=1.771, в 
// как 16/9=1.778.
if (Math.Abs(this.aspect - aspect) < this.aspect * 0.01f)
return true;
else
return false;
}
// Возвращает текущее соотношение сторон в удобочитаемом виде
public override string ToString() 
{
if (aspect == 0)
return "Любое";
if (Compare(4.0f / 3.0f))
return "4 : 3";
if (Compare(5.0f / 4.0f))
return "5 : 4";
if (Compare(16.0f / 9.0f)) return "16 : 9";
return aspect.ToString(); 
}
 }
// Инкапсулирует элемент списка разрешений экрана
public struct ResolutionItem : IComparable<ResolutionItem>
{
// Разрешение экрана
public int width;
public int height;
public ResolutionItem(int width, int height) 
{
this.width = width;
this.height = height;
 }
// Отношение количества пикселей вдоль осей X и Y для 
текущего разрешения экрана
public float Aspect 
{
get
 {
return (float)width / (float)height; 
} 
}
// Возвращает в удобочитаемом виде текст элемента 
списка public override string ToString() 
{
return width.ToString() + " x " + height.ToString(); 
}
// Реализация интерфейса IComparable<ResolutionItem>, 
используемого при сортировке элементов 
// списка
public int CompareTo(ResolutionItem other) 
{ 
// Сначала сравнивает ширина разрешений if (width > other.width) 
return 1;
if (width < other.width)
return -1;
// Если ширина одинаковая, сравнивается высота разрешений. 
В результате разрешения сначала 
// сортируются по ширине, а затем по высоте. if (height > 
other.height) return 1;
if (height < other.height) return -1;
return 0;
} 
}
// Инкапсулирует элемент списка форматов пикселей
public struct ColorDepthItem : IComparable<ColorDepthItem>
{
// Формат пикселей
public SurfaceFormat value;
public ColorDepthItem(SurfaceFormat value) 
{
this.value = value; 
}
// Возвращает строку с описанием формата пикселя
public override string ToString() 
{
string str;
switch (value) 
{
case SurfaceFormat.Bgr32:
str = "32 бита ({0})";
break;
case SurfaceFormat.Bgr565:
str = "16 бит ({0})";
break; case
SurfaceFormat.Rgba1010102:
str = "32 бит ({0})";
break; case
 SurfaceFormat.Bgr555:
str = "16 бит {0}";
break; default:
str = "{0}";
break; 
}
return string.Format(str, value);
 }
// Реализация интерфейса IComparable<ColorDepthItem>, 
используемого при сортировке элементов 
// списка
public int CompareTo(ColorDepthItem other) 
{
if (value > other.value)
 return -1;
if (value < other.value)
 return 1;
return 0; 
}
}
// Инкапсулирует элемент списка частот обновлений экрана public
 struct RefreshRateItem : IComparable<RefreshRateItem> 
{
// Частота обновления экрана
public int value;
public RefreshRateItem(int value) 
{
this.value = value; 
}
// Возвращает строку с частотой обновления экрана
 public override string ToString() 
{
return value.ToString() + " Гц"; 
}
// Реализация интерфейса IComparable< RefreshRateItem>, 
используемого при сортировке 
// элементов списка
public int CompareTo(RefreshRateItem other) 
{
if (value > other.value)
return 1;
if (value < other.value)
 return -1;
return 0; 
}
}
Листинг 3.11.
Андрей Леонов
Андрей Леонов

Reference = add reference, в висуал студия 2010 не могу найти в вкладке Solution Explorer, Microsoft.Xna.Framework. Его нету.