views:

4329

answers:

4

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)

A: 

I had to do something very similar recently on a specific printer driver and it required a vendor specific SDK. The tray doesn't seem to appear in DEVMODE or any of the other PRINTINFO_* structures so I guess I'd drop an email to the printer vendor.

As a last resort, I can think of two possible hacks. One is to automate the driver at GUI level using a scripted tool such as AutoIT. Second is to dump the registry to file, change the driver setting, dump the registry again, and compare the differences (may or may not work).

Shane MacLaughlin
DEVMODE has two parameters (dmDefaultSource and dmFormName) that seem to control tray. Am I misinterpreting what these members control?
Kevin Day
A: 

As far as I know, printers are controlled by the printer driver by sending them SNMP or PJL commands. But not all printers implement completely these sets of commands.

For HP printers I found at: http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid=reg_R1002_USEN some PJL commands (there are some related to the tray too).

I'm not sure this help, but take it as a hint for future searches...

Citrone
+1  A: 

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.

Douglas Anderson
This is a good reference for settings associated with the current app. If my app was initiating the print jobs, it would work perfectly. But we are instructing a different app to initiate the print job, so we either need to change settings in the other app, or change default system wide settings.
Kevin Day
+1  A: 

dmDefaultSource controls the tray. Unfortunately the values you'll want to set this to differs depending on your driver as this is a bin number and not necessarily the same number as the tray# printed on your printer.

The following link provides some VB6 code for gathering information about your printers tray/bin assignments. You can use that information to programatically assign dmDefaultSource to the appropriate bin # for a tray. You basically need to use DeviceCapabilities to return information about your printers and then search for a string (like "Tray 1") to get the associated bin number.

http://support.microsoft.com/kb/194789

Stimy
This looks quite promising - I'll post back when I can come up for air and give it a whirl - thanks!
Kevin Day