Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / 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.
//
//-----------------------------------------------------------------------------
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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Attributes.cs
- KeyInstance.cs
- SqlProviderManifest.cs
- MatrixAnimationUsingPath.cs
- TransactionalPackage.cs
- ButtonRenderer.cs
- OdbcEnvironment.cs
- ClientConfigPaths.cs
- PixelFormat.cs
- SoapSchemaMember.cs
- X509Utils.cs
- C14NUtil.cs
- DirtyTextRange.cs
- SudsWriter.cs
- XmlBufferReader.cs
- QueryRewriter.cs
- FloaterParagraph.cs
- RtfFormatStack.cs
- TextOnlyOutput.cs
- Main.cs
- ProxyGenerationError.cs
- ObjectDataSourceSelectingEventArgs.cs
- DelegateHelpers.cs
- Header.cs
- Pair.cs
- FlowDocumentView.cs
- XamlReader.cs
- ResourceExpressionBuilder.cs
- WebBaseEventKeyComparer.cs
- VariantWrapper.cs
- NgenServicingAttributes.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- PlaceHolder.cs
- TimersDescriptionAttribute.cs
- Vertex.cs
- WebPartConnectionsConfigureVerb.cs
- EditorPartChrome.cs
- AddInServer.cs
- TimelineGroup.cs
- Axis.cs
- PropertyBuilder.cs
- ContextStack.cs
- sqlinternaltransaction.cs
- EDesignUtil.cs
- CodeSnippetExpression.cs
- StringBuilder.cs
- TextSearch.cs
- TableSectionStyle.cs
- TransactionScopeDesigner.cs
- HttpCookieCollection.cs
- PersonalizationStateQuery.cs
- IdentityReference.cs
- AdRotator.cs
- GuidelineCollection.cs
- TypedReference.cs
- MultitargetingHelpers.cs
- DataMisalignedException.cs
- SystemColorTracker.cs
- TouchDevice.cs
- ServiceElementCollection.cs
- CompilationUtil.cs
- PerformanceCountersElement.cs
- TemplatedWizardStep.cs
- WmpBitmapDecoder.cs
- CompilationSection.cs
- ControlCachePolicy.cs
- XmlDocumentType.cs
- PageParser.cs
- TreeNodeStyle.cs
- BooleanKeyFrameCollection.cs
- SqlReferenceCollection.cs
- ServiceDescriptionImporter.cs
- PropertyDescriptorComparer.cs
- X509ThumbprintKeyIdentifierClause.cs
- ProcessHost.cs
- Screen.cs
- DrawingImage.cs
- HMACSHA512.cs
- HtmlInputPassword.cs
- ControlBindingsCollection.cs
- XmlDownloadManager.cs
- XmlSerializerSection.cs
- ArraySegment.cs
- ServicePointManagerElement.cs
- InternalResources.cs
- MILUtilities.cs
- Exception.cs
- XmlNamespaceManager.cs
- ExtendedPropertyInfo.cs
- TrackingServices.cs
- XmlCharCheckingReader.cs
- CellTreeNode.cs
- MemberInitExpression.cs
- MetadataCache.cs
- Int32RectConverter.cs
- SmtpException.cs
- ClientTargetSection.cs
- IgnoreFileBuildProvider.cs
- TraceSwitch.cs
- NamedObjectList.cs