[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct structSize
{
public Int32 width;
public Int32 height;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct structRect
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct structFormInfo
{
[MarshalAs(UnmanagedType.I4)]
public int Flags;
[MarshalAs(UnmanagedType.LPTStr)]
public String pName;
public structSize Size;
public structRect ImageableArea;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private 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;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private 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()]
private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)] string printerName, out IntPtr phPrinter, ref structPrinterDefaults pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
private static extern bool ClosePrinter(IntPtr phPrinter);
[DllImport("winspool.Drv", EntryPoint = "AddForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
private static extern bool AddForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.I4)] int level, ref structFormInfo form);
[DllImport("winspool.Drv", EntryPoint = "DeleteForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
private 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()]
private static extern bool SetForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.LPTStr)] string pName, [MarshalAs(UnmanagedType.I4)] int level, ref structFormInfo form);
[DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
private static extern Int32 GetLastError();
[DllImport("GDI32.dll", EntryPoint = "CreateDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
private 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()]
private 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()]
private static extern bool DeleteDC(IntPtr hDC);
public static void SetPrintForm(string printerName, string paperName, float width, float height)
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
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, ref defaults))
{
try
{
structFormInfo formInfo = new structFormInfo();
formInfo.Flags = 0;
formInfo.pName = paperName;
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 result = false;
short i = -1;
if (GetPrintForm(printerName, paperName, out i) != null)
{
result = SetForm(hPrinter, paperName, 1, ref formInfo);
}
else
{
AddCustomPaperSize(printerName, paperName, width, height);
result = true;
}
if (!result)
{
throw new Exception(string.Format("添加纸张“{0}”时发生错误,系统错误信息:{1}", paperName, GetLastError()));
}
}
catch (Exception ex)
{
throw new Exception(string.Format("添加纸张“{0}”时发生错误", paperName, GetLastError()), ex);
}
finally
{
ClosePrinter(hPrinter);
}
}
}
}
public static PaperSize GetPrintForm(string printerName, string paperName, out short id)
{
short i = 0;
id = -1;
System.Drawing.Printing.PrinterSettings printerSettings = new System.Drawing.Printing.PrinterSettings();
printerSettings.PrinterName = printerName;
foreach (System.Drawing.Printing.PaperSize ps in printerSettings.PaperSizes)
{
i++;
if (ps.PaperName.ToLower() == paperName.ToLower())
{
id = i;
return ps;
}
}
return null;
}
public static void AddCustomPaperSize(string printerName, string paperName, float width, float height)
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
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, ref defaults))
{
try
{
DeleteForm(hPrinter, paperName);
structFormInfo formInfo = new structFormInfo();
formInfo.Flags = 0;
formInfo.pName = paperName;
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))
{
throw new Exception(string.Format("添加纸张“{0}”时发生错误,系统错误信息:{1}", paperName, GetLastError()));
}
}
catch (Exception ex)
{
throw new Exception(string.Format("添加纸张“{0}”时发生错误", paperName, GetLastError()), ex);
}
finally
{
ClosePrinter(hPrinter);
}
}
else
{
throw new Exception(string.Format("打开打印机“{0}”时发生错误,系统错误信息:{1}", printerName, GetLastError()));
}
}
else
{
structDevMode devMode = new structDevMode();
IntPtr hDC = CreateDC(null, printerName, null, ref devMode);
if (hDC != IntPtr.Zero)
{
const long DM_PAPERSIZE = 0x00000002L;
const long DM_PAPERLENGTH = 0x00000004L;
const long DM_PAPERWIDTH = 0x00000008L;
devMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);
devMode.dmPaperSize = 256;
devMode.dmPaperWidth = (short)(width * 2.54 * 10000.0);
devMode.dmPaperLength = (short)(height * 2.54 * 10000.0);
ResetDC(hDC, ref devMode);
DeleteDC(hDC);
}
}
}
C# 实现打印机新增自定义页面大小
最新推荐文章于 2023-05-08 15:33:44 发布