I have multiple printers which contain a "Rotate 180 degree" checkbox like below:
Here's another one ("Nee" means "no"):
Is there a way to programmatically set this value, and change PrintTicket
? If not, how can I get the current value of it? For my software I need to know if this is set or not and if it's set it needs to be changed, if possible. For my software it would be the best if I don't have to open the printdialog, it's a piece of software where users can print directly without clicking any buttons, so setting or getting it programmatically is what I'm looking for.
I've been searching around using ManagementObjectSearcher
and in the normal PrintDocument.DefaultPageSettings
property but couldn't find anything!
If this option isn't set, I automatically want to set it temporarily for the users (otherwise it prints upside down with my particular printers). I've been messing around trying to set it for the users but I can't figure out how to get it to work. I've been looking at the DEVMODE
struct and tried to implement it but it also doesn't have a "rotate 180 degrees option" or anything similar.
NOTE: I'M NOT TRYING TO SET LANDSCAPE MODE. That's pretty easy and something different.
I tried doing the following:
pdialog.PrintQueue.CurrentJobSettings.CurrentPrintTicket.PageOrientation = PageOrientation.ReversePortrait;
However, this only inverts the page orientation and not the content (the content needs to be rotated as well).
If I rotate the visual that I'm printing, the margins aren't right anymore so that doesn't work either! Hope someone can help.
Thanks in advance.
EDIT
I used Hans' method to figure out which value to change. Note that his method would apply for any type of printer! The devmode
changes the value of the PrintDialog
. This took me hours and hours to solve so for whoever I can help, here's my code and I'm glad to share or help! First I was trying to change DefaultPrintTicket
from a new PrintServer()
which didn't work, but UserPrintTicket
seemed to be the right one where you can actually see the value change in WindowsControl Panel if you don't switch back to the original one. *However*, this only seemed to work on just my pc (which was necessary), on a virtual machine for example the
magic` value was already different. This was rather practice than real-life usage.
var pdialog = new PrintDialog();
pdialog.PrintQueue = new PrintQueue(new LocalPrintServer(), _printername, PrintSystemDesiredAccess.AdministratePrinter); // this will be your printer. any of these: new PrintServer().GetPrintQueues()
pdialog.PrintTicket.PageMediaSize = size;
pdialog.PrintTicket.CopyCount = _amount;
if (CheckPrinterDriverName(_printername))
{
int magic = 361;
var defaulttckt = pdialog.PrintQueue.UserPrintTicket;
pdialog.PrintQueue.UserPrintTicket = PrinterModifier.ChangeDevMode(pdialog, magic, vis);
pdialog.PrintQueue.Commit();
pdialog.PrintVisual(vis, "Label");
//Set back old settings so it's not permanently changed
pdialog.PrintQueue.UserPrintTicket = defaulttckt;
pdialog.PrintQueue.Commit();
}
...
class PrinterModifier
{
public static PrintTicket ChangeDevMode(PrintDialog pdialog, int prpty, DrawingVisual vis)
{
var queue = pdialog.PrintQueue;
var cvt = new PrintTicketConverter(queue.Name, PrintTicketConverter.MaxPrintSchemaVersion);
// Display dialog, don't make changes
var devmode1 = cvt.ConvertPrintTicketToDevMode(pdialog.PrintTicket, BaseDevModeType.UserDefault);
// Consistency check
var dmSize = BitConverter.ToInt16(devmode1, 68);
var dmDriverExtra = BitConverter.ToInt16(devmode1, 70);
if (devmode1[361] == 0)
{
devmode1[361] = 1;
}
return cvt.ConvertDevModeToPrintTicket(devmode1, PrintTicketScope.PageScope);
}
}
The value in the printdialog changes, but it still prints wrong. The changes don't apply. Any help is welcome!