'Imports System.IO 'Imports System.Xml 'Imports System.Drawing Imports System.ComponentModel 'Imports System.Drawing.Design Imports System.Drawing.Printing Imports System.Drawing.Imaging Imports System.Text Imports System.Runtime.InteropServices Imports System.Security 'Imports System.ComponentModel 'Imports System.Drawing.Printing Namespace UtilNamespace Util /**/'''<summary> ''' Summary description for MJMCustomPrintForm. '''</summary> PublicClass CustomPrintFormClass CustomPrintForm ' Make a static class PrivateSub New()SubNew() End Sub <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ FriendStructure structPrinterDefaultsStructure structPrinterDefaults <MarshalAs(UnmanagedType.LPTStr)> _ Public pDatatype AsString Public pDevMode As IntPtr <MarshalAs(UnmanagedType.I4)> _ Public DesiredAccess AsInteger End Structure <DllImport("winspool.Drv", EntryPoint:="OpenPrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction OpenPrinter()Function OpenPrinter(<MarshalAs(UnmanagedType.LPTStr)> _ ByVal printerName AsString, ByRef phPrinter As IntPtr, ByRef pd As structPrinterDefaults) AsBoolean End Function <DllImport("winspool.Drv", EntryPoint:="ClosePrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction ClosePrinter()Function ClosePrinter(ByVal phPrinter As IntPtr) AsBoolean End Function <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ FriendStructure structSizeStructure structSize Public width As Int32 Public height As Int32 End Structure <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ FriendStructure structRectStructure structRect PublicleftAs Int32 Public top As Int32 PublicrightAs Int32 Public bottom As Int32 End Structure <StructLayout(LayoutKind.Explicit, CharSet:=CharSet.Unicode)> _ FriendStructure FormInfo1Structure FormInfo1 <FieldOffset(0), MarshalAs(UnmanagedType.I4)> _ Public Flags AsUInteger <FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)> _ Public pName AsString <FieldOffset(8)> _ Public Size As structSize <FieldOffset(16)> _ Public ImageableArea As structRect End Structure ' changed from CharSet=CharSet.Auto <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _ FriendStructure structDevModeStructure structDevMode <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> _ Public dmDeviceName AsString <MarshalAs(UnmanagedType.U2)> _ Public dmSpecVersion AsShort <MarshalAs(UnmanagedType.U2)> _ Public dmDriverVersion AsShort <MarshalAs(UnmanagedType.U2)> _ Public dmSize AsShort <MarshalAs(UnmanagedType.U2)> _ Public dmDriverExtra AsShort <MarshalAs(UnmanagedType.U4)> _ Public dmFields AsInteger <MarshalAs(UnmanagedType.I2)> _ Public dmOrientation AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmPaperSize AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmPaperLength AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmPaperWidth AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmScale AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmCopies AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmDefaultSource AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmPrintQuality AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmColor AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmDuplex AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmYResolution AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmTTOption AsShort <MarshalAs(UnmanagedType.I2)> _ Public dmCollate AsShort <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> _ Public dmFormName AsString <MarshalAs(UnmanagedType.U2)> _ Public dmLogPixels AsShort <MarshalAs(UnmanagedType.U4)> _ Public dmBitsPerPel AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmPelsWidth AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmPelsHeight AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmNup AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmDisplayFrequency AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmICMMethod AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmICMIntent AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmMediaType AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmDitherType AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmReserved1 AsInteger <MarshalAs(UnmanagedType.U4)> _ Public dmReserved2 AsInteger End Structure <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ FriendStructure PRINTER_INFO_9Structure PRINTER_INFO_9 Public pDevMode As IntPtr End Structure <DllImport("winspool.Drv", EntryPoint:="AddFormW", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction AddForm()Function AddForm(ByVal phPrinter As IntPtr, <MarshalAs(UnmanagedType.I4)> _ ByVal level AsInteger, ByRef form As FormInfo1) AsBoolean End Function <DllImport("winspool.Drv", EntryPoint:="EnumForms", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction EnumForms()Function EnumForms(ByVal phPrinter As IntPtr, <MarshalAs(UnmanagedType.I4)> _ ByVal level AsInteger, ByRef form As FormInfo1, _ ByVal cbBuf AsInteger, _ ByRef pcbNeeded AsLong, _ ByRef pcReturned AsLong) AsBoolean End Function ' 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()> _ FriendSharedFunction DeleteForm()Function DeleteForm(ByVal phPrinter As IntPtr, <MarshalAs(UnmanagedType.LPTStr)> _ ByVal pName AsString) AsBoolean End Function <DllImport("kernel32.dll", EntryPoint:="GetLastError", SetLastError:=False, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction GetLastError()Function GetLastError() As Int32 End Function <DllImport("GDI32.dll", EntryPoint:="CreateDC", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction CreateDC()Function CreateDC(<MarshalAs(UnmanagedType.LPTStr)> _ ByVal pDrive AsString, <MarshalAs(UnmanagedType.LPTStr)> _ ByVal pName AsString, <MarshalAs(UnmanagedType.LPTStr)> _ ByVal pOutput AsString, ByRef pDevMode As structDevMode) As IntPtr End Function <DllImport("GDI32.dll", EntryPoint:="ResetDC", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction ResetDC()Function ResetDC(ByVal hDC As IntPtr, ByRef pDevMode As structDevMode) As IntPtr End Function <DllImport("GDI32.dll", EntryPoint:="DeleteDC", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction DeleteDC()Function DeleteDC(ByVal hDC As IntPtr) AsBoolean End Function <DllImport("winspool.Drv", EntryPoint:="SetPrinterA", SetLastError:=True, CharSet:=CharSet.Auto, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()> _ FriendSharedFunction SetPrinter()Function SetPrinter(ByVal hPrinter As IntPtr, <MarshalAs(UnmanagedType.I4)> _ ByVal level AsInteger, ByVal pPrinter As IntPtr, <MarshalAs(UnmanagedType.I4)> _ ByValcommandAsInteger) AsBoolean End Function ' ' 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 ' ); ' ' changed from String to string <DllImport("winspool.Drv", EntryPoint:="DocumentPropertiesA", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ PublicSharedFunction DocumentProperties()Function DocumentProperties(ByVal hwnd As IntPtr, ByVal hPrinter As IntPtr, <MarshalAs(UnmanagedType.LPStr)> _ ByVal pDeviceName AsString, ByVal pDevModeOutput As IntPtr, ByVal pDevModeInput As IntPtr, ByVal fMode AsInteger) AsInteger End Function ' changed type from Int32 ' chagned from Int32 <DllImport("winspool.Drv", EntryPoint:="GetPrinterA", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ PublicSharedFunction GetPrinter()Function GetPrinter(ByVal hPrinter As IntPtr, ByVal dwLevel AsInteger, ByVal pPrinter As IntPtr, ByVal dwBuf AsInteger, ByRef dwNeeded AsInteger) AsBoolean ' changed from Int32 End Function ' SendMessageTimeout tools <Flags()> _ PublicEnum SendMessageTimeoutFlagsEnum SendMessageTimeoutFlags AsUInteger SMTO_NORMAL =0 SMTO_BLOCK =1 SMTO_ABORTIFHUNG =2 SMTO_NOTIMEOUTIFNOTHUNG =8 End Enum Const WM_SETTINGCHANGE AsInteger=26 Const HWND_BROADCAST AsInteger=65535 <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _ PublicSharedFunction SendMessageTimeout()Function SendMessageTimeout(ByVal windowHandle As IntPtr, ByVal Msg AsUInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByVal flags As SendMessageTimeoutFlags, ByVal timeout AsUInteger, _ ByRef result As IntPtr) As IntPtr End Function 'Public Shared Sub AddMjm80MmPaperSizeToDefaultPrinter() ' AddCustomPaperSizeToDefaultPrinter("MJM 80mm * Receipt Length", 80.1F, 4003.9F) 'End Sub 'Public Shared Sub AddMjm104MmPaperSizeToDefaultPrinter() ' AddCustomPaperSizeToDefaultPrinter("MJM 104mm * Receipt Length", 104.1F, 4003.9F) 'End Sub /**/'''<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> PublicSharedSub AddCustomPaperSizeToDefaultPrinter()Sub AddCustomPaperSizeToDefaultPrinter(ByVal paperName AsString, ByVal widthMm AsSingle, ByVal heightMm AsSingle) Dim pd AsNew PrintDocument() Dim sPrinterName AsString= pd.PrinterSettings.PrinterName AddCustomPaperSize(sPrinterName, paperName, widthMm, heightMm) End Sub /**/'''<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> PublicSharedSub AddCustomPaperSize()Sub AddCustomPaperSize(ByVal printerName AsString, ByVal paperName AsString, ByVal widthMm AsSingle, ByVal heightMm AsSingle) If PlatformID.Win32NT = Environment.OSVersion.Platform Then ' The code to add a custom paper size is different for Windows NT then it is ' for previous versions of windows Const PRINTER_ACCESS_USE AsInteger=8 Const PRINTER_ACCESS_ADMINISTER AsInteger=4 'Const FORM_PRINTER As Integer = 2 Dim defaults AsNew structPrinterDefaults() defaults.pDatatype =Nothing defaults.pDevMode = IntPtr.Zero defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE Dim hPrinter As IntPtr = IntPtr.Zero ' Open the printer. If OpenPrinter(printerName, hPrinter, defaults) Then Try ' delete the form incase it already exists DeleteForm(hPrinter, paperName) ' create and initialize the FORM_INFO_1 structure Dim formInfo AsNew FormInfo1() formInfo.Flags =0 formInfo.pName = paperName ' all sizes in 1000ths of millimeters formInfo.Size.width =CInt((widthMm *1000)) formInfo.Size.height =CInt((heightMm *1000)) formInfo.ImageableArea.left =0 formInfo.ImageableArea.right = formInfo.Size.width formInfo.ImageableArea.top =0 formInfo.ImageableArea.bottom = formInfo.Size.height IfNot AddForm(hPrinter, 1, formInfo) Then Dim strBuilder AsNew StringBuilder() strBuilder.AppendFormat("Failed to add the custom paper size {0} to the printer {1}, System error number: {2}", paperName, printerName, GetLastError()) ThrowNew ApplicationException(strBuilder.ToString()) EndIf ' INIT Const DM_OUT_BUFFER AsInteger=2 Const DM_IN_BUFFER AsInteger=8 Dim devMode AsNew structDevMode() Dim hPrinterInfo As IntPtr, hDummy As IntPtr Dim printerInfo As PRINTER_INFO_9 printerInfo.pDevMode = IntPtr.Zero Dim iPrinterInfoSize AsInteger, iDummyInt AsInteger ' GET THE SIZE OF THE DEV_MODE BUFFER Dim iDevModeSize AsInteger= DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0) If iDevModeSize <0Then ThrowNew ApplicationException("Cannot get the size of the DEVMODE structure.") EndIf ' ALLOCATE THE BUFFER Dim hDevMode As IntPtr = Marshal.AllocCoTaskMem(iDevModeSize +100) ' GET A POINTER TO THE DEV_MODE BUFFER Dim iRet AsInteger= DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER) If iRet <0Then ThrowNew ApplicationException("Cannot get the DEVMODE structure.") EndIf ' FILL THE DEV_MODE STRUCTURE devMode =DirectCast(Marshal.PtrToStructure(hDevMode, devMode.[GetType]()), structDevMode) ' SET THE FORM NAME FIELDS TO INDICATE THAT THIS FIELD WILL BE MODIFIED devMode.dmFields =65536 ' 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 Or DM_OUT_BUFFER) If iRet <0Then ThrowNew ApplicationException("Unable to set the orientation setting for this printer.") EndIf ' GET THE PRINTER INFO SIZE GetPrinter(hPrinter, 9, IntPtr.Zero, 0, iPrinterInfoSize) If iPrinterInfoSize =0Then ThrowNew ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure") EndIf ' ALLOCATE THE BUFFER hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize +100) ' GET A POINTER TO THE PRINTER INFO BUFFER Dim bSuccess AsBoolean= GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, iDummyInt) IfNot bSuccess Then ThrowNew ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure") EndIf ' FILL THE PRINTER INFO STRUCTURE printerInfo =DirectCast(Marshal.PtrToStructure(hPrinterInfo, printerInfo.[GetType]()), PRINTER_INFO_9) 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) IfNot bSuccess Then ThrowNew Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed. Couldn't set the printer settings") EndIf ' Tell all open programs that this change occurred. SendMessageTimeout(New IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, CustomPrintForm.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, _ hDummy) Finally ClosePrinter(hPrinter) EndTry Else Dim strBuilder AsNew StringBuilder() strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}", printerName, GetLastError()) ThrowNew ApplicationException(strBuilder.ToString()) EndIf Else Dim pDevMode AsNew structDevMode() Dim hDC As IntPtr = CreateDC(Nothing, printerName, Nothing, pDevMode) If hDC <> IntPtr.Zero Then Const DM_PAPERSIZE AsLong=2 Const DM_PAPERLENGTH AsLong=4 Const DM_PAPERWIDTH AsLong=8 pDevMode.dmFields =CInt((DM_PAPERSIZE Or DM_PAPERWIDTH Or DM_PAPERLENGTH)) pDevMode.dmPaperSize =256 pDevMode.dmPaperWidth =CShort((widthMm *1000)) pDevMode.dmPaperLength =CShort((heightMm *1000)) ResetDC(hDC, pDevMode) DeleteDC(hDC) EndIf EndIf End Sub End Class End Namespace