Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / 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:
[....] ([....]) 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
- JoinElimination.cs
- sqlser.cs
- PermissionSet.cs
- OracleRowUpdatedEventArgs.cs
- DataGrid.cs
- RangeValueProviderWrapper.cs
- PointIndependentAnimationStorage.cs
- COMException.cs
- IIS7WorkerRequest.cs
- TextServicesPropertyRanges.cs
- XmlBinaryReader.cs
- IdleTimeoutMonitor.cs
- CmsInterop.cs
- TemplateControl.cs
- HMACRIPEMD160.cs
- WebConfigurationHostFileChange.cs
- DrawingState.cs
- LocalizabilityAttribute.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- Endpoint.cs
- RegexGroupCollection.cs
- QilValidationVisitor.cs
- HtmlInputSubmit.cs
- AttributeEmitter.cs
- ItemDragEvent.cs
- Vector3DCollection.cs
- ConvertEvent.cs
- SqlDataSourceStatusEventArgs.cs
- ElapsedEventArgs.cs
- WeakHashtable.cs
- ImageCodecInfo.cs
- GridViewDeletedEventArgs.cs
- HelloMessageCD1.cs
- Interlocked.cs
- ContentType.cs
- BitmapSizeOptions.cs
- Label.cs
- WindowHideOrCloseTracker.cs
- ResourceReferenceKeyNotFoundException.cs
- StringDictionary.cs
- GroupBox.cs
- DockPatternIdentifiers.cs
- BaseTemplateParser.cs
- URLAttribute.cs
- TreeBuilderXamlTranslator.cs
- SocketAddress.cs
- ButtonStandardAdapter.cs
- XmlBuffer.cs
- RuleSettingsCollection.cs
- NetworkAddressChange.cs
- GenericEnumConverter.cs
- AtomParser.cs
- SmtpFailedRecipientsException.cs
- HttpCacheParams.cs
- OleDbCommandBuilder.cs
- ConnectionManagementElementCollection.cs
- ResXDataNode.cs
- FullTextLine.cs
- BinaryMessageFormatter.cs
- ConfigDefinitionUpdates.cs
- ScrollEvent.cs
- AtomParser.cs
- GeneratedView.cs
- ReadOnlyAttribute.cs
- TraceContext.cs
- DockProviderWrapper.cs
- StringStorage.cs
- ComponentDispatcherThread.cs
- WebServicesInteroperability.cs
- TraceListener.cs
- CopyNamespacesAction.cs
- Graphics.cs
- WebBrowserNavigatedEventHandler.cs
- CqlParserHelpers.cs
- BitmapEditor.cs
- XmlSchemaSequence.cs
- GridViewSortEventArgs.cs
- CodeRegionDirective.cs
- RequestCacheValidator.cs
- EdmItemCollection.cs
- HierarchicalDataBoundControlAdapter.cs
- SafePointer.cs
- UnknownBitmapEncoder.cs
- BevelBitmapEffect.cs
- XmlPropertyBag.cs
- MimeFormatExtensions.cs
- XmlObjectSerializerWriteContextComplexJson.cs
- DataServiceContext.cs
- ProvidersHelper.cs
- WindowsListViewItemCheckBox.cs
- GACIdentityPermission.cs
- ConfigurationSectionGroup.cs
- ConstNode.cs
- ConnectionManagementSection.cs
- Inflater.cs
- BindableTemplateBuilder.cs
- PtsHelper.cs
- DataStreams.cs
- StackOverflowException.cs
- WindowsServiceCredential.cs