![]() |
| Home | Introduction | Table of Contents | Updates | New Stuff | Links | About the Authors | Ordering | ||
|
Enumerating and Changing the Display Settings Although it is not
common for an application to manipulate the end-user’s
display settings, there may be situations where this is
warranted. For example,
if your application works best under a specific resolution, you
may want to offer your consumers the ability to quickly switch to
this resolution from within the software. In other cases, for example when
displaying natural images, you many want to offer a feature that
allows the color-depth to be increased to the maximum value that
the current monitor can support. Or, if you’re creating a
GDI-based game, you may want to automatically switch the
end-user’s display settings from a high-resolution
high-color mode, to a low-resolution low-color mode, for
increased performance.
Enumerating the Available Display Settings Before you can switch to a specific display setting, you need to determine which settings are supported by the video device driver. To this end, Windows presents the EnumDisplaySettings function:
BOOL EnumDisplaySettings( IN LPCTSTR lpszDeviceName, // a string that specifies the display device IN DWORD iModeNum, // graphics mode index to query OUT LPDEVMODE lpDevMode // pointer to a DEVMODE structure );
The lpszDeviceName parameter is
assigned the name of the display device whose settings are to be
retrieved. Typically,
this value is specified as NULL, indicating that the
application’s current display device should be
queried. In fact, on
systems running Windows 95, this parameter must be set to NULL. On Windows 98/Me/NT/2000-based
systems, the lpszDeviceName parameter can
either be set to NULL,
or the literal “\\.\Display#”, where # is a number
ranging from one to three for systems running Windows NT, or from
one to the number of display devices for systems running Windows
98/Me/2000. The iMode parameter indicates the
display mode to be queried, and when incremented to a value
greater than the available display modes, the function will
return false. If successful, the EnumDisplaySettings function
returns true, and the
retrieved information is stored in the DEVMODE structure specified via
the lpDevMode
parameter. The DEVMODE type is a special
structure whose 37 data members serve to hold information about a
DEVice’s MODEs (settings). This structure is primarily used for
printer settings, so many of its data members are irrelevant when
working with a video display device. For most situations, you only need
concern yourself with all or only some of the five data members
that are exclusive to video display devices. These five data members are
explained in Table 1.13. Table 1.13 The DEVMODE data members that are exclusive to video display device drivers
When used in an iterative fashion, the EnumDisplaySettings function can yield information about all of the available display settings. That is, unlike other enumeration-type functions, there is no parameter that accepts a pointer to a callback function. Instead, the EnumDisplaySettings function is called repetitively, each time with an incremented iMode parameter, until the function returns false:
DEVMODE dm; memset(&dm, 0, sizeof(DEVMODE)); int current_mode = 0;
while (EnumDisplaySettings(NULL, current_mode++, &dm)) { // // examine the relevant data members // of "dm" and act accordingly... // }
Changing The
Current Display Settings
LONG ChangeDisplaySettings( IN LPDEVMODE lpDevMode, // pointer to an initialized DEVMODE structure IN DWORD dwflags // flags indicating the valid DEVMODE data members );
Because this function accepts a pointer to a DEVMODE structure as its first parameter, it is used almost exclusively in conjunction with the EnumDisplaySettings function. However, before you pass the address of the initialized DEVMODE structure as the lpDevMode parameter, you need to convey to the ChangeDisplaySettings functions which data members of the DEVMODE structure are valid. This is accomplished by assigning the appropriate flags to the structure’s dmFields data member. This data member can be assigned a combination of any of the values listed in Table 1.14. Table 1.14 Flags that can be assigned to the dmFields data member for use with the ChangeDisplaySettings function
The dwflags parameter of the ChangeDisplaySettings function is used to specify the nature of the change. The possible values for this parameter are listed in Table 1.15. Table 1.15 Values that can bas specified as the dwflags parameter of the ChangeDisplaySettings function
The return value of the ChangeDisplaySettings function indicates the success, failure, reason of failure, or requirements of the change. This value can take on one of the constants listed in Table 1.16. Table 1.16 Possible return values of the ChangeDisplaySettings function
Although the ChangeDisplaySettings
function has a multitude of accompanying constants as listed in
Tables 1.13, 1.14, and 1.15, using this function isn't as
complicated at it may seem. Typically, you pass the ChangeDisplaySettings function
the DEVMODE structure
that has been initialized by the EnumDisplaySettings function
along with the CDS_TEST flag as the dwflags parameter. This will ensure that the change in
settings can indeed be carried out. If successful, you call the ChangeDisplaySettings
function again, this time with the CDS_UPDATEREGISTRY flag as the
dwflags
parameter.
// // EXAMPLE #1: Changing the resolution // int ChangeResolution(LPSIZE lpSize) { DEVMODE dm; memset(&dm, 0, sizeof(DEVMODE));
int current_mode = 0; int result = DISP_CHANGE_BADMODE;
// enumerate the available graphic modes while (EnumDisplaySettings(NULL, current_mode++, &dm)) { // when the desired settings are met... if (dm.dmPelsWidth == static_cast<DWORD>(lpSize->cx) && dm.dmPelsHeight == static_cast<DWORD>(lpSize->cy)) { // tell the function which settings to change dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
// test to ensure that a change will succeed result = ChangeDisplaySettings(&dm, CDS_TEST);
// if successful... if (result == DISP_CHANGE_SUCCESSFUL) { // change to the new graphic mode return ChangeDisplaySettings( &dm, CDS_UPDATEREGISTRY ); } } } // otherwise, return the result return result; }
// // EXAMPLE #2: Changing the color-depth // int ChangeColorDepth(WORD bits_per_pixel) { DEVMODE dm; memset(&dm, 0, sizeof(DEVMODE));
int current_mode = 0; int result = DISP_CHANGE_BADMODE;
// enumerate the available graphic modes while (EnumDisplaySettings(NULL, current_mode++, &dm)) { // when the desired setting is met... if (dm.dmBitsPerPel == bits_per_pixel) { // tell the function which setting to change dm.dmFields = DM_BITSPERPEL;
// test to ensure that a change will succeed result = ChangeDisplaySettings(&dm, CDS_TEST);
// if successful... if (result == DISP_CHANGE_SUCCESSFUL) { // change to the new graphic mode return ChangeDisplaySettings( &dm, CDS_UPDATEREGISTRY ); } } } // otherwise, return the result return result; }
In most cases, the return value will indicate success (DISP_CHANGE_SUCCESS). For some configurations, the change may require that the system be rebooted (DISP_CHANGE_RESTART). If access restrictions apply, the DISP_CHANGE_NOTUPDATED identifier is returned. Using this typical scheme, unless your manipulate the initialized DEVMODE structure, rarely will you need deal with any other return values. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Copyright
© 2001 Damon Chandler and Michael Fötsch
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||