长江支流说的办法保留太多了,结果不行,很多类都是他在程序集里自定义的,源码又没公开
不过还是要感谢他的提示
今天和小陈搞了一天,他在国外的论坛上看到了一篇文章得到了启示,最后我们在凌晨3点终于把自定义纸张的代码给写出来了,看来必须用API,微软的.NET对打印的支持太菜了
现公开我们工作室实现此功能的部分代码
using System; using System.Text; using System.Runtime.InteropServices; using System.Security; using System.ComponentModel; using System.Drawing.Printing;
namespace MCCustomPrintForm { /// <summary> /// 成都微创工作室(电子科技大学微创工作室) /// Tell 028-82853098 /// Email zyspipi@163.com , you680@gmail.com /// 打印机纸张的真正自定义部分代码 /// 2006-1-2 /// </summary> public class MCCustomPrintForm { // Make a static class private MCCustomPrintForm() { } [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, ref 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.Explicit, CharSet=CharSet.Unicode)] internal struct FormInfo1 { [FieldOffset(0), MarshalAs(UnmanagedType.I4)] public uint Flags; [FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)] public String pName; [FieldOffset(8)] public structSize Size; [FieldOffset(16)] public structRect ImageableArea; };
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi/* changed from 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; }
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] internal struct PRINTER_INFO_9 { public IntPtr pDevMode; }
[DllImport("winspool.Drv", EntryPoint="AddFormW", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()] internal static extern bool AddForm( IntPtr phPrinter, [MarshalAs(UnmanagedType.I4)] int level, ref FormInfo1 form);
/* This method is not used [DllImport("winspool.Drv", EntryPoint="SetForm", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=false, CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()] internal static extern bool SetForm(IntPtr phPrinter, string paperName, [MarshalAs(UnmanagedType.I4)] int level, ref FormInfo1 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("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);
[DllImport("winspool.Drv", EntryPoint="SetPrinterA", SetLastError=true, CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()] internal static extern bool SetPrinter( IntPtr hPrinter, [MarshalAs(UnmanagedType.I4)] int level, IntPtr pPrinter, [MarshalAs(UnmanagedType.I4)] int command);
/* LONG DocumentProperties( HWND hWnd, // handle to parent window HANDLE hPrinter, // handle to printer object LPTSTR pDeviceName, // device name PDEVMODE pDevModeOutput, // modified device mode PDEVMODE pDevModeInput, // original device mode DWORD fMode // mode options ); */ [DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] public static extern int DocumentProperties( IntPtr hwnd, IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] string pDeviceName /* changed from String to string */, IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode );
[DllImport("winspool.Drv", EntryPoint="GetPrinterA", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] public static extern bool GetPrinter( IntPtr hPrinter, int dwLevel /* changed type from Int32 */, IntPtr pPrinter, int dwBuf /* chagned from Int32*/, out int dwNeeded /* changed from Int32*/ );
// SendMessageTimeout tools [Flags] public enum SendMessageTimeoutFlags : uint { SMTO_NORMAL = 0x0000, SMTO_BLOCK = 0x0001, SMTO_ABORTIFHUNG = 0x0002, SMTO_NOTIMEOUTIFNOTHUNG = 0x0008 } const int WM_SETTINGCHANGE = 0x001A; const int HWND_BROADCAST = 0xffff;
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] public static extern IntPtr SendMessageTimeout( IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result ); //打印纸张长宽设置 public static void AddMC80MmPaperSizeToDefaultPrinter() { AddCustomPaperSizeToDefaultPrinter("MC 80mm * Receipt Length", 80.1f, 4003.9f); }
public static void AddMC104MmPaperSizeToDefaultPrinter() { AddCustomPaperSizeToDefaultPrinter("MC 104mm * Receipt Length", 104.1f, 4003.9f); }
/// <summary> /// Adds the printer form to the default printer /// </summary> /// <param name="paperName">Name of the printer form</param> /// <param name="widthMm">Width given in millimeters</param> /// <param name="heightMm">Height given in millimeters</param> public static void AddCustomPaperSizeToDefaultPrinter(string paperName, float widthMm, float heightMm) { PrintDocument pd = new PrintDocument(); string sPrinterName = pd.PrinterSettings.PrinterName; AddCustomPaperSize(sPrinterName, paperName, widthMm, heightMm); }
/// <summary> /// Add the printer form to a printer /// </summary> /// <param name="printerName">The printer name</param> /// <param name="paperName">Name of the printer form</param> /// <param name="widthMm">Width given in millimeters</param> /// <param name="heightMm">Height given in millimeters</param> public static void AddCustomPaperSize(string printerName, string paperName, float widthMm, float heightMm) { if (PlatformID.Win32NT == Environment.OSVersion.Platform) { // The code to add a custom paper size is different for Windows NT then it is // for previous versions of windows
const int PRINTER_ACCESS_USE = 0x00000008; const int PRINTER_ACCESS_ADMINISTER = 0x00000004; const int FORM_PRINTER = 0x00000002; structPrinterDefaults defaults = new structPrinterDefaults(); defaults.pDatatype = null; defaults.pDevMode = IntPtr.Zero; defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;
IntPtr hPrinter = IntPtr.Zero;
// Open the printer. if (OpenPrinter(printerName, out hPrinter, ref defaults)) { try { // delete the form incase it already exists DeleteForm(hPrinter, paperName); // create and initialize the FORM_INFO_1 structure FormInfo1 formInfo = new FormInfo1(); formInfo.Flags = 0; formInfo.pName = paperName; // all sizes in 1000ths of millimeters formInfo.Size.width = (int)(widthMm * 1000.0); formInfo.Size.height = (int)(heightMm * 1000.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)) { StringBuilder strBuilder = new StringBuilder(); strBuilder.AppendFormat("Failed to add the custom paper size {0} to the printer {1}, System error number: {2}", paperName, printerName, GetLastError()); throw new ApplicationException(strBuilder.ToString()); }
// INIT const int DM_OUT_BUFFER = 2; const int DM_IN_BUFFER = 8; structDevMode devMode = new structDevMode(); IntPtr hPrinterInfo, hDummy; PRINTER_INFO_9 printerInfo; printerInfo.pDevMode = IntPtr.Zero; int iPrinterInfoSize, iDummyInt;
// GET THE SIZE OF THE DEV_MODE BUFFER int iDevModeSize = DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0);
if(iDevModeSize < 0) throw new ApplicationException("Cannot get the size of the DEVMODE structure.");
// ALLOCATE THE BUFFER IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize 100);
// GET A POINTER TO THE DEV_MODE BUFFER int iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER);
if(iRet < 0) throw new ApplicationException("Cannot get the DEVMODE structure.");
// FILL THE DEV_MODE STRUCTURE devMode = (structDevMode)Marshal.PtrToStructure(hDevMode, devMode.GetType());
// SET THE FORM NAME FIELDS TO INDICATE THAT THIS FIELD WILL BE MODIFIED devMode.dmFields = 0x10000; // DM_FORMNAME // SET THE FORM NAME devMode.dmFormName = paperName;
// PUT THE DEV_MODE STRUCTURE BACK INTO THE POINTER Marshal.StructureToPtr(devMode, hDevMode, true);
// MERGE THE NEW CHAGES WITH THE OLD iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, printerInfo.pDevMode, printerInfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if(iRet < 0) throw new ApplicationException("Unable to set the orientation setting for this printer.");
// GET THE PRINTER INFO SIZE GetPrinter(hPrinter, 9, IntPtr.Zero, 0, out iPrinterInfoSize); if(iPrinterInfoSize == 0) throw new ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure");
// ALLOCATE THE BUFFER hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize 100);
// GET A POINTER TO THE PRINTER INFO BUFFER bool bSuccess = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, out iDummyInt);
if(!bSuccess) throw new ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure");
// FILL THE PRINTER INFO STRUCTURE printerInfo = (PRINTER_INFO_9)Marshal.PtrToStructure(hPrinterInfo, printerInfo.GetType()); printerInfo.pDevMode = hDevMode;
// GET A POINTER TO THE PRINTER INFO STRUCTURE Marshal.StructureToPtr(printerInfo, hPrinterInfo, true);
// SET THE PRINTER SETTINGS bSuccess = SetPrinter(hPrinter, 9, hPrinterInfo, 0);
if(!bSuccess) throw new Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed. Couldn't set the printer settings");
// Tell all open programs that this change occurred. SendMessageTimeout( new IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, MCCustomPrintForm.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out hDummy); } finally { ClosePrinter(hPrinter); } } else { StringBuilder strBuilder = new StringBuilder(); strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}", printerName, GetLastError()); throw new ApplicationException(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)(widthMm * 1000.0); pDevMode.dmPaperLength = (short)(heightMm * 1000.0); ResetDC(hDC, ref pDevMode); DeleteDC(hDC); } } } } }
本文由来源 21aspnet,由 javajgs_com 整理编辑,其版权均为 21aspnet 所有,文章内容系作者个人观点,不代表 Java架构师必看 对观点赞同或支持。如需转载,请注明文章来源。