<PackageReference Include="System.Drawing.Common" Version="9.0.0-rc.2.24474.1" />

PrintController

public abstract class PrintController
Controls how a document is printed, when printing from a Windows Forms application.
using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Windows.Win32; using Windows.Win32.Foundation; namespace System.Drawing.Printing { [NullableContext(1)] [Nullable(0)] public abstract class PrintController { [Nullable(0)] internal sealed class SafeDeviceModeHandle : SafeHandle { public override bool IsInvalid => handle == (IntPtr)0; public SafeDeviceModeHandle() : base(IntPtr.Zero, true) { } internal SafeDeviceModeHandle(IntPtr handle) : base(IntPtr.Zero, true) { SetHandle(handle); } protected override bool ReleaseHandle() { if (!IsInvalid) PInvokeCore.GlobalFree((HGLOBAL)handle); handle = (IntPtr)0; return true; } public static implicit operator IntPtr(SafeDeviceModeHandle handle) { return handle?.handle ?? ((IntPtr)0); } public static explicit operator SafeDeviceModeHandle(IntPtr handle) { return new SafeDeviceModeHandle(handle); } public static implicit operator HGLOBAL(SafeDeviceModeHandle handle) { if (handle != null) return (HGLOBAL)handle.handle; return HGLOBAL.Null; } } [Nullable(2)] private protected SafeDeviceModeHandle _modeHandle; public virtual bool IsPreview => false; [return: Nullable(2)] public virtual Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e) { return null; } public virtual void OnEndPage(PrintDocument document, PrintPageEventArgs e) { } internal void Print(PrintDocument document) { PrintEventArgs printEventArgs = new PrintEventArgs(IsPreview ? PrintAction.PrintToPreview : ((!document.PrinterSettings.PrintToFile) ? PrintAction.PrintToPrinter : PrintAction.PrintToFile)); document.OnBeginPrint(printEventArgs); if (printEventArgs.Cancel) document.OnEndPrint(printEventArgs); else { OnStartPrint(document, printEventArgs); if (printEventArgs.Cancel) { document.OnEndPrint(printEventArgs); OnEndPrint(document, printEventArgs); } else { bool flag = true; try { flag = (System.LocalAppContextSwitches.OptimizePrintPreview ? PrintLoopOptimized(document) : PrintLoop(document)); } finally { try { document.OnEndPrint(printEventArgs); printEventArgs.Cancel = (flag | printEventArgs.Cancel); } finally { OnEndPrint(document, printEventArgs); } } } } } private bool PrintLoop(PrintDocument document) { QueryPageSettingsEventArgs queryPageSettingsEventArgs = new QueryPageSettingsEventArgs((PageSettings)document.DefaultPageSettings.Clone()); PrintPageEventArgs printPageEventArgs; do { document.OnQueryPageSettings(queryPageSettingsEventArgs); if (queryPageSettingsEventArgs.Cancel) return true; printPageEventArgs = CreatePrintPageEvent(queryPageSettingsEventArgs.PageSettings); Graphics graphics = OnStartPage(document, printPageEventArgs); printPageEventArgs.SetGraphics(graphics); try { document.OnPrintPage(printPageEventArgs); OnEndPage(document, printPageEventArgs); } finally { printPageEventArgs.Dispose(); } if (printPageEventArgs.Cancel) return true; } while (printPageEventArgs.HasMorePages); return false; } private bool PrintLoopOptimized(PrintDocument document) { PrintPageEventArgs printPageEventArgs = null; QueryPageSettingsEventArgs queryPageSettingsEventArgs = new QueryPageSettingsEventArgs((PageSettings)document.DefaultPageSettings.Clone()); do { queryPageSettingsEventArgs.PageSettingsChanged = false; document.OnQueryPageSettings(queryPageSettingsEventArgs); if (queryPageSettingsEventArgs.Cancel) return true; if (!queryPageSettingsEventArgs.PageSettingsChanged) { if (printPageEventArgs == null) printPageEventArgs = CreatePrintPageEvent(queryPageSettingsEventArgs.PageSettings); else printPageEventArgs.CopySettingsToDevMode = false; Graphics graphics = OnStartPage(document, printPageEventArgs); printPageEventArgs.SetGraphics(graphics); } else { printPageEventArgs = CreatePrintPageEvent(queryPageSettingsEventArgs.PageSettings); Graphics graphics2 = OnStartPage(document, printPageEventArgs); printPageEventArgs.SetGraphics(graphics2); } try { document.OnPrintPage(printPageEventArgs); OnEndPage(document, printPageEventArgs); } finally { printPageEventArgs.Graphics?.Dispose(); printPageEventArgs.SetGraphics(null); } if (printPageEventArgs.Cancel) return true; } while (printPageEventArgs.HasMorePages); return false; } private PrintPageEventArgs CreatePrintPageEvent(PageSettings pageSettings) { Rectangle bounds = pageSettings.GetBounds(_modeHandle); Rectangle marginBounds = new Rectangle(pageSettings.Margins.Left, pageSettings.Margins.Top, bounds.Width - (pageSettings.Margins.Left + pageSettings.Margins.Right), bounds.Height - (pageSettings.Margins.Top + pageSettings.Margins.Bottom)); return new PrintPageEventArgs(null, marginBounds, bounds, pageSettings); } public virtual void OnStartPrint(PrintDocument document, PrintEventArgs e) { _modeHandle = (SafeDeviceModeHandle)document.PrinterSettings.GetHdevmode(document.DefaultPageSettings); } public virtual void OnEndPrint(PrintDocument document, PrintEventArgs e) { _modeHandle?.Close(); } } }