HOWTO: Modify Printer Settings with DocumentProperties()ID: Q167345
|
Using a DEVMODE structure to modify printer settings is more complicated than simply changing the fields of the structure. Specifically, a valid DEVMODE structure for a device contains private data that can only be modified by the DocumentProperties() function. This article discusses the necessary steps to properly modify the contents of a DEVMODE structure with the DocumentProperties() function.
A DEVMODE structure, as documented by the Win32 SDK, contains public or "Device Independent data" and private or "Device Dependent data." The
private part of a DEVMODE exists immediately following the public part,
which is defined by the DEVMODE structure, in a contiguous buffer of
memory.
An application cannot predict the size of this buffer because it is
different from printer to printer and version to version of printer driver.
Further, a DEVMODE structure that is simply declared by an application does not contain sufficient space for private device data. If a DEVMODE buffer that lacks private data is passed to functions such as CreateDC(), ResetDC(), and DocumentProperties(), the function may fail.
To reliably use a DEVMODE with a device driver it should be properly
created and modified using the following procedure:
Q135387 HOWTO: Get and Set the Default Printer in WindowsNOTE: In this article the first two steps of allocating the correct size of buffer and initializing that buffer are performed with the DocumentProperties() function. The GetPrinter() function can also be used to perform these steps. For an example of this use, please see the following article in the Microsoft Knowledge Base:
Q140285 HOWTO: Modify Printer Settings by Using SetPrinter
LPDEVMODE GetLandscapeDevMode(HWND hWnd, char *pDevice)
{
HANDLE hPrinter;
LPDEVMODE pDevMode;
DWORD dwNeeded, dwRet;
/* Start by opening the printer */
if (!OpenPrinter(pDevice, &hPrinter, NULL))
return NULL;
/*
* Step 1:
* Allocate a buffer of the correct size.
*/
dwNeeded = DocumentProperties(hWnd,
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. */
pDevMode = (LPDEVMODE)malloc(dwNeeded);
/*
* Step 2:
* Get the default DevMode for the printer and
* modify it for our needs.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* The address of the buffer to fill. */
NULL, /* Not using the input buffer. */
DM_OUT_BUFFER); /* Have the output buffer filled. */
if (dwRet != IDOK)
{
/* if failure, cleanup and return failure */
free(pDevMode);
ClosePrinter(hPrinter);
return NULL;
}
/*
* Make changes to the DevMode which are supported.
*/
if (pDevMode->dmFields & DM_ORIENTATION)
{
/* if the printer supports paper orientation, set it*/
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}
if (pDevMode->dmFields & DM_DUPLEX)
{
/* if it supports duplex printing, use it */
</BLOCKQUOTE>
<BR/><BR/>
<BLOCKQUOTE>
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
}
/*
* Step 3:
* Merge the new settings with the old.
* This gives the driver a chance to update any private
* portions of the DevMode structure.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* Reuse our buffer for output. */
pDevMode, /* Pass the driver our changes. */
DM_IN_BUFFER | /* Commands to Merge our changes and */
DM_OUT_BUFFER); /* write the result. */
/* Done with the printer */
ClosePrinter(hPrinter);
if (dwRet != IDOK)
{
/* if failure, cleanup and return failure */
free(pDevMode);
return NULL;
}
/* return the modified DevMode structure */
return pDevMode;
}
For additional information, please see the following article in the Microsoft Knowledge Base:
Q132239 SAMPLE: Calling ExtDeviceMode/DeviceCapabilities in Win32s App
Additional query words:
Keywords : kbcode kbprint kbSDKWin32 kbDSupport
Version : WINDOWS:
Platform : WINDOWS
Issue type : kbhowto
Last Reviewed: June 30, 1999