MORE INFORMATION
When a Microsoft Windows application prints, it must identify the target printer by its full name. The
DEVMODE structure that was introduced in 16-bit Windows version 3.1 has a limitation of 32 characters for a printer name. However, printer names in Win32 operating systems can be much longer.
On Win32 platforms the full or long printer name is given by the
pPrinterName member of the
PRINTER_INFO_2 structure or by the
DEVNAMES structure. The
PRINTER_INFO_2 structure can be obtained from the
EnumPrinters function. The
DEVNAMES structure can be obtained by a call to either the
PrintDlg or
PrintDlgEx functions to fill a
PRINTDLG(EX) structure. The
DEVNAMES structure is managed by a global memory handle returned in the
PRINTDLG(EX) structure.
The
pPrinterName member of the
PRINTER_INFO_2 structure and the name of the device (
wDeviceOffset refers to the printer name) in the
DEVNAMES structure are pointers to a string buffer. Because they are pointers to a string, they do not have a 32-character limitation and will contain the long printer name of the target printer. See the Platform SDK Documentation for a discussion of the
PRINTDLG(EX) structure and the
DEVNAMES structure.
Some applications may need to open a printer by name while printing to a printer device context. Such a circumstance occurs when the application is
changing the settings of a
DEVMODE buffer as described in the following Microsoft Knowledge Base article:
167345 HOWTO: Modify Printer Settings with DocumentProperties()
The long printer name cannot be obtained from a handle to a printer device
context or the
DEVMODE buffer. The application must keep some independent reference to the printer. A reference to the printer can take the form of a string that contains the long printer name, a
DEVNAMES buffer, or a handle to a printer that can be used in a
GetPrinter function call.
The
GetPrinter function can fill out a single
PRINTER_INFO_2 structure much like the
EnumPrinters function can retrieve several such structures. Because proper changes to a
DEVMODE also require a handle to a printer, such a handle is a convenient reference to the printer.
The long printer name can be used to obtain a handle to a printer through the
OpenPrinter function, so the long name is also a convenient reference to the printer. It can be stored separately or as part of a
DEVNAMES structure.
The printer name in a
DEVNAMES buffer is stored in the extra space allocated beyond the
DEVNAMES structure. To locate the printer name string in the
DEVNAMES buffer, you can use the
wDeviceOffset member to compute a pointer value that is based on the start of the
DEVNAMES structure.
The following code fragment demonstrates the technique by creating a printer device context from a
DEVNAMES and a
DEVMODE structure:
HDC CreateDeviceContext( DEVMODE *pDevMode, DEVNAMES *pDevNames )
{
LPCTSTR szDriver;
LPCTSTR szDevice;
LPCTSTR szOutput;
szDriver = (LPCTSTR)pDevNames+pDevNames->wDriverOffset;
szDevice = (LPCTSTR)pDevNames+pDevNames->wDeviceOffset;
szOutput = (LPCTSTR)pDevNames+pDevNames->wOutputOffset;
return CreateDC(szDriver, szDevice, szOutput, pDevMode);
}