При разработке приложений, которые затем будут использоваться на большом числе различных ПК очень полезно иметь возможность не только получения информации о текущем видеорежиме, но и возможность получить все доступные видеорежимы для данного ПК. Еще одна область, где используется переключение видеорежимов при написании игр без использования DirectX.
https://mekka.spb.ru бумага для печати 500 листов купить купить бумагу а3 500 листов.Получение списка видеорежимов
Получить видеорежимы можно серией вызовов EnumDisplaySettings. Функция EnumDisplaySettings возвращает информацию о видеорежиме, указанном в параметре IModeNode. Функции необходимо передать структуру типа TDevMode, в которую будет записана информация о видеорежиме. Данная структура имеет поля, характеризующие видеорежим: разрешение (dmPelsWidth, dmPelsHeight), количество битов цветности (dmBitsPerPel), частота обновления экрана (dmDisplayFrequency) и др.
function EnumDisplaySettings(lpszDeviceName: PWideChar; iModeNum: DWORD; var lpDevMode: TdeviceMode): BOOL; stdcall;
Параметры
Поле Описание
Если lpDevMode равно nil, из реестра берется информация о видеорежиме установленном по умолчанию. Передавая в lpDevMode nil и в dwFlags 0 можно получить настройки текущего видеорежима.
Ниже приведена процедура, получающая и отображающая в ListBox все возможные видеорежимы.
procedure TForm1.FormCreate(Sender: TObject); var i: Integer; DevMode : TDeviceMode; begin i:=0; while EnumDisplaySettings(nil,i,DevMode) do begin with Devmode do ListBox1.Items.Add(Format('%dx%d %d Colors', [dmPelsWidth,dmPelsHeight,Int64(1) shl dmBitsperPel])); Inc(i); end; end;
Получение параметров текущего видеорежима
Помимо вызова EnumDisplaySettings инфомацию о текущем видеорежиме можно получать и другими способами.Получить количество битов цвета текущего видеорежима можно и другим способом:
GetDeviceCaps(Form1.Canvas.Handle, BITSPIXEL) * GetDeviceCaps(Form1.Canvas.Handle, PLANES)
Получаемые значения при этом:
Непосредственно количество цветов можно так же легко подсчитать:
NumberOfColors := (1 shl (GetDeviceCaps(Form1.Canvas.Handle, BITSPIXEL) * GetDeviceCaps(Form1.Canvas.Handle, PLANES));
Текущее разрешение экрана можно узнать с помощью вызова GetSystemMetrics() в качестве параметров передается:
Ниже приведен пример получения высоты и ширины рабочей области экрана (для всей экранной области надо просто поменять параметры вызова GetSystemMetrics):
var x, y: Integer; Mode: string; begin x:=GetSystemMetrics(Sm_Cxscreen); y:=GetSystemMetrics(Sm_CYscreen); Mode:=Format('%d x %d',[x,y]); if y=480 then Mode:=Mode+('Standard VGA') else Mode:=Mode+('Super VGA'); StaticText1.Caption:=Mode; end;
Установка видеорежима
Как мы убедились получения списка и параметров видеорежимов не проблема. Теперь разберемся с программной сменой видеорежимов. Функция ChangeDisplaySettings предназначена для изменения текущего видеорежима экрана и при необходимости обновления этой информации в реестре Windows.
function ChangeDisplaySettings(var lpDevMode: TDeviceMode; dwFlags: DWORD): Longint; stdcall;
Параметры:
При немедленном изменении видеорежима всем запущенным приложениям рассылается сообщение WM_DISPLAYCHANGE.
А вот и пример смены видеорежима:
{...} type TForm1 = class(TForm) Button1: TButton; ListView1: TListView; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ListView1DblClick(Sender: TObject); private { Private declarations } {Массив для хранения информации о видеорежимах} DevMode : array[0..20] of TDeviceMode; public { Public declarations } end; {...} procedure TForm1.FormCreate(Sender: TObject); begin {Настройка ListView} ListView1.ViewStyle := vsReport; ListView1.RowSelect := TRUE; ListView1.Columns.Add; ListView1.Columns.Add; ListView1.Columns[0].Caption := 'Width x Height'; ListView1.Columns[0].Width := 100; ListView1.Columns[1].Caption := 'Colors'; ListView1.Columns[1].Width := 100; end; {Процедура получения списка режимов} procedure TForm1.Button1Click(Sender: TObject); var tmpStr1, tmpStr2 : string; tmpDC : HDC; x, Selection, cxScreen, cyScreen, Resolution : Integer; begin { Запоминаем текущие настройки} tmpDC := getDC(Handle); try cxScreen := GetSystemMetrics(SM_CXSCREEN); cyScreen := GetSystemMetrics(SM_CYSCREEN); Resolution := GetDeviceCaps(tmpDC, BITSPIXEL); finally ReleaseDC(Handle, tmpDC); end; ListView1.Items.Clear; x := 0; { Получаем список видеорежимов} while EnumDisplaySettings(nil,x,DevMode[x]) do begin { Разрешение экрана } tmpStr1 := IntToStr(DevMode[x].dmPelsWidth) + 'x' + IntToStr(DevMode[x].dmPelsHeight); { Цвета } case DevMode[x].dmBitsPerPel of 4 : tmpStr2 := '16 Colors'; 8 : tmpStr2 := '256 Colors'; 16 : tmpStr2 := 'High Color (16 Bit)'; 32 : tmpStr2 := 'True Color (32 Bit)'; end; { А теперь полученную информацию надо отобразить } with ListView1.Items.Add do begin Caption := tmpStr1; SubItems.Add(tmpStr2); end; { В ListView надо встать не строку с описанием текущего режима, для этого сохраним индекс элемента с описанием этого режима } if ( cxScreen = DevMode[x].dmPelsWidth ) and ( cyScreen = DevMode[x].dmPelsHeight ) and ( Resolution = DevMode[x].dmBitsPerPel ) then Selection := x; inc(x); if x = 20 then Break; end; { В ListView перемещаемся на строчку с описанием текущего режима } ActiveControl := ListView1; ListView1.Selected := ListView1.Items.Item[Selection]; end; {Установка выбранного пользователем видеорежима} procedure TForm1.ListView1DblClick(Sender: TObject); var tmpDevMode : TDevMode; begin { Получаем сохраненную ранее информацию по выбранному режиму} tmpDevMode := DevMode[ListView1.Items.IndexOf(ListView1.Selected)]; { Скажем Windows, какие параметры надо сменить } tmpDevMode.dmFields := DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT or DM_DISPLAYFLAGS or DM_DISPLAYFREQUENCY; { Очень неплохо будет протестировать видеорежим и записать изменения в реестр} if ChangeDisplaySettings(tmpDevMode, CDS_TEST) = DISP_CHANGE_SUCCESSFUL then ChangeDisplaySettings(tmpDevMode, CDS_UPDATEREGISTRY); end;
Замечание 1:
Не рекомендуется устанавливать видеорежимы, отличные от полученных вызовами EnumDisplaySettings. Возможна ситуация, когда пользователь вместо рабочего стола увидит лишь черный экран.
Замечание 2:
Многие драйвера, особенно старые не поддерживают изменения видеорежима без перезагрузки компьютера.
Обнаружение изменений видеорежима
При изменениях видеорежима генерируется сообщение WM_DISPLAYCHANGE. Необходимо создать обработчик данного сообщения в вашем приложении.
... type TForm1 = class(TForm) ListBox1: TListBox; ... private procedure WMDisplayChange(var message:TMessage); message WM_DISPLAYCHANGE; ... procedure TForm1.WMDisplayChange(var message: TMessage); begin ShowMessage('Changes in display detected!'); inherited; end;