|
Hi
I'm trying to execute the code u've given. but where ever I change the setting of the printer (like... papersource, orientation...) it is not getting reflected into my printer driver properties. How do I make those settings permenent ?
karthik
|
|
|
|
|
This is just a helpful hint. I check the values of the enumerations defined in System.Drawing.Printing, and there values map directly to the short values in the DEVMODE structure. Knowing this I modified the above code to work off of the PageSettings, and PaperSettings rather than using the custom PrinterData class that was defined in on of the threads.
Here is the modifications that I made based on reusing the enumeration/classes already in the .NET framework:
using System;
using System.Runtime.InteropServices;
using System.Drawing.Printing;
using System.ComponentModel;
using NowDocs.Util;
namespace CustomprinterSettings
{
#region "Data structure"
#region PRINTER_DEFAULTS
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_DEFAULTS
{
public int pDatatype;
public int pDevMode;
public int DesiredAccess;
}
#endregion PRINTER_DEFAULTS
#region PRINTER_INFO_2
[StructLayout(LayoutKind.Sequential)]
struct PRINTER_INFO_2
{
[MarshalAs(UnmanagedType.LPStr)] public string pServerName;
[MarshalAs(UnmanagedType.LPStr)] public string pPrinterName;
[MarshalAs(UnmanagedType.LPStr)] public string pShareName;
[MarshalAs(UnmanagedType.LPStr)] public string pPortName;
[MarshalAs(UnmanagedType.LPStr)] public string pDriverName;
[MarshalAs(UnmanagedType.LPStr)] public string pComment;
[MarshalAs(UnmanagedType.LPStr)] public string pLocation;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.LPStr)] public string pSepFile;
[MarshalAs(UnmanagedType.LPStr)] public string pPrintProcessor;
[MarshalAs(UnmanagedType.LPStr)] public string pDatatype;
[MarshalAs(UnmanagedType.LPStr)] public string pParameters;
public IntPtr pSecurityDescriptor;
public Int32 Attributes;
public Int32 Priority;
public Int32 DefaultPriority;
public Int32 StartTime;
public Int32 UntilTime;
public Int32 Status;
public Int32 cJobs;
public Int32 AveragePPM;
}
#endregion PRINTER_INFO_2
#region DEVMODE
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
}
#endregion DEVMODE
#endregion "Data structure"
#region PrinterConfiguration
public class PrinterConfiguration
{
#region "Private Variables"
private IntPtr _hPrinter = new System.IntPtr() ;
private PRINTER_DEFAULTS _PrinterValues = new PRINTER_DEFAULTS();
private PRINTER_INFO_2 _pinfo = new PRINTER_INFO_2();
private DEVMODE _Devmode;
private IntPtr _PtrDM;
private IntPtr _PtrPrinterInfo;
private int _SizeOfDevMode = 0;
private int _LastError;
private int _NBytesNeeded;
private long _NRet;
private int _IntError;
private System.Int32 _NJunk;
private IntPtr _YDevModeData;
#endregion
#region "Win API Def"
[DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError=false,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern Int32 GetLastError();
[DllImport("winspool.Drv", EntryPoint="ClosePrinter", SetLastError=true,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern int DocumentProperties (IntPtr hwnd, IntPtr hPrinter,
[MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg,
IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);
[DllImport("winspool.Drv", EntryPoint="GetPrinterA", SetLastError=true, CharSet=CharSet.Ansi,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel,
IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded);
[DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
out IntPtr hPrinter, ref PRINTER_DEFAULTS pd);
[DllImport("winspool.drv", CharSet=CharSet.Ansi, SetLastError=true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr
pPrinter, int Command);
#endregion
#region "Constants"
private const int DM_DUPLEX = 0x1000;
private const int DM_IN_BUFFER = 8;
private const int DM_OUT_BUFFER = 2;
private const int PRINTER_ACCESS_ADMINISTER = 0x4;
private const int PRINTER_ACCESS_USE = 0x8;
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
#endregion
#region "Function to change printer settings"
#region ChangePrinterPaperSize(string PrinterName,PaperSize paperSize)
public bool ChangePrinterPaperSize (string printerName, PaperSize paperSize)
{
try
{
_Devmode = this.GetPrinterSettings( printerName);
_Devmode.dmPaperSize =(short)paperSize.Kind;
if (paperSize.Kind == PaperKind.Custom)
{
_Devmode.dmPaperWidth =
Convert.ToInt16 ((double)Math.Round (((Convert.ToDouble (pageSettings.PaperSize.Width))/100D)*25.4D*10D));
_Devmode.dmPaperLength =
Convert.ToInt16 ((double)Math.Round ((Convert.ToDouble (pageSettings.PaperSize.Height)/100D)*25.4D*10D));
}
Marshal.StructureToPtr( _Devmode,_YDevModeData,true);
_pinfo.pDevMode = _YDevModeData;
_pinfo.pSecurityDescriptor = IntPtr.Zero;
Marshal.StructureToPtr(_pinfo,_PtrPrinterInfo,true);
_LastError = Marshal.GetLastWin32Error();
_NRet = Convert.ToInt16(SetPrinter(_hPrinter, 2, _PtrPrinterInfo, 0));
if (_NRet == 0)
{
//Unable to set shared printer settings.
_LastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(_LastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (_hPrinter != IntPtr.Zero)
{
ClosePrinter(_hPrinter);
}
}
return Convert.ToBoolean(_NRet);
}
#endregion ChangePrinterPaperSize(string PrinterName,PrinterData PS)
#region ChangePrinterOrientation(string PrinterName,bool landscape)
public bool ChangePrinterOrientation (string printerName, bool landscape)
{
try
{
_Devmode = this.GetPrinterSettings( printerName);
_Devmode.dmOrientation = (short)((landscape)?2:1);
Marshal.StructureToPtr( _Devmode,_YDevModeData,true);
_pinfo.pDevMode = _YDevModeData;
_pinfo.pSecurityDescriptor = IntPtr.Zero;
Marshal.StructureToPtr(_pinfo,_PtrPrinterInfo,true);
_LastError = Marshal.GetLastWin32Error();
_NRet = Convert.ToInt16(SetPrinter(_hPrinter, 2, _PtrPrinterInfo, 0));
if (_NRet == 0)
{
//Unable to set shared printer settings.
_LastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(_LastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (_hPrinter != IntPtr.Zero)
{
ClosePrinter(_hPrinter);
}
}
return Convert.ToBoolean(_NRet);
}
#endregion ChangePrinterOrientation(string PrinterName,bool landscape)
#region ChangePrinterSetting(string PrinterName,PageSettings pageSettings)
public bool ChangePrinterSetting(string PrinterName,PageSettings pageSettings)
{
try
{
_Devmode = this.GetPrinterSettings( PrinterName);
_Devmode.dmDefaultSource =(short)pageSettings.PaperSource.Kind;
_Devmode.dmOrientation = (short)((pageSettings.Landscape)?2:1);
_Devmode.dmPaperSize =(short)pageSettings.PaperSize.Kind;
if (pageSettings.PaperSize.Kind == PaperKind.Custom)
{
_Devmode.dmPaperWidth =
Convert.ToInt16 ((double)Math.Round (((Convert.ToDouble (pageSettings.PaperSize.Width))/100D)*25.4D*10D));
_Devmode.dmPaperLength =
Convert.ToInt16 ((double)Math.Round ((Convert.ToDouble (pageSettings.PaperSize.Height)/100D)*25.4D*10D));
}
Marshal.StructureToPtr( _Devmode,_YDevModeData,true);
_pinfo.pDevMode = _YDevModeData;
_pinfo.pSecurityDescriptor = IntPtr.Zero;
/*update driver dependent part of the DEVMODE
1 = DocumentProperties(IntPtr.Zero, _hPrinter, sPrinterName, _YDevModeData
, ref _pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/
Marshal.StructureToPtr(_pinfo,_PtrPrinterInfo,true);
_LastError = Marshal.GetLastWin32Error();
_NRet = Convert.ToInt16(SetPrinter(_hPrinter, 2, _PtrPrinterInfo, 0));
if (_NRet == 0)
{
//Unable to set shared printer settings.
_LastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(_LastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (_hPrinter != IntPtr.Zero)
{
ClosePrinter(_hPrinter);
}
}
return Convert.ToBoolean(_NRet);
}
#endregion ChangePrinterSetting(string PrinterName,PageSettings pageSettings)
#region ChangePrinterSetting(string PrinterName,PageSettings pageSettings, Duplex duplex)
public bool ChangePrinterSetting(string PrinterName,PageSettings pageSettings, Duplex duplex)
{
try
{
_Devmode = this.GetPrinterSettings( PrinterName);
_Devmode.dmDefaultSource =(short)pageSettings.PaperSource.Kind;
_Devmode.dmOrientation = (short)((pageSettings.Landscape)?2:1);
_Devmode.dmPaperSize =(short)pageSettings.PaperSize.Kind;
if (pageSettings.PaperSize.Kind == PaperKind.Custom)
{
_Devmode.dmPaperWidth =
Convert.ToInt16 ((double)Math.Round (((Convert.ToDouble (pageSettings.PaperSize.Width))/100D)*25.4D*10D));
_Devmode.dmPaperLength =
Convert.ToInt16 ((double)Math.Round ((Convert.ToDouble (pageSettings.PaperSize.Height)/100D)*25.4D*10D));
}
_Devmode.dmDuplex = (short)duplex;
Marshal.StructureToPtr( _Devmode,_YDevModeData,true);
_pinfo.pDevMode = _YDevModeData;
_pinfo.pSecurityDescriptor = IntPtr.Zero;
/*update driver dependent part of the DEVMODE
1 = DocumentProperties(IntPtr.Zero, _hPrinter, sPrinterName, _YDevModeData
, ref _pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/
Marshal.StructureToPtr(_pinfo,_PtrPrinterInfo,true);
_LastError = Marshal.GetLastWin32Error();
_NRet = Convert.ToInt16(SetPrinter(_hPrinter, 2, _PtrPrinterInfo, 0));
if (_NRet == 0)
{
//Unable to set shared printer settings.
_LastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(_LastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (_hPrinter != IntPtr.Zero)
{
ClosePrinter(_hPrinter);
}
}
return Convert.ToBoolean(_NRet);
}
#endregion ChangePrinterSetting(string PrinterName,PageSettings pageSettings, bool landscape)
#region ChangePrinterSetting(string PrinterName,Duplex duplex)
public bool ChangePrinterSetting(string PrinterName,Duplex duplex)
{
try
{
_Devmode = this.GetPrinterSettings( PrinterName);
_Devmode.dmDuplex = (short)duplex;
Marshal.StructureToPtr( _Devmode,_YDevModeData,true);
_pinfo.pDevMode = _YDevModeData;
_pinfo.pSecurityDescriptor = IntPtr.Zero;
/*update driver dependent part of the DEVMODE
1 = DocumentProperties(IntPtr.Zero, _hPrinter, sPrinterName, _YDevModeData
, ref _pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/
Marshal.StructureToPtr(_pinfo,_PtrPrinterInfo,true);
_LastError = Marshal.GetLastWin32Error();
_NRet = Convert.ToInt16(SetPrinter(_hPrinter, 2, _PtrPrinterInfo, 0));
if (_NRet == 0)
{
//Unable to set shared printer settings.
_LastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(_LastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (_hPrinter != IntPtr.Zero)
{
ClosePrinter(_hPrinter);
}
}
return Convert.ToBoolean(_NRet);
}
#endregion ChangePrinterSetting(string PrinterName,Duplex duplex)
#region GetPrinterSettings(string PrinterName)
private DEVMODE GetPrinterSettings(string PrinterName)
{
DEVMODE devmode;
const int PRINTER_ACCESS_ADMINISTER = 0x4;
const int PRINTER_ACCESS_USE = 0x8;
const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
_PrinterValues.pDatatype =0;
_PrinterValues.pDevMode = 0 ;
_PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
_NRet = Convert.ToInt32(OpenPrinter(PrinterName, out _hPrinter, ref _PrinterValues));
if (_NRet == 0)
{
_LastError = Marshal.GetLastWin32Error();
throw new Win32Exception(Marshal.GetLastWin32Error());
}
GetPrinter(_hPrinter, 2, IntPtr.Zero, 0, out _NBytesNeeded);
if (_NBytesNeeded <= 0)
{
throw new System.Exception("Unable to allocate memory");
}
else
{
// Allocate enough space for PRINTER_INFO_2... {ptrPrinterIn fo = Marshal.AllocCoTaskMem(_NBytesNeeded)};
_PtrPrinterInfo = Marshal.AllocHGlobal(_NBytesNeeded);
// The second GetPrinter fills in all the current settings, so all you // need to do is modify what you're interested in...
_NRet = Convert.ToInt32(GetPrinter(_hPrinter, 2, _PtrPrinterInfo, _NBytesNeeded, out _NJunk));
if (_NRet == 0)
{
_LastError = Marshal.GetLastWin32Error();
throw new Win32Exception(Marshal.GetLastWin32Error());
}
_pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure(_PtrPrinterInfo, typeof(PRINTER_INFO_2));
IntPtr Temp = new IntPtr();
if (_pinfo.pDevMode == IntPtr.Zero)
{
// If GetPrinter didn't fill in the DEVMODE, try to get it by calling
// DocumentProperties...
IntPtr ptrZero = IntPtr.Zero;
//get the size of the devmode structure
_SizeOfDevMode = DocumentProperties(IntPtr.Zero, _hPrinter, PrinterName, ptrZero, ref ptrZero, 0);
_PtrDM = Marshal.AllocCoTaskMem(_SizeOfDevMode);
int i ;
i = DocumentProperties(IntPtr.Zero, _hPrinter, PrinterName, _PtrDM, ref ptrZero, DM_OUT_BUFFER);
if ((i < 0) || (_PtrDM == IntPtr.Zero))
{
//Cannot get the DEVMODE structure.
throw new System.Exception("Cannot get DEVMODE data");
}
_pinfo.pDevMode = _PtrDM;
}
_IntError = DocumentProperties(IntPtr.Zero, _hPrinter, PrinterName, IntPtr.Zero , ref Temp , 0);
//IntPtr _YDevModeData = Marshal.AllocCoTaskMem(i1);
_YDevModeData= Marshal.AllocHGlobal(_IntError);
_IntError = DocumentProperties(IntPtr.Zero, _hPrinter, PrinterName, _YDevModeData , ref Temp , 2);
devmode = (DEVMODE)Marshal.PtrToStructure(_YDevModeData, typeof(DEVMODE));
//_NRet = DocumentProperties(IntPtr.Zero, _hPrinter, sPrinterName, _YDevModeData
// , ref _YDevModeData, (DM_IN_BUFFER | DM_OUT_BUFFER));
if ((_NRet == 0) || (_hPrinter == IntPtr.Zero))
{
_LastError = Marshal.GetLastWin32Error();
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return devmode;
}
}
#endregion GetPrinterSettings(string PrinterName)
#endregion "Function to change printer settings"
}
#endregion PrinterConfiguration
}
|
|
|
|
|
Your alternative to the codes in the thread is quite helpful. But I wonder on how to code to set the dmFormName of DEVMODE structure and use the custom size form as the current form for the Device Context (DC) of the printer without changing current default setting of the printer in C#. Can you give me some hints on that?
Thank you.
|
|
|
|
|
Thanks for this. I wanted some code to change the default paper bin of a printer (so I could get Word to use it). After scouring the internet for a solution I finally came across this article and then your modifications.
I had this code working in minutes.
|
|
|
|
|
Hi,
I'm trying to get the status of the printer; offline, ready, etc. I've used the code in this article to implement a call to GetPrinter, but when i examine the contents of the PRINTER_INFO_2 struct after making the call, all the strings are empty and all the int values are 0. Could anyone shed some light on this problem?
Thanks
|
|
|
|
|
Hi,
GetPrint() works for me, it returns portName, job count, ...
But it always gives status=0 !
Reason is:
http://support.microsoft.com/kb/160129[^]
says:
There is one fundamental premise that must be true to determine the state of a physical printer: the Spooler must be attempting to send a print job to the physical printer. This is the only time the state of the printer is reported by the port monitor.
-- modified at 16:55 Tuesday 30th January, 2007
Luc Pattyn
|
|
|
|
|
I can't get this to change my PaperSource in .Net
Can anyone figure out how I can change the papersource?
Thanks,
Trint
|
|
|
|
|
Dear
Your code is working very fine. I have one confusion. I want to get the status of the printer (whether it is Offline, Paper Jam, Tonner Low etc). Is it possible with Printer_Info_2 structure. I have not seen any flag for these.
regards
|
|
|
|
|
Hi,
there is a uint Status field, but I always get zero.
Reason is:
http://support.microsoft.com/kb/160129[^]
says:
There is one fundamental premise that must be true to determine the state of a physical printer: the Spooler must be attempting to send a print job to the physical printer. This is the only time the state of the printer is reported by the port monitor.
-- modified at 16:55 Tuesday 30th January, 2007
Luc Pattyn
|
|
|
|
|
Hi, I would like to use this code to store the original tray and chenge the default tray to a new one.
can anybody help me
|
|
|
|
|
I am getting the information related to the local printers, but when I pass the network printer name it is displaying invalid printer name.
Could u help me.
|
|
|
|
|
Hello the code seems working, but how do i implement it i.e. how do i call this function, should i pass the printersettings to Word.print2000? or should just call this function and then do Word.print2000 ,
please provide me some hints.
Thx
Ganesh.K
|
|
|
|
|
Hello, were you able to implement this function? I'm kinda stuck on this too. Could you throw in some ideas how to accomplish this? I'm trying to change the printer settings to landscape.
TIA
-V
|
|
|
|
|
umeshb,
I am trying to access the advanced properties of a "toshiba print driver" and change the DM_COLOR_COLOR & DM_COLOR_MONOCHROME attributes.
I tried using your example but am struggling, can you provide me with some more detail about how I could accomplish this.
Cheers,
Joe Pirie
|
|
|
|
|
I am getting Accedd Denied Error while trying to open the Printer to get the Printer settings, while trying to change to Duplex mode.
However I am able to open the Network printer and print using Win32API single sided.
Any comments?
|
|
|
|
|
I m also getting Access denied error.
As per my requirement i need to access only network printers. So i can able to access that and can use all the Win32Api cals except for SetPrinter().
I want to change page orientation to LandScape so i tried with that function but on process of execution at SetPrinter() it fails and returns me Access Denied.
So can u please help me to atchieve this.
praveen.k.tumula@ib.ibm.com
9866640127
Praveen Kumar Tumula
|
|
|
|
|
Hi I'm still a newbie in c#. If i'm not mistaken, your code is to change the printer setting. But the setting itself is not custom.
What i want to know is, can we create a custom printer form to our local printer using c# or vb.net. then use the custom form to print.
Thank u for your attention
|
|
|
|
|
In the function "public bool ChangePrinterSetting(string PrinterName,PrinterData PS)" you are passing in PrinterData. I am getting a namespace error from this. You did not include your using statements so I do not know where this object is derived from. Can you explain? A buildable class library solution would be nice.
|
|
|
|
|
Hi
Sorry i did not give the complete code. Pls find the working code. Just copy and past the code , i should work.
using System;
using System.Runtime.InteropServices;
using System.Drawing.Printing ;
using System.ComponentModel;
namespace CustomprinterSettings
{
///
/// Summary description for Class1.
///
///
/*[Flags] private enum ACCESS_MASK
{
PRINTER_ACCESS_ADMINISTER = 4,
PRINTER_ACCESS_USE = 8,
PRINTER_ALL_ACCESS = 983052
}*/
public enum PageOrientation
{
DMORIENT_PORTRAIT =1,
DMORIENT_LANDSCAPE =2
}
public enum PaperSize
{
// Paper selections
DMPAPER_LETTER = 1, // Letter 8 1/2 x 11 in
DMPAPER_LETTERSMALL = 2, // Letter Small 8 1/2 x 11 in
DMPAPER_TABLOID = 3, // Tabloid 11 x 17 in
DMPAPER_LEDGER = 4, // Ledger 17 x 11 in
DMPAPER_LEGAL = 5, // Legal 8 1/2 x 14 in
DMPAPER_STATEMENT = 6, // Statement 5 1/2 x 8 1/2 in
DMPAPER_EXECUTIVE = 7, // Executive 7 1/4 x 10 1/2 in
DMPAPER_A3 = 8, // A3 297 x 420 mm
DMPAPER_A4 = 9, // A4 210 x 297 mm
DMPAPER_A4SMALL = 10, // A4 Small 210 x 297 mm
DMPAPER_A5 = 11, // A5 148 x 210 mm
DMPAPER_B4 = 12, // B4 250 x 354
DMPAPER_B5 = 13, // B5 182 x 257 mm
DMPAPER_FOLIO = 14, // Folio 8 1/2 x 13 in
DMPAPER_QUARTO = 15, // Quarto 215 x 275 mm
DMPAPER_10X14 = 16, // 10x14 in
DMPAPER_11X17 = 17, // 11x17 in
DMPAPER_NOTE = 18, // Note 8 1/2 x 11 in
DMPAPER_ENV_9 = 19, // Envelope #9 3 7/8 x 8 7/8
DMPAPER_ENV_10 = 20, // Envelope #10 4 1/8 x 9 1/2
DMPAPER_ENV_11 = 21, // Envelope #11 4 1/2 x 10 3/8
DMPAPER_ENV_12 = 22, // Envelope #12 4 \276 x 11
DMPAPER_ENV_14 = 23, // Envelope #14 5 x 11 1/2
DMPAPER_CSHEET = 24, // C size sheet
DMPAPER_DSHEET = 25, // D size sheet
DMPAPER_ESHEET = 26, // E size sheet
DMPAPER_ENV_DL = 27, // Envelope DL 110 x 220mm
DMPAPER_ENV_C5 = 28, // Envelope C5 162 x 229 mm
DMPAPER_ENV_C3 = 29, // Envelope C3 324 x 458 mm
DMPAPER_ENV_C4 = 30, // Envelope C4 229 x 324 mm
DMPAPER_ENV_C6 = 31, // Envelope C6 114 x 162 mm
DMPAPER_ENV_C65 = 32, // Envelope C65 114 x 229 mm
DMPAPER_ENV_B4 = 33, // Envelope B4 250 x 353 mm
DMPAPER_ENV_B5 = 34, // Envelope B5 176 x 250 mm
DMPAPER_ENV_B6 = 35, // Envelope B6 176 x 125 mm
DMPAPER_ENV_ITALY = 36, // Envelope 110 x 230 mm
DMPAPER_ENV_MONARCH = 37, // Envelope Monarch 3.875 x 7.5 in
DMPAPER_ENV_PERSONAL = 38, // 6 3/4 Envelope 3 5/8 x 6 1/2 in
DMPAPER_FANFOLD_US = 39, // US Std Fanfold 14 7/8 x 11 in
DMPAPER_FANFOLD_STD_GERMAN = 40 , // German Std Fanfold 8 1/2 x 12 in
DMPAPER_FANFOLD_LGL_GERMAN = 41, // German Legal Fanfold 8 1/2 x 13 in
DMPAPER_FIRST = DMPAPER_LETTER,
DMPAPER_LAST = DMPAPER_FANFOLD_LGL_GERMAN,
}
public enum PageDuplex
{
DMDUP_HORIZONTAL = 3,
DMDUP_SIMPLEX = 1,
DMDUP_VERTICAL = 2
}
public enum PaperSource
{
DMBIN_UPPER = 1,
DMBIN_LOWER = 2,
DMBIN_MIDDLE = 3,
DMBIN_MANUAL = 4,
DMBIN_ENVELOPE = 5,
DMBIN_ENVMANUAL = 6,
DMBIN_AUTO = 7,
DMBIN_TRACTOR = 8,
DMBIN_SMALLFMT = 9,
DMBIN_LARGEFMT = 10,
DMBIN_LARGECAPACITY = 11,
DMBIN_CASSETTE = 14,
DMBIN_FORMSOURCE = 15,
DMRES_DRAFT = -1,
DMRES_LOW = -2,
DMRES_MEDIUM = -3,
DMRES_HIGH = -4
}
#region "Data structure"
public struct PrinterData
{
public PageOrientation Orientation;
public PaperSize Size;
public PaperSource source;
public PageDuplex Duplex;
}
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_DEFAULTS
{
public int pDatatype;
public int pDevMode;
public int DesiredAccess;
}
/*[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct PRINTER_DEFAULTS
{
public int pDataType;
public IntPtr pDevMode;
public ACCESS_MASK DesiredAccess;
}*/
[StructLayout(LayoutKind.Sequential)]
struct PRINTER_INFO_2
{
[MarshalAs(UnmanagedType.LPStr)] public string pServerName;
[MarshalAs(UnmanagedType.LPStr)] public string pPrinterName;
[MarshalAs(UnmanagedType.LPStr)] public string pShareName;
[MarshalAs(UnmanagedType.LPStr)] public string pPortName;
[MarshalAs(UnmanagedType.LPStr)] public string pDriverName;
[MarshalAs(UnmanagedType.LPStr)] public string pComment;
[MarshalAs(UnmanagedType.LPStr)] public string pLocation;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.LPStr)] public string pSepFile;
[MarshalAs(UnmanagedType.LPStr)] public string pPrintProcessor;
[MarshalAs(UnmanagedType.LPStr)] public string pDatatype;
[MarshalAs(UnmanagedType.LPStr)] public string pParameters;
public IntPtr pSecurityDescriptor;
public Int32 Attributes;
public Int32 Priority;
public Int32 DefaultPriority;
public Int32 StartTime;
public Int32 UntilTime;
public Int32 Status;
public Int32 cJobs;
public Int32 AveragePPM;
}
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
}
#endregion
public class PrinterSettings
{
#region "Private Variables"
private IntPtr hPrinter = new System.IntPtr() ;
private PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();
private PRINTER_INFO_2 pinfo = new PRINTER_INFO_2();
private DEVMODE dm;
private IntPtr ptrDM;
private IntPtr ptrPrinterInfo;
private int sizeOfDevMode = 0;
private int lastError;
private int nBytesNeeded;
private long nRet;
private int intError;
private System.Int32 nJunk;
private IntPtr yDevModeData;
#endregion
#region "Win API Def"
[DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError=false,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern Int32 GetLastError();
[DllImport("winspool.Drv", EntryPoint="ClosePrinter", SetLastError=true,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern int DocumentProperties (IntPtr hwnd, IntPtr hPrinter,
[MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg,
IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);
[DllImport("winspool.Drv", EntryPoint="GetPrinterA", SetLastError=true, CharSet=CharSet.Ansi,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel,
IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded);
/*[DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
out IntPtr hPrinter, ref PRINTER_DEFAULTS pd)
[ DllImport( "winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=false,
CallingConvention=CallingConvention.StdCall )]
public static extern long OpenPrinter(string pPrinterName,ref IntPtr phPrinter, int pDefault);*/
/*[DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
out IntPtr hPrinter, ref PRINTER_DEFAULTS pd);
*/
[DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
out IntPtr hPrinter, ref PRINTER_DEFAULTS pd);
[DllImport("winspool.drv", CharSet=CharSet.Ansi, SetLastError=true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr
pPrinter, int Command);
/*[DllImport("winspool.drv", CharSet=CharSet.Ansi, SetLastError=true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr
pPrinter, int Command);*/
// Wrapper for Win32 message formatter.
/*[DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private unsafe static extern int FormatMessage( int dwFlags,
ref IntPtr pMessageSource,
int dwMessageID,
int dwLanguageID,
ref string lpBuffer,
int nSize,
IntPtr* pArguments);*/
#endregion
#region "Constants"
private const int DM_DUPLEX = 0x1000;
private const int DM_IN_BUFFER = 8;
private const int DM_OUT_BUFFER = 2;
private const int PRINTER_ACCESS_ADMINISTER = 0x4;
private const int PRINTER_ACCESS_USE = 0x8;
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
#endregion
#region "Function to change printer settings"
public bool ChangePrinterSetting(string PrinterName,PrinterData PS)
{
if (((int)PS.Duplex < 1) || ((int)PS.Duplex > 3) )
{
throw new ArgumentOutOfRangeException("nDuplexSetting","nDuplexSetting is incorrect.");
}
else
{
dm = this.GetPrinterSettings( PrinterName);
dm.dmDefaultSource =(short)PS.source;
dm.dmOrientation = (short)PS.Orientation;
dm.dmPaperSize =(short)PS.Size;
dm.dmDuplex = (short)PS.Duplex;
Marshal.StructureToPtr( dm,yDevModeData,true);
pinfo.pDevMode = yDevModeData;
pinfo.pSecurityDescriptor = IntPtr.Zero;
/*update driver dependent part of the DEVMODE
1 = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, yDevModeData
, ref pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/
Marshal.StructureToPtr(pinfo,ptrPrinterInfo,true);
lastError = Marshal.GetLastWin32Error();
nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));
if (nRet == 0)
{
//Unable to set shared printer settings.
lastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(lastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (hPrinter != IntPtr.Zero)
ClosePrinter(hPrinter);
return Convert.ToBoolean(nRet);
}
}
private DEVMODE GetPrinterSettings(string PrinterName)
{
PrinterData PData = new PrinterData();
DEVMODE dm;
const int PRINTER_ACCESS_ADMINISTER = 0x4;
const int PRINTER_ACCESS_USE = 0x8;
const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
PrinterValues.pDatatype =0;
PrinterValues.pDevMode = 0 ;
PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
nRet = Convert.ToInt32(OpenPrinter(PrinterName, out hPrinter, ref PrinterValues));
if (nRet == 0)
{
lastError = Marshal.GetLastWin32Error();
throw new Win32Exception(Marshal.GetLastWin32Error());
}
GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out nBytesNeeded);
if (nBytesNeeded <= 0)
{
throw new System.Exception("Unable to allocate memory");
}
else
{
// Allocate enough space for PRINTER_INFO_2... {ptrPrinterIn fo = Marshal.AllocCoTaskMem(nBytesNeeded)};
ptrPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded);
// The second GetPrinter fills in all the current settings, so all you // need to do is modify what you're interested in...
nRet = Convert.ToInt32(GetPrinter(hPrinter, 2, ptrPrinterInfo, nBytesNeeded, out nJunk));
if (nRet == 0)
{
lastError = Marshal.GetLastWin32Error();
throw new Win32Exception(Marshal.GetLastWin32Error());
}
pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure(ptrPrinterInfo, typeof(PRINTER_INFO_2));
IntPtr Temp = new IntPtr();
if (pinfo.pDevMode == IntPtr.Zero)
{
// If GetPrinter didn't fill in the DEVMODE, try to get it by calling
// DocumentProperties...
IntPtr ptrZero = IntPtr.Zero;
//get the size of the devmode structure
sizeOfDevMode = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrZero, ref ptrZero, 0);
ptrDM = Marshal.AllocCoTaskMem(sizeOfDevMode);
int i ;
i = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrDM,
ref ptrZero, DM_OUT_BUFFER);
if ((i < 0) || (ptrDM == IntPtr.Zero))
{
//Cannot get the DEVMODE structure.
throw new System.Exception("Cannot get DEVMODE data");
}
pinfo.pDevMode = ptrDM;
}
intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero , ref Temp , 0);
//IntPtr yDevModeData = Marshal.AllocCoTaskMem(i1);
yDevModeData= Marshal.AllocHGlobal(intError);
intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, yDevModeData , ref Temp , 2);
dm = (DEVMODE)Marshal.PtrToStructure(yDevModeData, typeof(DEVMODE));
//nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, yDevModeData
// , ref yDevModeData, (DM_IN_BUFFER | DM_OUT_BUFFER));
if ((nRet == 0) || (hPrinter == IntPtr.Zero))
{
lastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(lastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return dm;
}
#endregion
}
}
}
|
|
|
|
|
Iam getting error as "nDuplexSetting is incorrect.\r\nParameter name: nDuplexSetting" when i call the below code. I have no idea about this error if u have solution for this problem please respond me . my mail ID is ssundaram@zeisys.com
thank you
public bool ChangePrinterSetting(string PrinterName, PrinterData PS)
{
if (((int)PS.Duplex < 1) || ((int)PS.Duplex > 3))
{
throw new ArgumentOutOfRangeException("nDuplexSetting", "nDuplexSetting is incorrect.");
}
else
{
dm = this.GetPrinterSettings(PrinterName);
dm.dmDefaultSource = (short)PS.source;
dm.dmOrientation = (short)PS.Orientation;
dm.dmPaperSize = (short)PS.Size;
dm.dmDuplex = (short)PS.Duplex;
Marshal.StructureToPtr(dm, yDevModeData, true);
pinfo.pDevMode = yDevModeData;
pinfo.pSecurityDescriptor = IntPtr.Zero;
/*update driver dependent part of the DEVMODE
1 = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, yDevModeData
, ref pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/
Marshal.StructureToPtr(pinfo, ptrPrinterInfo, true);
lastError = Marshal.GetLastWin32Error();
nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));
if (nRet == 0)
{
//Unable to set shared printer settings.
lastError = Marshal.GetLastWin32Error();
//string myErrMsg = GetErrorMessage(lastError);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (hPrinter != IntPtr.Zero)
ClosePrinter(hPrinter);
return Convert.ToBoolean(nRet);
}
}
with regards
Shanmugam
|
|
|
|
|
Hello!
I've just implemented the code and it works very fine. Just a great work. Thanks.
I think you must set _all_ properties of the PrintData-Structure. The Properties have no default values.
Example:
PrinterData data = new PrinterData();
data.Orientation = PageOrientation.DMORIENT_LANDSCAPE;
data.Duplex = PageDuplex.DMDUP_SIMPLEX;
data.Size = PaperSize.DMPAPER_A3;
data.source = PaperSource.DMBIN_AUTO;
PrinterSettings settings = new PrinterSettings();
settings.ChangePrinterSetting("..", data);
With regards,
Steven
|
|
|
|
|
System.Drawing.Printing.
You can list all printers, print documents, change printer settings... yep...it's all there.
|
|
|
|
|
Hi
Yes i do agree that .NET provides class for chaning printer setting . But pls try to change the printer setting for MS word document, using printer class( particulary duplex property). I will be happy if i get a solution.
|
|
|
|
|
|
hi
You can change the paper size , paper source etc for the page or for full document using page Setup property of the document object using Word API. But we cannot change the duplex property for the printer using Word API. For that we go to use Win API.
When we change the printer setting using WIN API , it effect globally and will effect subsequent prints.
regards,
umesh.b
|
|
|
|
|