我有多台打印机,其中包含“旋转180度”复选框,如下所示:
这是另一个(“倪”的意思是“不”):
有没有办法以编程方式设置此值,并更改PrintTicket
?如果没有,我怎样才能得到它的当前值?对于我的软件,我需要知道是否已设置,如果已设置,则需要更改,如果可能的话。对于我的软件来说,如果我不需要打开printdialog就是最好的,它是一个软件,用户可以直接打印而无需点击任何按钮,因此设置或获取它是我正在寻找的。
我一直在使用ManagementObjectSearcher
并在普通的PrintDocument.DefaultPageSettings
属性中搜索但找不到任何内容!
如果未设置此选项,我会自动为用户临时设置它(否则它将使用我的特定打印机进行颠倒打印)。我一直在努力为用户设置它,但我无法弄清楚如何让它工作。我一直在查看DEVMODE
结构并尝试实现它,但它也没有“旋转180度选项”或类似的东西。
注意:我不打算设置风景模式。这很简单,也有所不同。
我尝试过以下操作:
pdialog.PrintQueue.CurrentJobSettings.CurrentPrintTicket.PageOrientation = PageOrientation.ReversePortrait;
但是,这只会反转页面方向而不是内容(内容也需要旋转)。
如果我旋转我正在打印的视觉效果,则边距不再正确,因此也不起作用!希望有人能提供帮助。
提前致谢。
修改
我使用Hans的方法来确定要改变的值。请注意,他的方法适用于任何类型的打印机! devmode
更改了PrintDialog
的值。这花了我几个小时来解决,所以对于我可以帮助的人,这是我的代码,我很高兴分享或帮助!首先,我尝试从DefaultPrintTicket
更改new PrintServer()
,但UserPrintTicket
似乎是正确的,您可以在其中实际看到Windows {{1}中的值更改魔术价值已经不同了。这比实际使用更具实践性。
Control 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
...
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();
}
printdialog中的值发生了变化,但仍然打印错误。这些更改不适用。欢迎任何帮助!
答案 0 :(得分:7)
这可能有助于实现这个属性的异常程度。有趣的真实故事是关于Pete Conrad的介绍,Pete Conrad是由NASA为双子座太空计划招募的宇航员。由于没有真正了解长期太空飞行如何影响人类,医生们基本上将他们暴露在他们能想到的任何事物中。经常非常干扰和不舒服的测试。康拉德反叛并失败了一次心理测验。医生递给他一张空白卡片,问“你看到了什么?”他立即将它推回去,并说“这是颠倒的”。
这台打印机很不寻常,总是值得担心。也许设计用于在包括某种自动纸张装订操作的生产线上操作。打印机驱动程序可以随意添加属性来自定义它们的行为,这就是一个这样的属性。您正在查看的属性表同样是非标准的,它来自打印机驱动程序。
要了解如何更改此设置,首先需要了解the DEVMODE structure。关于winapi中使用的最丑陋的结构。它是一个可变大小的结构,您在MSDN页面中看到的声明仅涵盖标准属性。打印机驱动程序可以任意扩展它,dmDriverExtra
字段跟踪添加了多少额外字节。 dmSize
字段报告结构的非变量部分的大小,在Windows版本6(Vista及更高版本)上为220。你需要检查的东西。
Winforms直接使用PrinterSettings.GetHdevmode()方法公开DEVMODE。 WPF通过PrintTicket类抽象出来。您必须使用PrintTicketConverter class从PrintTicket转换为DEVMODE并返回。
逆向工程所需的是存储此设置的专用驱动程序数据中的确切字段。只有打印机制造商知道这个细节,他们才会接听您的电话。一些示例代码可帮助您发现并验证该字段,只需在MainWindow构造函数中的无操作WPF应用程序中尝试:
using System.Printing; // Add reference to System.Printing
using System.Printing.Interop; // Add reference to ReachFramework
using System.Diagnostics;
....
public MainWindow() {
InitializeComponent();
// Assume default printer
var queue = new LocalPrintServer().DefaultPrintQueue;
var cvt = new PrintTicketConverter(queue.Name, PrintTicketConverter.MaxPrintSchemaVersion);
// Display dialog, don't make changes
var dlg = new PrintDialog();
dlg.ShowDialog();
var devmode1 = cvt.ConvertPrintTicketToDevMode(dlg.PrintTicket, BaseDevModeType.UserDefault);
// Consistency check
var dmSize = BitConverter.ToInt16(devmode1, 68);
var dmDriverExtra = BitConverter.ToInt16(devmode1, 70);
Debug.Assert(dmSize == 220);
Debug.Assert(dmDriverExtra > 0);
Debug.Assert(dmSize + dmDriverExtra == devmode1.Length);
// Display dialog again, do make the change
dlg.ShowDialog();
var devmode2 = cvt.ConvertPrintTicketToDevMode(dlg.PrintTicket, BaseDevModeType.UserDefault);
var len = Math.Min(devmode1.Length, devmode2.Length);
for (int ix = 0; ix < len; ++ix) {
if (devmode1[ix] != devmode2[ix]) {
Debug.Print("Change at {0} from {1} to {2}", ix, devmode1[ix], devmode2[ix]);
}
}
// Tinker with the DEVMODE...
var magic = dmSize + 0; // Change this
Debug.Assert(magic < dmSize + dmDriverExtra);
devmode1[magic] = devmode2[magic];
dlg.PrintTicket = cvt.ConvertDevModeToPrintTicket(devmode1);
// Verify that the setting changed!
dlg.ShowDialog();
}
}
请注意,您可能会看到许多字节更改。最有可能的猜测是你正在寻找一个从0变为1的调试。调试&gt; Windows&gt;记忆&gt; Memory1窗口可用于过滤字符串产生的噪音,将“devmode2”放在地址字段中。
预期结果是您现在知道如何自定义PrintTicket。请注意,它非常特定于该打印机,并且可以通过驱动程序更新进行更改。因此,您可以考虑以最合乎逻辑的方式执行此操作,使用LayoutTransform property旋转要打印的视觉效果。
答案 1 :(得分:1)
试试这个。 “LandscapeAngle”将返回打印对话框控件中设置的方向。
PrintDialog.PrinterSettings.LandscapeAngle
价: https://msdn.microsoft.com/en-us/library/system.drawing.printing.printersettings(v=vs.110).aspx
答案 2 :(得分:-1)
您是否尝试过Print Spooler API?
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162863(v=vs.85).aspx
Pinvoke.net显示了在C#中使用dll调用的C#语法。
在C#中打开对话框的示例: