Reputation: 30132
I have two black-and-white printers, two color printers, and some virtual printers (Fax, CutePDF Writer, etc).
According to the DC_COLORDEVICE
query to DeviceCapabilities
, only the Fax virtual printer is black-and-white.
According to PLANES
and BITSPIXEL
queries to GetDeviceCaps
, all of the printers have one plane, and only Fax and CutePDF have 1 bit/pixel (are black-and-white).
According to the NUMCOLORS
query to GetDeviceCaps
, only Fax is black-and-white.
I'm not excited about querying the driver directly, so I haven't tried it yet.
How do I accurately detect a color printer with Win32?
Upvotes: 5
Views: 471
Reputation: 47972
Bummer that DC_COLORDEVICE
doesn't give the right answer. The rest of your findings don't surprise me.
You could try creating an information context for the printer with CreateIC, and then use GetDeviceCaps to check the COLORRES
property.
(An information context is like a device context that you can query but can't actually draw to. It's useful when you want to know what a printer driver is going to do without actually creating a real device context, which may require the printer being online.)
Checking the number of planes is useless, since everything (to a good approximation) uses a single plane. The number of bits per pixel doesn't actually tell you if those pixels can be color or just grayscale (or just palette entries).
Another idea is to look at the dmColor
field in the default DEVMODE for the device.
I had to solve the same problem many, many years ago (before DeviceCapabilities), but I don't remember how I did it.
UPDATE 2022-12-27: I just came across my own answer while trying to figure out how to handle the Fax virtual printer. When querying DeviceCapabilitiesW with DC_COLORDEVICE
, the Fax driver returns value of -1 and GetLastError reports 122 (ERROR_INSUFFICIENT_BUFFER
"The data area passed to a system call is too small.") That's weird, since there's no requirement to pass a buffer for this query.
My current solution is to check everything. If DeviceCapabilities with DC_COLORDEVICE
doesn't explicitly say color OR if the DEVMODE's dmFields bitmask doesn't have the DM_COLOR bit set OR if the DEVMODE's dmColor field isn't explicitly DMCOLOR_COLOR OR if GetDeviceCaps NUMCOLORS isn't at least 8, then I assume it's a monochrome printer or that user selected monochrome for this print job.
Upvotes: 3