Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / CommonUI / System / Drawing / Printing / PrinterSettings.cs / 1305376 / PrinterSettings.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Drawing.Printing { using System.Runtime.Serialization.Formatters; using System.Configuration.Assemblies; using System.Runtime.InteropServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.IO; using System.Security; using System.Security.Permissions; using System.Collections; using System.Collections.Specialized; using System.Drawing; using System.Drawing.Internal; using System.Drawing.Imaging; using System.ComponentModel; using Microsoft.Win32; using System.Globalization; using System.Runtime.Versioning; ////// /// Information about how a document should be printed, including which printer /// to print it on. /// [Serializable] public class PrinterSettings : ICloneable { // All read/write data is stored in managed code, and whenever we need to call Win32, // we create new DEVMODE and DEVNAMES structures. We don't store device capabilities, // though. // // Also, all properties have hidden tri-state logic -- yes/no/default private const int PADDING_IA64 = 4; private string printerName; // default printer. private string driverName = ""; private string outputPort = ""; private bool printToFile; // Whether the PrintDialog has been shown (not whether it's currently shown). This is how we enforce SafePrinting. private bool printDialogDisplayed; private short extrabytes; private byte[] extrainfo; private short copies = -1; private Duplex duplex = System.Drawing.Printing.Duplex.Default; private TriState collate = TriState.Default; private PageSettings defaultPageSettings; private int fromPage; private int toPage; private int maxPage = 9999; private int minPage; private PrintRange printRange; private short devmodebytes; private byte[] cachedDevmode; ////// /// public PrinterSettings() { defaultPageSettings = new PageSettings(this); } ////// Initializes a new instance of the ///class. /// /// /// public bool CanDuplex { get { return DeviceCapabilities(SafeNativeMethods.DC_DUPLEX, IntPtr.Zero, 0) == 1;} } ////// Gets a value indicating whether the printer supports duplex (double-sided) printing. /// ////// /// public short Copies { get { if (copies != -1) return copies; else return GetModeField(ModeField.Copies, 1); } set { if (value < 0) throw new ArgumentException(SR.GetString(SR.InvalidLowBoundArgumentEx, "value", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); /* We shouldnt allow copies to be set since the copies can be a large number and can be reflected in PrintDialog. So for the Copies property, we prefer that for SafePrinting, copied cannot be set programmatically but through the print dialog. Any lower security could set copies to anything. Vs Whidbey 93475*/ IntSecurity.SafePrinting.Demand(); copies = value; } } ////// Gets or sets the number of copies to print. /// ////// /// public bool Collate { get { if (!collate.IsDefault) return(bool) collate; else return GetModeField(ModeField.Collate, SafeNativeMethods.DMCOLLATE_FALSE) == SafeNativeMethods.DMCOLLATE_TRUE; } set { collate = value;} } ////// Gets or sets /// a value indicating whether the print out is collated. /// ////// /// public PageSettings DefaultPageSettings { get { return defaultPageSettings;} } // As far as I can tell, Windows no longer pays attention to driver names and output ports. // But I'm leaving this code in place in case I'm wrong. internal string DriverName { get { return driverName;} // set { driverName = value;} } /* // No point in having a driver version if you can't get the driver name ////// Gets the default page settings for this printer. /// ////// ////// Gets the printer driver version number. /// ////// public int DriverVersion { get { return DeviceCapabilities(SafeNativeMethods.DC_DRIVER, 0, -1);} } */ ////// The printer driver version number. /// ////// /// public Duplex Duplex { get { if (duplex != Duplex.Default) return duplex; else return(Duplex) GetModeField(ModeField.Duplex, SafeNativeMethods.DMDUP_SIMPLEX); } set { //valid values are 0xffffffff to 0x3 if (!ClientUtils.IsEnumValid(value, (int)value, (int)Duplex.Default, (int)Duplex.Horizontal)) { throw new InvalidEnumArgumentException("value", (int)value, typeof(Duplex)); } duplex = value; } } ////// Gets or sets the printer's duplex setting. /// ////// /// public int FromPage { get { return fromPage;} set { if (value < 0) throw new ArgumentException(SR.GetString(SR.InvalidLowBoundArgumentEx, "value", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); fromPage = value; } } ///Gets or sets the first page to print. ////// /// public static StringCollection InstalledPrinters { get { IntSecurity.AllPrinting.Demand(); int returnCode; int bufferSize; int count; int level, sizeofstruct; // Note: Level 5 doesn't seem to work properly on NT platforms // (atleast the call to get the size of the buffer reqd.), // and Level 4 doesn't work on Win9x. // if (Environment.OSVersion.Platform == System.PlatformID.Win32NT) { level = 4; // PRINTER_INFO_4 are 12 bytes in size if (IntPtr.Size == 8) { sizeofstruct = (IntPtr.Size * 2) + (Marshal.SizeOf(typeof(int)) * 1) + PADDING_IA64; } else { sizeofstruct = (IntPtr.Size * 2) + (Marshal.SizeOf(typeof(int)) * 1); } } else { level = 5; // PRINTER_INFO_5 are 20 bytes in size sizeofstruct = (IntPtr.Size * 2) + (Marshal.SizeOf(typeof(int)) * 3); } string[] array; IntSecurity.UnmanagedCode.Assert(); try { SafeNativeMethods.EnumPrinters(SafeNativeMethods.PRINTER_ENUM_LOCAL | SafeNativeMethods.PRINTER_ENUM_CONNECTIONS, null, level, IntPtr.Zero, 0, out bufferSize, out count); IntPtr buffer = Marshal.AllocCoTaskMem(bufferSize); returnCode = SafeNativeMethods.EnumPrinters(SafeNativeMethods.PRINTER_ENUM_LOCAL | SafeNativeMethods.PRINTER_ENUM_CONNECTIONS, null, level, buffer, bufferSize, out bufferSize, out count); array = new string[count]; if (returnCode == 0) { Marshal.FreeCoTaskMem(buffer); throw new Win32Exception(); } for (int i = 0; i < count; i++) { // The printer name is at offset 0 // IntPtr namePointer = (IntPtr) Marshal.ReadIntPtr((IntPtr)((long)buffer + i * sizeofstruct)); array[i] = Marshal.PtrToStringAuto(namePointer); } Marshal.FreeCoTaskMem(buffer); } finally { CodeAccessPermission.RevertAssert(); } return new StringCollection(array); } } ////// Gets the names of all printers installed on the machine. /// ////// /// public bool IsDefaultPrinter { get { return (printerName == null || printerName == GetDefaultPrinterName()); } } ////// Gets a value indicating whether the ////// property designates the default printer. /// /// /// public bool IsPlotter { get { return GetDeviceCaps(SafeNativeMethods.TECHNOLOGY, SafeNativeMethods.DT_RASPRINTER) == SafeNativeMethods.DT_PLOTTER; } } ////// Gets a value indicating whether the printer is a plotter, as opposed to a raster printer. /// ////// /// public bool IsValid { get { return DeviceCapabilities(SafeNativeMethods.DC_COPIES, IntPtr.Zero, -1) != -1; } } ////// Gets a value indicating whether the ////// property designates a valid printer. /// /// /// public int LandscapeAngle { get { return DeviceCapabilities(SafeNativeMethods.DC_ORIENTATION, IntPtr.Zero, 0);} } ////// Gets the angle, in degrees, which the portrait orientation is rotated /// to produce the landscape orientation. /// ////// /// public int MaximumCopies { get { return DeviceCapabilities(SafeNativeMethods.DC_COPIES, IntPtr.Zero, 1);} } ////// Gets the maximum number of copies allowed by the printer. /// ////// /// public int MaximumPage { get { return maxPage;} set { if (value < 0) throw new ArgumentException(SR.GetString(SR.InvalidLowBoundArgumentEx, "value", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); maxPage = value; } } ////// Gets or sets the highest ///or /// which may be selected in a print dialog box. /// /// /// public int MinimumPage { get { return minPage;} set { if (value < 0) throw new ArgumentException(SR.GetString(SR.InvalidLowBoundArgumentEx, "value", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); minPage = value; } } internal string OutputPort { get { return outputPort; } set { outputPort = value; } } ///Gets or sets the lowest ///or /// which may be selected in a print dialog box. /// /// public string PrintFileName { get { string printFileName = OutputPort; if (!string.IsNullOrEmpty(printFileName)) { IntSecurity.DemandReadFileIO(printFileName); } return printFileName; } set { if (string.IsNullOrEmpty(value)) { throw new ArgumentNullException(value); } IntSecurity.DemandWriteFileIO(value); OutputPort = value; } } ////// Indicates the name of the printerfile. /// ////// /// public PaperSizeCollection PaperSizes { get { return new PaperSizeCollection(Get_PaperSizes());} } ////// Gets the paper sizes supported by this printer. /// ////// /// public PaperSourceCollection PaperSources { get { return new PaperSourceCollection(Get_PaperSources());} } ////// Gets the paper sources available on this printer. /// ////// internal bool PrintDialogDisplayed { // get { // no security check return printDialogDisplayed; } set { IntSecurity.AllPrinting.Demand(); printDialogDisplayed = value; } } ////// Whether the print dialog has been displayed. In SafePrinting mode, /// a print dialog is required to print. After printing, /// this property is set to false if the program does not have AllPrinting; /// this guarantees a document is only printed once each time the print dialog is shown. /// ////// /// public PrintRange PrintRange { get { return printRange;} [SuppressMessage("Microsoft.Performance", "CA1803:AvoidCostlyCallsWherePossible")] set { if (!Enum.IsDefined(typeof(PrintRange), value)) throw new InvalidEnumArgumentException("value", (int)value, typeof(PrintRange)); printRange = value; } } ////// Gets or sets the pages the user has asked to print. ////// /// Indicates whether to print to a file instead of a port. /// public bool PrintToFile { get { return printToFile; } set { printToFile = value; } } ////// /// public string PrinterName { get { IntSecurity.AllPrinting.Demand(); return PrinterNameInternal; } set { IntSecurity.AllPrinting.Demand(); PrinterNameInternal = value; } } private string PrinterNameInternal { get { if (printerName == null) return GetDefaultPrinterName(); else return printerName; } set { // Reset the DevMode and Extrabytes... cachedDevmode = null; extrainfo = null; printerName = value; // VsWhidbey : 235920: PrinterName can be set through a fulltrusted assembly without using the PrintDialog. // So dont set this variable here. //PrintDialogDisplayed = true; } } ////// Gets or sets the name of the printer. /// ////// /// public PrinterResolutionCollection PrinterResolutions { get { return new PrinterResolutionCollection(Get_PrinterResolutions());} } ////// Gets the resolutions supported by this printer. /// ////// /// If the image is a JPEG or a PNG (Image.RawFormat) and the printer returns true /// from ExtEscape(CHECKJPEGFORMAT) or ExtEscape(CHECKPNGFORMAT) then this function returns true. /// [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals")] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] public bool IsDirectPrintingSupported(ImageFormat imageFormat) { bool isDirectPrintingSupported = false; if (imageFormat.Equals(ImageFormat.Jpeg) || imageFormat.Equals(ImageFormat.Png)) { int nEscape = imageFormat.Equals(ImageFormat.Jpeg) ? SafeNativeMethods.CHECKJPEGFORMAT : SafeNativeMethods.CHECKPNGFORMAT; int outData = 0; DeviceContext dc = CreateInformationContext(DefaultPageSettings); HandleRef hdc = new HandleRef(dc, dc.Hdc); try { isDirectPrintingSupported = SafeNativeMethods.ExtEscape(hdc, SafeNativeMethods.QUERYESCSUPPORT, Marshal.SizeOf(typeof(int)), ref nEscape, 0, out outData) > 0; } finally { dc.Dispose(); } } return isDirectPrintingSupported; } ////// /// [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] public bool IsDirectPrintingSupported(Image image) { bool isDirectPrintingSupported = false; if (image.RawFormat.Equals(ImageFormat.Jpeg) || image.RawFormat.Equals(ImageFormat.Png)) { MemoryStream stream = new MemoryStream(); try { image.Save(stream, image.RawFormat); stream.Position = 0; using (BufferedStream inStream = new BufferedStream(stream)) { int pvImageLen = (int)inStream.Length; byte[] pvImage = new byte[pvImageLen]; int nRead = inStream.Read(pvImage, 0, (int)pvImageLen); int nEscape = image.RawFormat.Equals(ImageFormat.Jpeg) ? SafeNativeMethods.CHECKJPEGFORMAT : SafeNativeMethods.CHECKPNGFORMAT; int outData = 0; DeviceContext dc = CreateInformationContext(DefaultPageSettings); HandleRef hdc = new HandleRef(dc, dc.Hdc); try { bool querySupported = SafeNativeMethods.ExtEscape(hdc, SafeNativeMethods.QUERYESCSUPPORT, Marshal.SizeOf(typeof(int)), ref nEscape, 0, out outData) > 0; if (querySupported) { isDirectPrintingSupported = (SafeNativeMethods.ExtEscape(hdc, nEscape, pvImageLen, pvImage, Marshal.SizeOf(typeof(int)), out outData) > 0) && (outData == 1); } } finally { dc.Dispose(); } } } finally { stream.Close(); } } return isDirectPrintingSupported; } ////// This method utilizes the CHECKJPEGFORMAT/CHECKPNGFORMAT printer escape functions /// to determine whether the printer can handle a JPEG image. /// See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_51ys.asp /// for more information on this printer escape function. /// /// If the image is a JPEG or a PNG (Image.RawFormat) and the printer returns true /// from ExtEscape(CHECKJPEGFORMAT) or ExtEscape(CHECKPNGFORMAT) then this function returns true. /// ////// /// public bool SupportsColor { get { // return GetDeviceCaps(SafeNativeMethods.BITSPIXEL, 1) > 1; } } ////// Gets a /// value indicating whether the printer supports color printing. /// ////// /// Gets or sets the last page to print. /// public int ToPage { get { return toPage;} set { if (value < 0) throw new ArgumentException(SR.GetString(SR.InvalidLowBoundArgumentEx, "value", value.ToString(CultureInfo.CurrentCulture), (0).ToString(CultureInfo.CurrentCulture))); toPage = value; } } ////// /// public object Clone() { PrinterSettings clone = (PrinterSettings) MemberwiseClone(); clone.printDialogDisplayed = false; return clone; } [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")] // what is done in copytohdevmode cannot give unwanted access AllPrinting permission [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] internal DeviceContext CreateDeviceContext(PageSettings pageSettings) { IntPtr modeHandle = GetHdevmodeInternal(); DeviceContext dc = null; try { //Copy the PageSettings to the DEVMODE... //Assert permission as CopyToHdevmode() demands... IntSecurity.AllPrinting.Assert(); try { pageSettings.CopyToHdevmode(modeHandle); } finally { CodeAccessPermission.RevertAssert(); } dc = CreateDeviceContext(modeHandle); } finally { SafeNativeMethods.GlobalFree(new HandleRef(null, modeHandle)); } return dc; } [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] internal DeviceContext CreateDeviceContext(IntPtr hdevmode) { IntPtr modePointer = SafeNativeMethods.GlobalLock(new HandleRef(null, hdevmode)); DeviceContext dc = DeviceContext.CreateDC(DriverName, PrinterNameInternal, (string) null, new HandleRef(null, modePointer)); SafeNativeMethods.GlobalUnlock(new HandleRef(null, hdevmode)); return dc; } // A read-only DC, which is faster than CreateHdc [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")] // what is done in copytohdevmode cannot give unwanted access AllPrinting permission [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] internal DeviceContext CreateInformationContext(PageSettings pageSettings) { IntPtr modeHandle = GetHdevmodeInternal(); DeviceContext dc; try { //Copy the PageSettings to the DEVMODE... //Assert permission as CopyToHdevmode() demands... IntSecurity.AllPrinting.Assert(); try { pageSettings.CopyToHdevmode(modeHandle); } finally { CodeAccessPermission.RevertAssert(); } dc = CreateInformationContext(modeHandle); } finally { SafeNativeMethods.GlobalFree(new HandleRef(null, modeHandle)); } return dc; } // A read-only DC, which is faster than CreateHdc [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] internal DeviceContext CreateInformationContext(IntPtr hdevmode) { IntPtr modePointer = SafeNativeMethods.GlobalLock(new HandleRef(null, hdevmode)); DeviceContext dc = DeviceContext.CreateIC(DriverName, PrinterNameInternal, (string) null, new HandleRef(null, modePointer)); SafeNativeMethods.GlobalUnlock(new HandleRef(null, hdevmode)); return dc; } ////// Creates an identical copy of this object. /// ///[ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public Graphics CreateMeasurementGraphics() { return CreateMeasurementGraphics(DefaultPageSettings); } /// [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")] //whatever the call stack calling HardMarginX and HardMarginY here is safe [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public Graphics CreateMeasurementGraphics(bool honorOriginAtMargins) { Graphics g = CreateMeasurementGraphics(); if (g != null && honorOriginAtMargins) { IntSecurity.AllPrintingAndUnmanagedCode.Assert(); try { g.TranslateTransform(-defaultPageSettings.HardMarginX, -defaultPageSettings.HardMarginY); } finally { CodeAccessPermission.RevertAssert(); } g.TranslateTransform(defaultPageSettings.Margins.Left, defaultPageSettings.Margins.Top); } return g; } /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public Graphics CreateMeasurementGraphics(PageSettings pageSettings) { // returns the Graphics object for the printer DeviceContext dc = CreateDeviceContext(pageSettings); Graphics g = Graphics.FromHdcInternal(dc.Hdc); g.PrintingHelper = dc; // Graphics will dispose of the DeviceContext. return g; } /// [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")] //whatever the call stack calling HardMarginX and HardMarginY here is safe [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public Graphics CreateMeasurementGraphics(PageSettings pageSettings, bool honorOriginAtMargins) { Graphics g = CreateMeasurementGraphics(); if (g != null && honorOriginAtMargins) { IntSecurity.AllPrintingAndUnmanagedCode.Assert(); try { g.TranslateTransform(-pageSettings.HardMarginX, -pageSettings.HardMarginY); } finally { CodeAccessPermission.RevertAssert(); } g.TranslateTransform(pageSettings.Margins.Left, pageSettings.Margins.Top); } return g; } // Create a PRINTDLG with a few useful defaults. // Try to keep this consistent with PrintDialog.CreatePRINTDLG. private static SafeNativeMethods.PRINTDLGX86 CreatePRINTDLGX86() { SafeNativeMethods.PRINTDLGX86 data = new SafeNativeMethods.PRINTDLGX86(); data.lStructSize = Marshal.SizeOf(typeof(SafeNativeMethods.PRINTDLGX86)); data.hwndOwner = IntPtr.Zero; data.hDevMode = IntPtr.Zero; data.hDevNames = IntPtr.Zero; data.Flags = 0; data.hwndOwner = IntPtr.Zero; data.hDC = IntPtr.Zero; data.nFromPage = 1; data.nToPage = 1; data.nMinPage = 0; data.nMaxPage = 9999; data.nCopies = 1; data.hInstance = IntPtr.Zero; data.lCustData = IntPtr.Zero; data.lpfnPrintHook = IntPtr.Zero; data.lpfnSetupHook = IntPtr.Zero; data.lpPrintTemplateName = null; data.lpSetupTemplateName = null; data.hPrintTemplate = IntPtr.Zero; data.hSetupTemplate = IntPtr.Zero; return data; } // Create a PRINTDLG with a few useful defaults. // Try to keep this consistent with PrintDialog.CreatePRINTDLG. private static SafeNativeMethods.PRINTDLG CreatePRINTDLG() { SafeNativeMethods.PRINTDLG data = new SafeNativeMethods.PRINTDLG(); data.lStructSize = Marshal.SizeOf(typeof(SafeNativeMethods.PRINTDLG)); data.hwndOwner = IntPtr.Zero; data.hDevMode = IntPtr.Zero; data.hDevNames = IntPtr.Zero; data.Flags = 0; data.hwndOwner = IntPtr.Zero; data.hDC = IntPtr.Zero; data.nFromPage = 1; data.nToPage = 1; data.nMinPage = 0; data.nMaxPage = 9999; data.nCopies = 1; data.hInstance = IntPtr.Zero; data.lCustData = IntPtr.Zero; data.lpfnPrintHook = IntPtr.Zero; data.lpfnSetupHook = IntPtr.Zero; data.lpPrintTemplateName = null; data.lpSetupTemplateName = null; data.hPrintTemplate = IntPtr.Zero; data.hSetupTemplate = IntPtr.Zero; return data; } // Use FastDeviceCapabilities where possible -- computing PrinterName is quite slow private int DeviceCapabilities(short capability, IntPtr pointerToBuffer, int defaultValue) { IntSecurity.AllPrinting.Assert(); string printerName = PrinterName; CodeAccessPermission.RevertAssert(); IntSecurity.UnmanagedCode.Assert(); return FastDeviceCapabilities(capability, pointerToBuffer, defaultValue, printerName); } // We pass PrinterName in as a parameter rather than computing it ourselves because it's expensive to compute. // We need to pass IntPtr.Zero since passing HDevMode is non-performant. private static int FastDeviceCapabilities(short capability, IntPtr pointerToBuffer, int defaultValue, string printerName) { int result = SafeNativeMethods.DeviceCapabilities(printerName, GetOutputPort(), capability, pointerToBuffer, IntPtr.Zero); if (result == -1) return defaultValue; return result; } // Called by get_PrinterName [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] private static string GetDefaultPrinterName() { IntSecurity.UnmanagedCode.Assert(); if (IntPtr.Size == 8) { SafeNativeMethods.PRINTDLG data = CreatePRINTDLG(); data.Flags = SafeNativeMethods.PD_RETURNDEFAULT; bool status = SafeNativeMethods.PrintDlg(data); if (!status) return SR.GetString(SR.NoDefaultPrinter); IntPtr handle = data.hDevNames; IntPtr names = SafeNativeMethods.GlobalLock(new HandleRef(data, handle)); if (names == IntPtr.Zero) throw new Win32Exception(); string name = ReadOneDEVNAME(names, 1); SafeNativeMethods.GlobalUnlock(new HandleRef(data, handle)); names = IntPtr.Zero; // Windows allocates them, but we have to free them SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames)); SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode)); return name; } else { SafeNativeMethods.PRINTDLGX86 data = CreatePRINTDLGX86(); data.Flags = SafeNativeMethods.PD_RETURNDEFAULT; bool status = SafeNativeMethods.PrintDlg(data); if (!status) return SR.GetString(SR.NoDefaultPrinter); IntPtr handle = data.hDevNames; IntPtr names = SafeNativeMethods.GlobalLock(new HandleRef(data, handle)); if (names == IntPtr.Zero) throw new Win32Exception(); string name = ReadOneDEVNAME(names, 1); SafeNativeMethods.GlobalUnlock(new HandleRef(data, handle)); names = IntPtr.Zero; // Windows allocates them, but we have to free them SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames)); SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode)); return name; } } // Called by get_OutputPort [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] private static string GetOutputPort() { IntSecurity.UnmanagedCode.Assert(); if (IntPtr.Size == 8) { SafeNativeMethods.PRINTDLG data = CreatePRINTDLG(); data.Flags = SafeNativeMethods.PD_RETURNDEFAULT; bool status = SafeNativeMethods.PrintDlg(data); if (!status) return SR.GetString(SR.NoDefaultPrinter); IntPtr handle = data.hDevNames; IntPtr names = SafeNativeMethods.GlobalLock(new HandleRef(data, handle)); if (names == IntPtr.Zero) throw new Win32Exception(); string name = ReadOneDEVNAME(names, 2); SafeNativeMethods.GlobalUnlock(new HandleRef(data, handle)); names = IntPtr.Zero; // Windows allocates them, but we have to free them SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames)); SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode)); return name; } else { SafeNativeMethods.PRINTDLGX86 data = CreatePRINTDLGX86(); data.Flags = SafeNativeMethods.PD_RETURNDEFAULT; bool status = SafeNativeMethods.PrintDlg(data); if (!status) return SR.GetString(SR.NoDefaultPrinter); IntPtr handle = data.hDevNames; IntPtr names = SafeNativeMethods.GlobalLock(new HandleRef(data, handle)); if (names == IntPtr.Zero) throw new Win32Exception(); string name = ReadOneDEVNAME(names, 2); SafeNativeMethods.GlobalUnlock(new HandleRef(data, handle)); names = IntPtr.Zero; // Windows allocates them, but we have to free them SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames)); SafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode)); return name; } } [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] private int GetDeviceCaps(int capability, int defaultValue) { DeviceContext dc = CreateInformationContext(DefaultPageSettings); int result = defaultValue; try { result = UnsafeNativeMethods.GetDeviceCaps(new HandleRef(dc, dc.Hdc), capability); } catch (InvalidPrinterException) { // do nothing, will return defaultValue. } finally{ dc.Dispose(); } return result; } /// /// /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public IntPtr GetHdevmode() { IntSecurity.AllPrintingAndUnmanagedCode.Demand(); // Don't assert unmanaged code -- anyone using handles should have unmanaged code permission IntPtr modeHandle = GetHdevmodeInternal(); defaultPageSettings.CopyToHdevmode(modeHandle); return modeHandle; } [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] internal IntPtr GetHdevmodeInternal() { // getting the printer name is quite expensive if PrinterName is left default, // because it needs to figure out what the default printer is string printerName = PrinterNameInternal; // Create DEVMODE int modeSize = SafeNativeMethods.DocumentProperties(NativeMethods.NullHandleRef, NativeMethods.NullHandleRef, printerName, IntPtr.Zero, NativeMethods.NullHandleRef, 0); if (modeSize < 1) { throw new InvalidPrinterException(this); } IntPtr handle = SafeNativeMethods.GlobalAlloc(SafeNativeMethods.GMEM_MOVEABLE, (uint)modeSize); // cannot be <0 anyway IntPtr pointer = SafeNativeMethods.GlobalLock(new HandleRef(null, handle)); //Get the DevMode only if its not cached.... if (cachedDevmode != null) { Marshal.Copy(cachedDevmode, 0, pointer, devmodebytes); } else { int returnCode = SafeNativeMethods.DocumentProperties(NativeMethods.NullHandleRef, NativeMethods.NullHandleRef, printerName, pointer, NativeMethods.NullHandleRef, SafeNativeMethods.DM_OUT_BUFFER); if (returnCode < 0) { throw new Win32Exception(); } } SafeNativeMethods.DEVMODE mode = (SafeNativeMethods.DEVMODE) UnsafeNativeMethods.PtrToStructure(pointer, typeof(SafeNativeMethods.DEVMODE)); IntPtr pointeroffset = (IntPtr)((long)pointer + (long)mode.dmSize); if (extrainfo != null) Marshal.Copy(extrainfo,0, pointeroffset, extrabytes); if ((mode.dmFields & SafeNativeMethods.DM_COPIES) == SafeNativeMethods.DM_COPIES) { if (copies != -1) mode.dmCopies = copies; } if ((mode.dmFields & SafeNativeMethods.DM_DUPLEX) == SafeNativeMethods.DM_DUPLEX) { if ((int)duplex != -1) mode.dmDuplex = (short) duplex; } if ((mode.dmFields & SafeNativeMethods.DM_COLLATE) == SafeNativeMethods.DM_COLLATE) { if (collate.IsNotDefault) mode.dmCollate = (short) (((bool) collate) ? SafeNativeMethods.DMCOLLATE_TRUE : SafeNativeMethods.DMCOLLATE_FALSE); } Marshal.StructureToPtr(mode, pointer, false); int retCode = SafeNativeMethods.DocumentProperties(NativeMethods.NullHandleRef, NativeMethods.NullHandleRef, printerName, pointer, pointer, SafeNativeMethods.DM_IN_BUFFER | SafeNativeMethods.DM_OUT_BUFFER); if (retCode < 0) { SafeNativeMethods.GlobalFree(new HandleRef(null, handle)); SafeNativeMethods.GlobalUnlock(new HandleRef(null, handle)); return IntPtr.Zero; } SafeNativeMethods.GlobalUnlock(new HandleRef(null, handle)); return handle; } ///Creates a handle to a DEVMODE structure which correspond too the printer settings. /// When you are done with the handle, you must deallocate it yourself: /// Windows.GlobalFree(handle); /// Where "handle" is the return value from this method. ////// /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public IntPtr GetHdevmode(PageSettings pageSettings) { IntSecurity.AllPrintingAndUnmanagedCode.Demand(); // Don't assert unmanaged code -- anyone using handles should have unmanaged code permission IntPtr handle = GetHdevmodeInternal(); pageSettings.CopyToHdevmode(handle); return handle; } ////// Creates a handle to a DEVMODE structure which correspond to the printer /// and page settings. /// When you are done with the handle, you must deallocate it yourself: /// Windows.GlobalFree(handle); /// Where "handle" is the return value from this method. /// ////// /// Creates a handle to a DEVNAMES structure which correspond to the printer settings. /// When you are done with the handle, you must deallocate it yourself: /// Windows.GlobalFree(handle); /// Where "handle" is the return value from this method. /// [ResourceExposure(ResourceScope.Process)] [ResourceConsumption(ResourceScope.Process)] public IntPtr GetHdevnames() { IntSecurity.AllPrintingAndUnmanagedCode.Demand(); // Don't assert unmanaged code -- anyone using handles should have unmanaged code permission string printerName = PrinterName; // the PrinterName property is slow when using the default printer // Create DEVNAMES structure // +4 for null terminator int namesCharacters = 4 + printerName.Length + DriverName.Length + OutputPort.Length; // 8 = size of fixed portion of DEVNAMES short offset = (short) (8 / Marshal.SystemDefaultCharSize); // Offsets are in characters, not bytes uint namesSize = (uint)(Marshal.SystemDefaultCharSize * (offset + namesCharacters)); // always >0 IntPtr handle = SafeNativeMethods.GlobalAlloc(SafeNativeMethods.GMEM_MOVEABLE, namesSize); IntPtr namesPointer = SafeNativeMethods.GlobalLock(new HandleRef(null, handle)); Marshal.WriteInt16(namesPointer, offset); // wDriverOffset offset += WriteOneDEVNAME(DriverName, namesPointer, offset); Marshal.WriteInt16((IntPtr)((long)namesPointer + 2), offset); // wDeviceOffset offset += WriteOneDEVNAME(printerName, namesPointer, offset); Marshal.WriteInt16((IntPtr)((long)namesPointer + 4), offset); // wOutputOffset offset += WriteOneDEVNAME(OutputPort, namesPointer, offset); Marshal.WriteInt16((IntPtr)((long)namesPointer + 6), offset); // wDefault SafeNativeMethods.GlobalUnlock(new HandleRef(null, handle)); return handle; } // Handles creating then disposing a default DEVMODE internal short GetModeField(ModeField field, short defaultValue) { return GetModeField(field, defaultValue, IntPtr.Zero); } [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] internal short GetModeField(ModeField field, short defaultValue, IntPtr modeHandle) { bool ownHandle = false; short result; try { if (modeHandle == IntPtr.Zero) { try { modeHandle = GetHdevmodeInternal(); ownHandle = true; } catch (InvalidPrinterException) { return defaultValue; } } IntPtr modePointer = SafeNativeMethods.GlobalLock(new HandleRef(this, modeHandle)); SafeNativeMethods.DEVMODE mode = (SafeNativeMethods.DEVMODE) UnsafeNativeMethods.PtrToStructure(modePointer, typeof(SafeNativeMethods.DEVMODE)); switch (field) { case ModeField.Orientation: result = mode.dmOrientation; break; case ModeField.PaperSize: result = mode.dmPaperSize; break; case ModeField.PaperLength: result = mode.dmPaperLength; break; case ModeField.PaperWidth: result = mode.dmPaperWidth; break; case ModeField.Copies: result = mode.dmCopies; break; case ModeField.DefaultSource: result = mode.dmDefaultSource; break; case ModeField.PrintQuality: result = mode.dmPrintQuality; break; case ModeField.Color: result = mode.dmColor; break; case ModeField.Duplex: result = mode.dmDuplex; break; case ModeField.YResolution: result = mode.dmYResolution; break; case ModeField.TTOption: result = mode.dmTTOption; break; case ModeField.Collate: result = mode.dmCollate; break; default: Debug.Fail("Invalid field in GetModeField"); result = defaultValue; break; } SafeNativeMethods.GlobalUnlock(new HandleRef(this, modeHandle)); } finally { if (ownHandle) { SafeNativeMethods.GlobalFree(new HandleRef(this, modeHandle)); } } return result; } internal PaperSize[] Get_PaperSizes() { IntSecurity.AllPrintingAndUnmanagedCode.Assert(); string printerName = PrinterName; // this is quite expensive if PrinterName is left default int count = FastDeviceCapabilities(SafeNativeMethods.DC_PAPERNAMES, IntPtr.Zero, -1, printerName); if (count == -1) return new PaperSize[0]; int stringSize = Marshal.SystemDefaultCharSize * 64; IntPtr namesBuffer = Marshal.AllocCoTaskMem(stringSize * count); FastDeviceCapabilities(SafeNativeMethods.DC_PAPERNAMES, namesBuffer, -1, printerName); Debug.Assert(FastDeviceCapabilities(SafeNativeMethods.DC_PAPERS, IntPtr.Zero, -1, printerName) == count, "Not the same number of paper kinds as paper names?"); IntPtr kindsBuffer = Marshal.AllocCoTaskMem(2 * count); FastDeviceCapabilities(SafeNativeMethods.DC_PAPERS, kindsBuffer, -1, printerName); Debug.Assert(FastDeviceCapabilities(SafeNativeMethods.DC_PAPERSIZE, IntPtr.Zero, -1, printerName) == count, "Not the same number of paper kinds as paper names?"); IntPtr dimensionsBuffer = Marshal.AllocCoTaskMem(8 * count); FastDeviceCapabilities(SafeNativeMethods.DC_PAPERSIZE, dimensionsBuffer, -1, printerName); PaperSize[] result = new PaperSize[count]; for (int i = 0; i < count; i++) { string name = Marshal.PtrToStringAuto((IntPtr)((long)namesBuffer + stringSize * i), 64); int index = name.IndexOf('\0'); if (index > -1) { name = name.Substring(0, index); } short kind = Marshal.ReadInt16((IntPtr)((long)kindsBuffer + i*2)); int width = Marshal.ReadInt32((IntPtr)((long)dimensionsBuffer + i * 8)); int height = Marshal.ReadInt32((IntPtr)((long)dimensionsBuffer + i * 8 + 4)); result[i] = new PaperSize((PaperKind) kind, name, PrinterUnitConvert.Convert(width, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display), PrinterUnitConvert.Convert(height, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display)); } Marshal.FreeCoTaskMem(namesBuffer); Marshal.FreeCoTaskMem(kindsBuffer); Marshal.FreeCoTaskMem(dimensionsBuffer); return result; } internal PaperSource[] Get_PaperSources() { IntSecurity.AllPrintingAndUnmanagedCode.Assert(); string printerName = PrinterName; // this is quite expensive if PrinterName is left default int count = FastDeviceCapabilities(SafeNativeMethods.DC_BINNAMES, IntPtr.Zero, -1, printerName); if (count == -1) return new PaperSource[0]; // Contrary to documentation, DeviceCapabilities returns char[count, 24], // not char[count][24] int stringSize = Marshal.SystemDefaultCharSize * 24; IntPtr namesBuffer = Marshal.AllocCoTaskMem(stringSize * count); FastDeviceCapabilities(SafeNativeMethods.DC_BINNAMES, namesBuffer, -1, printerName); Debug.Assert(FastDeviceCapabilities(SafeNativeMethods.DC_BINS, IntPtr.Zero, -1, printerName) == count, "Not the same number of bin kinds as bin names?"); IntPtr kindsBuffer = Marshal.AllocCoTaskMem(2 * count); FastDeviceCapabilities(SafeNativeMethods.DC_BINS, kindsBuffer, -1, printerName); PaperSource[] result = new PaperSource[count]; for (int i = 0; i < count; i++) { string name = Marshal.PtrToStringAuto((IntPtr)((long)namesBuffer + stringSize * i)); short kind = Marshal.ReadInt16((IntPtr)((long)kindsBuffer + 2*i)); result[i] = new PaperSource((PaperSourceKind) kind, name); } Marshal.FreeCoTaskMem(namesBuffer); Marshal.FreeCoTaskMem(kindsBuffer); return result; } internal PrinterResolution[] Get_PrinterResolutions() { IntSecurity.AllPrintingAndUnmanagedCode.Assert(); string printerName = PrinterName; // this is quite expensive if PrinterName is left default PrinterResolution[] result; int count = FastDeviceCapabilities(SafeNativeMethods.DC_ENUMRESOLUTIONS, IntPtr.Zero, -1, printerName); if (count == -1) { //Just return the standrard values if custom resolutions absemt .... result = new PrinterResolution[4]; result[0] = new PrinterResolution(PrinterResolutionKind.High, -4, -1); result[1] = new PrinterResolution(PrinterResolutionKind.Medium, -3, -1); result[2] = new PrinterResolution(PrinterResolutionKind.Low, -2, -1); result[3] = new PrinterResolution(PrinterResolutionKind.Draft, -1, -1); return result; } result = new PrinterResolution[count + 4]; result[0] = new PrinterResolution(PrinterResolutionKind.High, -4, -1); result[1] = new PrinterResolution(PrinterResolutionKind.Medium, -3, -1); result[2] = new PrinterResolution(PrinterResolutionKind.Low, -2, -1); result[3] = new PrinterResolution(PrinterResolutionKind.Draft, -1, -1); IntPtr buffer = Marshal.AllocCoTaskMem(8 * count); FastDeviceCapabilities(SafeNativeMethods.DC_ENUMRESOLUTIONS, buffer, -1, printerName); for (int i = 0; i < count; i++) { int x = Marshal.ReadInt32((IntPtr)((long)buffer + i*8)); int y = Marshal.ReadInt32((IntPtr)((long)buffer + i*8 + 4)); result[i + 4] = new PrinterResolution(PrinterResolutionKind.Custom, x, y); } Marshal.FreeCoTaskMem(buffer); return result; } // names is pointer to DEVNAMES private static String ReadOneDEVNAME(IntPtr pDevnames, int slot) { int offset = Marshal.SystemDefaultCharSize * Marshal.ReadInt16((IntPtr)((long)pDevnames + slot * 2)); string result = Marshal.PtrToStringAuto((IntPtr)((long)pDevnames + offset)); return result; } ////// /// [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] public void SetHdevmode(IntPtr hdevmode) { IntSecurity.AllPrintingAndUnmanagedCode.Demand(); // Don't assert unmanaged code -- anyone using handles should have unmanaged code permission if (hdevmode == IntPtr.Zero) throw new ArgumentException(SR.GetString(SR.InvalidPrinterHandle, hdevmode)); IntPtr pointer = SafeNativeMethods.GlobalLock(new HandleRef(null, hdevmode)); SafeNativeMethods.DEVMODE mode = (SafeNativeMethods.DEVMODE) UnsafeNativeMethods.PtrToStructure(pointer, typeof(SafeNativeMethods.DEVMODE)); //Copy entire public devmode as a byte array... devmodebytes = mode.dmSize; if (devmodebytes > 0) { cachedDevmode = new byte[devmodebytes]; Marshal.Copy(pointer, cachedDevmode, 0, devmodebytes); } //Copy private devmode as a byte array.. extrabytes = mode.dmDriverExtra; if (extrabytes > 0) { extrainfo = new byte[extrabytes]; Marshal.Copy((IntPtr)((long)pointer + (long)mode.dmSize), extrainfo, 0, extrabytes); } if ((mode.dmFields & SafeNativeMethods.DM_COPIES) == SafeNativeMethods.DM_COPIES) { copies = mode.dmCopies; } if ((mode.dmFields & SafeNativeMethods.DM_DUPLEX) == SafeNativeMethods.DM_DUPLEX ) { duplex = (Duplex) mode.dmDuplex; } if ((mode.dmFields & SafeNativeMethods.DM_COLLATE) == SafeNativeMethods.DM_COLLATE) { collate = (mode.dmCollate == SafeNativeMethods.DMCOLLATE_TRUE); } SafeNativeMethods.GlobalUnlock(new HandleRef(null, hdevmode)); } ////// Copies the relevant information out of the handle and into the PrinterSettings. /// ////// /// [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] public void SetHdevnames(IntPtr hdevnames) { IntSecurity.AllPrintingAndUnmanagedCode.Demand(); if (hdevnames == IntPtr.Zero) throw new ArgumentException(SR.GetString(SR.InvalidPrinterHandle, hdevnames)); IntPtr namesPointer = SafeNativeMethods.GlobalLock(new HandleRef(null, hdevnames)); driverName = ReadOneDEVNAME(namesPointer, 0); printerName = ReadOneDEVNAME(namesPointer, 1); outputPort = ReadOneDEVNAME(namesPointer, 2); PrintDialogDisplayed = true; SafeNativeMethods.GlobalUnlock(new HandleRef(null, hdevnames)); } ///Copies the relevant information out of the handle and into the PrinterSettings. ////// /// /// public override string ToString() { string printerName = (IntSecurity.HasPermission(IntSecurity.AllPrinting)) ? PrinterName : "/// Provides some interesting information about the PrinterSettings in /// String form. /// ///"; return "[PrinterSettings " + printerName + " Copies=" + Copies.ToString(CultureInfo.InvariantCulture) + " Collate=" + Collate.ToString(CultureInfo.InvariantCulture) // + " DriverName=" + DriverName.ToString(CultureInfo.InvariantCulture) // + " DriverVersion=" + DriverVersion.ToString(CultureInfo.InvariantCulture) + " Duplex=" + TypeDescriptor.GetConverter(typeof(Duplex)).ConvertToString((int) Duplex) + " FromPage=" + FromPage.ToString(CultureInfo.InvariantCulture) + " LandscapeAngle=" + LandscapeAngle.ToString(CultureInfo.InvariantCulture) + " MaximumCopies=" + MaximumCopies.ToString(CultureInfo.InvariantCulture) + " OutputPort=" + OutputPort.ToString(CultureInfo.InvariantCulture) + " ToPage=" + ToPage.ToString(CultureInfo.InvariantCulture) + "]"; } // Write null terminated string, return length of string in characters (including null) private short WriteOneDEVNAME(string str, IntPtr bufferStart, int index) { if (str == null) str = ""; IntPtr address = (IntPtr)((long)bufferStart + index * Marshal.SystemDefaultCharSize); if (Marshal.SystemDefaultCharSize == 1) { byte[] bytes = System.Text.Encoding.Default.GetBytes(str); Marshal.Copy(bytes, 0, address, bytes.Length); Marshal.WriteByte((IntPtr)((long)address + bytes.Length), 0); } else { char[] data = str.ToCharArray(); Marshal.Copy(data, 0, address, data.Length); Marshal.WriteInt16((IntPtr)((long)address + data.Length*2), 0); } return(short) (str.Length + 1); } /// /// /// public class PaperSizeCollection : ICollection { private PaperSize[] array; ////// Collection of PaperSize's... /// ////// /// public PaperSizeCollection(PaperSize[] array) { this.array = array; } ////// Initializes a new instance of the ///class. /// /// /// public int Count { get { return array.Length; } } ////// Gets a value indicating the number of paper sizes. /// ////// /// public virtual PaperSize this[int index] { get { return array[index]; } } ////// Retrieves the PaperSize with the specified index. /// ////// /// public IEnumerator GetEnumerator() { return new ArrayEnumerator(array, 0, Count); } ////// /// ICollection private interface implementation. /// ///int ICollection.Count { get { return this.Count; } } /// /// /// ICollection private interface implementation. /// ///bool ICollection.IsSynchronized { get { return false; } } /// /// /// ICollection private interface implementation. /// ///object ICollection.SyncRoot { get { return this; } } /// /// /// ICollection private interface implementation. /// ///void ICollection.CopyTo(Array array, int index) { Array.Copy(this.array, index, array, 0, this.array.Length); } public void CopyTo(PaperSize[] paperSizes, int index) { Array.Copy(this.array, index, paperSizes, 0, this.array.Length); } /// /// /// IEnumerable private interface implementation. /// ///IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// /// Empty implementation required for serialization of PrinterSettings object. /// ///[ EditorBrowsable(EditorBrowsableState.Never) ] public Int32 Add(PaperSize paperSize) { PaperSize[] newArray = new PaperSize[this.Count + 1]; ((ICollection) this).CopyTo(newArray, 0); newArray[this.Count] = paperSize; this.array = newArray; return this.Count; } } /// /// /// public class PaperSourceCollection : ICollection { private PaperSource[] array; ////// Collection of PaperSource's... /// ////// /// public PaperSourceCollection(PaperSource[] array) { this.array = array; } ////// Initializes a new instance of the ///class. /// /// /// public int Count { get { return array.Length; } } ////// Gets a value indicating the number of paper sources. /// ////// /// public virtual PaperSource this[int index] { get { return array[index]; } } ////// Gets the PaperSource with the specified index. /// ////// /// ////// ////// public IEnumerator GetEnumerator() { return new ArrayEnumerator(array, 0, Count); } ////// /// ICollection private interface implementation. /// ///int ICollection.Count { get { return this.Count; } } /// /// /// ICollection private interface implementation. /// ///bool ICollection.IsSynchronized { get { return false; } } /// /// /// ICollection private interface implementation. /// ///object ICollection.SyncRoot { get { return this; } } /// /// /// ICollection private interface implementation. /// ///void ICollection.CopyTo(Array array, int index) { Array.Copy(this.array, index, array, 0, this.array.Length); } public void CopyTo(PaperSource[] paperSources, int index) { Array.Copy(this.array, index, paperSources, 0, this.array.Length); } /// /// /// IEnumerable private interface implementation. /// ///IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// /// Empty implementation required for serialization of PrinterSettings object. /// ///[ EditorBrowsable(EditorBrowsableState.Never) ] public Int32 Add(PaperSource paperSource) { PaperSource[] newArray = new PaperSource[this.Count + 1]; ((ICollection) this).CopyTo(newArray, 0); newArray[this.Count] = paperSource; this.array = newArray; return this.Count; } } /// /// /// public class PrinterResolutionCollection : ICollection { private PrinterResolution[] array; ////// Collection of PrinterResolution's... /// ////// /// public PrinterResolutionCollection(PrinterResolution[] array) { this.array = array; } ////// Initializes a new instance of the ///class. /// /// /// public int Count { get { return array.Length; } } ////// Gets a /// value indicating the number of available printer resolutions. /// ////// /// public virtual PrinterResolution this[int index] { get { return array[index]; } } ////// Retrieves the PrinterResolution with the specified index. /// ////// /// ////// ////// public IEnumerator GetEnumerator() { return new ArrayEnumerator(array, 0, Count); } ////// /// ICollection private interface implementation. /// ///int ICollection.Count { get { return this.Count; } } /// /// /// ICollection private interface implementation. /// ///bool ICollection.IsSynchronized { get { return false; } } /// /// /// ICollection private interface implementation. /// ///object ICollection.SyncRoot { get { return this; } } /// /// /// ICollection private interface implementation. /// ///void ICollection.CopyTo(Array array, int index) { Array.Copy(this.array, index, array, 0, this.array.Length); } public void CopyTo(PrinterResolution[] printerResolutions, int index) { Array.Copy(this.array, index, printerResolutions, 0, this.array.Length); } /// /// /// IEnumerable private interface implementation. /// ///IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// /// Empty implementation required for serialization of PrinterSettings object. /// ///[ EditorBrowsable(EditorBrowsableState.Never) ] public Int32 Add(PrinterResolution printerResolution) { PrinterResolution[] newArray = new PrinterResolution[this.Count + 1]; ((ICollection) this).CopyTo(newArray, 0); newArray[this.Count] = printerResolution; this.array = newArray; return this.Count; } } /// /// /// ////// Collection of String's... /// ///public class StringCollection : ICollection { private String[] array; /// /// /// public StringCollection(String[] array) { this.array = array; } ////// Initializes a new instance of the ///class. /// /// /// public int Count { get { return array.Length; } } ////// Gets a value indicating the number of strings. /// ////// /// public virtual String this[int index] { get { return array[index]; } } ////// Gets the string with the specified index. /// ////// /// ////// ////// public IEnumerator GetEnumerator() { return new ArrayEnumerator(array, 0, Count); } ////// /// ICollection private interface implementation. /// ///int ICollection.Count { get { return this.Count; } } /// /// /// ICollection private interface implementation. /// ///bool ICollection.IsSynchronized { get { return false; } } /// /// /// ICollection private interface implementation. /// ///object ICollection.SyncRoot { get { return this; } } /// /// /// ICollection private interface implementation. /// ///void ICollection.CopyTo(Array array, int index) { Array.Copy(this.array, index, array, 0, this.array.Length); } public void CopyTo(string[] strings, int index) { Array.Copy(this.array, index, strings, 0, this.array.Length); } /// /// /// IEnumerable private interface implementation. /// ///IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// /// Empty implementation required for serialization of PrinterSettings object. /// ///[ EditorBrowsable(EditorBrowsableState.Never) ] public Int32 Add(String value) { String[] newArray = new String[this.Count + 1]; ((ICollection) this).CopyTo(newArray, 0); newArray[this.Count] = value; this.array = newArray; return this.Count; } } private class ArrayEnumerator : IEnumerator { private object[] array; private object item; private int index; private int startIndex; private int endIndex; public ArrayEnumerator(object[] array, int startIndex, int count) { this.array = array; this.startIndex = startIndex; endIndex = index + count; index = this.startIndex; } public object Current { get { return item; } } public bool MoveNext() { if (index >= endIndex) return false; item = array[index++]; return true; } public void Reset() { // Position enumerator before first item index = startIndex; item = null; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Component.cs
- StringWriter.cs
- InheritanceService.cs
- TextRunTypographyProperties.cs
- MatrixCamera.cs
- WebPartZoneCollection.cs
- StatusBarItem.cs
- WindowsSecurityToken.cs
- ControlUtil.cs
- ToolStripDropDown.cs
- NetCodeGroup.cs
- RawTextInputReport.cs
- SuppressMergeCheckAttribute.cs
- SchemaNotation.cs
- Hashtable.cs
- CDSCollectionETWBCLProvider.cs
- MiniAssembly.cs
- SelectedGridItemChangedEvent.cs
- FixedTextPointer.cs
- GlobalProxySelection.cs
- Main.cs
- WebPermission.cs
- NetworkInformationException.cs
- TextEditorDragDrop.cs
- SaveWorkflowCommand.cs
- QilTernary.cs
- Table.cs
- InputScopeAttribute.cs
- MetadataElement.cs
- CheckStoreFileValidityRequest.cs
- GeometryCombineModeValidation.cs
- InlineCollection.cs
- LicenseManager.cs
- FileDetails.cs
- DataList.cs
- GroupItem.cs
- WebDescriptionAttribute.cs
- CurrentTimeZone.cs
- RegexRunnerFactory.cs
- MaskedTextBoxTextEditorDropDown.cs
- OlePropertyStructs.cs
- ToolStripDropDown.cs
- OptimalBreakSession.cs
- TextLineResult.cs
- EventMappingSettings.cs
- Expr.cs
- UnsafeNativeMethodsCLR.cs
- StagingAreaInputItem.cs
- FullTextBreakpoint.cs
- PartialArray.cs
- WorkflowStateRollbackService.cs
- FixedPosition.cs
- WorkflowQueuingService.cs
- WebEvents.cs
- LookupNode.cs
- ExpressionsCollectionConverter.cs
- ViewgenContext.cs
- WmlValidatorAdapter.cs
- CommandHelper.cs
- SystemColorTracker.cs
- SocketPermission.cs
- WebBrowserEvent.cs
- AuthenticationSection.cs
- QilXmlReader.cs
- SoapAttributeAttribute.cs
- Reference.cs
- ArrangedElementCollection.cs
- XmlAttributes.cs
- MessageAction.cs
- PeerChannelListener.cs
- ComponentDesigner.cs
- DynamicResourceExtension.cs
- _SslState.cs
- CodeCatchClause.cs
- ClientSettingsStore.cs
- DbConnectionStringBuilder.cs
- XmlExtensionFunction.cs
- ColumnHeaderCollectionEditor.cs
- XamlVector3DCollectionSerializer.cs
- RouteData.cs
- StyleXamlParser.cs
- ReadOnlyAttribute.cs
- _CookieModule.cs
- TraceHwndHost.cs
- CheckoutException.cs
- XmlCompatibilityReader.cs
- SqlConnectionFactory.cs
- Brushes.cs
- PageStatePersister.cs
- ReceiveContent.cs
- ProviderUtil.cs
- ApplicationGesture.cs
- EditableRegion.cs
- FormsAuthenticationUser.cs
- UInt64Converter.cs
- SchemaImporterExtensionElement.cs
- SqlWebEventProvider.cs
- While.cs
- BinaryUtilClasses.cs
- CallContext.cs