Click here to Skip to main content
15,890,897 members
Articles / Programming Languages / C#

Adding Custom Paper Sizes to Named Printers

Rate me:
Please Sign up or sign in to vote.
4.92/5 (31 votes)
11 Nov 20054 min read 338.7K   10.1K   59   66
Using PIinvoke and marshaling techniques to call the winspool library's AddForm

Introduction

My company needed me to programmatically add a custom paper size (a printer form) to the default printer and set the printer to use the custom paper size. After looking around, the best alternative we could find was to make use of the printing and print spooling Win32 API functions found in winspool.drv. The functions used in the project are AddForm, DeleteForm, DocumentProperties, GetPrinter and SetPrinter along with some others. The target platform is WinNT / 2000 / XP although there was already some support for earlier versions of Windows added before I began working on the project. I've never tried to use that section of code but I'm pretty sure that it will only add the custom paper size and not set the printer to use it.

Challenges

Calling these from C# required a little bit more knowledge of marshaling techniques than I had under my belt as I was only able to get as far as getting a handle to the default printer using the winspool functions GetDefaultPrinter and OpenPrinter before requiring some help. At that point, we opened a support case with Microsoft and they sent a nice C# project with the working AddForm calls. However, when we asked about setting the printer to use the newly created form, the best they could do was provide a VB.NET project. So, I ported VB.NET over to C#. Our last requirement was to signal the previously open applications of the settings change and this was done using SendMessageTimeout from user32.dll.

Implementation

Rather than make a call to the Win32 GetDefaultPrinter function (which you have to call twice, once to get the size of the string and another time to get the string) there is an easier way to get the default printer name provided in the .NET platform:

C#
using System.Drawing.Printing;
...
PrintDocument pd = new PrintDocument();
string sPrinterName = pd.PrinterSettings.PrinterName;

After getting the printer name, get a handle to the printer:

C#
bool bGotPrinter = OpenPrinter(printerName, out hPrinter, ref defaults);

At this point, we can delete the custom paper size by name:

C#
// delete the form incase it already exists
DeleteForm(hPrinter, paperName);

And create the paper size:

C#
// 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;

Add the paper size to the printer's list of available paper sizes:

C#
bool bFormAdded = AddForm(hPrinter, 1, ref formInfo);

I'll leave setting the printer to use the newly added form and signaling open apps of the settings change out for now. Have a look at the demo project, it's all there.

Caveat

This project is currently set up to add a custom paper size of 104 mm*4000 mm to the default printer. It attempts to do this in the Form1_Load event of Test.cs. If you run this on a computer with a default printer that doesn't support these dimensions, the paper size will not show up in the list of available paper sizes for your default printer and no exceptions will be generated. If you'd like to test run a test that will work, specify a smaller paper size that your printer will support. You can convert millimeters to inches by multiplying the millimeters by 25.4. I didn't take the time to add any 'add custom paper size in inches' functionality to this project. It could be done very easily by dividing the inches by 25.4 and passing off to the 'add custom paper size by mm' function which already exists.

Check to See If It Worked

The project is set to open small form with single 'Open Dialog' button after adding the custom paper size. Clicking the button opens a print dialog window. To see the list of available printer sizes for the default printer, click the properties button (opens the Properties window) and then the advanced button (opens advanced options window). You can now see the list of available paper sizes for the printer.

To check that it worked from Windows XP, open the printers and faxes window (start menu, printers and faxes), right click on your default printer (the one with the check box next to it) and select properties (opens Properties window), click the printing preferences button (opens Preferences window), click the advanced button (opens Advanced Options window) and then you can see a list of paper sizes.

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralContact me at componentworks.net Pin
twostepted18-Jan-07 17:15
twostepted18-Jan-07 17:15 
Generalthanks for this nice code Pin
Shah Kazmi18-Jan-07 6:48
Shah Kazmi18-Jan-07 6:48 
GeneralRe: thanks for this nice code Pin
twostepted18-Jan-07 17:12
twostepted18-Jan-07 17:12 
GeneralIt made some kind of problem Pin
Aviad Barel16-Nov-06 5:45
Aviad Barel16-Nov-06 5:45 
GeneralRe: It made some kind of problem Pin
twostepted16-Nov-06 7:42
twostepted16-Nov-06 7:42 
QuestionDo you have these code in VB.net? Pin
taneyezone14-Nov-06 22:13
taneyezone14-Nov-06 22:13 
AnswerRe: Do you have these code in VB.net? Pin
twostepted14-Nov-06 23:45
twostepted14-Nov-06 23:45 
AnswerRe: Do you have these code in VB.net? Pin
junk3305-Apr-07 12:14
junk3305-Apr-07 12:14 
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 />
	/// <summary><br />
	/// Summary description for CLS_PrintPaper.<br />
	/// Original creator Website: http://www.codeproject.com/csharp/custom_paper_sizes.asp<br />
	/// <br />
	/// As I am unable to convert this to vb.net 2003(do no understand whats going on), <br />
	/// I did the most obvios thing. Create a DLL of it. Wich can be referenced and called in vb.net<br />
	/// <br />
	/// added the support (copy/paste work) for removing custom paper sizes)<br />
	/// <br />
	/// <br />
	/// <br />
	/// </summary><br />
	public class CLS_PrintPaper<br />
	{<br />
		// Make a static class<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/* changed from CharSet=CharSet.Auto */)]<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 />
		/*    This method is not used<br />
				[DllImport("winspool.Drv", EntryPoint="SetForm", SetLastError=true,<br />
					 CharSet=CharSet.Unicode, ExactSpelling=false,<br />
					 CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]<br />
				internal static extern bool SetForm(IntPtr phPrinter, string paperName,<br />
					[MarshalAs(UnmanagedType.I4)] int level, ref FormInfo1 form);<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 />
		 LONG DocumentProperties(<br />
		   HWND hWnd,               // handle to parent window <br />
		   HANDLE hPrinter,         // handle to printer object<br />
		   LPTSTR pDeviceName,      // device name<br />
		   PDEVMODE pDevModeOutput, // modified device mode<br />
		   PDEVMODE pDevModeInput,  // original device mode<br />
		   DWORD fMode              // mode options<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 /* changed from String to string */,<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 /* changed type from Int32 */,<br />
			IntPtr pPrinter,<br />
			int dwBuf /* chagned from Int32*/, <br />
			out int dwNeeded /* changed from Int32*/<br />
			); <br />
<br />
		// SendMessageTimeout tools<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 />
		/// <summary><br />
		/// Adds the printer form to the default printer<br />
		/// </summary><br />
		/// <param name="paperName">Name of the printer form</param><br />
		/// <param name="widthMm">Width given in millimeters</param><br />
		/// <param name="heightMm">Height given in millimeters</param><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 />
		/// <summary><br />
		/// Add the printer form to a printer <br />
		/// </summary><br />
		/// <param name="printerName">The printer name</param><br />
		/// <param name="paperName">Name of the printer form</param><br />
		/// <param name="widthMm">Width given in millimeters</param><br />
		/// <param name="heightMm">Height given in millimeters</param><br />
		public static void AddCustomPaperSize(string printerName, string paperName, float<br />
			widthMm, float heightMm)<br />
		{<br />
			if (PlatformID.Win32NT == Environment.OSVersion.Platform)<br />
			{<br />
				// The code to add a custom paper size is different for Windows NT then it is<br />
				// for previous versions of windows<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 />
				// Open the printer.<br />
				if (OpenPrinter(printerName, out hPrinter, ref defaults))<br />
				{<br />
					try<br />
					{<br />
						// delete the form incase it already exists<br />
						DeleteForm(hPrinter, paperName);<br />
						// create and initialize the FORM_INFO_1 structure<br />
						FormInfo1 formInfo = new FormInfo1();<br />
						formInfo.Flags = 0;<br />
						formInfo.pName = paperName;<br />
						// all sizes in 1000ths of millimeters<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 />
						// INIT<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 />
						// GET THE SIZE OF THE DEV_MODE BUFFER<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 />
						// ALLOCATE THE BUFFER<br />
						IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize + 100);<br />
<br />
						// GET A POINTER TO THE DEV_MODE BUFFER <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 />
						// FILL THE DEV_MODE STRUCTURE<br />
						devMode = (structDevMode)Marshal.PtrToStructure(hDevMode, devMode.GetType());<br />
<br />
						// SET THE FORM NAME FIELDS TO INDICATE THAT THIS FIELD WILL BE MODIFIED<br />
						devMode.dmFields = 0x10000; // DM_FORMNAME <br />
						// SET THE FORM NAME<br />
						devMode.dmFormName = paperName; <br />
<br />
						// PUT THE DEV_MODE STRUCTURE BACK INTO THE POINTER<br />
						Marshal.StructureToPtr(devMode, hDevMode, true);<br />
<br />
						// MERGE THE NEW CHAGES WITH THE OLD<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 />
						// GET THE PRINTER INFO SIZE<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 />
						// ALLOCATE THE BUFFER<br />
						hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100);<br />
<br />
						// GET A POINTER TO THE PRINTER INFO BUFFER<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 />
						// FILL THE PRINTER INFO STRUCTURE<br />
						printerInfo = (PRINTER_INFO_9)Marshal.PtrToStructure(hPrinterInfo, printerInfo.GetType());<br />
						printerInfo.pDevMode = hDevMode;<br />
<br />
						// GET A POINTER TO THE PRINTER INFO STRUCTURE<br />
						Marshal.StructureToPtr(printerInfo, hPrinterInfo, true);<br />
<br />
						// SET THE PRINTER SETTINGS<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 />
						// Tell all open programs that this change occurred.<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 />
				// The code to add a custom paper size is different for Windows NT then it is<br />
				// for previous versions of windows<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 />
				// Open the printer.<br />
				if (OpenPrinter(printerName, out hPrinter, ref defaults))<br />
				{<br />
					try<br />
					{<br />
						// delete the form incase it already exists<br />
						DeleteForm(hPrinter, paperName);<br />
						<br />
						IntPtr  hDummy;<br />
						// Tell all open programs that this change occurred.<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 />

AnswerRe: Do you have these code in VB.net? Pin
Deoinbox2-Aug-07 16:47
Deoinbox2-Aug-07 16:47 
GeneralWhy does it not work Pin
Murre5-Nov-06 21:40
Murre5-Nov-06 21:40 
GeneralRe: Why does it not work Pin
Murre6-Nov-06 20:28
Murre6-Nov-06 20:28 
GeneralRe: Why does it not work Pin
tommydxz220-Aug-07 3:35
tommydxz220-Aug-07 3:35 
GeneralAdding form Pin
Amphysvena6-Dec-05 20:27
Amphysvena6-Dec-05 20:27 
GeneralRe: Adding form Pin
twostepted7-Dec-05 18:44
twostepted7-Dec-05 18:44 
GeneralRe: Adding form Pin
Amphysvena7-Dec-05 19:28
Amphysvena7-Dec-05 19:28 
GeneralRe: Adding form Pin
twostepted11-Dec-05 16:56
twostepted11-Dec-05 16:56 
GeneralRe: Adding form Pin
Amphysvena11-Dec-05 17:16
Amphysvena11-Dec-05 17:16 
QuestionRemoving forms Pin
o_pontios15-Nov-05 17:14
o_pontios15-Nov-05 17:14 
AnswerRe: Removing forms Pin
twostepted16-Nov-05 16:08
twostepted16-Nov-05 16:08 
GeneralRe: Removing forms Pin
o_pontios16-Nov-05 18:16
o_pontios16-Nov-05 18:16 
GeneralDownload link Pin
o_pontios13-Nov-05 10:30
o_pontios13-Nov-05 10:30 
GeneralRe: Download link Pin
twostepted15-Nov-05 15:34
twostepted15-Nov-05 15:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.