I need a good way to programmatically set the Pages per Sheet setting when printing.
I know that a user can select this option via a printer settings dialog and that I could make such a dialog display if I wanted to. But in the context of the program I'm working on, I need this to be selected by the software itself without requiring to user to delve into the printer settings.
While it appears I can ask Windows if a printer supports this using the dmNup
member of the DEVMODE
structure, there doesn't seem to be any official way to actually set it for the current print job.
Obviously, one solution would be to alter the printing algorithm in my software so that it lays out the pages appropriately on the device context to get multiple pages per sheet in the resulting output. However, I haven't seen any simple way to do that which doesn't require significant changes throughout all of the code that draws to the printer device context. For various reasons, I would rather avoid massive code changes.
Another solution is to install multiple copies of the printer in Windows while directing them all to the same printer port. Each copy of the printer is set with a different default Pages per Sheet. Then the software can select the appropriate printer and the end result is as if it had programmatically selected the necessary pages per sheet option. However, I have encountered various problems with this scheme, and so I am looking for an alternative that would be less of a support burden.
This article offers another possible solution: manipulating the appropriate byte in the private driver data that follows the official DEVMODE structure. The problem is that there is no guarantee that any particular printer driver actually uses the same byte, and I need to support essentially any printer that could reasonably by used in an office environment. It would seem my software would need a configuration where I could specify different byte offsets for drivers that don't use the default. This could be a rare occurrence or a frequent headache depending how many printer drivers have decided to use different bytes for this setting.
So here are my questions:
- Does anyone have any real-world experience using the last technique of manipulating private driver data? How well does it hold up when dealing with various printers from various manufacturers?
- Are there any other techniques that I have overlooked?
- If nothing else, then are there any simple ways to take code that draws text, lines, graphics, etc to the printer device context and somehow force it to scale, move, and possible rotate (for 2 pages per sheet) the output to the necessary location in the device context without writing all of the code (and without losing 1-pixel wide lines)?
Note: For what it's worth, the program I'm working on is using C++ and MFC. However, all of this should be equally applicable to any program that deals with device contexts and the rest of the Windows API itself.