无法更改打印机的DEVMODE [英] Can't change DEVMODE of a printer

查看:121
本文介绍了无法更改打印机的DEVMODE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为当前的打印任务更改打印机的DEVMODE,以通过标准和特定于设备的设置.我执行以下操作:

I need to change DEVMODE of printer for current printing task to pass standard and device-specific settings. I do the following:

PrintDocument d = new PrintDocument();
d.PrinterSettings.PrinterName = "Microsoft XPS Document Writer"; // example printer name           
byte[] devmode_data; // contains a valid value that is obtained from registry
IntPtr devmode = IntPtr.Zero;
GCHandle handle = GCHandle.Alloc(devmode_data, GCHandleType.Pinned);
try
{
    devmode = handle.AddrOfPinnedObject();
    if (devmode != IntPtr.Zero) d.PrinterSettings.SetHdevmode(devmode);
}
finally
{
    if (handle.IsAllocated) handle.Free();
}

当我尝试使用NullReferenceException执行PrinterSettings.SetHdevmode并且没有任何有意义的错误信息时,它将失败. d.PrinterSettings不为null,在PrinterSettings.SetHdevmode方法内部引发异常.
所以我的问题是:怎么了? byte[]IntPtr投放错误吗?也许SetHdevmode期望的不是byte[]数组?

It fails when I attempt to execute PrinterSettings.SetHdevmode with a NullReferenceException and without any meaningful error info. d.PrinterSettings is not null, the exception is thrown inside of PrinterSettings.SetHdevmode method.
So my question is: what is wrong? Is the byte[] to IntPtr cast wrong? Maybe SetHdevmode expects something other than a byte[] array?

我从注册表中获得了byte[] devmode_data数组.这是一个有效值,并且与当前打印机设置中使用的值相同.

I get the byte[] devmode_data array from the registry. It is a valid value and it is same value that is used in current printer settings.

推荐答案

SetHdevmode需要HGLOBAL.您可以通过Marshal.AllocHGlobal从.Net获取HGLOBAL.然后,您可以使用Marshal.Copy(byte[], int, IntPtr, int)从托管字节数组复制到HGLOBAL.见下文:

SetHdevmode expects an HGLOBAL. You can get an HGLOBAL from .Net via Marshal.AllocHGlobal. Then, you can use Marshal.Copy(byte[], int, IntPtr, int) to copy from your managed byte array to the HGLOBAL. See below:

var pDevMode = Marshal.AllocHGlobal(devmode_data.Length);
Marshal.Copy(devmode_data, 0, pDevMode, devmode_data.Length);

d.PrinterSettings.SetHdevmode(pDevMode);
Marshal.FreeHGlobal(pDevMode);

字节数组可以部分地作为结构来处理,但这需要 p/调用定义.但是,PrinterSettings类将不接受结构,因此在这种情况下将不需要这样做.另外,DEVMODE结构的长度可变,以允许打印机驱动程序添加其他不透明数据,因此转换时不会丢失数据.

The byte array can be partially handled as a structure, but that will require p/Invoke definitions. The PrinterSettings class, however, will not accept a structure, so doing so would be unneeded in this case. Additionally, the DEVMODE structure is variable length to allow for printer drivers to add additional opaque data, so it would not be possible to convert without data loss.

请参见如何保存和恢复`PrinterSettings`?更多.

这篇关于无法更改打印机的DEVMODE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆