| File: MS\Internal\Printing\Win32PrintDialog.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #if !DONOTREFPRINTINGASMMETA using System.Printing.Interop; using System.Printing; using System.Runtime.InteropServices; using System.Windows.Controls; namespace MS.Internal.Printing { /// <summary> /// This entire class is implemented in this file. However, the class /// is marked partial because this class utilizes/implements a marshaler /// class that is private to it in another file. The object is called /// PrintDlgExMarshaler and warranted its own file. /// </summary> internal partial class Win32PrintDialog { #region Constructor /// <summary> /// Constructs an instance of the Win32PrintDialog. This class is used for /// displaying the Win32 PrintDlgEx dialog and obtaining a user selected /// printer and PrintTicket for a print operation. /// </summary> public Win32PrintDialog() { _printTicket = null; _printQueue = null; _minPage = 1; _maxPage = 9999; _pageRangeSelection = PageRangeSelection.AllPages; } #endregion Constructor #region Internal methods /// <summary> /// Displays a modal Win32 print dialog to allow the user to select the desired /// printer and set the printing options. The data generated by this method /// can be accessed via the properties on the instance of this class. /// </summary> internal UInt32 ShowDialog() { UInt32 result = NativeMethods.PD_RESULT_CANCEL; // // Get the process main window handle // IntPtr owner = IntPtr.Zero; if ((System.Windows.Application.Current != null) && (System.Windows.Application.Current.MainWindow != null)) { System.Windows.Interop.WindowInteropHelper helper = new System.Windows.Interop.WindowInteropHelper(System.Windows.Application.Current.MainWindow); owner = helper.Handle; } try { if (this._printQueue == null || this._printTicket == null) { // Normally printDlgEx.SyncToStruct() probes the printer if both the print queue and print // ticket are not null. // If either is null we probe the printer ourselves // If we dont end users will get notified that printing is disabled *after* // the print dialog has been displayed. ProbeForPrintingSupport(); } // // Create a PrintDlgEx instance to invoke the Win32 Print Dialog // using (PrintDlgExMarshaler printDlgEx = new PrintDlgExMarshaler(owner, this)) { printDlgEx.SyncToStruct(); // // Display the Win32 print dialog // Int32 hr = UnsafeNativeMethods.PrintDlgEx(printDlgEx.UnmanagedPrintDlgEx); if (hr == MS.Win32.NativeMethods.S_OK) { result = printDlgEx.SyncFromStruct(); } } } // // NOTE: // This code was previously catch(PrintingNotSupportedException), but that created a circular dependency // between ReachFramework.dll and PresentationFramework.dll. Instead, we now catch Exception, check its full type name // and rethrow if it doesn't match. Not perfect, but better than having a circular dependency. // catch(Exception e) { if (String.Equals(e.GetType().FullName, "System.Printing.PrintingNotSupportedException", StringComparison.Ordinal)) { string message = System.Windows.SR.PrintDialogInstallPrintSupportMessageBox; string caption = System.Windows.SR.PrintDialogInstallPrintSupportCaption; bool isRtlCaption = caption != null && caption.Length > 0 && caption[0] == RightToLeftMark; System.Windows.MessageBoxOptions mbOptions = isRtlCaption ? System.Windows.MessageBoxOptions.RtlReading : System.Windows.MessageBoxOptions.None; int type = (int) System.Windows.MessageBoxButton.OK | (int) System.Windows.MessageBoxImage.Information | (int) mbOptions; if (owner == IntPtr.Zero) { owner = MS.Win32.UnsafeNativeMethods.GetActiveWindow(); } if(0 != MS.Win32.UnsafeNativeMethods.MessageBox(new HandleRef(null, owner), message, caption, type)) { result = NativeMethods.PD_RESULT_CANCEL; } } else { // Not a PrintingNotSupportedException, rethrow throw; } } return result; } #endregion Internal methods #region Internal properties internal PrintTicket PrintTicket { get { return _printTicket; } set { _printTicket = value; } } internal PrintQueue PrintQueue { get { return _printQueue; } set { _printQueue = value; } } /// <summary> /// Gets or sets the minimum page number allowed in the page ranges. /// </summary> internal UInt32 MinPage { get { return _minPage; } set { _minPage = value; } } /// <summary> /// Gets or sets the maximum page number allowed in the page ranges. /// </summary> internal UInt32 MaxPage { get { return _maxPage; } set { _maxPage = value; } } /// <summary> /// Gets or Sets the PageRangeSelection option for the print dialog. /// </summary> internal PageRangeSelection PageRangeSelection { get { return _pageRangeSelection; } set { _pageRangeSelection = value; } } /// <summary> /// Gets or sets a PageRange objects used when the PageRangeSelection /// option is set to UserPages. /// </summary> internal PageRange PageRange { get { return _pageRange; } set { _pageRange = value; } } /// <summary> /// Gets or sets a flag to enable/disable the page range control on the dialog. /// </summary> internal bool PageRangeEnabled { get { return _pageRangeEnabled; } set { _pageRangeEnabled = value; } } /// <summary> /// Gets or sets a flag to enable/disable the current page selection control on the dialog. /// </summary> internal bool SelectedPagesEnabled { get { return _selectedPagesEnabled; } set { _selectedPagesEnabled = value; } } /// <summary> /// Gets or sets a flag to enable/disable the current page control on the dialog. /// </summary> internal bool CurrentPageEnabled { get { return _currentPageEnabled; } set { _currentPageEnabled = value; } } #endregion Internal properties #region Private methods /// <summary> /// Probe to see if printing support is installed /// </summary> private void ProbeForPrintingSupport() { // Without a print queue object we have to make up a name for the printer. // We will just swallow the print queue exception it generates later. // We could avoid the exception if we had access to // MS.Internal.Printing.Configuration.NativeMethods.BindPTProviderThunk string printerName = (this._printQueue != null) ? this._printQueue.FullName : string.Empty; try { // If printer support is not installed this should throw a PrintingNotSupportedException using (IDisposable converter = new PrintTicketConverter(printerName, 1)) { } } catch (PrintQueueException) { // We can swallow print queue exceptions because they imply that printing // support is installed } } #endregion #region Private data private PrintTicket _printTicket; private PrintQueue _printQueue; private PageRangeSelection _pageRangeSelection; private PageRange _pageRange; private bool _pageRangeEnabled; private bool _selectedPagesEnabled; private bool _currentPageEnabled; private UInt32 _minPage; private UInt32 _maxPage; private const char RightToLeftMark = '\u200F'; #endregion Private data } } #endif