|
My website (under construction) is componentworks.net. You can email me at travis@componentworks.net
--Travis
|
|
|
|
|
thanks for this Article that work for dot matrix printer.in Epson LX 800 printer driver have no any option through which we can set custome paper size. but your application do this one. it safe us against customer which is far away from us and is in different continent
thanks on this kind Anticipation.
syed zaim raza kazmi
|
|
|
|
|
I'm not sure what your problem is. I know you can run into problems with certain paper sizes on certain printers. AFAIK, the code I posted doesn't correctly check that a the paper size was added. We had to ask the printer manufacturer about it or maybe in documentation?
|
|
|
|
|
After I used it, my application that was printing throw exception - "Handle is invalid".
This same application was working prior to operation on this project.
Can some one help me please?
|
|
|
|
|
I'm not sure what your problem could be unless you just have the wrong name for the printer. I've seen that cause an invalid handle before.
--Travis
|
|
|
|
|
Do you have these code in VB.net?
|
|
|
|
|
No, sorry I don't have it in VB.NET. I had to port some similar code from VB.NET and it wasn't too hard. Let me know if you run into any roadblocks porting to VB.NET.
--Travis
|
|
|
|
|
As I am unable to convert this to vb.net 2003(do no understand whats going on),
I did the most obvios thing. Create a DLL of it. Wich can be referenced and called in vb.net.
Maybe a solution for you to.
<br />
using System;<br />
using System.Text;<br />
using System.Runtime.InteropServices;<br />
using System.Security;<br />
using System.ComponentModel;<br />
using System.Drawing.Printing;<br />
<br />
namespace CLS_PrintPaper<br />
{<br />
public class CLS_PrintPaper<br />
{<br />
private CLS_PrintPaper()<br />
{<br />
}<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]<br />
internal struct structPrinterDefaults<br />
{<br />
[MarshalAs(UnmanagedType.LPTStr)] public String pDatatype;<br />
public IntPtr pDevMode;<br />
[MarshalAs(UnmanagedType.I4)] public int DesiredAccess;<br />
};<br />
<br />
[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);<br />
[DllImport("winspool.Drv", EntryPoint="ClosePrinter", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=false, CallingConvention=CallingConvention.StdCall),SuppressUnmanagedCodeSecurityAttribute()] internal static extern bool ClosePrinter(IntPtr phPrinter);<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]<br />
internal struct structSize<br />
{<br />
public Int32 width;<br />
public Int32 height;<br />
}<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]<br />
internal struct structRect<br />
{<br />
public Int32 left;<br />
public Int32 top;<br />
public Int32 right;<br />
public Int32 bottom;<br />
}<br />
<br />
[StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]<br />
internal struct FormInfo1<br />
{<br />
[FieldOffset(0), MarshalAs(UnmanagedType.I4)] public uint Flags;<br />
[FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)] public String pName;<br />
[FieldOffset(8)] public structSize Size;<br />
[FieldOffset(16)] public structRect ImageableArea;<br />
};<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]<br />
internal struct structDevMode<br />
{<br />
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public String<br />
dmDeviceName;<br />
[MarshalAs(UnmanagedType.U2)] public short dmSpecVersion;<br />
[MarshalAs(UnmanagedType.U2)] public short dmDriverVersion;<br />
[MarshalAs(UnmanagedType.U2)] public short dmSize;<br />
[MarshalAs(UnmanagedType.U2)] public short dmDriverExtra;<br />
[MarshalAs(UnmanagedType.U4)] public int dmFields;<br />
[MarshalAs(UnmanagedType.I2)] public short dmOrientation;<br />
[MarshalAs(UnmanagedType.I2)] public short dmPaperSize;<br />
[MarshalAs(UnmanagedType.I2)] public short dmPaperLength;<br />
[MarshalAs(UnmanagedType.I2)] public short dmPaperWidth;<br />
[MarshalAs(UnmanagedType.I2)] public short dmScale;<br />
[MarshalAs(UnmanagedType.I2)] public short dmCopies;<br />
[MarshalAs(UnmanagedType.I2)] public short dmDefaultSource;<br />
[MarshalAs(UnmanagedType.I2)] public short dmPrintQuality;<br />
[MarshalAs(UnmanagedType.I2)] public short dmColor;<br />
[MarshalAs(UnmanagedType.I2)] public short dmDuplex;<br />
[MarshalAs(UnmanagedType.I2)] public short dmYResolution;<br />
[MarshalAs(UnmanagedType.I2)] public short dmTTOption;<br />
[MarshalAs(UnmanagedType.I2)] public short dmCollate;<br />
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public String dmFormName;<br />
[MarshalAs(UnmanagedType.U2)] public short dmLogPixels;<br />
[MarshalAs(UnmanagedType.U4)] public int dmBitsPerPel;<br />
[MarshalAs(UnmanagedType.U4)] public int dmPelsWidth;<br />
[MarshalAs(UnmanagedType.U4)] public int dmPelsHeight;<br />
[MarshalAs(UnmanagedType.U4)] public int dmNup;<br />
[MarshalAs(UnmanagedType.U4)] public int dmDisplayFrequency;<br />
[MarshalAs(UnmanagedType.U4)] public int dmICMMethod;<br />
[MarshalAs(UnmanagedType.U4)] public int dmICMIntent;<br />
[MarshalAs(UnmanagedType.U4)] public int dmMediaType;<br />
[MarshalAs(UnmanagedType.U4)] public int dmDitherType;<br />
[MarshalAs(UnmanagedType.U4)] public int dmReserved1;<br />
[MarshalAs(UnmanagedType.U4)] public int dmReserved2;<br />
}<br />
<br />
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] <br />
internal struct PRINTER_INFO_9 <br />
{<br />
public IntPtr pDevMode;<br />
}<br />
<br />
[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);<br />
<br />
<br />
<br />
[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);<br />
<br />
[DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError=false, ExactSpelling=true, CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()] internal static extern Int32 GetLastError();<br />
<br />
[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);<br />
<br />
[DllImport("GDI32.dll", EntryPoint="ResetDC", SetLastError=true,<br />
CharSet=CharSet.Unicode, ExactSpelling=false,<br />
CallingConvention=CallingConvention.StdCall),<br />
SuppressUnmanagedCodeSecurityAttribute()]<br />
internal static extern IntPtr ResetDC(<br />
IntPtr hDC, <br />
ref structDevMode<br />
pDevMode);<br />
<br />
[DllImport("GDI32.dll", EntryPoint="DeleteDC", SetLastError=true,<br />
CharSet=CharSet.Unicode, ExactSpelling=false,<br />
CallingConvention=CallingConvention.StdCall),<br />
SuppressUnmanagedCodeSecurityAttribute()]<br />
internal static extern bool DeleteDC(IntPtr hDC);<br />
<br />
[DllImport("winspool.Drv", EntryPoint="SetPrinterA", SetLastError=true,<br />
CharSet=CharSet.Auto, ExactSpelling=true,<br />
CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]<br />
internal static extern bool SetPrinter(<br />
IntPtr hPrinter,<br />
[MarshalAs(UnmanagedType.I4)] int level, <br />
IntPtr pPrinter, <br />
[MarshalAs(UnmanagedType.I4)] int command);<br />
<br />
<br />
[DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true, <br />
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] <br />
public static extern int DocumentProperties(<br />
IntPtr hwnd, <br />
IntPtr hPrinter,<br />
[MarshalAs(UnmanagedType.LPStr)] string pDeviceName ,<br />
IntPtr pDevModeOutput, <br />
IntPtr pDevModeInput, <br />
int fMode<br />
);<br />
<br />
[DllImport("winspool.Drv", EntryPoint="GetPrinterA", SetLastError=true, <br />
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] <br />
public static extern bool GetPrinter(<br />
IntPtr hPrinter, <br />
int dwLevel ,<br />
IntPtr pPrinter,<br />
int dwBuf , <br />
out int dwNeeded <br />
); <br />
<br />
[Flags] public enum SendMessageTimeoutFlags : uint<br />
{<br />
SMTO_NORMAL = 0x0000,<br />
SMTO_BLOCK = 0x0001,<br />
SMTO_ABORTIFHUNG = 0x0002,<br />
SMTO_NOTIMEOUTIFNOTHUNG = 0x0008<br />
}<br />
const int WM_SETTINGCHANGE = 0x001A;<br />
const int HWND_BROADCAST = 0xffff;<br />
<br />
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]<br />
public static extern IntPtr SendMessageTimeout(<br />
IntPtr windowHandle, <br />
uint Msg, <br />
IntPtr wParam, <br />
IntPtr lParam, <br />
SendMessageTimeoutFlags flags, <br />
uint timeout, <br />
out IntPtr result<br />
);<br />
<br />
public static void AddCustomPaperSizeToDefaultPrinter(string paperName, float widthMm, float heightMm)<br />
{<br />
PrintDocument pd = new PrintDocument();<br />
string sPrinterName = pd.PrinterSettings.PrinterName;<br />
AddCustomPaperSize(sPrinterName, paperName, widthMm, heightMm);<br />
}<br />
<br />
public static void AddCustomPaperSize(string printerName, string paperName, float<br />
widthMm, float heightMm)<br />
{<br />
if (PlatformID.Win32NT == Environment.OSVersion.Platform)<br />
{<br />
<br />
const int PRINTER_ACCESS_USE = 0x00000008;<br />
const int PRINTER_ACCESS_ADMINISTER = 0x00000004;<br />
<br />
structPrinterDefaults defaults = new structPrinterDefaults();<br />
defaults.pDatatype = null;<br />
defaults.pDevMode = IntPtr.Zero;<br />
defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;<br />
<br />
IntPtr hPrinter = IntPtr.Zero;<br />
<br />
if (OpenPrinter(printerName, out hPrinter, ref defaults))<br />
{<br />
try<br />
{<br />
DeleteForm(hPrinter, paperName);<br />
FormInfo1 formInfo = new FormInfo1();<br />
formInfo.Flags = 0;<br />
formInfo.pName = paperName;<br />
formInfo.Size.width = (int)(widthMm * 1000.0); <br />
formInfo.Size.height = (int)(heightMm * 1000.0);<br />
formInfo.ImageableArea.left = 0;<br />
formInfo.ImageableArea.right = formInfo.Size.width;<br />
formInfo.ImageableArea.top = 0;<br />
formInfo.ImageableArea.bottom = formInfo.Size.height;<br />
if (!AddForm(hPrinter, 1, ref formInfo))<br />
{<br />
StringBuilder strBuilder = new StringBuilder();<br />
strBuilder.AppendFormat("Failed to add the custom paper size {0} to the printer {1}, System error number: {2}",<br />
paperName, printerName, GetLastError());<br />
throw new ApplicationException(strBuilder.ToString());<br />
}<br />
<br />
const int DM_OUT_BUFFER = 2;<br />
const int DM_IN_BUFFER = 8;<br />
structDevMode devMode = new structDevMode();<br />
IntPtr hPrinterInfo, hDummy;<br />
PRINTER_INFO_9 printerInfo;<br />
printerInfo.pDevMode = IntPtr.Zero;<br />
int iPrinterInfoSize, iDummyInt;<br />
<br />
<br />
int iDevModeSize = DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0);<br />
<br />
if(iDevModeSize < 0)<br />
throw new ApplicationException("Cannot get the size of the DEVMODE structure.");<br />
<br />
IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize + 100);<br />
<br />
int iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER);<br />
<br />
if(iRet < 0)<br />
throw new ApplicationException("Cannot get the DEVMODE structure.");<br />
<br />
devMode = (structDevMode)Marshal.PtrToStructure(hDevMode, devMode.GetType());<br />
<br />
devMode.dmFields = 0x10000;
devMode.dmFormName = paperName; <br />
<br />
Marshal.StructureToPtr(devMode, hDevMode, true);<br />
<br />
iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, <br />
printerInfo.pDevMode, printerInfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);<br />
<br />
if(iRet < 0)<br />
throw new ApplicationException("Unable to set the orientation setting for this printer.");<br />
<br />
GetPrinter(hPrinter, 9, IntPtr.Zero, 0, out iPrinterInfoSize);<br />
if(iPrinterInfoSize == 0)<br />
throw new ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure");<br />
<br />
hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100);<br />
<br />
bool bSuccess = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, out iDummyInt);<br />
<br />
if(!bSuccess)<br />
throw new ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure");<br />
<br />
printerInfo = (PRINTER_INFO_9)Marshal.PtrToStructure(hPrinterInfo, printerInfo.GetType());<br />
printerInfo.pDevMode = hDevMode;<br />
<br />
Marshal.StructureToPtr(printerInfo, hPrinterInfo, true);<br />
<br />
bSuccess = SetPrinter(hPrinter, 9, hPrinterInfo, 0);<br />
<br />
if(!bSuccess)<br />
throw new Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed. Couldn't set the printer settings");<br />
<br />
SendMessageTimeout(<br />
new IntPtr(HWND_BROADCAST), <br />
WM_SETTINGCHANGE, <br />
IntPtr.Zero, <br />
IntPtr.Zero, <br />
CLS_PrintPaper.SendMessageTimeoutFlags.SMTO_NORMAL, <br />
1000, <br />
out hDummy);<br />
}<br />
finally<br />
{<br />
ClosePrinter(hPrinter);<br />
}<br />
}<br />
else<br />
{<br />
StringBuilder strBuilder = new StringBuilder();<br />
strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}",<br />
printerName, GetLastError());<br />
throw new ApplicationException(strBuilder.ToString());<br />
}<br />
}<br />
else<br />
{<br />
structDevMode pDevMode = new structDevMode();<br />
IntPtr hDC = CreateDC(null, printerName, null, ref pDevMode);<br />
if (hDC != IntPtr.Zero)<br />
{<br />
const long DM_PAPERSIZE = 0x00000002L;<br />
const long DM_PAPERLENGTH = 0x00000004L;<br />
const long DM_PAPERWIDTH = 0x00000008L;<br />
pDevMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);<br />
pDevMode.dmPaperSize = 256;<br />
pDevMode.dmPaperWidth = (short)(widthMm * 1000.0);<br />
pDevMode.dmPaperLength = (short)(heightMm * 1000.0);<br />
ResetDC(hDC, ref pDevMode);<br />
DeleteDC(hDC);<br />
}<br />
}<br />
}<br />
<br />
public static void RemoveCustomPaperSizeToDefaultPrinter(string paperName)<br />
{<br />
PrintDocument pd = new PrintDocument();<br />
string sPrinterName = pd.PrinterSettings.PrinterName;<br />
RemoveCustomPaperSize(sPrinterName, paperName);<br />
}<br />
<br />
public static void RemoveCustomPaperSize(string printerName, string paperName)<br />
{<br />
if (PlatformID.Win32NT == Environment.OSVersion.Platform)<br />
{<br />
<br />
const int PRINTER_ACCESS_USE = 0x00000008;<br />
const int PRINTER_ACCESS_ADMINISTER = 0x00000004;<br />
<br />
structPrinterDefaults defaults = new structPrinterDefaults();<br />
defaults.pDatatype = null;<br />
defaults.pDevMode = IntPtr.Zero;<br />
defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;<br />
<br />
IntPtr hPrinter = IntPtr.Zero;<br />
<br />
if (OpenPrinter(printerName, out hPrinter, ref defaults))<br />
{<br />
try<br />
{<br />
DeleteForm(hPrinter, paperName);<br />
<br />
IntPtr hDummy;<br />
SendMessageTimeout(<br />
new IntPtr(HWND_BROADCAST), <br />
WM_SETTINGCHANGE, <br />
IntPtr.Zero, <br />
IntPtr.Zero, <br />
CLS_PrintPaper.SendMessageTimeoutFlags.SMTO_NORMAL, <br />
1000, <br />
out hDummy);<br />
}<br />
finally<br />
{<br />
ClosePrinter(hPrinter);<br />
}<br />
}<br />
else<br />
{<br />
StringBuilder strBuilder = new StringBuilder();<br />
strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}",<br />
printerName, GetLastError());<br />
throw new ApplicationException(strBuilder.ToString());<br />
}<br />
}<br />
else<br />
{<br />
<br />
}<br />
}<br />
}<br />
}<br />
|
|
|
|
|
'################################################################
'MJMCustomPrintForm (VB.net)
'################################################################
Imports System
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Security
Imports System.ComponentModel
Imports System.Drawing.Printing
Namespace MJMCustomPrintForm
'''
''' Summary description for MJMCustomPrintForm.
'''
Public Class MJMCustomPrintForm
' Make a static class
Private Sub New()
End Sub
<structlayout(layoutkind.sequential, charset:="CharSet.Auto)"> _
Friend Structure structPrinterDefaults
<marshalas(unmanagedtype.lptstr)> _
Public pDatatype As String
Public pDevMode As IntPtr
<marshalas(unmanagedtype.i4)> _
Public DesiredAccess As Integer
End Structure
<dllimport("winspool.drv", entrypoint:="OpenPrinter" ,="" setlasterror:="True," charset:="CharSet.Unicode," exactspelling:="False," callingconvention:="CallingConvention.StdCall)," suppressunmanagedcodesecurityattribute()=""> _
Friend Shared Function OpenPrinter(<marshalas(unmanagedtype.lptstr)> _
ByVal printerName As String, ByRef phPrinter As IntPtr, ByRef pd As structPrinterDefaults) As Boolean
End Function
<dllimport("winspool.drv", entrypoint:="ClosePrinter" ,="" setlasterror:="True," charset:="CharSet.Unicode," exactspelling:="False," callingconvention:="CallingConvention.StdCall)," suppressunmanagedcodesecurityattribute()=""> _
Friend Shared Function ClosePrinter(ByVal phPrinter As IntPtr) As Boolean
End Function
<structlayout(layoutkind.sequential, charset:="CharSet.Auto)"> _
Friend Structure structSize
Public width As Int32
Public height As Int32
End Structure
<structlayout(layoutkind.sequential, charset:="CharSet.Auto)"> _
Friend Structure structRect
Public left As Int32
Public top As Int32
Public right As Int32
Public bottom As Int32
End Structure
<structlayout(layoutkind.[explicit], charset:="CharSet.Unicode)"> _
Friend Structure FormInfo1
<fieldoffset(0), marshalas(unmanagedtype.i4)=""> _
Public Flags As UInteger
<fieldoffset(4), marshalas(unmanagedtype.lpwstr)=""> _
Public pName As String
<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)"> _
Friend Structure structDevMode
<marshalas(unmanagedtype.byvaltstr, sizeconst:="32)"> _
Public dmDeviceName As String
<marshalas(unmanagedtype.u2)> _
Public dmSpecVersion As Short
<marshalas(unmanagedtype.u2)> _
Public dmDriverVersion As Short
<marshalas(unmanagedtype.u2)> _
Public dmSize As Short
<marshalas(unmanagedtype.u2)> _
Public dmDriverExtra As Short
<marshalas(unmanagedtype.u4)> _
Public dmFields As Integer
<marshalas(unmanagedtype.i2)> _
Public dmOrientation As Short
<marshalas(unmanagedtype.i2)> _
Public dmPaperSize As Short
<marshalas(unmanagedtype.i2)> _
Public dmPaperLength As Short
<marshalas(unmanagedtype.i2)> _
Public dmPaperWidth As Short
<marshalas(unmanagedtype.i2)> _
Public dmScale As Short
<marshalas(unmanagedtype.i2)> _
Public dmCopies As Short
<marshalas(unmanagedtype.i2)> _
Public dmDefaultSource As Short
<marshalas(unmanagedtype.i2)> _
Public dmPrintQuality As Short
<marshalas(unmanagedtype.i2)> _
Public dmColor As Short
<marshalas(unmanagedtype.i2)> _
Public dmDuplex As Short
<marshalas(unmanagedtype.i2)> _
Public dmYResolution As Short
<marshalas(unmanagedtype.i2)> _
Public dmTTOption As Short
<marshalas(unmanagedtype.i2)> _
Public dmCollate As Short
<marshalas(unmanagedtype.byvaltstr, sizeconst:="32)"> _
Public dmFormName As String
<marshalas(unmanagedtype.u2)> _
Public dmLogPixels As Short
<marshalas(unmanagedtype.u4)> _
Public dmBitsPerPel As Integer
<marshalas(unmanagedtype.u4)> _
Public dmPelsWidth As Integer
<marshalas(unmanagedtype.u4)> _
Public dmPelsHeight As Integer
<marshalas(unmanagedtype.u4)> _
Public dmNup As Integer
<marshalas(unmanagedtype.u4)> _
Public dmDisplayFrequency As Integer
<marshalas(unmanagedtype.u4)> _
Public dmICMMethod As Integer
<marshalas(unmanagedtype.u4)> _
Public dmICMIntent As Integer
<marshalas(unmanagedtype.u4)> _
Public dmMediaType As Integer
<marshalas(unmanagedtype.u4)> _
Public dmDitherType As Integer
<marshalas(unmanagedtype.u4)> _
Public dmReserved1 As Integer
<marshalas(unmanagedtype.u4)> _
Public dmReserved2 As Integer
End Structure
<structlayout(layoutkind.sequential, charset:="CharSet.Auto)"> _
Friend Structure 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()=""> _
Friend Shared Function AddForm(ByVal phPrinter As IntPtr, <marshalas(unmanagedtype.i4)> _
ByVal level As Integer, ByRef form As FormInfo1) As Boolean
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()=""> _
Friend Shared Function DeleteForm(ByVal phPrinter As IntPtr, <marshalas(unmanagedtype.lptstr)> _
ByVal pName As String) As Boolean
End Function
<dllimport("kernel32.dll", entrypoint:="GetLastError" ,="" setlasterror:="False," exactspelling:="True," callingconvention:="CallingConvention.StdCall)," suppressunmanagedcodesecurityattribute()=""> _
Friend Shared Function GetLastError() As Int32
End Function
<dllimport("gdi32.dll", entrypoint:="CreateDC" ,="" setlasterror:="True," charset:="CharSet.Unicode," exactspelling:="False," callingconvention:="CallingConvention.StdCall)," suppressunmanagedcodesecurityattribute()=""> _
Friend Shared Function CreateDC(<marshalas(unmanagedtype.lptstr)> _
ByVal pDrive As String, <marshalas(unmanagedtype.lptstr)> _
ByVal pName As String, <marshalas(unmanagedtype.lptstr)> _
ByVal pOutput As String, ByRef pDevMode As structDevMode) As IntPtr
End Function
<dllimport("gdi32.dll", entrypoint:="ResetDC" ,="" setlasterror:="True," charset:="CharSet.Unicode," exactspelling:="False," callingconvention:="CallingConvention.StdCall)," suppressunmanagedcodesecurityattribute()=""> _
Friend Shared 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()=""> _
Friend Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
End Function
<dllimport("winspool.drv", entrypoint:="SetPrinterA" ,="" setlasterror:="True," charset:="CharSet.Auto," exactspelling:="True," callingconvention:="CallingConvention.StdCall)," suppressunmanagedcodesecurityattribute()=""> _
Friend Shared Function SetPrinter(ByVal hPrinter As IntPtr, <marshalas(unmanagedtype.i4)> _
ByVal level As Integer, ByVal pPrinter As IntPtr, <marshalas(unmanagedtype.i4)> _
ByVal command As Integer) As Boolean
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)"> _
Public Shared Function DocumentProperties(ByVal hwnd As IntPtr, ByVal hPrinter As IntPtr, <marshalas(unmanagedtype.lpstr)> _
ByVal pDeviceName As String, ByVal pDevModeOutput As IntPtr, ByVal pDevModeInput As IntPtr, ByVal fMode As Integer) As Integer
End Function
' changed type from Int32
' chagned from Int32
<dllimport("winspool.drv", entrypoint:="GetPrinterA" ,="" setlasterror:="True," exactspelling:="True," callingconvention:="CallingConvention.StdCall)"> _
Public Shared Function GetPrinter(ByVal hPrinter As IntPtr, ByVal dwLevel As Integer, ByVal pPrinter As IntPtr, ByVal dwBuf As Integer, ByRef dwNeeded As Integer) As Boolean
' changed from Int32
End Function
' SendMessageTimeout tools
<flags()> _
Public Enum SendMessageTimeoutFlags As UInteger
SMTO_NORMAL = 0
SMTO_BLOCK = 1
SMTO_ABORTIFHUNG = 2
SMTO_NOTIMEOUTIFNOTHUNG = 8
End Enum
Const WM_SETTINGCHANGE As Integer = 26
Const HWND_BROADCAST As Integer = 65535
<dllimport("user32.dll", setlasterror:="True," charset:="CharSet.Auto)"> _
Public Shared Function SendMessageTimeout(ByVal windowHandle As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByVal flags As SendMessageTimeoutFlags, ByVal timeout As UInteger, _
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
'''
''' Adds the printer form to the default printer
'''
''' <param name="paperName" />Name of the printer form
''' <param name="widthMm" />Width given in millimeters
''' <param name="heightMm" />Height given in millimeters
Public Shared Sub AddCustomPaperSizeToDefaultPrinter(ByVal paperName As String, ByVal widthMm As Single, ByVal heightMm As Single)
Dim pd As New PrintDocument()
Dim sPrinterName As String = pd.PrinterSettings.PrinterName
AddCustomPaperSizeToSelectedPrinter(sPrinterName, paperName, widthMm, heightMm)
End Sub
'''
''' Add the printer form to a printer
'''
''' <param name="printerName" />The printer name
''' <param name="paperName" />Name of the printer form
''' <param name="widthMm" />Width given in millimeters
''' <param name="heightMm" />Height given in millimeters
Public Shared Sub AddCustomPaperSizeToSelectedPrinter(ByVal printerName As String, ByVal paperName As String, ByVal widthMm As Single, ByVal heightMm As Single)
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 As Integer = 8
Const PRINTER_ACCESS_ADMINISTER As Integer = 4
Const FORM_PRINTER As Integer = 2
Dim defaults As New 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 As New 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
If Not AddForm(hPrinter, 1, formInfo) Then
Dim strBuilder As 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())
End If
' INIT
Const DM_OUT_BUFFER As Integer = 2
Const DM_IN_BUFFER As Integer = 8
Dim devMode As New structDevMode()
Dim hPrinterInfo As IntPtr, hDummy As IntPtr
Dim printerInfo As PRINTER_INFO_9
printerInfo.pDevMode = IntPtr.Zero
Dim iPrinterInfoSize As Integer, iDummyInt As Integer
' GET THE SIZE OF THE DEV_MODE BUFFER
Dim iDevModeSize As Integer = DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0)
If iDevModeSize < 0 Then
Throw New ApplicationException("Cannot get the size of the DEVMODE structure.")
End If
' ALLOCATE THE BUFFER
Dim hDevMode As IntPtr = Marshal.AllocCoTaskMem(iDevModeSize + 100)
' GET A POINTER TO THE DEV_MODE BUFFER
Dim iRet As Integer = DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER)
If iRet < 0 Then
Throw New ApplicationException("Cannot get the DEVMODE structure.")
End If
' 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 < 0 Then
Throw New ApplicationException("Unable to set the orientation setting for this printer.")
End If
' GET THE PRINTER INFO SIZE
GetPrinter(hPrinter, 9, IntPtr.Zero, 0, iPrinterInfoSize)
If iPrinterInfoSize = 0 Then
Throw New ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure")
End If
' ALLOCATE THE BUFFER
hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100)
' GET A POINTER TO THE PRINTER INFO BUFFER
Dim bSuccess As Boolean = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, iDummyInt)
If Not bSuccess Then
Throw New ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure")
End If
' 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)
If Not bSuccess Then
Throw New Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed. Couldn't set the printer settings")
End If
' Tell all open programs that this change occurred.
SendMessageTimeout(New IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, MJMCustomPrintForm.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, _
hDummy)
Finally
ClosePrinter(hPrinter)
End Try
Else
Dim strBuilder As New StringBuilder()
strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}", printerName, GetLastError())
Throw New ApplicationException(strBuilder.ToString())
End If
Else
Dim pDevMode As New structDevMode()
Dim hDC As IntPtr = CreateDC(Nothing, printerName, Nothing, pDevMode)
If hDC <> IntPtr.Zero Then
Const DM_PAPERSIZE As Long = 2
Const DM_PAPERLENGTH As Long = 4
Const DM_PAPERWIDTH As Long = 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)
End If
End If
End Sub
End Class
End Namespace
'################################################################
|
|
|
|
|
It seems like when trying to add a custom size nothing happens. This would indicate that the printer does not allow this size, but I am trying to add a custom size that actually already existed in the list. I removed that size from the printersettings (using printers and faxes, etc..) and then I tried to add this size through this peace of code, but nothing is added to the list when I look at it.
Does anyone have any clues??
Thanks...
|
|
|
|
|
Ok, now I see that the new form that is created is added to "Forms" tab in "Printers and Faxes" - File - Server Properties. How can I get this form programmatically as:
DefaultPageSettings.PaperSize = "the form that was created under Server properties"??
|
|
|
|
|
Did anyone solve this problem?
I see the custom form under "Forms", but I don't see it under pager size when it goes to print it.
How can I use the custom forms to actually print?
Thanks,
Tom
|
|
|
|
|
Hi, I haven't tried your code yet, but I'm interested in what u said that, there is some paper dimension that a printer doesn't support.
Cos I have an application that adding a custom form to a spesific printer name, but in some printer, the form doesn't show. For example, I tried to add a 8.5 inch X 5.5 inch paper to Epson LQ-2180, It works.
If I look into the control panel->printers & faxes->server properties, my custom form show.
& if it also shows in my code:
dim pDoc as New PrintDocument
pDoc.PrinterSettings.PrinterName = "Epson LQ-2180"
For Each obj As PaperSize In pDoc.PrinterSettings.PaperSizes
cboForms.Items.Add(obj.PaperName)
Next
But if I add the same paper (8.5 x 5.5), for example to Canon BubbleJet, It doesn't work. I mean, it shows in the control panel->printers & faxes->server properties.
But it doesn't show in my code.
Could u give me some advice? Any help would be appreciated. Thx
Regards,
Alphonsus Eka
|
|
|
|
|
All that I know to say about this is that some printer drivers don't like certain paper sizes. I'm not sure how to tell. One obvious constraint might be printer width. If you try to add a paper size which is larger than your printer's width, the driver rejects the paper size. As you've noticed, you'll still be able to add the paper size and see it under the printer's list with control panel->printers & faxes->(click on printer)->file->server properties. But as far as I can tell, there is no way to force the printer to allow you to select a paper size it doesn't like.
Are you saying that you've added the paper size (8.5 x 5.5) to the Cannon BubbleJet in code or from the Printers & Faxes window? If you're adding from the Printers & Faxes window, be sure that you've clicked on the printer and that it's highlighted when you add the paper size.
BTW, if anyone knows how to query the driver & see what the maximum / minimum paper dimensions are, I would love to know how to do this. Thanks,
--Travis
|
|
|
|
|
Yes,i add the paper size (8.5 x 5.5) to the Cannon BubbleJet in code. My code works without errors, & it also shows in the paper sizes list in Printers & Faxes window.
But if I'm looping it using, ForEach PaperSize In PrinterSettings.PaperSizes, The new custom paper size, doesn't show.
I also realize, that It always works with dot matrix printer. I mean I could add my custom paper size, then when I'm looping it, it shows.
I've read that, some printers doesn't support custom paper size. Yeah, I would like to know too if there is a way to see the min/max dimensions supported by a printer. Thx 4 ur fast reply.
Regards,
Alphonsus Eka
|
|
|
|
|
In regard to the BubbleJet printer, it sounds like the paper size may have been added to the system's overall list of available paper sizes, but not actually added to your BubbleJet printer's list of available paper sizes? I still have alot to learn in this area.
I'm not sure what to reccommend. If the printer won't accept the paper size, you'll have to ask the Manufacturer what to do about it. We have had a similar problem at work and finally got StarMicronics tech support department to send a different driver which supported our paper size. Man, they're one of the most difficult tech support depts ever!
|
|
|
|
|
yes, I think the paper size may have been added to the system's overall list of available paper sizes, but not added to my BubbleJet printer's list of available paper sizes.
Yeah, if u need a printer to use custom paper size, think you should contact the manufacturer, asking for driver to support the paper size.
I've just contacted by my manager, says that the printer that we'll use, will always dot matrix. So I don't think there will be any problem.
May be, I'll try to do some research, how to make an exception if the papersize added, is not supported by the printer.
Thanks for the assistance. Sorry 4 my English
Regards,
Alphonsus Eka
|
|
|
|
|
If i want to remove the form altogether will this work or do i have to do anything else
<br />
public static void RemoveCustomPaperSizeFromPrinter(string paperName, string printerName)<br />
{<br />
if (PlatformID.Win32NT == Environment.OSVersion.Platform)<br />
{<br />
const int PRINTER_ACCESS_USE = 0x00000008;<br />
const int PRINTER_ACCESS_ADMINISTER = 0x00000004;<br />
const int FORM_PRINTER = 0x00000002;<br />
<br />
structPrinterDefaults defaults = new structPrinterDefaults();<br />
defaults.pDatatype = null;<br />
defaults.pDevMode = IntPtr.Zero;<br />
defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;<br />
<br />
IntPtr hPrinter = IntPtr.Zero;<br />
<br />
if (OpenPrinter(printerName, out hPrinter, ref defaults))<br />
{<br />
try<br />
{<br />
DeleteForm(hPrinter, paperName);<br />
}<br />
catch<br />
{ }<br />
finally<br />
{<br />
ClosePrinter(hPrinter);<br />
}<br />
}<br />
}<br />
}
|
|
|
|
|
That looks correct to me. Have you had any luck with it?
|
|
|
|
|
i havent tried it yet to be honest ill let you know how it goes and you can add it to the code if you want.
|
|
|
|
|
download link doesnt seem to be working.
I was trying to do this a while back but couldnt figure it out and gave up. Cant wait to see how you approached it.
|
|
|
|
|
Thanks for the heads up. Its fixed now
--Travis
|
|
|
|
|