PrintDialog.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / Printing / PrintDialog.cs / 1 / PrintDialog.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Windows.Forms { 
 
    using Microsoft.Win32;
    using System; 
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Printing; 
    using System.Runtime.InteropServices;
    using System.Security; 
 
    /// 
    ///  
    ///     Allows users to select a printer and choose which
    ///       portions of the document to print.
    /// 
    [DefaultProperty("Document")] 
    [SRDescription(SR.DescriptionPrintDialog)]
    [Designer("System.Windows.Forms.Design.PrintDialogDesigner, " + AssemblyRef.SystemDesign)] 
    // The only event this dialog has is HelpRequested, which isn't very useful 
    public sealed class PrintDialog : CommonDialog {
        private const int printRangeMask = (int) (PrintRange.AllPages | PrintRange.SomePages 
                                                  | PrintRange.Selection | PrintRange.CurrentPage);

        // If PrintDocument != null, settings == printDocument.PrinterSettings
        private PrinterSettings settings = null; 
        private PrintDocument printDocument = null;
 
        // Implementing "current page" would require switching to PrintDlgEx, which is windows 2000 and later only 
        private bool allowCurrentPage;
 
        private bool allowPages;
        private bool allowPrintToFile;
        private bool allowSelection;
        private bool printToFile; 
        private bool showHelp;
        private bool showNetwork; 
 
        private bool useEXDialog = false;
 
        /// 
        /// 
        /// Initializes a new instance of the  class.
        ///  
        public PrintDialog() {
            Reset(); 
        } 

 
        /// 
        ///    
        ///       Gets or sets a value indicating whether the Current Page option button is enabled.
        ///     
        /// 
        [ 
        DefaultValue(false), 
        SRDescription(SR.PDallowCurrentPageDescr)
        ] 
        public bool AllowCurrentPage {
            get { return allowCurrentPage;}
            set { allowCurrentPage = value;}
        } 

 
        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether the Pages option button is enabled.
        ///    
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(false), 
        SRDescription(SR.PDallowPagesDescr) 
        ]
        public bool AllowSomePages { 
            get { return allowPages;}
            set { allowPages = value;}
        }
 
        /// 
        ///  
        ///    Gets or sets a value indicating whether the Print to file check box is enabled. 
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(true),
        SRDescription(SR.PDallowPrintToFileDescr)
        ] 
        public bool AllowPrintToFile {
            get { return allowPrintToFile;} 
            set { allowPrintToFile = value;} 
        }
 
        /// 
        /// 
        ///    
        ///       Gets or sets a value indicating whether the From... To... Page option button is enabled. 
        ///    
        ///  
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(false), 
        SRDescription(SR.PDallowSelectionDescr)
        ]
        public bool AllowSelection {
            get { return allowSelection;} 
            set { allowSelection = value;}
        } 
 
        /// 
        ///  
        ///    
        ///       Gets or sets a value indicating the  used to obtain .
        ///    
        ///  
        [
        SRCategory(SR.CatData), 
        DefaultValue(null), 
        SRDescription(SR.PDdocumentDescr)
        ] 
        public PrintDocument Document {
            get { return printDocument;}
            set {
                printDocument = value; 
                if (printDocument == null)
                    settings = new PrinterSettings(); 
                else 
                    settings = printDocument.PrinterSettings;
            } 
        }

        private PageSettings PageSettings {
            get { 
                if (Document == null)
                    return PrinterSettings.DefaultPageSettings; 
                else 
                    return Document.DefaultPageSettings;
            } 
        }

        /// 
        ///  
        ///    
        ///       Gets or sets the  the 
        ///       dialog box will be modifying. 
        ///    
        ///  
        [
        SRCategory(SR.CatData),
        DefaultValue(null),
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        SRDescription(SR.PDprinterSettingsDescr) 
        ] 
        public PrinterSettings PrinterSettings {
            get { 

                if (settings == null)
                {
                    settings = new PrinterSettings(); 
                }
                return settings; 
            } 
            set {
                if (value != PrinterSettings) 
                {
                    settings = value;
                    printDocument = null;
                } 
            }
        } 
 
        /// 
        ///  
        ///    Gets or sets a value indicating whether the Print to file check box is checked.
        /// 
        [
        SRCategory(SR.CatBehavior), 
        DefaultValue(false),
        SRDescription(SR.PDprintToFileDescr) 
        ] 
        public bool PrintToFile {
            get { return printToFile;} 
            set { printToFile = value;}
        }

        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether the Help button is displayed. 
        ///    
        ///  
        [
        SRCategory(SR.CatBehavior),
        DefaultValue(false),
        SRDescription(SR.PDshowHelpDescr) 
        ]
        public bool ShowHelp { 
            get { return showHelp;} 
            set { showHelp = value;}
        } 

        /// 
        /// 
        ///     
        ///       Gets or sets a value indicating whether the Network button is displayed.
        ///     
        ///  
        [
        SRCategory(SR.CatBehavior), 
        DefaultValue(true),
        SRDescription(SR.PDshowNetworkDescr)
        ]
        public bool ShowNetwork { 
            get { return showNetwork;}
            set { showNetwork = value;} 
        } 

 
        /// 
        ///    
        ///      UseEXDialog = true means to use the EX versions of the dialogs when running on XP or above, and to ignore the ShowHelp & ShowNetwork properties.
        ///      If running below XP then UseEXDialog is ignored and the non-EX dialogs are used & ShowHelp & ShowNetwork are respected. 
        ///      UseEXDialog = false means to never use the EX versions of the dialog regardless of which O/S app is running on. ShowHelp & ShowNetwork will work in this case.
        ///     
        ///  
        [
        DefaultValue(false), 
        SRDescription(SR.PDuseEXDialog)
        ]
        public bool UseEXDialog {
            get { return useEXDialog;} 
            set { useEXDialog = value;}
        } 
 
        private int GetFlags() {
            int flags = 0; 

            // VSWhidbey 93449: Only set this flag when using PRINTDLG and PrintDlg,
            // and not when using PrintDlgEx and PRINTDLGEX.
            if (!UseEXDialog || (Environment.OSVersion.Platform != System.PlatformID.Win32NT || 
                Environment.OSVersion.Version.Major < 5)) {
                flags |= NativeMethods.PD_ENABLEPRINTHOOK; 
            } 

            if (!allowCurrentPage) flags |= NativeMethods.PD_NOCURRENTPAGE; 
            if (!allowPages) flags |= NativeMethods.PD_NOPAGENUMS;
            if (!allowPrintToFile) flags |= NativeMethods.PD_DISABLEPRINTTOFILE;
            if (!allowSelection) flags |= NativeMethods.PD_NOSELECTION;
 
            flags |= (int) PrinterSettings.PrintRange;
 
            if (printToFile) flags |= NativeMethods.PD_PRINTTOFILE; 
            if (showHelp) flags |= NativeMethods.PD_SHOWHELP;
            if (!showNetwork) flags |= NativeMethods.PD_NONETWORKBUTTON; 
            if (PrinterSettings.Collate) flags |= NativeMethods.PD_COLLATE;
            return flags;
        }
 
        /// 
        ///  
        ///     
        ///       Resets all options, the last selected printer, and the page
        ///       settings to their default values. 
        ///    
        /// 
        public override void Reset() {
            allowCurrentPage = false; 
            allowPages = false;
            allowPrintToFile = true; 
            allowSelection = false; 
            printDocument = null;
            printToFile = false; 
            settings = null;
            showHelp = false;
            showNetwork = true;
        } 

        // Create a PRINTDLG with a few useful defaults. 
        internal static NativeMethods.PRINTDLG CreatePRINTDLG() { 
            NativeMethods.PRINTDLG data = new NativeMethods.PRINTDLG();
            data.lStructSize = Marshal.SizeOf(data); 
            data.hwndOwner = IntPtr.Zero;
            data.hDevMode = IntPtr.Zero;
            data.hDevNames = IntPtr.Zero;
            data.Flags = 0; 
            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 = null; 
            data.lpfnSetupHook = null;
            data.lpPrintTemplateName = null; 
            data.lpSetupTemplateName = null; 
            data.hPrintTemplate = IntPtr.Zero;
            data.hSetupTemplate = IntPtr.Zero; 
            return data;
        }

        // VSWhidbey 93449: Use PRINTDLGEX on Win2k and newer OS'. Note that at the time of this 
        // fix, PrinterSettings did not support multiple page ranges. (See VSWhidbey 193829.)
        // Create a PRINTDLGEX with a few useful defaults. 
        internal static NativeMethods.PRINTDLGEX CreatePRINTDLGEX() { 
            NativeMethods.PRINTDLGEX data = new NativeMethods.PRINTDLGEX();
            data.lStructSize = Marshal.SizeOf(data); 
            data.hwndOwner = IntPtr.Zero;
            data.hDevMode = IntPtr.Zero;
            data.hDevNames = IntPtr.Zero;
            data.hDC = IntPtr.Zero; 
            data.Flags = 0;
            data.Flags2 = 0; 
            data.ExclusionFlags = 0; 
            data.nPageRanges = 0;
            data.nMaxPageRanges = 1; 
            data.pageRanges = UnsafeNativeMethods.GlobalAlloc(NativeMethods.GPTR,
                                                              data.nMaxPageRanges * Marshal.SizeOf(typeof(NativeMethods.PRINTPAGERANGE)));
            data.nMinPage = 0;
            data.nMaxPage = 9999; 
            data.nCopies = 1;
            data.hInstance = IntPtr.Zero; 
            data.lpPrintTemplateName = null; 
            data.nPropertyPages = 0;
            data.lphPropertyPages = IntPtr.Zero; 
            data.nStartPage = NativeMethods.START_PAGE_GENERAL;
            data.dwResultAction = 0;
            return data;
        } 

        ///  
        ///  
        /// 
        ///  
        // VSWhidbey 93449: Use PrintDlgEx and PRINTDLGEX on Win2k and newer OS'.
        protected override bool RunDialog(IntPtr hwndOwner) {
            bool returnValue = false;
 
            IntSecurity.SafePrinting.Demand();
 
            NativeMethods.WndProc hookProcPtr = new NativeMethods.WndProc(this.HookProc); 

            if (!UseEXDialog || (Environment.OSVersion.Platform != System.PlatformID.Win32NT || 
                Environment.OSVersion.Version.Major < 5)) {
                NativeMethods.PRINTDLG data = CreatePRINTDLG();
                returnValue = ShowPrintDialog(hwndOwner, hookProcPtr, data);
            } 
            else {
                NativeMethods.PRINTDLGEX data = CreatePRINTDLGEX(); 
                returnValue = ShowPrintDialog(hwndOwner, data); 
            }
 
            return returnValue;
        }

        // VSWhidbey 93449: Due to the nature of PRINTDLGEX vs PRINTDLG, separate but similar methods 
        // are required for showing the print dialog on Win2k and newer OS'.
        private bool ShowPrintDialog(IntPtr hwndOwner, NativeMethods.WndProc hookProcPtr, NativeMethods.PRINTDLG data) { 
 
            data.Flags = GetFlags();
            data.nCopies = (short) PrinterSettings.Copies; 
            data.hwndOwner = hwndOwner;
            data.lpfnPrintHook = hookProcPtr;

            IntSecurity.AllPrintingAndUnmanagedCode.Assert(); 

            try { 
                if (PageSettings == null) 
                    data.hDevMode = PrinterSettings.GetHdevmode();
                else 
                    data.hDevMode = PrinterSettings.GetHdevmode(PageSettings);

                data.hDevNames = PrinterSettings.GetHdevnames();
            } 
            catch (InvalidPrinterException) {
                data.hDevMode = IntPtr.Zero; 
                data.hDevNames = IntPtr.Zero; 
                // Leave those fields null; Windows will fill them in
            } 
            finally {
                CodeAccessPermission.RevertAssert();
            }
 
            try {
                // Windows doesn't like it if page numbers are invalid 
                if (AllowSomePages) { 
                    if (PrinterSettings.FromPage < PrinterSettings.MinimumPage
                        || PrinterSettings.FromPage > PrinterSettings.MaximumPage) 
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "FromPage"));
                    if (PrinterSettings.ToPage < PrinterSettings.MinimumPage
                        || PrinterSettings.ToPage > PrinterSettings.MaximumPage)
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "ToPage")); 
                    if (PrinterSettings.ToPage < PrinterSettings.FromPage)
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "FromPage")); 
 
                    data.nFromPage = (short) PrinterSettings.FromPage;
                    data.nToPage = (short) PrinterSettings.ToPage; 
                    data.nMinPage = (short) PrinterSettings.MinimumPage;
                    data.nMaxPage = (short) PrinterSettings.MaximumPage;
                }
 
                if (!UnsafeNativeMethods.PrintDlg(data))
                    return false; 
 
                IntSecurity.AllPrintingAndUnmanagedCode.Assert();
                try { 
                    UpdatePrinterSettings(data.hDevMode, data.hDevNames, data.nCopies, data.Flags, settings, PageSettings);
                }
                finally {
                    CodeAccessPermission.RevertAssert(); 
                }
                PrintToFile = ((data.Flags & NativeMethods.PD_PRINTTOFILE) != 0); 
                PrinterSettings.PrintToFile = PrintToFile; 

                if (AllowSomePages) { 
                    PrinterSettings.FromPage = data.nFromPage;
                    PrinterSettings.ToPage = data.nToPage;
                }
 
                return true;
            } 
            finally { 
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode));
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames)); 
            }
        }

        // VSWhidbey 93449: Due to the nature of PRINTDLGEX vs PRINTDLG, separate but similar methods 
        // are required for showing the print dialog on Win2k and newer OS'.
        private bool ShowPrintDialog(IntPtr hwndOwner, NativeMethods.PRINTDLGEX data) { 
 
            data.Flags = GetFlags();
            data.nCopies = PrinterSettings.Copies; 
            data.hwndOwner = hwndOwner;

            IntSecurity.AllPrintingAndUnmanagedCode.Assert();
            try { 
                if (PageSettings == null)
                    data.hDevMode = PrinterSettings.GetHdevmode(); 
                else 
                    data.hDevMode = PrinterSettings.GetHdevmode(PageSettings);
 
                data.hDevNames = PrinterSettings.GetHdevnames();
            }
            catch (InvalidPrinterException) {
                data.hDevMode = IntPtr.Zero; 
                data.hDevNames = IntPtr.Zero;
                // Leave those fields null; Windows will fill them in 
            } 
            finally {
                CodeAccessPermission.RevertAssert(); 
            }

            try {
                // Windows doesn't like it if page numbers are invalid 
                if (AllowSomePages) {
                    if (PrinterSettings.FromPage < PrinterSettings.MinimumPage 
                        || PrinterSettings.FromPage > PrinterSettings.MaximumPage) 
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "FromPage"));
                    if (PrinterSettings.ToPage < PrinterSettings.MinimumPage 
                        || PrinterSettings.ToPage > PrinterSettings.MaximumPage)
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "ToPage"));
                    if (PrinterSettings.ToPage < PrinterSettings.FromPage)
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "FromPage")); 

                    unsafe { 
                        int* pageRangeField = (int*)data.pageRanges; 
                        *pageRangeField = PrinterSettings.FromPage;
                        pageRangeField += 1; 
                        *pageRangeField = PrinterSettings.ToPage;
                    }
                    data.nPageRanges = 1;
 
                    data.nMinPage = PrinterSettings.MinimumPage;
                    data.nMaxPage = PrinterSettings.MaximumPage; 
                } 

                // 
                // The flags NativeMethods.PD_SHOWHELP and NativeMethods.PD_NONETWORKBUTTON don't work with
                // PrintDlgEx. So we have to strip them out.
                data.Flags &= ~(NativeMethods.PD_SHOWHELP | NativeMethods.PD_NONETWORKBUTTON);
 
                int hr = UnsafeNativeMethods.PrintDlgEx(data);
                if (NativeMethods.Failed(hr) || data.dwResultAction == NativeMethods.PD_RESULT_CANCEL) { 
                    return false; 
                }
 
                IntSecurity.AllPrintingAndUnmanagedCode.Assert();
                try {
                    UpdatePrinterSettings(data.hDevMode, data.hDevNames, (short)data.nCopies, data.Flags, PrinterSettings, PageSettings);
                } 
                finally {
                    CodeAccessPermission.RevertAssert(); 
                } 
                PrintToFile = ((data.Flags & NativeMethods.PD_PRINTTOFILE) != 0);
                PrinterSettings.PrintToFile = PrintToFile; 
                if (AllowSomePages) {
                    unsafe {
                        int* pageRangeField = (int*)data.pageRanges;
                        PrinterSettings.FromPage = *pageRangeField; 
                        pageRangeField += 1;
                        PrinterSettings.ToPage = *pageRangeField; 
                    } 
                }
                // We should return true only if the user pressed the "Print" button while dismissing the dialog. 
                // Please refer to VsW: 403124 for more details.
                return (data.dwResultAction == NativeMethods.PD_RESULT_PRINT);
            }
            finally { 
                if (data.hDevMode != IntPtr.Zero)
                    UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode)); 
                if (data.hDevNames != IntPtr.Zero) 
                    UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames));
                if (data.pageRanges != IntPtr.Zero) 
                    UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.pageRanges));
            }
        }
 
        // VSWhidbey 93449: Due to the nature of PRINTDLGEX vs PRINTDLG, separate but similar methods
        // are required for updating the settings from the structure utilized by the dialog. 
        // Take information from print dialog and put in PrinterSettings 
        private static void UpdatePrinterSettings(IntPtr hDevMode, IntPtr hDevNames, short copies, int flags, PrinterSettings settings, PageSettings pageSettings) {
            // Mode 
            settings.SetHdevmode(hDevMode);
            settings.SetHdevnames(hDevNames);

            if (pageSettings!= null) 
                pageSettings.SetHdevmode(hDevMode);
 
            //Check for Copies == 1 since we might get the Right number of Copies from hdevMode.dmCopies... 
            //this is Native PrintDialogs
            if (settings.Copies == 1) 
                settings.Copies = copies;

            settings.PrintRange = (PrintRange) (flags & printRangeMask);
        } 

    } 
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK