ID Number: Q76260
3.00
WINDOWS
Summary:
Windows provides a device-independent platform for application
developers. Device independence applies to printing as well. To write
code to work with any printer driver, applications must not rely on
any special feature in a printer driver. Instead, applications should
direct all requests through the Windows Graphical Device Interface
(GDI).
More Information:
There are two major classes of printers: raster printers and
PostScript printers. This article is directed towards application
support for raster printers. For information on PostScript printers,
query on the words:
prod(winsdk) and postscript
With the exception of the standard printer escapes, applications
should not rely on any printer escape to be supported in a particular
printer driver.
The standard escapes are: STARTDOC, ENDDOC, NEXTBAND, NEWFRAME,
SETABORTPROC, and ABORTDOC. The remaining escapes are optional for
printer drivers. Applications should use the QUERYESCSUPPORT escape to
test for the support of optional escapes. Applications should not
depend on private knowledge of how a particular driver works.
For example, the DRAWPATTERNRECT escape is available on certain
devices. The following code fragment determines if the DRAWPATTERNRECT
escape is supported on the installed device. If not, an alternative
function, PatBlt(), is used to create the output.
short i;
i = DRAWPATTERNRECT;
if (Escape(hPr, QUERYESCSUPPORT, sizeof(i), (LPSTR)&i, NULL))
Escape(hPr, DRAWPATTERNRECT, sizeof(lpPatRect),
(LPSTR)lpPatRect, NULL);
else
PatBlt(hPr, .....);
Of the remaining escapes, the following are used frequently:
GETPHYSPAGESIZE, GETPRINTINGOFFSET, PASSTHROUGH, and DRAWPATTERNRECT.
An application should minimize the number of escapes that it uses.
Another area of device independence applies to the DeviceMode
function. Applications should not allow the user to change the device
mode settings globally. If the user wants to change the device mode
setting, the Control Panel utility should be used. It is more
appropriate for the device mode to be associated with an application,
a document, or a particular set of pages in a document.
The following code demonstrates the required steps to use
EXTDEVICEMODE:
lpfnExtDeviceMode = GetProcAddress(hDriver, (LPSTR)"EXTDEVICEMODE");
if (lpfnExtDeviceMode != NULL)
{
count = (*lpfnExtDeviceMode)((HWND)NULL,
(HANDLE)hDriver,
(LPDEVMODE)NULL,
(LPSTR)lpPrintType,
(LPSTR)lpPrintPort,
(LPDEVMODE)NULL,
(LPSTR)NULL,
(WORD)0);
hDevModeOut = LocalAlloc(LHND, count);
if (hDevModeOut)
{
lpDevModeOut = LocalLock(hDevModeOut);
lstrcpy(DevModeIn.dmDeviceName, lpPrintType);
DevModeIn.dmSpecVersion = DM_SPECVERSION;
DevModeIn.dmDriverVersion = 0;
DevModeIn.dmSize = sizeof(DEVMODE);
DevModeIn.dmDriverExtra = 0;
DevModeIn.dmFields = DM_ORIENTATION;
DevModeIn.dmOrientation = DMORIENT_LANDSCAPE;
count = (*lpfnExtDeviceMode)((HWND)NULL,
(HANDLE)hDriver,
(LPDEVMODE)lpDevModeOut,
(LPSTR)lpPrintType,
(LPDEVMODE)&DevModeIn,
(LPSTR)NULL,
DM_COPY);
CreateDC(lpPrintDrvier, lpPrintType, lpPrintPort,
(LPSTR)lpDevModeOut);
}
Note that it is very important to query the driver for the size of the
device mode structure. The DEVMODE structure is driver-dependent and
also driver version-dependent.
On a final note, applications should not hard code a driver name or a
device name. Applications should always search in the [Devices]
section of the WIN.INI file for the name of the installed printer.
Explicitly searching for "PSCRIPT.DRV" or "HPPCL.DRV" is strongly
discouraged.