Изменение расширения экрана

WinHack

Администратор
23 Фев 2015
2,907
1,916
bsfo.ru
Как же программно изменить расширение экрана? Здесь очень подойдет функция API Windows EnumDisplaySettings для получения доступных режимов, а также функция ChangeDisplaySettings для изменения расширения экрана.

get-resolution-screen.png

Для того, чтобы узнать, какие же режимы нам доступны, нужно поместить на форму компонент TListBox, а также TButton, для изменения расширения экрана.

Чтение режимов экрана
[hr][/hr]

Функция EnumDisplaySettings определяет количество возможных режимов, перечисляя их, пока результат будет True.

Эта функция требует переменной типа TDevMode, в которую помещаются установки. TDevMode имеет ряд переменных, которые относятся к устройствам отображения. Она включает в себя разрешение экрана в пикселях (dmPelsWidth и dmPelsHeight), глубину цвета в битах на пиксел (dmBitsPerPel), частоту обновления экрана (dmDisplayFrequency) и другие.


Код чтения режимов экрана и заполнение списка этими значениями.

Код:
[/B]
[B]procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  DevMode: TDevMode;
begin
  i:= 0;
  while EnumDisplaySettings(nil, i, DevMode) do
  begin
    with DevMode do
      lbResolutions.Items.Add(Format('%d x %d   %d    цветов',
            [dmPelsWidth, dmPelsHeight,
            int64(1) shl dmBitsPerPel]));
      inc(i);
  end;
end;

Установка режимов экрана
[hr][/hr]


Как только мы получим все возможные режимы расширения экрана, при помощи функции ChangeDisplaySettings мы можем изменить режим экрана. После этого необходимо обновить реестр Windows.

Код:
procedure TForm1.btnChangeResolutionClick([/B]
[B]                 Sender: TObject);
var
  DevMode: TDeviceMode;
  iRet: LongInt;
begin
  if EnumDisplaySettings(
           nil, lbResolutions.ItemIndex, DevMode) then
    iRet:= ChangeDisplaySettings(
           DevMode, CDS_UPDATEREGISTRY);
  SendMessage(HWND_BROADCAST, WM_DISPLAYCHANGE,
           SPI_SETNONCLIENTMETRICS, 0);
end;

Функция ChangeDisplaySettings возвращает значение LongInt. Это значение можно сравнить со списком констант и определить, завершилась ли функция успешно.

Примечание: Многие драйвера не будут производить изменение расширения экрана без перезагрузки. Функция SendMessage информирует все окна, что режим экрана был изменен.


Контроль за изменением расширения экрана
[hr][/hr]


Для обнаружения изменения режима экрана можно создать ловушку сообщения WM_DISPLAYCHANGE.

get-resolution-screen.png

Для этого нужно добавить процедуру WMDisplayChange в раздел private формы и написать обработчик:

Код:
[/B]
[B]private
  { Private declarations }
  procedure WMDisplayChange(
        var Msg: TMessage); message WM_DISPLAYCHANGE;
   
{ ... }

procedure TForm1.WMDisplayChange(var Msg: TMessage);
begin
  ShowMessage('Режим экрана был изменен!');
  inherited;
end;