|
//------------------------------------------------------------------------------
// <copyright file="PageSetupDialog.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
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;
using System.Text;
using System.Globalization;
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog"]/*' />
/// <devdoc>
/// <para> Represents
/// a dialog box that allows users to manipulate page settings, including margins and paper orientation.</para>
/// </devdoc>
[DefaultProperty("Document")]
[SRDescription(SR.DescriptionPageSetupDialog)]
// The only event this dialog has is HelpRequested, which isn't very useful
public sealed class PageSetupDialog : CommonDialog {
// If PrintDocument != null, pageSettings == printDocument.PageSettings
private PrintDocument printDocument = null;
private PageSettings pageSettings = null;
private PrinterSettings printerSettings = null;
private bool allowMargins;
private bool allowOrientation;
private bool allowPaper;
private bool allowPrinter;
private Margins minMargins;
private bool showHelp;
private bool showNetwork;
private bool enableMetric;
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.PageSetupDialog"]/*' />
/// <devdoc>
/// <para>Initializes a new instance of the <see cref='System.Windows.Forms.PageSetupDialog'/> class.</para>
/// </devdoc>
public PageSetupDialog() {
Reset();
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.AllowMargins"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the margins section of the dialog box is enabled.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(true),
SRDescription(SR.PSDallowMarginsDescr)
]
public bool AllowMargins {
get {
return allowMargins;
}
set {
allowMargins = value;
}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.AllowOrientation"]/*' />
/// <devdoc>
/// <para> Gets or sets a value indicating whether the orientation section of the dialog box (landscape vs. portrait)
/// is enabled.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(true),
SRDescription(SR.PSDallowOrientationDescr)
]
public bool AllowOrientation {
get { return allowOrientation;}
set { allowOrientation = value;}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.AllowPaper"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the paper section of the dialog box (paper size and paper source)
/// is enabled.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(true),
SRDescription(SR.PSDallowPaperDescr)
]
public bool AllowPaper {
get { return allowPaper;}
set { allowPaper = value;}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.AllowPrinter"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the Printer button is enabled.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(true),
SRDescription(SR.PSDallowPrinterDescr)
]
public bool AllowPrinter {
get { return allowPrinter;}
set { allowPrinter = value;}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.Document"]/*' />
/// <devdoc>
/// <para>Gets or sets a value indicating the <see cref='System.Drawing.Printing.PrintDocument'/>
/// to get page settings from.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatData),
DefaultValue(null),
SRDescription(SR.PDdocumentDescr)
]
public PrintDocument Document {
get { return printDocument;}
set {
printDocument = value;
if (printDocument != null) {
pageSettings = printDocument.DefaultPageSettings;
printerSettings = printDocument.PrinterSettings;
}
}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.EnableMetric"]/*' />
/// <devdoc>
/// This allows the user to override the current behavior where the Metric is converted to ThousandOfInch even for METRIC MEASUREMENTSYSTEM
/// which returns a HUNDREDSOFMILLIMETER value.
/// </devdoc>
[
DefaultValue(false),
SRDescription(SR.PSDenableMetricDescr),
Browsable(true), EditorBrowsable(EditorBrowsableState.Always)
]
public bool EnableMetric {
get { return enableMetric;}
set { enableMetric = value;}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.MinMargins"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value indicating the minimum margins the
/// user is allowed to select, in hundredths of an inch.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatData),
SRDescription(SR.PSDminMarginsDescr)
]
public Margins MinMargins {
get { return minMargins;}
set {
if (value == null)
value = new Margins(0, 0, 0, 0);
minMargins = value;
}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.PageSettings"]/*' />
/// <devdoc>
/// <para>
/// Gets
/// or sets
/// a value indicating
/// the page settings modified by the dialog box.
///
/// </para>
/// </devdoc>
[
SRCategory(SR.CatData),
DefaultValue(null),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
SRDescription(SR.PSDpageSettingsDescr)
]
public PageSettings PageSettings {
get { return pageSettings;}
set {
pageSettings = value;
printDocument = null;
}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.PrinterSettings"]/*' />
/// <devdoc>
/// <para>
/// Gets
/// or sets the printer
/// settings the dialog box will modify if the user clicks the Printer button.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatData),
DefaultValue(null),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
SRDescription(SR.PSDprinterSettingsDescr)
]
public PrinterSettings PrinterSettings {
get { return printerSettings;}
set {
printerSettings = value;
printDocument = null;
}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.ShowHelp"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the Help button is visible.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(false),
SRDescription(SR.PSDshowHelpDescr)
]
public bool ShowHelp {
get { return showHelp;}
set { showHelp = value;}
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.ShowNetwork"]/*' />
/// <devdoc>
/// <para>
/// Gets or sets a value indicating whether the Network button is visible.
/// </para>
/// </devdoc>
[
SRCategory(SR.CatBehavior),
DefaultValue(true),
SRDescription(SR.PSDshowNetworkDescr)
]
public bool ShowNetwork {
get { return showNetwork;}
set { showNetwork = value;}
}
private int GetFlags() {
int flags = 0;
flags |= NativeMethods.PSD_ENABLEPAGESETUPHOOK;
if (!allowMargins) flags |= NativeMethods.PSD_DISABLEMARGINS;
if (!allowOrientation) flags |= NativeMethods.PSD_DISABLEORIENTATION;
if (!allowPaper) flags |= NativeMethods.PSD_DISABLEPAPER;
if (!allowPrinter || printerSettings == null) flags |= NativeMethods.PSD_DISABLEPRINTER;
if (showHelp) flags |= NativeMethods.PSD_SHOWHELP;
if (!showNetwork) flags |= NativeMethods.PSD_NONETWORKBUTTON;
if (minMargins != null) flags |= NativeMethods.PSD_MINMARGINS;
if (pageSettings.Margins != null) flags |= NativeMethods.PSD_MARGINS;
//
return flags;
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.Reset"]/*' />
/// <devdoc>
/// <para>
/// Resets all options to their default values.
/// </para>
/// </devdoc>
public override void Reset() {
allowMargins = true;
allowOrientation = true;
allowPaper = true;
allowPrinter = true;
MinMargins = null; // turns into Margin with all zeros
pageSettings = null;
printDocument = null;
printerSettings = null;
showHelp = false;
showNetwork = true;
}
private void ResetMinMargins() {
MinMargins = null;
}
/// <include file='doc\PageSetupDialog.uex' path='docs/doc[@for="PageSetupDialog.ShouldSerializeMinMargins"]/*' />
/// <devdoc>
/// <para>
/// Indicates whether the <see cref='System.Windows.Forms.PageSetupDialog.MinMargins'/>
/// property should be
/// persisted.
/// </para>
/// </devdoc>
private bool ShouldSerializeMinMargins() {
return minMargins.Left != 0
|| minMargins.Right != 0
|| minMargins.Top != 0
|| minMargins.Bottom != 0;
}
private static void UpdateSettings(NativeMethods.PAGESETUPDLG data, PageSettings pageSettings,
PrinterSettings printerSettings) {
// SetHDevMode demands AllPrintingAndUnmanagedCode Permission : Since we are calling that function we should Assert the permision,
IntSecurity.AllPrintingAndUnmanagedCode.Assert();
try
{
pageSettings.SetHdevmode(data.hDevMode);
if (printerSettings != null) {
printerSettings.SetHdevmode(data.hDevMode);
printerSettings.SetHdevnames(data.hDevNames);
}
}
finally
{
CodeAccessPermission.RevertAssert();
}
Margins newMargins = new Margins();
newMargins.Left = data.marginLeft;
newMargins.Top = data.marginTop;
newMargins.Right = data.marginRight;
newMargins.Bottom = data.marginBottom;
PrinterUnit fromUnit = ((data.Flags & NativeMethods.PSD_INHUNDREDTHSOFMILLIMETERS) != 0)
? PrinterUnit.HundredthsOfAMillimeter
: PrinterUnit.ThousandthsOfAnInch;
pageSettings.Margins = PrinterUnitConvert.Convert(newMargins, fromUnit, PrinterUnit.Display);
}
/// <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;
PrinterUnit toUnit = PrinterUnit.ThousandthsOfAnInch;
// Refer VSWhidbey: 331160. 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...
//bug (121347)...
StringBuilder sb = new StringBuilder(2);
int result = UnsafeNativeMethods.GetLocaleInfo(NativeMethods.LOCALE_USER_DEFAULT,NativeMethods.LOCALE_IMEASURE, sb,sb.Capacity);
if (result > 0 && Int32.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 == null) ? pageSettings.PrinterSettings : printerSettings;
// GetHDevmode demands AllPrintingAndUnmanagedCode Permission : Since we are calling that function we should Assert the permision,
IntSecurity.AllPrintingAndUnmanagedCode.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));
}
}
}
}
|