How to Determine Whether a Printer Supports Color

Introduction

A recent project required me to determine whether a printer supported printing in color. This seemed like the kind of task that others before me must have faced. I searched CodeGuru and other forums and found some approaches to this problem. However, none were too convincing or complete. Each article I found pointed out some flaw in the approach. With a little bit of research, I was able to develop my own approach to the problem.

Printer Drivers Reveal All

I always had a gut feeling that the information I needed was at a very basic low level. With some research, I stumbled across the DrvDeviceCapabilities() function. This function comes from the Microsoft DDK (Driver Development Kit). Microsoft recommends each hadrware vendor export this function from their drivers to provide requested information about a printer’s capabilities. By using this function, it’s pretty easy to determine color capabilities.

The Code

The first step in determining color capabilities is to open the printer. This is accomplished by the following:

BOOL rc = OpenPrinter(printer.GetBuffer(0), &hPrinter, NULL);

Once this is done, you’ll need to get the printer and driver structures:


// get printer info.
rc = GetPrinter(hPrinter, 2, NULL, NULL, &dwBytesNeeded);
pinfo2 = (PRINTER_INFO_2*) LocalAlloc(LPTR, dwBytesNeeded);
rc = GetPrinter(hPrinter, 2, (LPBYTE)pinfo2, dwBytesNeeded,
&dwBytesNeeded);
// get driver info.
rc = GetPrinterDriver(hPrinter, NULL, 2, NULL, NULL,
&dwBytesNeeded);
dinfo2 = (DRIVER_INFO_2*) LocalAlloc(LPTR, dwBytesNeeded);
rc = GetPrinterDriver(hPrinter, NULL, 2, (LPBYTE)dinfo2,
dwBytesNeeded, &dwBytesNeeded);

The function we’re interested in resides in the driver configuration file. Once we have it, we can call the function:


// get handle to printer driver config module
HMODULE hmod = LoadLibrary(dinfo2->pConfigFile);
if (hmod)
{
DWORD (WINAPI* DriverCaps)(HANDLE, LPWSTR, WORD, VOID*, PDEVMODE);
// get pointer to exported function.
DriverCaps = (DWORD (WINAPI*) (HANDLE, LPWSTR, WORD, VOID*,
PDEVMODE))
GetProcAddress(hmod, “DrvDeviceCapabilities”);
if (DriverCaps)
{
WCHAR wszPrinter[256] = {0};
MultiByteToWideChar(CP_ACP, 0, printer, -1, wszPrinter, 256);
// call exported function.
dwColor = (*DriverCaps)(hPrinter, wszPrinter,
32 /*DC_COLORDEVICE*/,
(VOID*)NULL, pinfo2->pDevMode);
}
FreeLibrary(hmod);
}

In the preceding code snippet, the DC_COLORDEVICE flag tells “DrvDeviceCapabillites” to return a 1 if the printer supports color, or a 0 if it does not.

To Use

Download the .zip file. It contains the following function:

int CheckForColorPrinter(CString printer)

Include the function in your code and pass it the name of the printer. (You can obtain the name of the printer from CPrintDialog.) If the printer supports color, the function returns “1”. If color is NOT supported, it returns “0”.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read