Example #1
0
        public void GetHdevnames_ReturnsExpected()
        {
            var    printerSettings = new PrinterSettings();
            IntPtr handle          = IntPtr.Zero;

            handle = printerSettings.GetHdevnames();
            Assert.NotEqual(IntPtr.Zero, handle);
        }
Example #2
0
        public void SetHdevnames_IntPtr_Success()
        {
            var    printerSettings    = new PrinterSettings();
            var    newPrinterSettings = new PrinterSettings();
            IntPtr handle             = printerSettings.GetHdevnames();

            newPrinterSettings.SetHdevnames(handle);
            Assert.Equal(newPrinterSettings.PrinterName, printerSettings.PrinterName);
        }
Example #3
0
        protected override bool RunDialog(IntPtr hwndOwner)
        {
            NativeMethods.WndProc hookProcPtr = new NativeMethods.WndProc(HookProc);
            if (pageSettings == null)
            {
                throw new ArgumentException(SR.PSDcantShowWithoutPage);
            }

            NativeMethods.PAGESETUPDLG data = new NativeMethods.PAGESETUPDLG();
            data.lStructSize       = Marshal.SizeOf(data);
            data.Flags             = GetFlags();
            data.hwndOwner         = hwndOwner;
            data.lpfnPageSetupHook = hookProcPtr;

            PrinterUnit toUnit = PrinterUnit.ThousandthsOfAnInch;

            // Below was a breaking change from RTM and EVERETT even though this was a correct FIX.
            // EnableMetric is a new Whidbey property which we allow the users to choose between the AutoConversion or not.
            if (EnableMetric)
            {
                //take the Units of Measurement while determining the PrinterUnits...
                //
                StringBuilder sb     = new StringBuilder(2);
                int           result = UnsafeNativeMethods.GetLocaleInfo(NativeMethods.LOCALE_USER_DEFAULT, NativeMethods.LOCALE_IMEASURE, sb, sb.Capacity);

                if (result > 0 && int.Parse(sb.ToString(), CultureInfo.InvariantCulture) == 0)
                {
                    toUnit = PrinterUnit.HundredthsOfAMillimeter;
                }
            }

            if (MinMargins != null)
            {
                Margins margins = PrinterUnitConvert.Convert(MinMargins, PrinterUnit.Display, toUnit);
                data.minMarginLeft   = margins.Left;
                data.minMarginTop    = margins.Top;
                data.minMarginRight  = margins.Right;
                data.minMarginBottom = margins.Bottom;
            }

            if (pageSettings.Margins != null)
            {
                Margins margins = PrinterUnitConvert.Convert(pageSettings.Margins, PrinterUnit.Display, toUnit);
                data.marginLeft   = margins.Left;
                data.marginTop    = margins.Top;
                data.marginRight  = margins.Right;
                data.marginBottom = margins.Bottom;
            }

            // Ensure that the margins are >= minMargins.
            // This is a requirement of the PAGESETUPDLG structure.
            //
            data.marginLeft   = Math.Max(data.marginLeft, data.minMarginLeft);
            data.marginTop    = Math.Max(data.marginTop, data.minMarginTop);
            data.marginRight  = Math.Max(data.marginRight, data.minMarginRight);
            data.marginBottom = Math.Max(data.marginBottom, data.minMarginBottom);

            PrinterSettings printer = printerSettings ?? pageSettings.PrinterSettings;

            data.hDevMode  = printer.GetHdevmode(pageSettings);
            data.hDevNames = printer.GetHdevnames();

            try
            {
                bool status = UnsafeNativeMethods.PageSetupDlg(data);
                if (!status)
                {
                    // Debug.WriteLine(Windows.CommonDialogErrorToString(Windows.CommDlgExtendedError()));
                    return(false);
                }

                UpdateSettings(data, pageSettings, printerSettings); // yes, printerSettings, not printer
                return(true);
            }
            finally
            {
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode));
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames));
            }
        }
Example #4
0
        // 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;

            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
            }

            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(string.Format(SR.PDpageOutOfRange, "FromPage"));
                    }

                    if (PrinterSettings.ToPage < PrinterSettings.MinimumPage ||
                        PrinterSettings.ToPage > PrinterSettings.MaximumPage)
                    {
                        throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "ToPage"));
                    }

                    if (PrinterSettings.ToPage < PrinterSettings.FromPage)
                    {
                        throw new ArgumentException(string.Format(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);
                }

                UpdatePrinterSettings(data.hDevMode, data.hDevNames, (short)data.nCopies, data.Flags, PrinterSettings, PageSettings);

                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;
                    }
                }

                // When the flag PD_USEDEVMODECOPIESANDCOLLATE is not set,
                // PRINTDLG.nCopies or PRINTDLG.nCopies indicates the number of copies the user wants
                // to print, and the PD_COLLATE flag in the Flags member indicates
                // whether the user wants to print them collated.
                if ((data.Flags & NativeMethods.PD_USEDEVMODECOPIESANDCOLLATE) == 0)
                {
                    PrinterSettings.Copies  = (short)(data.nCopies);
                    PrinterSettings.Collate = ((data.Flags & NativeMethods.PD_COLLATE) == NativeMethods.PD_COLLATE);
                }

                // We should return true only if the user pressed the "Print" button while dismissing the dialog.
                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));
                }
            }
        }
Example #5
0
        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;

            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
            }

            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(string.Format(SR.PDpageOutOfRange, "FromPage"));
                    }

                    if (PrinterSettings.ToPage < PrinterSettings.MinimumPage ||
                        PrinterSettings.ToPage > PrinterSettings.MaximumPage)
                    {
                        throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "ToPage"));
                    }

                    if (PrinterSettings.ToPage < PrinterSettings.FromPage)
                    {
                        throw new ArgumentException(string.Format(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);
                }

                UpdatePrinterSettings(data.hDevMode, data.hDevNames, data.nCopies, data.Flags, settings, PageSettings);

                PrintToFile = ((data.Flags & NativeMethods.PD_PRINTTOFILE) != 0);
                PrinterSettings.PrintToFile = PrintToFile;

                if (AllowSomePages)
                {
                    PrinterSettings.FromPage = data.nFromPage;
                    PrinterSettings.ToPage   = data.nToPage;
                }

                // When the flag PD_USEDEVMODECOPIESANDCOLLATE is not set,
                // PRINTDLG.nCopies or PRINTDLG.nCopies indicates the number of copies the user wants
                // to print, and the PD_COLLATE flag in the Flags member indicates
                // whether the user wants to print them collated.
                if ((data.Flags & NativeMethods.PD_USEDEVMODECOPIESANDCOLLATE) == 0)
                {
                    PrinterSettings.Copies  = data.nCopies;
                    PrinterSettings.Collate = ((data.Flags & NativeMethods.PD_COLLATE) == NativeMethods.PD_COLLATE);
                }

                return(true);
            }
            finally
            {
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode));
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames));
            }
        }
        /// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.RunDialog"]/*' />
        /// <devdoc>
        /// </devdoc>
        /// <internalonly/>
        protected override bool RunDialog(IntPtr hwndOwner)
        {
            IntSecurity.SafePrinting.Demand();

            NativeMethods.WndProc hookProcPtr = new NativeMethods.WndProc(this.HookProc);
            if (pageSettings == null)
            {
                throw new ArgumentException(SR.GetString(SR.PSDcantShowWithoutPage));
            }

            NativeMethods.PAGESETUPDLG data = new NativeMethods.PAGESETUPDLG();
            data.lStructSize       = Marshal.SizeOf(data);
            data.Flags             = GetFlags();
            data.hwndOwner         = hwndOwner;
            data.lpfnPageSetupHook = hookProcPtr;

            if (MinMargins != null)
            {
                PrinterUnit toUnit  = PrinterUnit.ThousandthsOfAnInch;
                Margins     margins = PrinterUnitConvert.Convert(MinMargins, PrinterUnit.Display, toUnit);
                data.minMarginLeft   = margins.Left;
                data.minMarginTop    = margins.Top;
                data.minMarginRight  = margins.Right;
                data.minMarginBottom = margins.Bottom;
            }

            if (pageSettings.Margins != null)
            {
                PrinterUnit toUnit  = PrinterUnit.ThousandthsOfAnInch;
                Margins     margins = PrinterUnitConvert.Convert(pageSettings.Margins, PrinterUnit.Display, toUnit);
                data.marginLeft   = margins.Left;
                data.marginTop    = margins.Top;
                data.marginRight  = margins.Right;
                data.marginBottom = margins.Bottom;
            }

            // Ensure that the margins are >= minMargins.
            // This is a requirement of the PAGESETUPDLG structure.
            //
            data.marginLeft   = Math.Max(data.marginLeft, data.minMarginLeft);
            data.marginTop    = Math.Max(data.marginTop, data.minMarginTop);
            data.marginRight  = Math.Max(data.marginRight, data.minMarginRight);
            data.marginBottom = Math.Max(data.marginBottom, data.minMarginBottom);

            PrinterSettings printer = (printerSettings == null) ? pageSettings.PrinterSettings : printerSettings;

            IntSecurity.AllPrinting.Assert();

            try {
                data.hDevMode  = printer.GetHdevmode(pageSettings);
                data.hDevNames = printer.GetHdevnames();
            }
            finally {
                CodeAccessPermission.RevertAssert();
            }

            try {
                bool status = UnsafeNativeMethods.PageSetupDlg(data);
                if (!status)
                {
                    // Debug.WriteLine(Windows.CommonDialogErrorToString(Windows.CommDlgExtendedError()));
                    return(false);
                }

                UpdateSettings(data, pageSettings, printerSettings); // yes, printerSettings, not printer
                return(true);
            }
            finally {
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode));
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames));
            }
        }
Example #7
0
        private unsafe bool ShowPrintDialog(IntPtr hwndOwner)
        {
            PRINTDLGW data;

            if (IntPtr.Size == 4)
            {
                data = new PRINTDLGW_32
                {
                    lStructSize = (uint)sizeof(PRINTDLGW_32)
                };
            }
            else
            {
                data = new PRINTDLGW_64
                {
                    lStructSize = (uint)sizeof(PRINTDLGW_64)
                };
            }

            data.nFromPage = 1;
            data.nToPage   = 1;
            data.nMinPage  = 0;
            data.nMaxPage  = 9999;
            data.Flags     = GetFlags();
            data.nCopies   = (ushort)PrinterSettings.Copies;
            data.hwndOwner = hwndOwner;

            User32.WNDPROCINT wndproc = new User32.WNDPROCINT(HookProc);
            data.lpfnPrintHook = Marshal.GetFunctionPointerForDelegate(wndproc);

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

                data.hDevNames = PrinterSettings.GetHdevnames();
            }
            catch (InvalidPrinterException)
            {
                // Leave those fields null; Windows will fill them in
                data.hDevMode  = IntPtr.Zero;
                data.hDevNames = IntPtr.Zero;
            }

            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(string.Format(SR.PDpageOutOfRange, "FromPage"));
                    }

                    if (PrinterSettings.ToPage < PrinterSettings.MinimumPage ||
                        PrinterSettings.ToPage > PrinterSettings.MaximumPage)
                    {
                        throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "ToPage"));
                    }

                    if (PrinterSettings.ToPage < PrinterSettings.FromPage)
                    {
                        throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "FromPage"));
                    }

                    data.nFromPage = (ushort)PrinterSettings.FromPage;
                    data.nToPage   = (ushort)PrinterSettings.ToPage;
                    data.nMinPage  = (ushort)PrinterSettings.MinimumPage;
                    data.nMaxPage  = (ushort)PrinterSettings.MaximumPage;
                }

                if (PrintDlg(ref data).IsFalse())
                {
                    var result = CommDlgExtendedError();
                    return(false);
                }

                UpdatePrinterSettings(data.hDevMode, data.hDevNames, (short)data.nCopies, data.Flags, settings, PageSettings);

                PrintToFile = (data.Flags & PD.PRINTTOFILE) != 0;
                PrinterSettings.PrintToFile = PrintToFile;

                if (AllowSomePages)
                {
                    PrinterSettings.FromPage = data.nFromPage;
                    PrinterSettings.ToPage   = data.nToPage;
                }

                // When the flag PD_USEDEVMODECOPIESANDCOLLATE is not set,
                // PRINTDLG.nCopies or PRINTDLG.nCopies indicates the number of copies the user wants
                // to print, and the PD_COLLATE flag in the Flags member indicates
                // whether the user wants to print them collated.
                if ((data.Flags & PD.USEDEVMODECOPIESANDCOLLATE) == 0)
                {
                    PrinterSettings.Copies  = (short)data.nCopies;
                    PrinterSettings.Collate = (data.Flags & PD.COLLATE) == PD.COLLATE;
                }

                return(true);
            }
            finally
            {
                GC.KeepAlive(wndproc);
                Kernel32.GlobalFree(data.hDevMode);
                Kernel32.GlobalFree(data.hDevNames);
            }
        }
Example #8
0
        // NOTE: this code is taken from C1Report printing.
        /// <summary>
        /// Creates a PrintDocument based on passed printer settings and current page settings.
        /// </summary>
        /// <param name="printerSettings">The printer settings to use. Must not be null.</param>
        /// <returns>An instance of PrintDocument that has the specified printer and page settings.</returns>
        /// <remarks>
        /// The code in this method tries to work around an issue with the standard page setup dialog:
        /// if the target printer supports papers that are absent from the System.Drawing.Printing.PaperKind
        /// enum, and such a paper is selected - in certain use scenarios the integrity of the printer and
        /// page settings is broken by the dialog, and on subsequent calls the dialog shows only the
        /// default paper. The key to avoiding this seems to be to use a PrintDocument, and to
        /// set the printer settings with Sethdevnames/Sethdevmode calls, and then to individually
        /// set the relevant page settings. TFS~~17823.
        /// </remarks>
        private PrintDocument _makePageSettingsPrintDocument(PageSettings pageSettings, PrinterSettings printerSettings)
        {
            var pdoc = new PrintDocument();

            // Set printer settings:
            pdoc.PrinterSettings.SetHdevnames(printerSettings.GetHdevnames());
            pdoc.PrinterSettings.SetHdevmode(printerSettings.GetHdevmode());

            // Set relevant page settings (code is copied from C1PageSettings.ToPageSettings):
            var page = pageSettings; // cache page settings as they are created on the fly

            // color:
            pdoc.DefaultPageSettings.Color = page.Color;

            // orientation:
            pdoc.DefaultPageSettings.Landscape = page.Landscape;

            // margins:
            pdoc.DefaultPageSettings.Margins.Left   = page.Margins.Left;
            pdoc.DefaultPageSettings.Margins.Right  = page.Margins.Right;
            pdoc.DefaultPageSettings.Margins.Top    = page.Margins.Top;
            pdoc.DefaultPageSettings.Margins.Bottom = page.Margins.Bottom;

            // paper source:
            PaperSource ps = null;

            if (page.PaperSource.Kind == PaperSourceKind.Custom)
            {
                foreach (PaperSource paperSource in pdoc.PrinterSettings.PaperSources)
                {
                    if (paperSource.Kind == PaperSourceKind.Custom && paperSource.RawKind == page.PaperSource.RawKind)
                    {
                        ps = paperSource;
                        break;
                    }
                }
            }
            else
            {
                foreach (PaperSource paperSource in pdoc.PrinterSettings.PaperSources)
                {
                    if (paperSource.Kind == page.PaperSource.Kind)
                    {
                        ps = paperSource;
                        break;
                    }
                }
            }
            if (ps == null)
            {
                ps            = new PaperSource();
                ps.SourceName = page.PaperSource.SourceName;
                ps.RawKind    = page.PaperSource.RawKind;
            }
            pdoc.DefaultPageSettings.PaperSource = ps;

            // printer resolution:
            if (page.PrinterResolution != null && page.PrinterResolution.Kind == System.Drawing.Printing.PrinterResolutionKind.Custom)
            {
                PrinterResolution pr = new PrinterResolution();
                pr.Kind = page.PrinterResolution.Kind;
                pr.X    = page.PrinterResolution.X;
                pr.Y    = page.PrinterResolution.Y;
                pdoc.DefaultPageSettings.PrinterResolution = pr;
            }
            else
            {
                foreach (PrinterResolution printerResolution in pdoc.PrinterSettings.PrinterResolutions)
                {
                    if (printerResolution.Kind == page.PrinterResolution.Kind)
                    {
                        pdoc.DefaultPageSettings.PrinterResolution = printerResolution;
                        break;
                    }
                }
            }

            // paper size: assigning .NET PaperSize to a size where Kind is one missing from the PaperKind enum
            // (e.g. A0) causes the PageSetupDialog to break the associated devmode's integrity for subsequent calls,
            // so we don't mess with such papers at all:
            if (page.PaperSize.Kind != PaperKind.Custom)
            {
                foreach (PaperSize psize in pdoc.PrinterSettings.PaperSizes)
                {
                    if (psize.Kind == page.PaperSize.Kind && pdoc.DefaultPageSettings.PaperSize.Kind != page.PaperSize.Kind)
                    {
                        pdoc.DefaultPageSettings.PaperSize = page.PaperSize;
                        break;
                    }
                }
            }

            return(pdoc);
        }
Example #9
0
        // 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;
                }

                // Fix Dev10 #575399, when the flag PD_USEDEVMODECOPIESANDCOLLATE is not set,
                // PRINTDLG.nCopies or PRINTDLG.nCopies indicates the number of copies the user wants
                // to print, and the PD_COLLATE flag in the Flags member indicates
                // whether the user wants to print them collated.
                // Due to a Windows OS Bug 558734, we don't need to consider Windows XP and before
                if ((data.Flags & NativeMethods.PD_USEDEVMODECOPIESANDCOLLATE) == 0)
                {
                    if (Environment.OSVersion.Version.Major >= 6)
                    {
                        PrinterSettings.Copies  = data.nCopies;
                        PrinterSettings.Collate = ((data.Flags & NativeMethods.PD_COLLATE) == NativeMethods.PD_COLLATE);
                    }
                }

                return(true);
            }
            finally {
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode));
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames));
            }
        }
Example #10
0
        /// <include file='doc\PrintDialog.uex' path='docs/doc[@for="PrintDialog.RunDialog"]/*' />
        /// <devdoc>
        /// </devdoc>
        /// <internalonly/>
        protected override bool RunDialog(IntPtr hwndOwner)
        {
            IntSecurity.SafePrinting.Demand();

            NativeMethods.WndProc hookProcPtr = new NativeMethods.WndProc(this.HookProc);
            if (settings == null)
            {
                throw new ArgumentException(SR.GetString(SR.PDcantShowWithoutPrinter));
            }

            NativeMethods.PRINTDLG data = CreatePRINTDLG();
            data.Flags         = GetFlags();
            data.nCopies       = (short)settings.Copies;
            data.hwndOwner     = hwndOwner;
            data.lpfnPrintHook = hookProcPtr;

            IntSecurity.AllPrinting.Assert();

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

                data.hDevNames = settings.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 (settings.FromPage < settings.MinimumPage ||
                        settings.FromPage > settings.MaximumPage)
                    {
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "FromPage"));
                    }
                    if (settings.ToPage < settings.MinimumPage ||
                        settings.ToPage > settings.MaximumPage)
                    {
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "ToPage"));
                    }
                    if (settings.ToPage < settings.FromPage)
                    {
                        throw new ArgumentException(SR.GetString(SR.PDpageOutOfRange, "FromPage"));
                    }

                    data.nFromPage = (short)settings.FromPage;
                    data.nToPage   = (short)settings.ToPage;
                    data.nMinPage  = (short)settings.MinimumPage;
                    data.nMaxPage  = (short)settings.MaximumPage;
                }

                if (!UnsafeNativeMethods.PrintDlg(data))
                {
                    return(false);
                }

                UpdatePrinterSettings(data, settings, PageSettings);
                PrintToFile          = ((data.Flags & NativeMethods.PD_PRINTTOFILE) != 0);
                settings.PrintToFile = PrintToFile;

                if (AllowSomePages)
                {
                    settings.FromPage = data.nFromPage;
                    settings.ToPage   = data.nToPage;
                }

                return(true);
            }
            finally {
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevMode));
                UnsafeNativeMethods.GlobalFree(new HandleRef(data, data.hDevNames));
            }
        }