Click here to Skip to main content
15,896,154 members
Articles / Programming Languages / C#

Printers and SafeHandles (Part 2)

Rate me:
Please Sign up or sign in to vote.
3.00/5 (7 votes)
16 Apr 20073 min read 105.1K   3K   36  
Using SafeHandles to monitor a printer.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Drawing.Printing;
using System.Security.Permissions;

namespace qPrintComponent
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
    public class DevMode
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        internal string dmDeviceName;
        internal short dmSpecVersion;
        internal short dmDriverVersion;
        internal short dmSize;
        internal short dmDriverExtra;
        internal int dmFields;
        internal short dmOrientation;
        internal short dmPaperSize;
        internal short dmPaperLength;
        internal short dmPaperWidth;
        internal short dmScale;
        internal short dmCopies;
        internal short dmDefaultSource;
        internal short dmPrintQuality;
        internal short dmColor;
        internal short dmDuplex;
        internal short dmYResolution;
        internal short dmTTOption;
        internal short dmCollate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        internal string dmFormName;
        internal UInt16 dmLogPixels;
        internal UInt32 dmBitsPerPel;
        internal UInt32 dmPelsWidth;
        internal UInt32 dmPelsHeight;
        internal UInt32 dmNup;
        internal UInt32 dmDisplayFrequency;
        internal UInt32 dmICMMethod;
        internal UInt32 dmICMIntent;
        internal UInt32 dmMediaType;
        internal UInt32 dmDitherType;
        internal UInt32 dmReserved1;
        internal UInt32 dmReserved2;
        internal UInt32 dmPanningWidth;
        internal UInt32 dmPanningHeight;



       
        internal DevMode(IntPtr DevModeHandle)
        {
            Marshal.PtrToStructure(DevModeHandle,this);
        }
        
        public override string ToString()
        {
            return FormName;
        }

        [Description(@"Specifies the 'friendly' name of the printer or display; for example, 'PCL/HP LaserJet' in the case of PCL/HP LaserJet. This string is unique among device drivers. Note that this name may be truncated.")]
        public string DeviceName
        {
            get { if (dmDeviceName == null) return ""; return dmDeviceName; }
        }
        [Description(@"Specifies the version number of the initialization data specification on which the structure is based.")]
        public short SpecVersion
        {
            get 
            {
                return dmSpecVersion; 
            }
        }
        [Description(@"Specifies the driver version number assigned by the driver developer.")]
        public short DriverVersion
        {
            get { return dmDriverVersion; }
        }
        [Description(@"Selects the orientation of the paper. This member can be either ORIENT_PORTRAIT (1) or ORIENT_LANDSCAPE (2).")]
        public Page_Orientation Orientation
        {
            get 
            {
                if (dmOrientation == 0) return Page_Orientation.PORTRAIT;
                Page_Orientation p;
                try { p =  (Page_Orientation)dmOrientation;}
                catch { p = Page_Orientation.PORTRAIT; }
                return p;
            }
            set
            {
                if ((dmOrientation != 0) && (dmOrientation != (short)value) && ((PrintComponent.SafePrinterHandle.PrinterInfoQ.Fields & 0x1) == 0x1))
                {
                    dmOrientation = (short)value;
                    UpdateDevMode(0x1);
                }
            }
        }
        [Description(@"Specifies the name of the form to use; for example, 'Letter' or 'Legal'.")]
        [TypeConverter(typeof(qPrintComponent.qPaperSizeConverter))]
        public string FormName
        {
            get { return dmFormName; }
            set
            {
                if (FormName != value)
                {
                    int f = PrintComponent.SafePrinterHandle.PrinterInfoQ.sPaperNames.IndexOf(value);
                    if (f != -1)
                    {
                        System.Drawing.Point pt = PrintComponent.SafePrinterHandle.PrinterInfoQ.PaperSizes[f];
                        dmFormName = value;
                        dmPaperSize = (short)PrintComponent.SafePrinterHandle.PrinterInfoQ.Papers[f];
                        dmPaperLength = (short)(pt.Y);
                        dmPaperWidth = (short)(pt.X);
                        UpdateDevMode(2 | 4 | 8 | 0x10000);
                    }
                }
            }
        }
        [Description(@"Selects the size of the paper to print on.")]
        public short PaperSize
        {
            get
            { return dmPaperSize; }
        }

        [Description(@"The length of the paper specified by the dmPaperSize member, either for custom paper sizes or for devices such as dot-matrix printers that can print on a page of arbitrary length. These values, along with all other values in this structure that specify a physical length, are in tenths of a millimeter.")]
        public short PaperLength
        {
            get { return dmPaperLength; }
        }
        [Description(@"The width of the paper specified by the dmPaperSize member, either for custom paper sizes or for devices such as dot-matrix printers that can print on a page of arbitrary length. These values, along with all other values in this structure that specify a physical length, are in tenths of a millimeter.")]
        public short PaperWidth
        {
            get { return dmPaperWidth; }
        }
        [Description(@"Specifies the factor by which the printed output is to be scaled. The apparent page size is scaled from the physical page size by a factor of dmScale/100. For example, a letter-sized page with a dmScale value of 50 would contain as much data as a page of 17- by 22-inches because the output text and graphics would be half their original height and width.")]
        public short Scale
        {
            get { return dmScale; }
            set
            {
                if ((value < 1001) && (value > 0) && (value != dmScale)  && ((PrintComponent.SafePrinterHandle.PrinterInfoQ.Fields & 0x10) == 0x10))
                {
                    dmScale = value;
                    UpdateDevMode(0x10); 
                }
            }
        }
        [Description(@"Selects the number of copies printed if the device supports multiple-page copies.")]
        public short Copies
        {
            get { return dmCopies; }
            set
            {
                if ((value != dmCopies) && ((PrintComponent.SafePrinterHandle.PrinterInfoQ.Fields & 0x100) == 0x100) && (value > 0) && (value <=  PrintComponent.SafePrinterHandle.PrinterInfoQ.Copies))
                {
                    dmCopies = value;
                    UpdateDevMode(0x100);
                }
                else
                    System.Windows.Forms.MessageBox.Show("The value has to be between 1 and " + PrintComponent.SafePrinterHandle.PrinterInfoQ.Copies.ToString());
            }
        }
        
        [Description(@"Specifies the paper source.")]
        [TypeConverter(typeof (qDefaultSourceConverter))]
        public string DefaultSource
        {
            get
            {
                string s = string.Empty;
                try
                {
                    int i = PrintComponent.SafePrinterHandle.PrinterInfoQ.iBinNames.IndexOf(dmDefaultSource);
                    if (i != -1) 
                        s = PrintComponent.SafePrinterHandle.PrinterInfoQ.sBinNames[i];
                }
                catch { }
                return s;

            }
            [PrintingPermission(SecurityAction.Demand, Level = PrintingPermissionLevel.AllPrinting)]
            set
            {
                if (DefaultSource != value)
                {
                    int i = PrintComponent.SafePrinterHandle.PrinterInfoQ.sBinNames.IndexOf(value);
                    if (i != -1)
                    {
                        dmDefaultSource = (short) PrintComponent.SafePrinterHandle.PrinterInfoQ.iBinNames[i];
                        UpdateDevMode(0x200);
                    }
                }
            }
        }

        [Description(@"DPI")]
        [TypeConverter(typeof(qPrintQualityConverter))]
        public string PrintQuality
        {
            get { return dmPrintQuality.ToString() + " DPI"; }
            set 
            {
                value = value.Replace(" DPI", "");
                if (short.TryParse(value, out dmPrintQuality))
                {
                    dmYResolution = dmPrintQuality;
                    UpdateDevMode(0x400 | 0x2000);
                }
            }
        }
        [Description(@"Switches between color and monochrome on color printers.")]
        public Print_Color Color
        {
            get
            {
                if (dmColor == 0) return Print_Color.MONOCHROME;
                Print_Color c;
                try { c =  (Print_Color)dmColor; }
                catch  { c = Print_Color.MONOCHROME; }
                return c;
            }
            set
            {
                if ((dmColor != (short)value) && ((PrintComponent.SafePrinterHandle.PrinterInfoQ.Fields & 0x800) == 0x800) && PrintComponent.SafePrinterHandle.PrinterInfoQ.CanProcessColor)
                {
                    dmColor = (short)value;
                    UpdateDevMode(0x800);
                }
                else
                    System.Windows.Forms.MessageBox.Show("The printer does not support color");
            }
        }
        [Description(@"Selects duplex or double-sided printing for printers capable of duplex printing.")]
        public Page_Duplex Duplex
        {
            get
            {
                if (dmDuplex == 0) return Page_Duplex.SIMPLEX;
                Page_Duplex d;
                try { d = (Page_Duplex)dmDuplex; }
                catch { d= Page_Duplex.SIMPLEX; }
                return d;
            }
            set
            {
                if ((dmDuplex != (short)value) && ((PrintComponent.SafePrinterHandle.PrinterInfoQ.Fields & 0x1000) == 0x1000) && PrintComponent.SafePrinterHandle.PrinterInfoQ.CanDuplex)
                {
                    dmDuplex = (short)value;
                    UpdateDevMode(0x1000);
                }
                else
                    System.Windows.Forms.MessageBox.Show("The printer does not support duplexing");
            }
        }
        [Description(@"Specifies how TrueType fonts should be printed.")]
        public Print_TrueType TTOption
        {
            get
            {
                if (dmTTOption == 0) return Print_TrueType.BITMAP;
                Print_TrueType t;
                try { t = (Print_TrueType)dmTTOption; }
                catch { t = Print_TrueType.BITMAP; }
                return t;
            }
        }
        [Description(@"Specifies whether collation should be used when printing multiple copies.")]
        public Printer_Collate Collate
        {
            get
            {
                if (dmCollate == 0) return Printer_Collate.FALSE;
                Printer_Collate c;
                try { c = (Printer_Collate)dmCollate; }
                catch { c= Printer_Collate.FALSE; }
                return c;
            }
            set
            {
                if ((dmCollate != (short)value) && ((PrintComponent.SafePrinterHandle.PrinterInfoQ.Fields & 0x8000) == 0x8000) && PrintComponent.SafePrinterHandle.PrinterInfoQ.CanCollate)
                    {
                        dmCollate = (short)value;
                        UpdateDevMode(0x8000);
                    }
                    else
                        System.Windows.Forms.MessageBox.Show("The printer does not support collating");
            }
        }

        [Description(@"Specifies where the NUP is done.")]
        public UInt32 Nup
        {
            get { return dmNup; }
        }
        [Description(@"Specifies how ICM is handled. For a non-ICM application, this member determines if ICM is enabled or disabled. For ICM applications, the system examines this member to determine how to handle ICM support.")]
        public Printer_ICMMethod ICMMethod
        {
            get
            {
                if (dmICMMethod == 0) return Printer_ICMMethod.NONE;
                Printer_ICMMethod m;
                try { m= (Printer_ICMMethod)dmICMMethod; }
                catch { m= Printer_ICMMethod.USER; }
                return m;
            }
        }
        [Description(@"Specifies which color matching method, or intent, should be used by default. This member is primarily for non-ICM applications. ICM applications can establish intents by using the ICM functions.")]
        public Printer_ICMIntend ICMIntent
        {
            get
            {
                if (dmICMIntent==0)  return Printer_ICMIntend.USER;
                Printer_ICMIntend i;
                try { i = (Printer_ICMIntend)dmICMIntent; }
                catch { i =  Printer_ICMIntend.USER; }
                return i;
            }
        }
        [Description(@"Specifies the type of media being printed on. ")]
        public string MediaType
        {
            get 
            {
                string s = string.Empty;
                try
                {
                    int i = PrintComponent.SafePrinterHandle.PrinterInfoQ.MediaTypes.IndexOf((int)dmMediaType);
                    if (i != -1)
                        s = PrintComponent.SafePrinterHandle.PrinterInfoQ.MediaNames[i];
                }
                catch { }
                return s;
            }
        }
        [Description(@"Specifies how dithering is to be done.")]
        public Printer_Dither DitherType
        {
            get
            {
                if (dmDitherType == 0) return Printer_Dither.NONE;
                Printer_Dither d;
                try { d =  (Printer_Dither)dmDitherType; }
                catch { d = Printer_Dither.USER; }
                return d;
            }
        }


        private bool UpdateDevMode(int field)
        {
            if (PrintComponent.SafePrinterHandle.IsInvalid) return false;
            dmFields = field;
            IntPtr ptr1 = PrintComponent.SafePrinterHandle.PrinterInfo2.GetIntPtrField(7);
            Marshal.StructureToPtr(this, ptr1, true);
            return PrintComponent.SafePrinterHandle.PrinterInfo2.SetIntPtrField(7, ptr1);
        }
    }
}

    
    

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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
Software Developer
Belgium Belgium
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions