Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you control printer tray selection for printer in Windows

We need to be able to change the default selected print tray of a given printer. Does anyone have VC++/win32 code for doing this?

In case it matters, I believe we have to change the default setting for the printer. Our print jobs are executed by an application other than ours, so we can't make these kinds of changes in the context of a print operation originating from inside our application. Unless there is some way to modify the default print settings in a different application, I think we are stuck changing the user's defaults for the printer, initiating our print job, then setting the defaults back to the original values.

We'd really prefer to have the defaults change for the current user only, and not require any special UAC elevation, etc...

I suspect that it will use something similar to what is shown in this MSDN article, and involve setting fields in the DEVMODE structure (either dmDefaultSource or dmFormName or both).

Any takers? Or does anyone have any gotchas they'd like to share?

EDIT: Here is a link for DEVMODE documentation DEVMODE documentation

EDIT: I should also point out that we are looking for a general solution - not something specific to a particular printer (we deploy in many, many environments)

like image 665
Kevin Day Avatar asked Oct 15 '22 18:10

Kevin Day


2 Answers

FYI - the solution we wound up using was to capture the DEVMODE structure. We have a small win32 app that presents the printer settings dialog (via DocumentProperties with fMode set to DM_IN_PROMPT). The resultant DEVMODE is then saved to disk. When we do our printing, we capture the current DEVMODE, set the stored DEVMODE, initiate the print, then restore the original DEVMODE.

This actually works quite well. Occasionally, the print drivers will update and cause the stored DEVMODE to break, but that doesn't happen very often and it's easy enough for users to fix.

As an extra bonus, this approach allows us to capture ALL of the printer settings (not just the output tray) - so we were able to support advanced settings like stapling, collating, etc...

Tip: If you try this, be sure to write to disk as a binary output stream. In my initial evaluation of this approach, I accidentally set the output stream up as a text output stream. Things would work fine for many cases, then suddenly break for some printers (that used high order bytes in their DEVMODE private data). A dumb, but easy, mistake to make - and one that took a very nice solution off the table for awhile.

like image 190
Kevin Day Avatar answered Jan 01 '23 00:01

Kevin Day


Setting features like this can be tricky, especially if the driver doesn't follow Microsoft's print guidelines. That being said, we've had some success with System.Drawing.Printing.PrinterSettings. You can set PaperSource but I'm not sure you can set the defaults.

If you haven't seen this example you may want to look further at it. It describes a method to store and reload printer settings. One of my guys pointed it to me: PrinterSettings - Changing, Storing and Loading Printer Settings

Another method, that could work but might not work for you, is to determine your the handful of setups you need. Install a printer with each of these (ie: Tray 1, Tray 2) setups. Then simply switch the default printer on print. Not what you are looking for but it may help.

What we typically do in these situations is have the 3rd party app write the data to a folder that we are monitoring, we then pick up the file and parse the Postscript or PCL ourselves and change the paper tray and then send onto the destination device. A lot simpler then it may sound.

like image 36
Douglas Anderson Avatar answered Dec 31 '22 23:12

Douglas Anderson