前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >打印自定义纸张大小

打印自定义纸张大小

作者头像
Java架构师必看
发布2021-03-22 11:21:47
7240
发布2021-03-22 11:21:47
举报
文章被收录于专栏:Java架构师必看

长江支流说的办法保留太多了,结果不行,很多类都是他在程序集里自定义的,源码又没公开

不过还是要感谢他的提示

   今天和小陈搞了一天,他在国外的论坛上看到了一篇文章得到了启示,最后我们在凌晨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架构师必看 对观点赞同或支持。如需转载,请注明文章来源。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档