Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / System / Windows / Controls / PrintDialog.cs / 1 / PrintDialog.cs
/*++
Copyright (C) 2004 - 2005 Microsoft Corporation.
All rights reserved.
Module Name:
PrintDialog.cs
Abstract:
This file contains the implementation of the PrintDialog class
and its supporting enums.
Author:
Robert Anderson (robertan) 9-May-2005
--*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Printing;
using System.Security;
using System.Security.Permissions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Xps;
using System.Xml;
using MS.Internal.Printing;
using MS.Internal;
using System.Windows.Xps.Serialization;
using System.Windows.Documents;
using System.Windows.Documents.Serialization; // WritingCompletedEventArgs
using System.Drawing.Printing;
using MS.Internal.PresentationFramework;
namespace System.Windows.Controls
{
///
/// This class is used to show a print which will configure a
/// user PrintTicket and Printer based on user input. This
/// PrintTicket and Printer is then used to perform a print job.
///
public class PrintDialog
{
#region Constructors
///
/// Instantiates an instance of the Print Dialog.
///
///
/// Critical: - setting critical data (_printQueue, _printTicket, _dialogInvoked)
/// PublicOk: - We are setting these to "known" values of null. There
/// is no data exposure here.
///
[SecurityCritical]
public
PrintDialog(
)
{
_dialogInvoked = false;
_printQueue = null;
_printTicket = null;
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = false;
_pageRangeSelection = PageRangeSelection.AllPages;
_minPage = 1;
_maxPage = 9999;
_userPageRangeEnabled = false;
}
#endregion Constructors
#region Public properties
///
/// Gets or Sets the PageRangeSelection option for the print dialog.
///
public PageRangeSelection PageRangeSelection
{
get
{
return _pageRangeSelection;
}
set
{
_pageRangeSelection = value;
}
}
///
/// Gets or sets a PageRange objects used when the PageRangeSelection
/// option is set to UserPages.
///
public PageRange PageRange
{
get
{
return _pageRange;
}
set
{
if ((value.PageTo <= 0) || (value.PageFrom <= 0))
{
throw new System.ArgumentException(SR.Get(SRID.PrintDialogInvalidPageRange), "PageRange");
}
_pageRange = value;
if (_pageRange.PageFrom > _pageRange.PageTo)
{
int temp = _pageRange.PageFrom;
_pageRange.PageFrom = _pageRange.PageTo;
_pageRange.PageTo = temp;
}
}
}
///
/// Gets or a sets a flag to enable/disable the user page range support on
/// the print dialog.
///
public bool UserPageRangeEnabled
{
get
{
return _userPageRangeEnabled;
}
set
{
_userPageRangeEnabled = value;
}
}
// the following two properties return non CLS-compliant type UInt32 (bug 1788246)
#pragma warning disable 3003
///
/// Gets or sets the minimum page number allowed in the page ranges.
///
public UInt32 MinPage
{
get
{
return _minPage;
}
set
{
if (_minPage <= 0)
{
throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MinPage"));
}
_minPage = value;
}
}
///
/// Gets or sets the maximum page number allowed in the page ranges.
///
public UInt32 MaxPage
{
get
{
return _maxPage;
}
set
{
if (_maxPage <= 0)
{
throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MaxPage"));
}
_maxPage = value;
}
}
#pragma warning restore 3003
///
/// Gets or sets the printer selection.
///
///
/// Critical: - The getter is critical since it accesses critical data in web application mode.
/// - The getter is calling critical code (AcquireDefaultPrintQueue).
/// - The setter is critical since it is returning critical data.
/// PublicOk: - A demand is made for default printing before returning the print queue. This
/// would be the same permission required to get the print queue in the first place.
/// - We also demand before setting the print queue object. If they can satisfy the
/// the demand then they are safe to print anyways.
///
public PrintQueue PrintQueue
{
[SecurityCritical]
get
{
SecurityHelper.DemandPrintDialogPermissions();
if (_printQueue == null)
{
_printQueue = AcquireDefaultPrintQueue();
}
return _printQueue;
}
[SecurityCritical]
set
{
SecurityHelper.DemandPrintDialogPermissions();
_printQueue = value;
}
}
///
/// Get or sets the current PrintTicket object.
///
///
/// Critical: - The getter is critical since it accesses critical data.
/// - The getter is calling critical code (AcquireDefaultPrintTicket).
/// - The setter is critical since it is returning critical data.
/// PublicOk: - A demand is made for default printing before returning the print ticket. This
/// would be the same permission required to get the print ticket in the first place.
/// - We also demand before setting the print ticket object. If they can satisfy the
/// the demand then they are safe to print anyways.
///
public PrintTicket PrintTicket
{
[SecurityCritical]
get
{
SecurityHelper.DemandPrintDialogPermissions();
if (_printTicket == null)
{
_printTicket = AcquireDefaultPrintTicket(this.PrintQueue);
}
return _printTicket;
}
[SecurityCritical]
set
{
SecurityHelper.DemandPrintDialogPermissions();
_printTicket = value;
}
}
///
/// Get the Width of the area on paper to which the application can print
///
public
double
PrintableAreaWidth
{
get
{
if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) ||
((_isPrintableAreaWidthUpdated == true) && (_isPrintableAreaHeightUpdated == false)))
{
_isPrintableAreaWidthUpdated = true;
_isPrintableAreaHeightUpdated = false;
UpdatePrintableAreaSize();
}
return _printableAreaWidth;
}
}
///
/// Get the Height of the area on paper to which the application can print
///
public
double
PrintableAreaHeight
{
get
{
if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) ||
((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == true)))
{
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = true;
UpdatePrintableAreaSize();
}
return _printableAreaHeight;
}
}
#endregion Public properties
#region Public methods
///
/// Pops the dialog up to the user in a modal form.
///
///
/// Critical: - Accesses and sets critical data.
/// PublicOk: - Data is internal to this dialog and can only be retrieved
/// by other critical code. No information leaves this method.
///
[SecurityCritical]
public
Nullable
ShowDialog()
{
//
// Reset this flag as we have not displayed the dialog yet.
//
_dialogInvoked = false;
Win32PrintDialog dlg = new Win32PrintDialog();
//
// Setup the old values if any exist.
//
dlg.PrintTicket = _printTicket;
dlg.PrintQueue = _printQueue;
dlg.MinPage = Math.Max(1, Math.Min(_minPage, _maxPage));
dlg.MaxPage = Math.Max(dlg.MinPage, Math.Max(_minPage, _maxPage));
dlg.PageRangeEnabled = _userPageRangeEnabled;
dlg.PageRange = new PageRange(
Math.Max((int)dlg.MinPage, _pageRange.PageFrom),
Math.Min((int)dlg.MaxPage, _pageRange.PageTo));
dlg.PageRangeSelection = _pageRangeSelection;
//
// Invoke the Win32 dialog
//
UInt32 dialogResult = dlg.ShowDialog();
if ((dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_APPLY) ||
(dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT))
{
_printTicket = dlg.PrintTicket;
_printQueue = dlg.PrintQueue;
_pageRange = dlg.PageRange;
_pageRangeSelection = dlg.PageRangeSelection;
_dialogInvoked = true;
}
return (dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT);
}
///
/// Prints a Visual to the currently selected Print Queue.
///
///
/// The visual to be printed.
///
///
/// Description of the job to be printed. This shows in the Printer UI
///
///
/// Critical: - Sets a critical data property.
/// PublicOk: - The critical data is a flag that needs to be reset for each print
/// job to enforce the dialog invocation on every print operation. Without
/// this method resetting this flag we would not be honoring the security
/// goal of displaying the dialog once per print job.
///
[SecurityCritical]
public
void
PrintVisual(
Visual visual,
String description
)
{
if (visual == null)
{
throw new ArgumentNullException("visual");
}
XpsDocumentWriter writer = CreateWriter(description);
writer.Write(visual);
_printableAreaWidth = 0;
_printableAreaHeight = 0;
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = false;
_dialogInvoked = false;
}
///
/// Prints an DocumentPaginator based document to the currently selected Print Queue.
///
///
/// The DocumentPaginator to be printed.
///
///
/// Description of the job to be printed. This shows in the Printer UI
///
///
/// Critical: - Sets a critical data property.
/// PublicOk: - The critical data is a flag that needs to be reset for each print
/// job to enforce the dialog invocation on every print operation. Without
/// this method resetting this flag we would not be honoring the security
/// goal of displaying the dialog once per print job.
///
[SecurityCritical]
public
void
PrintDocument(
DocumentPaginator documentPaginator,
String description
)
{
if (documentPaginator == null)
{
throw new ArgumentNullException("documentPaginator");
}
XpsDocumentWriter writer = CreateWriter(description);
writer.Write(documentPaginator);
_printableAreaWidth = 0;
_printableAreaHeight = 0;
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = false;
_dialogInvoked = false;
}
#endregion Public methods
#region Private methods
///
/// Critical: - Asserts to obtain the default print queue from the local server.
///
[SecurityCritical]
private
PrintQueue
AcquireDefaultPrintQueue()
{
PrintQueue printQueue = null;
(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert
try
{
try
{
LocalPrintServer server = new LocalPrintServer();
printQueue = server.DefaultPrintQueue;
}
catch (PrintSystemException)
{
//
// It is entirely possible for there to be no "default" printer. In this case,
// the printing system throws an exception. We do not want this to propagate
// up. Instead, returning null is fine.
//
printQueue = null;
}
}
finally
{
PrintingPermission.RevertAssert();
}
return printQueue;
}
///
/// Critical: - Asserts to obtain the PrintTicket from the specified PrintQueue
/// object or create a blank PrintTicket object (i.e. PrintTicket::ctor).
///
[SecurityCritical]
private
PrintTicket
AcquireDefaultPrintTicket(
PrintQueue printQueue
)
{
PrintTicket printTicket = null;
(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert
try
{
try
{
if (printQueue != null)
{
printTicket = printQueue.UserPrintTicket;
if (printTicket == null)
{
printTicket = printQueue.DefaultPrintTicket;
}
}
}
catch (PrintSystemException)
{
//
// The printing subsystem can throw an exception in certain cases when
// the print ticket is unavailable. If it does we will handle this
// below. There is no real need to bubble this up to the application.
//
printTicket = null;
}
}
finally
{
PrintingPermission.RevertAssert();
}
//
// If the printing subsystem could not give us a print ticket either due to
// a failure or because a user/system default was not available, then just
// create a blank/empty one.
//
if (printTicket == null)
{
printTicket = new PrintTicket();
}
return printTicket;
}
///
/// Critical: - Invokes a critical method (PickCorrectPrintingEnvironment).
/// TreatAsSafe: - Critical data returned from above method is internal and does
/// not leave the scope of this method. It is only used to calculate
/// non-critical values.
///
[SecurityCritical, SecurityTreatAsSafe]
private
void
UpdatePrintableAreaSize(
)
{
PrintQueue printQueue = null;
PrintTicket printTicket = null;
PickCorrectPrintingEnvironment(ref printQueue, ref printTicket);
PrintCapabilities printCap = null;
if (printQueue != null)
{
printCap = printQueue.GetPrintCapabilities(printTicket);
}
// PrintCapabilities OrientedPageMediaWidth/Height are Nullable
if ((printCap != null) &&
(printCap.OrientedPageMediaWidth != null) &&
(printCap.OrientedPageMediaHeight != null))
{
_printableAreaWidth = (double)printCap.OrientedPageMediaWidth;
_printableAreaHeight = (double)printCap.OrientedPageMediaHeight;
}
else
{
// Initialize page size to portrait Letter size.
// This is our fallback if PrintTicket doesn't specify the page size.
_printableAreaWidth = 816;
_printableAreaHeight = 1056;
// PrintTicket's PageMediaSize could be null and PageMediaSize Width/Height are Nullable
if ((printTicket.PageMediaSize != null) &&
(printTicket.PageMediaSize.Width != null) &&
(printTicket.PageMediaSize.Height != null))
{
_printableAreaWidth = (double)printTicket.PageMediaSize.Width;
_printableAreaHeight = (double)printTicket.PageMediaSize.Height;
}
// If we are using PrintTicket's PageMediaSize dimensions to populate the widht/height values,
// we need to adjust them based on current orientation. PrintTicket's PageOrientation is Nullable.
if (printTicket.PageOrientation != null)
{
PageOrientation orientation = (PageOrientation)printTicket.PageOrientation;
// need to swap width/height in landscape orientation
if ((orientation == PageOrientation.Landscape) ||
(orientation == PageOrientation.ReverseLandscape))
{
double t = _printableAreaWidth;
_printableAreaWidth = _printableAreaHeight;
_printableAreaHeight = t;
}
}
}
}
///
/// Critical: - Asserts for PrintingPermissionLevel.DefaultPrinting
/// to be able to use the printQueue to create the
/// XpsDocumentWriter.
/// TreatAsSafe: - The assert is only done after ensuring that the user
/// has conciously made a decision to print by successfully
/// dismissing the Print Dialog. This logic of a dialog
/// being required is only needed for partial trust applications.
/// The logic of checking this criteria is contained within the
/// PickCorrectPrintingEnvironment method.
/// - The XpsDocumentWriter instance returned from this method
/// is not unsafe since the application is either full trust
/// or the user chose to print. It is okay for the application
/// to use the XpsDocumentWriter to print at this point.
///
[SecurityCritical, SecurityTreatAsSafe]
private
XpsDocumentWriter
CreateWriter(
String description
)
{
PrintQueue printQueue = null;
PrintTicket printTicket = null;
XpsDocumentWriter writer = null;
PickCorrectPrintingEnvironment(ref printQueue, ref printTicket);
(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert
try
{
if(printQueue != null)
{
printQueue.CurrentJobSettings.Description = description;
}
writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
PrintDlgPrintTicketEventHandler eventHandler = new PrintDlgPrintTicketEventHandler(printTicket);
writer.WritingPrintTicketRequired +=
new WritingPrintTicketRequiredEventHandler(eventHandler.SetPrintTicket);
}
finally
{
PrintingPermission.RevertAssert();
}
return writer;
}
///
/// Critical: - Accesses critical data and returns it to the caller.
/// - Calls critical code (AcquireDefaultPrintQueue/AcquireDefaultPrintTicket)
/// - Detects whether a caller is allowed to acquire this data
/// based on a demand. This demand is only performed if the
/// dialog was not invoked already. It is fine to return the
/// data if the dialog was invoked, however, the data is still
/// critical.
///
/// NOTE: This method validates that a dialog was invoked prior to returning the
/// PrintQueue and PrintTicket for the case of web applications. If the
/// dialog was not invoked then an exception is thrown.
///
[SecurityCritical]
private
void
PickCorrectPrintingEnvironment(
ref PrintQueue printQueue,
ref PrintTicket printTicket
)
{
if (_dialogInvoked == false)
{
//
// If the dialog has not been invoked then the user needs printing permissions.
// If the demand succeeds then they can print. If the demand fails, then we
// tell them that the print dialog must be displayed first by throwing a dialog
// exception.
//
try
{
SecurityHelper.DemandPrintDialogPermissions();
}
catch (SecurityException)
{
throw new PrintDialogException(SR.Get(SRID.PartialTrustPrintDialogMustBeInvoked));
}
}
//
// If the default print queue and print ticket have not already
// been selected then update them now since we need them.
//
// NOTE: If this code gets called then we know the dialog has never
// been invoked but the above demand was satisfied. In this
// case we want to just pickup the user defaults.
//
if (_printQueue == null)
{
_printQueue = AcquireDefaultPrintQueue();
}
if (_printTicket == null)
{
_printTicket = AcquireDefaultPrintTicket(_printQueue);
}
//
// We should have valid print queue and print ticket objects to
// return now. As a note, a null PrintQueue is valid for this
// since the dialog will automatically pick up the user default
// printer for us.
//
printQueue = _printQueue;
printTicket = _printTicket;
}
#endregion Private methods
#region Private data
///
/// The PrintTicket is critical and not obtainable from a partial
/// trust application unless they can satisfy a printing permission
/// demand.
///
[SecurityCritical]
private
PrintTicket _printTicket;
///
/// The PrintQueue is critical and not obtainable from a partial
/// trust application unless they can satisfy a printing permission
/// demand.
///
[SecurityCritical]
private
PrintQueue _printQueue;
///
/// This variable is used to determine whether a user actually invoked
/// and dismissed the dialog prior to printing. In a partial trust app,
/// we can safely perform the necessary asserts to print as long as the
/// user said printing was okay.
///
[SecurityCritical]
private
bool _dialogInvoked;
private
PageRangeSelection _pageRangeSelection;
private
PageRange _pageRange;
private
bool _userPageRangeEnabled;
private
UInt32 _minPage;
private
UInt32 _maxPage;
private
double _printableAreaWidth;
private
double _printableAreaHeight;
private
bool _isPrintableAreaWidthUpdated;
private
bool _isPrintableAreaHeightUpdated;
#endregion Private data
#region Internal classes
internal class PrintDlgPrintTicketEventHandler
{
#region Constructor
public
PrintDlgPrintTicketEventHandler(
PrintTicket printTicket
)
{
_printTicket = printTicket;
}
#endregion Constructor
#region Public Methods
public
void
SetPrintTicket(
Object sender,
WritingPrintTicketRequiredEventArgs args
)
{
if (args.CurrentPrintTicketLevel == PrintTicketLevel.FixedDocumentSequencePrintTicket)
{
args.CurrentPrintTicket = _printTicket;
}
}
#endregion Public Methods
#region Private Data
private
PrintTicket _printTicket;
#endregion Private Data
};
#endregion Internal classes
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/*++
Copyright (C) 2004 - 2005 Microsoft Corporation.
All rights reserved.
Module Name:
PrintDialog.cs
Abstract:
This file contains the implementation of the PrintDialog class
and its supporting enums.
Author:
Robert Anderson (robertan) 9-May-2005
--*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Printing;
using System.Security;
using System.Security.Permissions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Xps;
using System.Xml;
using MS.Internal.Printing;
using MS.Internal;
using System.Windows.Xps.Serialization;
using System.Windows.Documents;
using System.Windows.Documents.Serialization; // WritingCompletedEventArgs
using System.Drawing.Printing;
using MS.Internal.PresentationFramework;
namespace System.Windows.Controls
{
///
/// This class is used to show a print which will configure a
/// user PrintTicket and Printer based on user input. This
/// PrintTicket and Printer is then used to perform a print job.
///
public class PrintDialog
{
#region Constructors
///
/// Instantiates an instance of the Print Dialog.
///
///
/// Critical: - setting critical data (_printQueue, _printTicket, _dialogInvoked)
/// PublicOk: - We are setting these to "known" values of null. There
/// is no data exposure here.
///
[SecurityCritical]
public
PrintDialog(
)
{
_dialogInvoked = false;
_printQueue = null;
_printTicket = null;
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = false;
_pageRangeSelection = PageRangeSelection.AllPages;
_minPage = 1;
_maxPage = 9999;
_userPageRangeEnabled = false;
}
#endregion Constructors
#region Public properties
///
/// Gets or Sets the PageRangeSelection option for the print dialog.
///
public PageRangeSelection PageRangeSelection
{
get
{
return _pageRangeSelection;
}
set
{
_pageRangeSelection = value;
}
}
///
/// Gets or sets a PageRange objects used when the PageRangeSelection
/// option is set to UserPages.
///
public PageRange PageRange
{
get
{
return _pageRange;
}
set
{
if ((value.PageTo <= 0) || (value.PageFrom <= 0))
{
throw new System.ArgumentException(SR.Get(SRID.PrintDialogInvalidPageRange), "PageRange");
}
_pageRange = value;
if (_pageRange.PageFrom > _pageRange.PageTo)
{
int temp = _pageRange.PageFrom;
_pageRange.PageFrom = _pageRange.PageTo;
_pageRange.PageTo = temp;
}
}
}
///
/// Gets or a sets a flag to enable/disable the user page range support on
/// the print dialog.
///
public bool UserPageRangeEnabled
{
get
{
return _userPageRangeEnabled;
}
set
{
_userPageRangeEnabled = value;
}
}
// the following two properties return non CLS-compliant type UInt32 (bug 1788246)
#pragma warning disable 3003
///
/// Gets or sets the minimum page number allowed in the page ranges.
///
public UInt32 MinPage
{
get
{
return _minPage;
}
set
{
if (_minPage <= 0)
{
throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MinPage"));
}
_minPage = value;
}
}
///
/// Gets or sets the maximum page number allowed in the page ranges.
///
public UInt32 MaxPage
{
get
{
return _maxPage;
}
set
{
if (_maxPage <= 0)
{
throw new System.ArgumentException(SR.Get(SRID.PrintDialogZeroNotAllowed, "MaxPage"));
}
_maxPage = value;
}
}
#pragma warning restore 3003
///
/// Gets or sets the printer selection.
///
///
/// Critical: - The getter is critical since it accesses critical data in web application mode.
/// - The getter is calling critical code (AcquireDefaultPrintQueue).
/// - The setter is critical since it is returning critical data.
/// PublicOk: - A demand is made for default printing before returning the print queue. This
/// would be the same permission required to get the print queue in the first place.
/// - We also demand before setting the print queue object. If they can satisfy the
/// the demand then they are safe to print anyways.
///
public PrintQueue PrintQueue
{
[SecurityCritical]
get
{
SecurityHelper.DemandPrintDialogPermissions();
if (_printQueue == null)
{
_printQueue = AcquireDefaultPrintQueue();
}
return _printQueue;
}
[SecurityCritical]
set
{
SecurityHelper.DemandPrintDialogPermissions();
_printQueue = value;
}
}
///
/// Get or sets the current PrintTicket object.
///
///
/// Critical: - The getter is critical since it accesses critical data.
/// - The getter is calling critical code (AcquireDefaultPrintTicket).
/// - The setter is critical since it is returning critical data.
/// PublicOk: - A demand is made for default printing before returning the print ticket. This
/// would be the same permission required to get the print ticket in the first place.
/// - We also demand before setting the print ticket object. If they can satisfy the
/// the demand then they are safe to print anyways.
///
public PrintTicket PrintTicket
{
[SecurityCritical]
get
{
SecurityHelper.DemandPrintDialogPermissions();
if (_printTicket == null)
{
_printTicket = AcquireDefaultPrintTicket(this.PrintQueue);
}
return _printTicket;
}
[SecurityCritical]
set
{
SecurityHelper.DemandPrintDialogPermissions();
_printTicket = value;
}
}
///
/// Get the Width of the area on paper to which the application can print
///
public
double
PrintableAreaWidth
{
get
{
if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) ||
((_isPrintableAreaWidthUpdated == true) && (_isPrintableAreaHeightUpdated == false)))
{
_isPrintableAreaWidthUpdated = true;
_isPrintableAreaHeightUpdated = false;
UpdatePrintableAreaSize();
}
return _printableAreaWidth;
}
}
///
/// Get the Height of the area on paper to which the application can print
///
public
double
PrintableAreaHeight
{
get
{
if( ((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == false)) ||
((_isPrintableAreaWidthUpdated == false) && (_isPrintableAreaHeightUpdated == true)))
{
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = true;
UpdatePrintableAreaSize();
}
return _printableAreaHeight;
}
}
#endregion Public properties
#region Public methods
///
/// Pops the dialog up to the user in a modal form.
///
///
/// Critical: - Accesses and sets critical data.
/// PublicOk: - Data is internal to this dialog and can only be retrieved
/// by other critical code. No information leaves this method.
///
[SecurityCritical]
public
Nullable
ShowDialog()
{
//
// Reset this flag as we have not displayed the dialog yet.
//
_dialogInvoked = false;
Win32PrintDialog dlg = new Win32PrintDialog();
//
// Setup the old values if any exist.
//
dlg.PrintTicket = _printTicket;
dlg.PrintQueue = _printQueue;
dlg.MinPage = Math.Max(1, Math.Min(_minPage, _maxPage));
dlg.MaxPage = Math.Max(dlg.MinPage, Math.Max(_minPage, _maxPage));
dlg.PageRangeEnabled = _userPageRangeEnabled;
dlg.PageRange = new PageRange(
Math.Max((int)dlg.MinPage, _pageRange.PageFrom),
Math.Min((int)dlg.MaxPage, _pageRange.PageTo));
dlg.PageRangeSelection = _pageRangeSelection;
//
// Invoke the Win32 dialog
//
UInt32 dialogResult = dlg.ShowDialog();
if ((dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_APPLY) ||
(dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT))
{
_printTicket = dlg.PrintTicket;
_printQueue = dlg.PrintQueue;
_pageRange = dlg.PageRange;
_pageRangeSelection = dlg.PageRangeSelection;
_dialogInvoked = true;
}
return (dialogResult == MS.Internal.Printing.NativeMethods.PD_RESULT_PRINT);
}
///
/// Prints a Visual to the currently selected Print Queue.
///
///
/// The visual to be printed.
///
///
/// Description of the job to be printed. This shows in the Printer UI
///
///
/// Critical: - Sets a critical data property.
/// PublicOk: - The critical data is a flag that needs to be reset for each print
/// job to enforce the dialog invocation on every print operation. Without
/// this method resetting this flag we would not be honoring the security
/// goal of displaying the dialog once per print job.
///
[SecurityCritical]
public
void
PrintVisual(
Visual visual,
String description
)
{
if (visual == null)
{
throw new ArgumentNullException("visual");
}
XpsDocumentWriter writer = CreateWriter(description);
writer.Write(visual);
_printableAreaWidth = 0;
_printableAreaHeight = 0;
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = false;
_dialogInvoked = false;
}
///
/// Prints an DocumentPaginator based document to the currently selected Print Queue.
///
///
/// The DocumentPaginator to be printed.
///
///
/// Description of the job to be printed. This shows in the Printer UI
///
///
/// Critical: - Sets a critical data property.
/// PublicOk: - The critical data is a flag that needs to be reset for each print
/// job to enforce the dialog invocation on every print operation. Without
/// this method resetting this flag we would not be honoring the security
/// goal of displaying the dialog once per print job.
///
[SecurityCritical]
public
void
PrintDocument(
DocumentPaginator documentPaginator,
String description
)
{
if (documentPaginator == null)
{
throw new ArgumentNullException("documentPaginator");
}
XpsDocumentWriter writer = CreateWriter(description);
writer.Write(documentPaginator);
_printableAreaWidth = 0;
_printableAreaHeight = 0;
_isPrintableAreaWidthUpdated = false;
_isPrintableAreaHeightUpdated = false;
_dialogInvoked = false;
}
#endregion Public methods
#region Private methods
///
/// Critical: - Asserts to obtain the default print queue from the local server.
///
[SecurityCritical]
private
PrintQueue
AcquireDefaultPrintQueue()
{
PrintQueue printQueue = null;
(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert
try
{
try
{
LocalPrintServer server = new LocalPrintServer();
printQueue = server.DefaultPrintQueue;
}
catch (PrintSystemException)
{
//
// It is entirely possible for there to be no "default" printer. In this case,
// the printing system throws an exception. We do not want this to propagate
// up. Instead, returning null is fine.
//
printQueue = null;
}
}
finally
{
PrintingPermission.RevertAssert();
}
return printQueue;
}
///
/// Critical: - Asserts to obtain the PrintTicket from the specified PrintQueue
/// object or create a blank PrintTicket object (i.e. PrintTicket::ctor).
///
[SecurityCritical]
private
PrintTicket
AcquireDefaultPrintTicket(
PrintQueue printQueue
)
{
PrintTicket printTicket = null;
(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert
try
{
try
{
if (printQueue != null)
{
printTicket = printQueue.UserPrintTicket;
if (printTicket == null)
{
printTicket = printQueue.DefaultPrintTicket;
}
}
}
catch (PrintSystemException)
{
//
// The printing subsystem can throw an exception in certain cases when
// the print ticket is unavailable. If it does we will handle this
// below. There is no real need to bubble this up to the application.
//
printTicket = null;
}
}
finally
{
PrintingPermission.RevertAssert();
}
//
// If the printing subsystem could not give us a print ticket either due to
// a failure or because a user/system default was not available, then just
// create a blank/empty one.
//
if (printTicket == null)
{
printTicket = new PrintTicket();
}
return printTicket;
}
///
/// Critical: - Invokes a critical method (PickCorrectPrintingEnvironment).
/// TreatAsSafe: - Critical data returned from above method is internal and does
/// not leave the scope of this method. It is only used to calculate
/// non-critical values.
///
[SecurityCritical, SecurityTreatAsSafe]
private
void
UpdatePrintableAreaSize(
)
{
PrintQueue printQueue = null;
PrintTicket printTicket = null;
PickCorrectPrintingEnvironment(ref printQueue, ref printTicket);
PrintCapabilities printCap = null;
if (printQueue != null)
{
printCap = printQueue.GetPrintCapabilities(printTicket);
}
// PrintCapabilities OrientedPageMediaWidth/Height are Nullable
if ((printCap != null) &&
(printCap.OrientedPageMediaWidth != null) &&
(printCap.OrientedPageMediaHeight != null))
{
_printableAreaWidth = (double)printCap.OrientedPageMediaWidth;
_printableAreaHeight = (double)printCap.OrientedPageMediaHeight;
}
else
{
// Initialize page size to portrait Letter size.
// This is our fallback if PrintTicket doesn't specify the page size.
_printableAreaWidth = 816;
_printableAreaHeight = 1056;
// PrintTicket's PageMediaSize could be null and PageMediaSize Width/Height are Nullable
if ((printTicket.PageMediaSize != null) &&
(printTicket.PageMediaSize.Width != null) &&
(printTicket.PageMediaSize.Height != null))
{
_printableAreaWidth = (double)printTicket.PageMediaSize.Width;
_printableAreaHeight = (double)printTicket.PageMediaSize.Height;
}
// If we are using PrintTicket's PageMediaSize dimensions to populate the widht/height values,
// we need to adjust them based on current orientation. PrintTicket's PageOrientation is Nullable.
if (printTicket.PageOrientation != null)
{
PageOrientation orientation = (PageOrientation)printTicket.PageOrientation;
// need to swap width/height in landscape orientation
if ((orientation == PageOrientation.Landscape) ||
(orientation == PageOrientation.ReverseLandscape))
{
double t = _printableAreaWidth;
_printableAreaWidth = _printableAreaHeight;
_printableAreaHeight = t;
}
}
}
}
///
/// Critical: - Asserts for PrintingPermissionLevel.DefaultPrinting
/// to be able to use the printQueue to create the
/// XpsDocumentWriter.
/// TreatAsSafe: - The assert is only done after ensuring that the user
/// has conciously made a decision to print by successfully
/// dismissing the Print Dialog. This logic of a dialog
/// being required is only needed for partial trust applications.
/// The logic of checking this criteria is contained within the
/// PickCorrectPrintingEnvironment method.
/// - The XpsDocumentWriter instance returned from this method
/// is not unsafe since the application is either full trust
/// or the user chose to print. It is okay for the application
/// to use the XpsDocumentWriter to print at this point.
///
[SecurityCritical, SecurityTreatAsSafe]
private
XpsDocumentWriter
CreateWriter(
String description
)
{
PrintQueue printQueue = null;
PrintTicket printTicket = null;
XpsDocumentWriter writer = null;
PickCorrectPrintingEnvironment(ref printQueue, ref printTicket);
(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting)).Assert(); //BlessedAssert
try
{
if(printQueue != null)
{
printQueue.CurrentJobSettings.Description = description;
}
writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
PrintDlgPrintTicketEventHandler eventHandler = new PrintDlgPrintTicketEventHandler(printTicket);
writer.WritingPrintTicketRequired +=
new WritingPrintTicketRequiredEventHandler(eventHandler.SetPrintTicket);
}
finally
{
PrintingPermission.RevertAssert();
}
return writer;
}
///
/// Critical: - Accesses critical data and returns it to the caller.
/// - Calls critical code (AcquireDefaultPrintQueue/AcquireDefaultPrintTicket)
/// - Detects whether a caller is allowed to acquire this data
/// based on a demand. This demand is only performed if the
/// dialog was not invoked already. It is fine to return the
/// data if the dialog was invoked, however, the data is still
/// critical.
///
/// NOTE: This method validates that a dialog was invoked prior to returning the
/// PrintQueue and PrintTicket for the case of web applications. If the
/// dialog was not invoked then an exception is thrown.
///
[SecurityCritical]
private
void
PickCorrectPrintingEnvironment(
ref PrintQueue printQueue,
ref PrintTicket printTicket
)
{
if (_dialogInvoked == false)
{
//
// If the dialog has not been invoked then the user needs printing permissions.
// If the demand succeeds then they can print. If the demand fails, then we
// tell them that the print dialog must be displayed first by throwing a dialog
// exception.
//
try
{
SecurityHelper.DemandPrintDialogPermissions();
}
catch (SecurityException)
{
throw new PrintDialogException(SR.Get(SRID.PartialTrustPrintDialogMustBeInvoked));
}
}
//
// If the default print queue and print ticket have not already
// been selected then update them now since we need them.
//
// NOTE: If this code gets called then we know the dialog has never
// been invoked but the above demand was satisfied. In this
// case we want to just pickup the user defaults.
//
if (_printQueue == null)
{
_printQueue = AcquireDefaultPrintQueue();
}
if (_printTicket == null)
{
_printTicket = AcquireDefaultPrintTicket(_printQueue);
}
//
// We should have valid print queue and print ticket objects to
// return now. As a note, a null PrintQueue is valid for this
// since the dialog will automatically pick up the user default
// printer for us.
//
printQueue = _printQueue;
printTicket = _printTicket;
}
#endregion Private methods
#region Private data
///
/// The PrintTicket is critical and not obtainable from a partial
/// trust application unless they can satisfy a printing permission
/// demand.
///
[SecurityCritical]
private
PrintTicket _printTicket;
///
/// The PrintQueue is critical and not obtainable from a partial
/// trust application unless they can satisfy a printing permission
/// demand.
///
[SecurityCritical]
private
PrintQueue _printQueue;
///
/// This variable is used to determine whether a user actually invoked
/// and dismissed the dialog prior to printing. In a partial trust app,
/// we can safely perform the necessary asserts to print as long as the
/// user said printing was okay.
///
[SecurityCritical]
private
bool _dialogInvoked;
private
PageRangeSelection _pageRangeSelection;
private
PageRange _pageRange;
private
bool _userPageRangeEnabled;
private
UInt32 _minPage;
private
UInt32 _maxPage;
private
double _printableAreaWidth;
private
double _printableAreaHeight;
private
bool _isPrintableAreaWidthUpdated;
private
bool _isPrintableAreaHeightUpdated;
#endregion Private data
#region Internal classes
internal class PrintDlgPrintTicketEventHandler
{
#region Constructor
public
PrintDlgPrintTicketEventHandler(
PrintTicket printTicket
)
{
_printTicket = printTicket;
}
#endregion Constructor
#region Public Methods
public
void
SetPrintTicket(
Object sender,
WritingPrintTicketRequiredEventArgs args
)
{
if (args.CurrentPrintTicketLevel == PrintTicketLevel.FixedDocumentSequencePrintTicket)
{
args.CurrentPrintTicket = _printTicket;
}
}
#endregion Public Methods
#region Private Data
private
PrintTicket _printTicket;
#endregion Private Data
};
#endregion Internal classes
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SettingsBase.cs
- XmlBinaryReaderSession.cs
- SmiConnection.cs
- ToolStripDropDownClosingEventArgs.cs
- DescendantOverDescendantQuery.cs
- ReferentialConstraint.cs
- Brushes.cs
- XmlSyndicationContent.cs
- webproxy.cs
- M3DUtil.cs
- Script.cs
- StateItem.cs
- UTF7Encoding.cs
- DataGridTextBoxColumn.cs
- TraceContextEventArgs.cs
- GroupBox.cs
- SmiConnection.cs
- DesignerLinkAdapter.cs
- BulletDecorator.cs
- WindowsGraphicsCacheManager.cs
- TextBoxBase.cs
- util.cs
- DtdParser.cs
- SecureEnvironment.cs
- WebHttpSecurityModeHelper.cs
- TraceLog.cs
- DbProviderConfigurationHandler.cs
- RectangleF.cs
- MarkupExtensionParser.cs
- WebPartCancelEventArgs.cs
- IdnMapping.cs
- Expression.DebuggerProxy.cs
- SimpleHandlerFactory.cs
- TypeUnloadedException.cs
- ConnectionPoint.cs
- unsafenativemethodstextservices.cs
- ReferenceService.cs
- sapiproxy.cs
- FlowDocumentFormatter.cs
- FunctionQuery.cs
- NavigationHelper.cs
- DataKeyCollection.cs
- Page.cs
- XamlLoadErrorInfo.cs
- EventManager.cs
- DataObjectAttribute.cs
- StrokeFIndices.cs
- COM2ExtendedBrowsingHandler.cs
- CurrentTimeZone.cs
- InnerItemCollectionView.cs
- TextBox.cs
- XmlMtomWriter.cs
- IChannel.cs
- OperatorExpressions.cs
- InputLanguageSource.cs
- DataTablePropertyDescriptor.cs
- ListViewItem.cs
- LinkUtilities.cs
- NoneExcludedImageIndexConverter.cs
- BooleanToSelectiveScrollingOrientationConverter.cs
- XmlNavigatorFilter.cs
- JsonEncodingStreamWrapper.cs
- DocumentXPathNavigator.cs
- FileSystemWatcher.cs
- Color.cs
- OdbcPermission.cs
- TransactionChannelFaultConverter.cs
- FixedSOMFixedBlock.cs
- _AuthenticationState.cs
- ProgressBarAutomationPeer.cs
- PolicyManager.cs
- EDesignUtil.cs
- XsdDuration.cs
- BrushMappingModeValidation.cs
- AssemblySettingAttributes.cs
- RadioButton.cs
- DataKey.cs
- CTreeGenerator.cs
- VectorAnimationBase.cs
- UrlParameterWriter.cs
- EntitySqlQueryCacheKey.cs
- HuffCodec.cs
- CommandLibraryHelper.cs
- StaticSiteMapProvider.cs
- SqlDataSourceCache.cs
- UIElementPropertyUndoUnit.cs
- KernelTypeValidation.cs
- StatusBar.cs
- LogExtentCollection.cs
- RecognitionResult.cs
- HostedHttpTransportManager.cs
- DataGridViewCellCollection.cs
- DocumentScope.cs
- RayMeshGeometry3DHitTestResult.cs
- SpellerStatusTable.cs
- AppModelKnownContentFactory.cs
- TabletDeviceInfo.cs
- SqlTriggerContext.cs
- XmlSchemaAttribute.cs
- MatrixTransform3D.cs