The print class instance code implemented by API in C

  • 2020-05-19 05:33:24
  • OfStack


 using System;
using System.Collections;
using System.Text;
using System.Runtime.InteropServices; 
using System.Security; 
using System.ComponentModel; 
using System.Drawing.Printing; 
namespace PrinterAPI
{
 public class Printer 
 { 
  private Printer() 
  { 

  } 
 /// Clay figurine zhang version enhanced version 
  #region API The statement  

  [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)] 
   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); 

  [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); 

  [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true, 
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
  internal static extern int DocumentProperties( 
   IntPtr hwnd, 
   IntPtr hPrinter, 
   [MarshalAs(UnmanagedType.LPStr)] string pDeviceName, 
   IntPtr pDevModeOutput, 
   IntPtr pDevModeInput, 
   int fMode 
   ); 

  [DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true, 
    ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
  internal static extern bool GetPrinter( 
   IntPtr hPrinter, 
   int dwLevel, 
   IntPtr pPrinter, 
   int dwBuf, 
   out int dwNeeded 
   ); 

  [Flags] 
   internal 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)] 
  internal static extern IntPtr SendMessageTimeout( 
   IntPtr windowHandle, 
   uint Msg, 
   IntPtr wParam, 
   IntPtr lParam, 
   SendMessageTimeoutFlags flags, 
   uint timeout, 
   out IntPtr result 
   ); 

  //EnumPrinters The function and the structure that you're using  
  [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] 
  private static extern bool EnumPrinters(PrinterEnumFlags Flags, string Name, uint Level, 
   IntPtr pPrinterEnum, uint cbBuf, 
   ref uint pcbNeeded, ref uint pcReturned); 

  [StructLayout(LayoutKind.Sequential)] 
   internal struct PRINTER_INFO_2 
  { 
   public string pServerName; 
   public string pPrinterName; 
   public string pShareName; 
   public string pPortName; 
   public string pDriverName; 
   public string pComment; 
   public string pLocation; 
   public IntPtr pDevMode; 
   public string pSepFile; 
   public string pPrintProcessor; 
   public string pDatatype; 
   public string pParameters; 
   public IntPtr pSecurityDescriptor; 
   public uint Attributes; 
   public uint Priority; 
   public uint DefaultPriority; 
   public uint StartTime; 
   public uint UntilTime; 
   public uint Status; 
   public uint cJobs; 
   public uint AveragePPM; 
  } 

  [FlagsAttribute] 
   internal enum PrinterEnumFlags 
  { 
   PRINTER_ENUM_DEFAULT = 0x00000001, 
   PRINTER_ENUM_LOCAL = 0x00000002, 
   PRINTER_ENUM_CONNECTIONS = 0x00000004, 
   PRINTER_ENUM_FAVORITE = 0x00000004, 
   PRINTER_ENUM_NAME = 0x00000008, 
   PRINTER_ENUM_REMOTE = 0x00000010, 
   PRINTER_ENUM_SHARED = 0x00000020, 
   PRINTER_ENUM_NETWORK = 0x00000040, 
   PRINTER_ENUM_EXPAND = 0x00004000, 
   PRINTER_ENUM_CONTAINER = 0x00008000, 
   PRINTER_ENUM_ICONMASK = 0x00ff0000, 
   PRINTER_ENUM_ICON1 = 0x00010000, 
   PRINTER_ENUM_ICON2 = 0x00020000, 
   PRINTER_ENUM_ICON3 = 0x00040000, 
   PRINTER_ENUM_ICON4 = 0x00080000, 
   PRINTER_ENUM_ICON5 = 0x00100000, 
   PRINTER_ENUM_ICON6 = 0x00200000, 
   PRINTER_ENUM_ICON7 = 0x00400000, 
   PRINTER_ENUM_ICON8 = 0x00800000, 
   PRINTER_ENUM_HIDE = 0x01000000 
  } 

  // Printer status  
  [FlagsAttribute] 
   internal enum PrinterStatus 
  { 
   PRINTER_STATUS_BUSY                 =       0x00000200, 
   PRINTER_STATUS_DOOR_OPEN            =       0x00400000, 
   PRINTER_STATUS_ERROR                =       0x00000002, 
   PRINTER_STATUS_INITIALIZING         =       0x00008000, 
   PRINTER_STATUS_IO_ACTIVE            =       0x00000100, 
   PRINTER_STATUS_MANUAL_FEED          =       0x00000020, 
   PRINTER_STATUS_NO_TONER             =       0x00040000, 
   PRINTER_STATUS_NOT_AVAILABLE        =       0x00001000, 
   PRINTER_STATUS_OFFLINE              =       0x00000080, 
   PRINTER_STATUS_OUT_OF_MEMORY        =       0x00200000, 
   PRINTER_STATUS_OUTPUT_BIN_FULL      =       0x00000800, 
   PRINTER_STATUS_PAGE_PUNT            =       0x00080000, 
   PRINTER_STATUS_PAPER_JAM            =       0x00000008, 
   PRINTER_STATUS_PAPER_OUT            =       0x00000010, 
   PRINTER_STATUS_PAPER_PROBLEM        =       0x00000040, 
   PRINTER_STATUS_PAUSED               =       0x00000001, 
   PRINTER_STATUS_PENDING_DELETION     =       0x00000004, 
   PRINTER_STATUS_PRINTING             =       0x00000400, 
   PRINTER_STATUS_PROCESSING           =       0x00004000, 
   PRINTER_STATUS_TONER_LOW            =       0x00020000, 
   PRINTER_STATUS_USER_INTERVENTION    =       0x00100000, 
   PRINTER_STATUS_WAITING              =       0x20000000, 
   PRINTER_STATUS_WARMING_UP           =       0x00010000 
  } 

  //GetDefaultPrinter Use of API Function description  
  [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] 
  internal static extern bool GetDefaultPrinter(StringBuilder pszBuffer, ref int size); 

  //SetDefaultPrinter Use of API Function declaration  
  [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] 
  internal static extern bool SetDefaultPrinter(string Name); 

  //EnumFormsA The function declaration used should be sum EnumPrinters similar  
  [DllImport("winspool.drv", EntryPoint = "EnumForms")] 
  internal static extern int EnumFormsA(IntPtr hPrinter, int Level, ref byte pForm, int cbBuf, ref int pcbNeeded, ref int pcReturned);
 
  #endregion   API The statement 
  internal static int GetPrinterStatusInt(string PrinterName) 
  { 
   int intRet = 0; 
   IntPtr hPrinter; 
   structPrinterDefaults defaults = new structPrinterDefaults(); 

   if (OpenPrinter(PrinterName, out hPrinter, ref defaults)) 
   { 
    int cbNeeded = 0; 
    bool bolRet = GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out cbNeeded); 
    if (cbNeeded > 0) 
    { 
     IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded); 
     bolRet = GetPrinter(hPrinter, 2, pAddr, cbNeeded, out cbNeeded); 
     if (bolRet) 
     { 
      PRINTER_INFO_2 Info2 = new PRINTER_INFO_2(); 

      Info2 = (PRINTER_INFO_2)Marshal.PtrToStructure(pAddr, typeof(PRINTER_INFO_2)); 

      intRet = System.Convert.ToInt32(Info2.Status); 
     } 
     Marshal.FreeHGlobal(pAddr); 
    } 
    ClosePrinter(hPrinter); 
   } 

   return intRet; 
  } 

  internal static PRINTER_INFO_2[] EnumPrintersByFlag(PrinterEnumFlags Flags) 
  { 
   uint cbNeeded = 0; 
   uint cReturned = 0; 
   bool ret = EnumPrinters( PrinterEnumFlags.PRINTER_ENUM_LOCAL, null, 2, IntPtr.Zero, 0, ref cbNeeded, ref cReturned); 

   IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded); 
   ret = EnumPrinters(PrinterEnumFlags.PRINTER_ENUM_LOCAL, null, 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned); 

   if (ret) 
   { 
    PRINTER_INFO_2[] Info2 = new PRINTER_INFO_2[cReturned]; 

    int offset = pAddr.ToInt32(); 

    for (int i = 0; i < cReturned; i++) 
    { 
     Info2[i].pServerName = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pPrinterName = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pShareName = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pPortName = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pDriverName = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pComment = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pLocation = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pDevMode = Marshal.ReadIntPtr(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].pSepFile = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pPrintProcessor = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pDatatype = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pParameters = Marshal.PtrToStringAuto(Marshal.ReadIntPtr(new IntPtr(offset))); 
     offset += 4; 
     Info2[i].pSecurityDescriptor = Marshal.ReadIntPtr(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].Attributes = (uint )Marshal.ReadIntPtr(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].Priority = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].DefaultPriority = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].StartTime = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].UntilTime = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].Status = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].cJobs = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 
     Info2[i].AveragePPM = (uint)Marshal.ReadInt32(new IntPtr(offset)); 
     offset += 4; 

    } 

    Marshal.FreeHGlobal(pAddr); 

    return Info2; 

   } 
   else 
   { 
    return new PRINTER_INFO_2[0]; 
   }
  }
  #region  Gets the current state of the specified printer 
  /// </summary> 
  ///  Gets the current state of the specified printer  
  /// </summary> 
  /// <param name="PrinterName"> Printer name </param> 
  /// <returns> Printer status description </returns> 

  public static string GetPrinterStatus(string PrinterName) 
  { 
   int intValue = GetPrinterStatusInt(PrinterName); 
   string strRet = string.Empty; 
   switch (intValue) 
   { 
    case 0: 
     strRet = " Ready to go ( Ready ) "; 
     break; 
    case 0x00000200: 
     strRet = " busy (Busy ) "; 
     break; 
    case 0x00400000: 
     strRet = " The door was opened ( Printer Door Open ) "; 
     break; 
    case 0x00000002: 
     strRet = " error (Printer Error ) "; 
     break; 
    case 0x0008000: 
     strRet = " initializing (Initializing ) "; 
     break; 
    case 0x00000100: 
     strRet = " Input or output ( I/O Active ) "; 
     break; 
    case 0x00000020: 
     strRet = " Hand-fed paper ( Manual Feed ) "; 
     break; 
    case 0x00040000: 
     strRet = " No toner ( No Toner ) "; 
     break; 
    case 0x00001000: 
     strRet = " Is not available, Not Available ) "; 
     break; 
    case 0x00000080: 
     strRet = " Offline ( Off Line ) "; 
     break; 
    case 0x00200000: 
     strRet = " Memory overflow ( Out of Memory ) "; 
     break; 
    case 0x00000800: 
     strRet = " Outlet full ( Output Bin Full ) "; 
     break; 
    case 0x00080000: 
     strRet = " Current page cannot be printed ( Page Punt ) "; 
     break; 
    case 0x00000008: 
     strRet = " Paper ( Paper Jam ) "; 
     break; 
    case 0x00000010: 
     strRet = " Run out of printing paper ( Paper Out ) "; 
     break; 
    case 0x00000040: 
     strRet = " Paper problem ( Page Problem ) "; 
     break; 
    case 0x00000001: 
     strRet = " Pause, Paused ) "; 
     break; 
    case 0x00000004: 
     strRet = " Deleting ( Pending Deletion ) "; 
     break; 
    case 0x00000400: 
     strRet = " Printing ( Printing ) "; 
     break; 
    case 0x00004000: 
     strRet = " In process ( Processing ) "; 
     break; 
    case 0x00020000: 
     strRet = " Insufficient toner ( Toner Low ) "; 
     break; 
    case 0x00100000: 
     strRet = " User intervention is required ( User Intervention ) "; 
     break; 
    case 0x20000000: 
     strRet = " Waiting for, Waiting ) "; 
     break; 
    case 0x00010000: 
     strRet = " Preparing ( Warming Up ) "; 
     break; 
    default: 
     strRet = " Unknown state ( Unknown Status ) "; 
     break; 
   } 
   return strRet;
  }
  #endregion  Gets the current state of the specified printer 
  #region  Delete existing custom paper 
  /**/
  /// <summary> 
  ///  Delete existing custom paper  
  /// </summary> 
  /// <param name="PrinterName"> Printer name </param> 
  /// <param name="PaperName"> The paper name </param> 
  public static void DeleteCustomPaperSize(string PrinterName, string PaperName) 
  { 
   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; 

   // Turn on the printer  
   if (OpenPrinter(PrinterName, out hPrinter, ref defaults)) 
   { 
    try 
    { 
     DeleteForm(hPrinter, PaperName); 
     ClosePrinter(hPrinter); 
    } 
    catch 
    { 

    } 
   }
  }
  #endregion  Delete existing custom paper 
  #region  The specified printer is set to mm Is the unit of custom paper (Form)
  /**/
  /// <summary> 
  ///  The specified printer is set to mm Is the unit of custom paper (Form) 
  /// </summary> 
  /// <param name="PrinterName"> Printer name </param> 
  /// <param name="PaperName">Form The name of the </param> 
  /// <param name="WidthInMm"> In order to mm Is the width in units </param> 
  /// <param name="HeightInMm"> In order to mm Is the height in units </param> 
  public static void AddCustomPaperSize(string PrinterName, string PaperName, float WidthInMm, float HeightInMm) 
  { 
   if (PlatformID.Win32NT == Environment.OSVersion.Platform) 
   { 
    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; 

    // Turn on the printer  
    if (OpenPrinter(PrinterName, out hPrinter, ref defaults)) 
    { 
     try 
     { 
      // if Form Existing deleted  
      DeleteForm(hPrinter, PaperName); 
      // Create and initialize FORM_INFO_1 
      FormInfo1 formInfo = new FormInfo1(); 
      formInfo.Flags = 0; 
      formInfo.pName = PaperName; 
      formInfo.Size.width = (int)(WidthInMm * 1000.0); 
      formInfo.Size.height = (int)(HeightInMm * 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(" To the printer  {1}  Add custom paper  {0}  Failure! Error code: {2}", 
        PaperName, PrinterName, GetLastError()); 
       throw new ApplicationException(strBuilder.ToString()); 
      } 

      // Initialize the  
      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; 

 
      int iDevModeSize = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero, IntPtr.Zero, 0); 

      if (iDevModeSize < 0) 
       throw new ApplicationException(" Unable to obtain DEVMODE The size of the structure! "); 

      // Allocate the buffer  
      IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize + 100); 

      // To obtain DEV_MODE Pointer to the  
      int iRet = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER); 

      if (iRet < 0) 
       throw new ApplicationException(" Unable to get DEVMODE Structure! "); 

      // fill DEV_MODE 
      devMode = (structDevMode)Marshal.PtrToStructure(hDevMode, devMode.GetType()); 

 
      devMode.dmFields = 0x10000; 

      //FORM The name of the  
      devMode.dmFormName = PaperName; 

      Marshal.StructureToPtr(devMode, hDevMode, true); 

      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 printing direction for printer! "); 

      GetPrinter(hPrinter, 9, IntPtr.Zero, 0, out iPrinterInfoSize); 
      if (iPrinterInfoSize == 0) 
       throw new ApplicationException(" call GetPrinter Method failed! "); 

      hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100); 

      bool bSuccess = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, out iDummyInt); 

      if (!bSuccess) 
       throw new ApplicationException(" call GetPrinter Method failed! "); 

      printerInfo = (PRINTER_INFO_9)Marshal.PtrToStructure(hPrinterInfo, printerInfo.GetType()); 
      printerInfo.pDevMode = hDevMode; 

      Marshal.StructureToPtr(printerInfo, hPrinterInfo, true); 

      bSuccess = SetPrinter(hPrinter, 9, hPrinterInfo, 0); 

      if (!bSuccess) 
       throw new Win32Exception(Marshal.GetLastWin32Error(), " call SetPrinter Method failed, unable to set printer! "); 

      SendMessageTimeout( 
       new IntPtr(HWND_BROADCAST), 
       WM_SETTINGCHANGE, 
       IntPtr.Zero, 
       IntPtr.Zero, 
       Printer.SendMessageTimeoutFlags.SMTO_NORMAL, 
       1000, 
       out hDummy); 
     } 
     finally 
     { 
      ClosePrinter(hPrinter); 
     } 
    } 
    else 
    { 
     StringBuilder strBuilder = new StringBuilder(); 
     strBuilder.AppendFormat(" Unable to open printer {0},  The error code : {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)(WidthInMm * 1000.0); 
     pDevMode.dmPaperLength = (short)(HeightInMm * 1000.0); 
     ResetDC(hDC, ref pDevMode); 
     DeleteDC(hDC); 
    } 
   }
  }
  #endregion  The specified printer is set to mm Is the unit of custom paper (Form)
  #region  Gets a list of local printers 
  /**/
  /// <summary> 
  ///  Gets a list of local printers  
  ///  Network printer can be obtained by setting parameters  
  /// </summary> 
  /// <returns> Printer list </returns> 
  public static System.Collections.ArrayList GetPrinterList() 
  { 
   System.Collections.ArrayList alRet = new System.Collections.ArrayList(); 
   PRINTER_INFO_2[] Info2 = EnumPrintersByFlag(PrinterEnumFlags.PRINTER_ENUM_LOCAL); 
   for (int i = 0; i < Info2.Length; i++) 
   { 
    alRet.Add(Info2[i].pPrinterName); 
   } 
   return alRet;
  }
  #endregion  Gets a list of local printers 
  #region  Gets the default printer name of the machine 
  /**/
  /// <summary> 
  ///  Gets the default printer name of the machine  
  /// </summary> 
  /// <returns> Default printer name </returns> 
  public static string GetDeaultPrinterName() 
  { 
   StringBuilder dp = new StringBuilder(256); 
   int size = dp.Capacity; 
   if (GetDefaultPrinter(dp, ref size)) 
   { 
    return dp.ToString(); 
   } 
   else 
   { 
    return string.Empty; 
   }
  }
  #endregion  Gets the default printer name of the machine 
  #region  Set the default printer 
  /**/
  /// <summary> 
  ///  Set the default printer  
  /// </summary> 
  /// <param name="PrinterName"> The name of the printer available </param> 
  public static void SetPrinterToDefault(string PrinterName) 
  { 
   SetDefaultPrinter(PrinterName);
  }
  #endregion  Set the default printer 
  #region  Determines if the printer is in the list of printers available to the system 
  /**/
  ///// <summary> 
  /////  Determines if the printer is in the list of printers available to the system  
  ///// </summary> 
  ///// <param name="PrinterName"> Printer name </param> 
  ///// <returns> Is that in; No: don't </returns> 
  public static bool PrinterInList(string PrinterName) 
  { 
   bool bolRet = false; 

   System.Collections.ArrayList alPrinters = GetPrinterList(); 

   for (int i = 0; i < alPrinters.Count; i++) 
   { 
    if (PrinterName == alPrinters[i].ToString()) 
    { 
     bolRet = true; 
     break; 
    } 
   } 

   alPrinters.Clear(); 
   alPrinters = null; 

   return bolRet;
  }
  #endregion  Determines if the printer is in the list of printers available to the system 
  #region  Determines if the form is in the list of pages supported by the specified printer 
  /**/
  ///// <summary> 
  /////  Determines if the form is in the list of pages supported by the specified printer , A form is what we call paper  
  ///// </summary> 
  ///// <param name="PrinterName"> Printer name </param> 
  ///// <param name="PaperName"> The paper name </param> 
  ///// <returns> Is that in; No: don't </returns> 
  public static bool FormInPrinter(string PrinterName, string PaperName) 
  { 
   bool bolRet = false; 

   System.Drawing.Printing.PrintDocument pd = new System.Drawing.Printing.PrintDocument(); 

   pd.PrinterSettings.PrinterName = PrinterName; 

   foreach (System.Drawing.Printing.PaperSize ps in pd.PrinterSettings.PaperSizes) 
   { 
    if (ps.PaperName == PaperName) 
    { 
     bolRet = true; 
     break; 
    } 
   } 

   pd.Dispose(); 

   return bolRet;
  }
  #endregion  Determines if the form is in the list of pages supported by the specified printer 
  #region  Determines whether the specified width and height of the paper matches the specified width and height of the printed content 
  /**/
  /// <summary> 
  ///  Determines whether the specified width and height of the paper matches the specified width and height of the printed content  
  /// </summary> 
  /// <param name="PrinterName"> Printer name </param> 
  /// <param name="FormName"> Form name </param> 
  /// <param name="Width"> The width of the </param> 
  /// <param name="Height"> highly </param> 
  /// <returns></returns> 
  public static bool FormSameSize(string PrinterName, string FormName, decimal Width, decimal Height) 
  { 
   bool bolRet = false; 

   System.Drawing.Printing.PrintDocument pd = new System.Drawing.Printing.PrintDocument(); 

   pd.PrinterSettings.PrinterName = PrinterName; 

   foreach (System.Drawing.Printing.PaperSize ps in pd.PrinterSettings.PaperSizes) 
   { 
    if (ps.PaperName == FormName) 
    { 
     decimal decWidth = FromInchToCM(System.Convert.ToDecimal(ps.Width)); 
     decimal decHeight = FromInchToCM(System.Convert.ToDecimal(ps.Height)); 
     // As long as the integer bits are the same, it is considered the same 1 Paper, after all inch to cm The transformation of theta is not divisible  
     if (Math.Round(decWidth, 0) == Math.Round(Width, 0) && Math.Round(decHeight, 0) == Math.Round(Height, 0)) 
      bolRet = true; 
     break; 
    } 
   } 

   pd.Dispose(); 

   return bolRet;
  }
  #endregion  Determines whether the specified width and height of the paper matches the specified width and height of the printed content 
  #region  Inches to centimeters 
  /**/
  /// <summary> 
  ///  Inches to centimeters  
        /// /* = = = = = = = = = = = = = = = = *\ 
        /// |  conversion 1 The unit of measurement, and convert it to centimeters   |
        /// |     cm       pixel       inches          |
        /// |     1        38     0.395         |
        /// |   0.026       1      0.01         |
        /// |    2.54      96        1          |
        /// \* = = = = = = = = = = = = = = = = */
  /// </summary> 
  /// <param name="inch"> inches </param> 
  /// <returns> Centimeters, two decimal places </returns> 
        /// 
  public static decimal FromInchToCM(decimal inch) 
  { 
   return Math.Round((System.Convert.ToDecimal((inch / 100)) * System.Convert.ToDecimal(2.5400)), 2);
  }
  #endregion  Inches to centimeters 
 }
}
 


Related articles: