用api函数添加自定义纸张,能成功添加,却获取不到,求救!
//具体的问题在代码的注释上,用红字标出using System;
using System.Text;
using System.Runtime;
using System.Security;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ClientCommon.CustomControls
{
/// <summary>
/// 添加自定义纸张
/// </summary>
public class DBPaperSize
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct structPrinterDefaults
{
[MarshalAs(UnmanagedType.LPTStr)]
public String pDatatype;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.I4)]
public int DesiredAccess;
};
[DllImport("winspool.Drv", EntryPoint = "OpenPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)]
string printerName, out IntPtr phPrinter, structPrinterDefaults pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool ClosePrinter(IntPtr phPrinter);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct structSize
{
public Int32 width;
public Int32 height;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct structRect
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct structFormInfo1
{
[MarshalAs(UnmanagedType.I4)]
public int Flags;
[MarshalAs(UnmanagedType.LPTStr)]
public String pName;
public structSize Size;
public structRect ImageableArea;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct structDevMode
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public String dmDeviceName;
[MarshalAs(UnmanagedType.U2)]
public short dmSpecVersion;
[MarshalAs(UnmanagedType.U2)]
public short dmDriverVersion;
[MarshalAs(UnmanagedType.U2)]
public short dmSize;
[MarshalAs(UnmanagedType.U2)]
public short dmDriverExtra;
[MarshalAs(UnmanagedType.U4)]
public int dmFields;
[MarshalAs(UnmanagedType.I2)]
public short dmOrientation;
[MarshalAs(UnmanagedType.I2)]
public short dmPaperSize;
[MarshalAs(UnmanagedType.I2)]
public short dmPaperLength;
[MarshalAs(UnmanagedType.I2)]
public short dmPaperWidth;
[MarshalAs(UnmanagedType.I2)]
public short dmScale;
[MarshalAs(UnmanagedType.I2)]
public short dmCopies;
[MarshalAs(UnmanagedType.I2)]
public short dmDefaultSource;
[MarshalAs(UnmanagedType.I2)]
public short dmPrintQuality;
[MarshalAs(UnmanagedType.I2)]
public short dmColor;
[MarshalAs(UnmanagedType.I2)]
public short dmDuplex;
[MarshalAs(UnmanagedType.I2)]
public short dmYResolution;
[MarshalAs(UnmanagedType.I2)]
public short dmTTOption;
[MarshalAs(UnmanagedType.I2)]
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public String dmFormName;
[MarshalAs(UnmanagedType.U2)]
public short dmLogPixels;
[MarshalAs(UnmanagedType.U4)]
public int dmBitsPerPel;
[MarshalAs(UnmanagedType.U4)]
public int dmPelsWidth;
[MarshalAs(UnmanagedType.U4)]
public int dmPelsHeight;
[MarshalAs(UnmanagedType.U4)]
public int dmNup;
[MarshalAs(UnmanagedType.U4)]
public int dmDisplayFrequency;
[MarshalAs(UnmanagedType.U4)]
public int dmICMMethod;
[MarshalAs(UnmanagedType.U4)]
public int dmICMIntent;
[MarshalAs(UnmanagedType.U4)]
public int dmMediaType;
[MarshalAs(UnmanagedType.U4)]
public int dmDitherType;
[MarshalAs(UnmanagedType.U4)]
public int dmReserved1;
[MarshalAs(UnmanagedType.U4)]
public int dmReserved2;
}
[DllImport("winspool.Drv", EntryPoint = "AddForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern int AddForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.I4)] int level, ref structFormInfo1 form);
[DllImport("winspool.Drv", EntryPoint = "DeleteForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool DeleteForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.LPTStr)] string pName);
[DllImport("winspool.Drv", EntryPoint = "SetForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool SetForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.LPTStr)] string pName, [MarshalAs(UnmanagedType.I4)] int level, ref structFormInfo1 form);
[DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern Int32 GetLastError();
[DllImport("GDI32.dll", EntryPoint = "CreateDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPTStr)]string pDrive, [MarshalAs(UnmanagedType.LPTStr)] string pName, [MarshalAs(UnmanagedType.LPTStr)] string pOutput, ref structDevMode pDevMode);
[DllImport("GDI32.dll", EntryPoint = "ResetDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern IntPtr ResetDC(IntPtr hDC, ref structDevMode pDevMode);
[DllImport("GDI32.dll", EntryPoint = "DeleteDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool DeleteDC(IntPtr hDC);
public System.Drawing.Printing.PaperSize GetPrintForm(string printerName, string 易做图Name)
{
System.Drawing.Printing.PaperSize 易做图 = null;
System.Drawing.Printing.PrinterSettings printer = new System.Drawing.Printing.PrinterSettings();
printer.PrinterName = printerName;
foreach (System.Drawing.Printing.PaperSize ps in printer.PaperSizes)
{
if (ps.PaperName.ToLower() == 易做图Name.ToLower())
{
易做图 = ps;
break;
}
}
return 易做图;
}
--------------------编程问答-------------------- /// <summary>
/// 设置打印的纸张为指定名称的自定义纸张
/// </summary>
/// <param name="printerName">打印机名称</param>
/// <param name="易做图Name">纸张名称</param>
/// <param name="width">纸张宽度</param>
/// <param name="height">纸张高度</param>
public void SetPrintForm(string printerName, string 易做图Name, float width, float height)
{
if (PlatformID.Win32NT == Environment.OSVersion.Platform)
{
const int PRINTER_ACCESS_USE = 0x00000008;
const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
const int STANDARD_RIGHTS_REQUIRED = 0xf0000;
const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
structPrinterDefaults defaults = new structPrinterDefaults();
defaults.pDatatype = null;
defaults.pDevMode = IntPtr.Zero;
defaults.DesiredAccess = PRINTER_ALL_ACCESS;
IntPtr hPrinter = IntPtr.Zero;
if (OpenPrinter(printerName, out hPrinter, defaults))
{
try
{
structFormInfo1 formInfo = new structFormInfo1();
formInfo.Flags = 0;
formInfo.pName = 易做图Name;
formInfo.Size.width = (int)(width * 100.0);
formInfo.Size.height = (int)(height * 100.0);
formInfo.ImageableArea.left = 0;
formInfo.ImageableArea.right = formInfo.Size.width;
formInfo.ImageableArea.top = 0;
formInfo.ImageableArea.bottom = formInfo.Size.height;
bool rslt = false;
if (GetPrintForm(printerName, 易做图Name) != null)
{
//如果手工添加的自定义纸张经过此函数设置后,原来能获取的现在也获取不到了 ????
rslt = SetForm(hPrinter, 易做图Name, 1, ref formInfo);
}
else
{
this.AddCustomPaperSize(printerName, 易做图Name, width, height);
rslt = true;
}
if (!rslt)
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.AppendFormat("添加纸张{0}时发生错误!, 系统错误号: {1}", 易做图Name, GetLastError());
BaseClass.MessageError.OnlyShowErrorMessage.Show(strBuilder.ToString());
}
}
finally
{
ClosePrinter(hPrinter);
}
}
}
}
/// <summary>
/// 为打印机添加自定义纸张
/// </summary>
/// <param name="printerName">打印机名称</param>
/// <param name="易做图Name">自定义纸张名称</param>
/// <param name="width">纸张宽度</param>
/// <param name="height">纸张高度</param>
public void AddCustomPaperSize(string printerName, string 易做图Name, float width, float height)
{
if (PlatformID.Win32NT == Environment.OSVersion.Platform)
{
const int PRINTER_ACCESS_USE = 0x00000008;
const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
structPrinterDefaults defaults = new structPrinterDefaults();
defaults.pDatatype = null;
defaults.pDevMode = IntPtr.Zero;
defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;
IntPtr hPrinter = IntPtr.Zero;
if (OpenPrinter(printerName, out hPrinter, defaults))
{
try
{
DeleteForm(hPrinter, 易做图Name);
structFormInfo1 formInfo = new structFormInfo1();
formInfo.Flags = 0;
formInfo.pName = 易做图Name;
formInfo.Size.width = (int)(width * 100.0);
formInfo.Size.height = (int)(height * 100.0);
formInfo.ImageableArea.left = 0;
formInfo.ImageableArea.right = formInfo.Size.width;
formInfo.ImageableArea.top = 0;
formInfo.ImageableArea.bottom = formInfo.Size.height;
if (AddForm(hPrinter, 1, ref formInfo) == 0)
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.AppendFormat("添加纸张{0}时发生错误!,系统错误号:{1}", 易做图Name, GetLastError());
BaseClass.MessageError.OnlyShowErrorMessage.Show(strBuilder.ToString());
}
}
finally
{
ClosePrinter(hPrinter);
}
}
else
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.AppendFormat("打开打印机{0}时出现异常!,系统错误号:{1}", printerName, GetLastError());
BaseClass.MessageError.OnlyShowErrorMessage.Show(strBuilder.ToString());
}
}
else
{
structDevMode pDevMode = new structDevMode();
IntPtr hDC = CreateDC(null, printerName, null, ref pDevMode);
if (hDC != IntPtr.Zero)
{
const long DM_PAPERSIZE = 0x00000002L;
const long DM_PAPERLENGTH = 0x00000004L;
const long DM_PAPERWIDTH = 0x00000008L;
pDevMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);
pDevMode.dmPaperSize = 256;
pDevMode.dmPaperWidth = (short)(width * 2.54 * 10000.0);
pDevMode.dmPaperLength = (short)(height * 2.54 * 10000.0);
ResetDC(hDC, ref pDevMode);
DeleteDC(hDC);
}
}
}
}
}
调用 :
DBPaperSize myDBPaperSize = new DBPaperSize();
myDBPaperSize = new DBPaperSize();
myDBPaperSize.SetPrintForm(printDocument1.PrinterSettings.DefaultPageSettings.PrinterSettings.PrinterName,
"测试", 1400, 750);
//执行到这儿,在打印服务器属性中能看到这个新增的自定义纸张,但是在下面的函数中却获取不到。
//如果在打印服务器属性中手工加自定义纸张的话,是能获取的,所以怀疑程序添加自定义纸张哪里有问题,请各位大虾指教
//????
printDocument1.DefaultPageSettings.PaperSize = myDBPaperSize.GetPrintForm(printDocument1.PrinterSettings.DefaultPageSettings.PrinterSettings.PrinterName,
"测试");
--------------------编程问答-------------------- 代码的关键部分没啥问题,如果PaperSize没在PrinterSettings.PaperSizes出现的话,说明该打印机不支持该定义的纸张大小(长宽和边距,不在该打印机支持的泛围内)
你可以通过打印机文件夹中选定的打印首选项,看它是否支持你定义的纸张,如果列表中没有出现,说明不支持
--------------------编程问答-------------------- 同样的纸张大小如果在打印服务器属性中手工加自定义纸张的话,是能获取的,我怀疑是不是有什么权限或者其他什么问题 --------------------编程问答-------------------- --------------------编程问答-------------------- 跟踪一下GetPrintForm方法的返回值,只要不是返回null问题就不大
你这个方法其实多余
正式设置打印页面时,还得从PrintDocument.PrinterSettings.PaperSizes中去取,否则还是容易出现设定不过去(A4之类的没问题,自定义的就是这种样) --------------------编程问答-------------------- jointan能不能给俺一段参考代码?我的QQ是149302885,能否在线讨论 --------------------编程问答-------------------- 难道就没有真正的高手帮俺看一下吗
补充:.NET技术 , C#