Getting Screen Modes

From Scriptionary.com

Jump to: navigation, search
Author Eddy Luten
Author Link Scriptionary.com
Contributors n/a
Notes
n/a


The Windows API includes a mechanism to retrieve a list of all the available display modes the hardware is capable of. There are some tips and tricks that you might have to apply to get the correct results, but the function itself is rather simple. Below you will find the core mechanism on how to achieve this.

int i = 0;
DEVMODE dMode;
 
while( EnumDisplaySettings(NULL, i, &dMode) == TRUE )
{
	// Handle the data here in the dMode variable
	i++;
};

Before we go into more depth on how you might retrieve the results, the functionality used above must be explained.


Contents


The DEVMODE Datatype

The DEVMODE datatype is a struct containing a large amount of information about the device you're querying. This structure may include information for both computer displays and printers alike. Below is the structure's prototype directly taken from the Windows API, beware that it is quite long.

typedef struct _devicemodeA {
    BYTE   dmDeviceName[CCHDEVICENAME];
    WORD dmSpecVersion;
    WORD dmDriverVersion;
    WORD dmSize;
    WORD dmDriverExtra;
    DWORD dmFields;
    union {
      /* printer only fields */
      struct {
        short dmOrientation;
        short dmPaperSize;
        short dmPaperLength;
        short dmPaperWidth;
        short dmScale;
        short dmCopies;
        short dmDefaultSource;
        short dmPrintQuality;
      };
      /* display only fields */
      struct {
        POINTL dmPosition;
        DWORD  dmDisplayOrientation;
        DWORD  dmDisplayFixedOutput;
      };
    };
    short dmColor;
    short dmDuplex;
    short dmYResolution;
    short dmTTOption;
    short dmCollate;
    BYTE   dmFormName[CCHFORMNAME];
    WORD   dmLogPixels;
    DWORD  dmBitsPerPel;
    DWORD  dmPelsWidth;
    DWORD  dmPelsHeight;
    union {
        DWORD  dmDisplayFlags;
        DWORD  dmNup;
    };
    DWORD  dmDisplayFrequency;
#if(WINVER >= 0x0400)
    DWORD  dmICMMethod;
    DWORD  dmICMIntent;
    DWORD  dmMediaType;
    DWORD  dmDitherType;
    DWORD  dmReserved1;
    DWORD  dmReserved2;
#if (WINVER >= 0x0500) || (_WIN32_WINNT >= _WIN32_WINNT_NT4)
    DWORD  dmPanningWidth;
    DWORD  dmPanningHeight;
#endif
#endif /* WINVER >= 0x0400 */
} DEVMODEA, *PDEVMODEA, *NPDEVMODEA, *LPDEVMODEA;

As you can see, there are quite some fields which would never be used in graphics programming but are reserved for printing application. It is likely you will be using the dmBitsPerPel, dmDisplayFrequency, dmPelsWidth and dmPelsHeight only. Which, in normal terms, are the Bits Per Pixel (often called Color Depth), Refresh Rate (also called Flicker Rate), Screen Width and Screen Height fields, combined they are the screen's resolution.

The EnumDisplaySettings Function

The EnumDisplaySettings function is simply a mechanism which queries the DEVMODES from Windows. Its prototype (as found on MSDN) is:

BOOL EnumDisplaySettings(
  LPCTSTR lpszDeviceName,  // display device
  DWORD iModeNum,          // graphics mode
  LPDEVMODE lpDevMode      // graphics mode settings
);

The first variables, lpszDeviceName is a null terminated character string containing the name of the device you wish to query. In the examples provided we will simply use NULL since the device queried is the current display device. If you wish to query a different device, see the MSDN documentation for EnumDisplayDevices to retrieve the display devices available on the current machine.

Device Mode Result Listing

We return to the previous code sample in the first section of this document and alter it slightly to output its results to the console through a regular C main function.

#include <windows.h>
#include <iostream>
 
int main()
{
	int i = 0;
	DEVMODE dMode;
 
	std::cout << "Listing Resolutions (Width*Height, BPP @Refresh Rate):" << std::endl;
 
	while( EnumDisplaySettings(NULL, i, &dMode) == TRUE )
	{
		std::cout << "Resolution found: " << dMode.dmPelsWidth << '*' << dMode.dmPelsHeight 
			<< ", " << dMode.dmBitsPerPel << "bpp @" << dMode.dmDisplayFrequency << "Hz" << std::endl;
		i++;
	};
 
	return EXIT_SUCCESS;
};

The output might look similar to the following listing:

Listing Resolutions (Width*Height, BPP @Refresh Rate):
Resolution found: 320*200, 8bpp @70Hz
Resolution found: 320*200, 16bpp @70Hz
Resolution found: 320*200, 32bpp @70Hz
Resolution found: 320*240, 8bpp @70Hz
Resolution found: 320*240, 16bpp @70Hz
Resolution found: 320*240, 32bpp @70Hz
Resolution found: 400*300, 8bpp @70Hz
Resolution found: 400*300, 16bpp @70Hz
Resolution found: 400*300, 32bpp @70Hz
Resolution found: 512*384, 8bpp @70Hz
Resolution found: 512*384, 16bpp @70Hz
Resolution found: 512*384, 32bpp @70Hz
Resolution found: 640*400, 8bpp @70Hz
Resolution found: 640*400, 16bpp @70Hz
Resolution found: 640*400, 32bpp @70Hz
Resolution found: 640*480, 8bpp @60Hz
Resolution found: 640*480, 16bpp @60Hz
Resolution found: 640*480, 32bpp @60Hz
Resolution found: 640*480, 8bpp @70Hz
Resolution found: 640*480, 16bpp @70Hz
Resolution found: 640*480, 32bpp @70Hz
Resolution found: 640*480, 8bpp @72Hz
Resolution found: 640*480, 16bpp @72Hz
Resolution found: 640*480, 32bpp @72Hz
... Etcetera ...

From this point on you could save the results for later usage in your application and sort them by Color Depth and Refresh Rate for easier end-usage rather than printing them to the console.

Personal tools