The DEVMODEW Structure

The DEVMODEW structure is the Unicode version of the DEVMODE structure, which is described in the Microsoft Windows SDK documentation. (The 'W' suffix on DEVMODEW stands for "wide", or Unicode characters.) While applications can use either structure, drivers are required to use the DEVMODEW structure rather than the DEVMODE structure.

Public and Private Members

Immediately following a DEVMODEW structure's defined members (often referred to as its public DEVMODEW members), there can be a set of driver-defined members (its private DEVMODEW members). The following figure shows the public section (the actual DEVMODEW structure itself) and the private section.

Diagram illustrating the public and private sections of the DEVMODEW structure.

Normally, the private members are used only by printer drivers. The driver supplies the size, in bytes, of this private area in the dmDriverExtra member. Driver-defined private members are for exclusive use by the driver.

For printer drivers, the DEVMODEW structure is used to specify user choices for a print document. It is also used to specify default values of these choices for printers, such as the number of copies to print, paper size, and other attributes. For display devices, the DEVMODEW structure specifies display attributes such as the number of bits per pixel, pixel dimensions, and display frequency.

Initializing a DEVMODEW Structure

Depending on whether it is to be used by a display driver or by a printer driver, a DEVMODEW structure is initialized in two different ways.

  • Display driver DEVMODEW initialization

    A display driver's DrvGetModes entry point initializes all members of the DEVMODEW structure to zero. DrvGetModes then copies the name of the display driver DLL to the dmDeviceName member, fills in the dmSpecVersion and dmDriverVersion members with the version of the DEVMODEW structure, and copies display attribute information to the appropriate members.

  • Printer driver DEVMODEW initialization

    When an application makes a call to either DocumentProperties (a printer interface DLL function that is described in the Microsoft Windows SDK documentation) or DrvDocumentPropertySheets (an NT-based operating system graphics DDI), a DEVMODEW structure is created with default values. An application is then free to modify any of the public DEVMODEW members. After any changes, the application should then make a second call to the same function it called before, in order to merge the changed members with those of the driver's internal DEVMODEW structure. The second call is necessary since some changes may not work correctly; the printer driver must be called to correct the DEVMODEW structure. When the document is about to be printed, the application passes the merged DEVMODEW structure to CreateDC (described in the Microsoft Windows SDK documentation), which passes it on to the DrvEnablePDEV DDI. At that time, the driver's rendering DLL validates the DEVMODEW structure and makes repairs, if necessary, before carrying out the print job.

Using a DEVMODEW Structure

Several APIs and graphics DDIs use the information in the DEVMODEW structure for such purposes as printing, querying device capabilities, showing user interface, and others. For example, DrvConvertDevMode is a print spooler graphics DDI that translates the DEVMODEW structure from one operating system version to another. This might be necessary if a printer driver gets a DEVMODEW structure from another machine that is running on a different operating system version.

Modifying a DEVMODEW Structure

Applications and drivers are free to ask for a DEVMODEW structure and modify its public part directly. Only drivers, however, are permitted to modify the private DEVMODEW structure members.

In order to modify private DEVMODEW structure members, a driver must first determine the offset of the beginning of the private data. Given a pointer to the beginning of this structure, and the dmSize member, which holds the size of the public portion of the structure, the beginning of the private portion can be found. The following example shows how to initialize a pointer to the beginning of the private section. In this example, pdm points to the beginning of the DEVMODEW structure.

PVOID pvDriverData = (PVOID)  (((BYTE *) pdm) + (pdm -> dmSize));

Printer Driver/Display Driver DEVMODEW Differences

The DEVMODEW structure members fall into three categories:

  • Members used only by printer drivers

  • Members used only by display drivers

  • Members used by both printer and display drivers

The following table lists several public DEVMODEW members that are used only by printer drivers:

Used Only by Printer Drivers Purpose
dmScale Specifies the percentage by which the image is to be scaled for printing.
dmCopies Specifies the number of copies to be printed.
dmColor Specifies whether a color printer should print color or monochrome.
dmOrientation Specifies the orientation of the paper, either portrait or landscape.

The next table lists several public DEVMODEW members that are used only by display drivers:

Used Only by Display Drivers Purpose
dmBitsPerPel Specifies the color resolution, in bits per pixel, of the display device.
dmPelsWidth Specifies the width, in pixels, of the visible device surface.
dmPelsHeight Specifies the height, in pixels, of the visible device surface.
dmDisplayFlags Specifies the display mode - color versus monochrome, interlaced versus noninterlaced.
dmDisplayFrequency Specifies, in hertz, the display's refresh rate.

The third table lists several public DEVMODEW members that are used by both printer and display drivers:

Used by Printer and Display Drivers Purpose
dmDeviceName For displays, specifies the display driver's DLL. For printers, specifies the "friendly name" of the printer.
dmFields Specifies bit flags identifying which of the DEVMODEW members that follow it are in use. For example, the DM_BITSPERPEL flag is set when the dmBitsPerPel member contains valid data.
dmSize Specifies the size, in bytes, of the public portion of the DEVMODEW structure.
dmDriverExtra Specifies the number of bytes of private driver data following the public structure members. For display drivers, this is usually zero.