1. Computing

Get and Set Screen Resolution (Display Device Modes)

Display Device Modes; Handle Change

By

Changing Display Modes from Delphi code

When developing Windows software that is to be distributed to a wide variety of personal computers, it's often useful to have some kind of routine that will allow us to get not only the current display settings but to get and set all possible device modes of the display device.

In this article we'll see how to actually use Windows API function EnumDisplaySettings to get a list of valid mode settings, and the ChangeDisplaySettings function to change the display setting.

Retrieve Possible Display Modes

You can obtain information for all of the display device's graphics modes by making a series of calls to EnumDisplaySettings function. EnumDisplaySettings finds the number of possible modes by enumerating them until the function result is no longer True.

This function requires a TDevMode type variable in which to place the settings. The TDevMode type has a number of variables that refer to display devices (among others). These include the display device resolution in pixels (dmPelsWidth, dmPelsHeight), the color depth (in bits per pixel) supported at the resolution (dmBitsPerPel), refresh rate (dmDisplayFrequency) and others.

 procedure TForm1.FormCreate(Sender: TObject) ;
 var
   cnt : Integer;
   DevMode : TDevMode;
 begin
   cnt := 0;
   while EnumDisplaySettings(nil,cnt,DevMode) do
   begin
     with Devmode do
      ListBox1.Items.Add(Format('%dx%d %d Colors', [dmPelsWidth,dmPelsHeight,Int64(1) shl dmBitsperPel])) ;
     Inc(cnt) ;
   end;
 end; 

Set Screen Resolution and Colors

Once we have all the possible display modes, setting the desired-appropriate display mode is very simple. The ChangeDisplaySettings function is then used to change the current display mode and update the Windows Registry as necessary.
 procedure TForm1.Button1Click(Sender: TObject) ;
 var
    DevMode : TDeviceMode;
    liRetValue : Longint;
 begin
   if EnumDisplaySettings (nil, Listbox1.ItemIndex, Devmode) then liRetValue := ChangeDisplaySettings(DevMode, CDS_UPDATEREGISTRY) ;
 
    SendMessage(HWND_BROADCAST, WM_DISPLAYCHANGE, SPI_SETNONCLIENTMETRICS,0) ;
 end; 
The ChangeDisplaySettings function returns a long integer value. This value can be compared to a list of constants to determine whether the function was successful or not.

Notes:

  1. It is not recommended that we set the display modes individually, rather than choosing from the Enumerated list. This will prevent us from bringing a blank screen in front of the user. For example: setting the dmBitsPerPel variable to a color depth unsupported by the resolution could blank the screen.
  2. Many drivers (especially older ones) will not perform the change without rebooting the computer, even though they are capable of doing so.
  3. SendMessage is used to inform all windows that the screen resolution was changed.

Detecting Changes in Display

To detect changes in the display, we'll create a message handler to trap the WM_DISPLAYCHANGE message. If your application makes use of graphics, you may want to restart the application, as there may be many changes to the system that may be difficult to overcome as the screen resolution, color depth and default fonts may change.
 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; 

©2014 About.com. All rights reserved.