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

Тема в разделе "Delphi", создана пользователем WinHack, 23 ноя 2016.

  1. WinHack
    Как же программно изменить расширение экрана? Здесь очень подойдет функция API Windows EnumDisplaySettings для получения доступных режимов, а также функция ChangeDisplaySettings для изменения расширения экрана.

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

    Чтение режимов экрана


    Функция 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;


    Установка режимов экрана



    Как только мы получим все возможные режимы расширения экрана, при помощи функции 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 информирует все окна, что режим экрана был изменен.


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



    Для обнаружения изменения режима экрана можно создать ловушку сообщения 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;