DEVMODE is a Windows structure that holds initialization and environment information about a printer.
It is made up of two parts: public and private. Using the Windows structure the developer can fully
control the printer settings of the Amyuni PDF Converter.
The public part contains data that is common to all printers. The private part contains data that is
specific to a particular printer. The private part can be of variable length and can contain anything the
printer driver designer decides to include in it.
One of trickier aspects of working with the DEVMODE structure is that it depends on the operating
system. Its length and content cannot be known beforehand. No assumptions can or should be made as
to the size of this structure in either its private or public part.
The DocumentProperties function retrieves or modifies printer initialization information or displays a
printer-configuration property sheet for the specified printer. To get the size of the DEVMODE structure
specific to the printer, we should use the DocumentProperties API call. This method is defined in
WINSPOOL.H as:
Code: Select all
DocumentProperties(hWnd, /* Handle of the parent window */
hPrinter, /* Handle to our printer. */
pDevice, /* Name of the printer. */
NULL, /* Asking for size, so */
NULL, /* these are not used. */
0); /* Zero returns buffer size. */
last parameter is set to 0. To obtain the size of the DEVMODE structure, we can use the following
instructions:
Code: Select all
/*
Obtain the size of the DEVMODE structure
*/
LONG lSize = 0 ;
LPDEVMODE lpDevMode = NULL ;
lSize = DocumentProperties( NULL, NULL, szPrinterName, NULL, NULL, 0 ) ;
if ( 0 == lSize )
{
// error , printer is unknown
return;
}
function to get the DEVMODE structure. The OpenPrinter function retrieves a handle to the specified
printer or print server or other types of handles in the print subsystem.
Code: Select all
/*
Alternative way of obtaining the size of the DEVMODE structure
*/
HANDLE hPrinter;
/* Start by opening the printer */
if ( !OpenPrinter( lpDeviceName, &hPrinter, NULL ) )
return FALSE;
// get real size of DEVMODE
int nSize = DocumentProperties( NULL, hPrinter, NULL, NULL, NULL, 0 );
values for all parameters:
Code: Select all
lpDevMode = (LPDEVMODE)GlobalAllocPtr( lSize ) ;
DocumentProperties( NULL, NULL, szPrinterName, lpDevMode, NULL, DM_OUT_BUFFER );
- lpDevMode->dmSize is the size of the public structure (common to all printers)
- lpDevMode->dmDriverExtra is the size of the private structure (specific to each
printer)
To modify one of the public printer parameters, for example printer resolution and paper orientation,
we can use the following instructions:
Code: Select all
lpDevMode->dmPrintQuality = 600; // set the resolution to 600 DPI
lpDevMode->dmOrientation = DMORIENT_PORTRAIT; // set orientation to landscape
lpDevMode->dmFields = DM_ORIENTATION | DM_PRINTQUALITY; // indicate which fields are modified
dwMargins
dwOptions contains compression and font embedding options as follows:
Bit 0 : flate compression of page content
Bit 1 : font embedding option
Bit 2 : JPEG compression
Bit 3 : 256 color compression
Example, to read or set the JPEG compression option, we would use the following instructions:
Code: Select all
LPDWORD lpdwFlags = (LPDWORD)((LPBYTE)lpDevMode + lpDevMode->dmSize );
BOOL bJpegCompression = (BOOL)(*lpdwFlags & 4); // this returns JPEG compression flag
// now invert the JPEG compression option
if ( bJpegCompression )
{
*lpdwFlags = *lpdwFlags & ~4; // clear the JPEG compression flag
}
else
{
*lpdwFlags = *lpdwFlags | 4; // set the JPEG compression flag
}
Code: Select all
lpFlags = (LPDWORD)((LPBYTE)lpDevMode + lpDevMode->dmSize );
lpMargins = (LPDWORD)( (LPBYTE)lpDevMode + lpDevMode->dmSize + sizeof( DWORD ) );
*lpFlags |= DM_EMBED_FONTS|DM_EMBED_STANDARD_FONTS|DM_LICENSED_EMBEDDING|DM_MULTILINGUAL_SUPPORT;
high part. These are defined in 0.1 mm units.
To modify the minimum margins, we can use the following instructions:
Code: Select all
lpMargins = (LPDWORD)( (LPBYTE)lpDevMode + lpDevMode->dmSize + sizeof( DWORD ) );
*lpMargins = MAKELONG( 30, 30 ); // this will set the margins to 3 mm
printer device context using the CreateDC API call:
Code: Select all
HDC hDC = CreateDC( _T( "winspool" ), szPrinter, NULL, lpDevMode );
Code: Select all
DWORD dw;
PRINTER_INFO_2 *pi2;
// get default printer info structure which contains the DEVMODE
GetPrinter( m_hPrinter, 2, NULL, 0, &dw );
pi2 = (PRINTER_INFO_2 *)GlobalAllocPtr( GHND, dw );
GetPrinter( m_hPrinter, 2, (LPBYTE)pi2, dw, &dw );
// set the new printer info structure
pi2->pDevMode = lpDevMode;
SetPrinter( m_hPrinter, 2, (LPBYTE)pi2, 0 );
GlobalFreePtr( pi2 );
// notify applications that the default DEVMODE has changed
SendMessageTimeout( HWND_BROADCAST, WM_DEVMODECHANGE, 0, (LPARAM)szPrinter,
SMTO_NORMAL, 1000, NULL );
illustrates use Windows DEVMODE structure to fully control the settings of the Amyuni PDF Converter
virtual printer driver.
http://www.amyuni.com/downloads/TN02.zip
Note: A driver supports only those DEVMODE members that are appropriate for the printer technology.