PrinterSettings
Specifies information about how a document is printed, including the printer that prints it, when printing from a Windows Forms application.
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.Graphics.Printing;
using Windows.Win32.Storage.Xps;
using Windows.Win32.System.Memory;
using Windows.Win32.UI.Controls.Dialogs;
namespace System.Drawing.Printing
{
[NullableContext(1)]
[Nullable(0)]
public class PrinterSettings : ICloneable
{
[NullableContext(2)]
[Nullable(0)]
private sealed class ArrayEnumerator : IEnumerator
{
[Nullable(1)]
private readonly object[] _array;
private readonly int _endIndex;
private int _index;
private object _item;
public object Current => _item;
[NullableContext(1)]
public ArrayEnumerator(object[] array, int count)
{
_array = array;
_endIndex = count;
}
public bool MoveNext()
{
if (_index >= _endIndex)
return false;
_item = _array[_index++];
return true;
}
public void Reset()
{
_index = 0;
_item = null;
}
}
[Nullable(0)]
public class PaperSizeCollection : ICollection, IEnumerable
{
private PaperSize[] _array;
public int Count => _array.Length;
public virtual PaperSize this[int index] {
get {
return _array[index];
}
}
int ICollection.Count {
get {
return Count;
}
}
bool ICollection.IsSynchronized {
get {
return false;
}
}
object ICollection.SyncRoot {
get {
return this;
}
}
public PaperSizeCollection(PaperSize[] array)
{
_array = array;
}
public IEnumerator GetEnumerator()
{
object[] array = _array;
return new ArrayEnumerator(array, Count);
}
void ICollection.CopyTo(Array array, int index)
{
Array.Copy(_array, index, array, 0, _array.Length);
}
public void CopyTo(PaperSize[] paperSizes, int index)
{
Array.Copy(_array, index, paperSizes, 0, _array.Length);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public int Add(PaperSize paperSize)
{
PaperSize[] array = new PaperSize[Count + 1];
((ICollection)this).CopyTo((Array)array, 0);
array[Count] = paperSize;
_array = array;
return Count;
}
}
[Nullable(0)]
public class PaperSourceCollection : ICollection, IEnumerable
{
private PaperSource[] _array;
public int Count => _array.Length;
public virtual PaperSource this[int index] {
get {
return _array[index];
}
}
int ICollection.Count {
get {
return Count;
}
}
bool ICollection.IsSynchronized {
get {
return false;
}
}
object ICollection.SyncRoot {
get {
return this;
}
}
public PaperSourceCollection(PaperSource[] array)
{
_array = array;
}
public IEnumerator GetEnumerator()
{
object[] array = _array;
return new ArrayEnumerator(array, Count);
}
void ICollection.CopyTo(Array array, int index)
{
Array.Copy(_array, index, array, 0, _array.Length);
}
public void CopyTo(PaperSource[] paperSources, int index)
{
Array.Copy(_array, index, paperSources, 0, _array.Length);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public int Add(PaperSource paperSource)
{
PaperSource[] array = new PaperSource[Count + 1];
((ICollection)this).CopyTo((Array)array, 0);
array[Count] = paperSource;
_array = array;
return Count;
}
}
[Nullable(0)]
public class PrinterResolutionCollection : ICollection, IEnumerable
{
private PrinterResolution[] _array;
public int Count => _array.Length;
public virtual PrinterResolution this[int index] {
get {
return _array[index];
}
}
int ICollection.Count {
get {
return Count;
}
}
bool ICollection.IsSynchronized {
get {
return false;
}
}
object ICollection.SyncRoot {
get {
return this;
}
}
public PrinterResolutionCollection(PrinterResolution[] array)
{
_array = array;
}
public IEnumerator GetEnumerator()
{
object[] array = _array;
return new ArrayEnumerator(array, Count);
}
void ICollection.CopyTo(Array array, int index)
{
Array.Copy(_array, index, array, 0, _array.Length);
}
public void CopyTo(PrinterResolution[] printerResolutions, int index)
{
Array.Copy(_array, index, printerResolutions, 0, _array.Length);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public int Add(PrinterResolution printerResolution)
{
PrinterResolution[] array = new PrinterResolution[Count + 1];
((ICollection)this).CopyTo((Array)array, 0);
array[Count] = printerResolution;
_array = array;
return Count;
}
}
[Nullable(0)]
public class StringCollection : ICollection, IEnumerable, IEnumerable<string>
{
private readonly List<string> _list;
public int Count => _list.Count;
public virtual string this[int index] {
get {
return _list[index];
}
}
int ICollection.Count {
get {
return Count;
}
}
bool ICollection.IsSynchronized {
get {
return false;
}
}
object ICollection.SyncRoot {
get {
return this;
}
}
public StringCollection(string[] array)
{
_list = array.ToList();
}
public IEnumerator GetEnumerator()
{
return ((IEnumerable)_list).GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
((ICollection)_list).CopyTo(array, index);
}
public void CopyTo(string[] strings, int index)
{
((ICollection)_list).CopyTo((Array)strings, index);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public int Add(string value)
{
_list.Add(value);
return _list.Count;
}
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return _list.GetEnumerator();
}
}
[Nullable(2)]
private string _printerName;
private string _driverName = "";
private ushort _extraBytes;
[Nullable(2)]
private byte[] _extraInfo;
private short _copies = -1;
private Duplex _duplex = Duplex.Default;
private TriState _collate = TriState.Default;
private readonly PageSettings _defaultPageSettings;
private int _fromPage;
private int _toPage;
private int _maxPage = 9999;
private int _minPage;
private PrintRange _printRange;
private ushort _devmodeBytes;
[Nullable(2)]
private byte[] _cachedDevmode;
public bool CanDuplex => DeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_DUPLEX, null, -1) == 1;
public short Copies {
get {
if (_copies == -1)
return GetModeField(ModeField.Copies, 1);
return _copies;
}
set {
if (value < 0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidLowBoundArgumentEx, "value", value, 0));
_copies = value;
}
}
public bool Collate {
get {
if (!_collate.IsDefault)
return (bool)_collate;
return GetModeField(ModeField.Collate, 0) == 1;
}
set {
_collate = value;
}
}
public PageSettings DefaultPageSettings => _defaultPageSettings;
internal string DriverName => _driverName;
public Duplex Duplex {
get {
if (_duplex == Duplex.Default)
return (Duplex)GetModeField(ModeField.Duplex, 1);
return _duplex;
}
set {
if ((value < Duplex.Default || value > Duplex.Horizontal) ? true : false)
throw new InvalidEnumArgumentException("value", (int)value, typeof(Duplex));
_duplex = value;
}
}
public int FromPage {
get {
return _fromPage;
}
set {
if (value < 0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidLowBoundArgumentEx, "value", value, 0));
_fromPage = value;
}
}
public unsafe static StringCollection InstalledPrinters {
get {
uint minimumLength = default(uint);
uint num = default(uint);
if (!(bool)PInvoke.EnumPrinters(6, null, 4, null, 0, &minimumLength, &num)) {
WIN32_ERROR lastPInvokeError = (WIN32_ERROR)Marshal.GetLastPInvokeError();
if (lastPInvokeError != WIN32_ERROR.ERROR_INSUFFICIENT_BUFFER)
throw new Win32Exception((int)lastPInvokeError);
}
BufferScope<byte> bufferScope = new BufferScope<byte>((int)minimumLength);
try {
fixed (byte* ptr = &bufferScope.GetPinnableReference()) {
if (!(bool)PInvoke.EnumPrinters(6, null, 4, ptr, (uint)bufferScope.Length, &minimumLength, &num))
throw new Win32Exception();
string[] array = new string[num];
ReadOnlySpan<PRINTER_INFO_4W> readOnlySpan = new ReadOnlySpan<PRINTER_INFO_4W>(ptr, (int)num);
for (int i = 0; i < num; i++) {
array[i] = new string(readOnlySpan[i].pPrinterName);
}
return new StringCollection(array);
}
} finally {
bufferScope.Dispose();
}
}
}
public bool IsDefaultPrinter {
get {
if (_printerName != null)
return _printerName == GetDefaultPrinterName();
return true;
}
}
public bool IsPlotter => (long)GetDeviceCaps(GET_DEVICE_CAPS_INDEX.TECHNOLOGY) == 0;
public bool IsValid => DeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_COPIES, null, -1) != -1;
public int LandscapeAngle => DeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_ORIENTATION, null, 0);
public int MaximumCopies => DeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_COPIES, null, 1);
public int MaximumPage {
get {
return _maxPage;
}
set {
if (value < 0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidLowBoundArgumentEx, "value", value, 0));
_maxPage = value;
}
}
public int MinimumPage {
get {
return _minPage;
}
set {
if (value < 0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidLowBoundArgumentEx, "value", value, 0));
_minPage = value;
}
}
internal string OutputPort { get; set; } = "";
public string PrintFileName {
get {
return OutputPort;
}
set {
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException(value);
OutputPort = value;
}
}
public PaperSizeCollection PaperSizes => new PaperSizeCollection(Get_PaperSizes());
public PaperSourceCollection PaperSources => new PaperSourceCollection(Get_PaperSources());
internal bool PrintDialogDisplayed { get; set; }
public PrintRange PrintRange {
get {
return _printRange;
}
set {
if (!Enum.IsDefined(value))
throw new InvalidEnumArgumentException("value", (int)value, typeof(PrintRange));
_printRange = value;
}
}
public bool PrintToFile { get; set; }
public string PrinterName {
get {
return PrinterNameInternal;
}
set {
PrinterNameInternal = value;
}
}
private string PrinterNameInternal {
get {
return _printerName ?? GetDefaultPrinterName();
}
set {
_cachedDevmode = null;
_extraInfo = null;
_printerName = value;
}
}
public PrinterResolutionCollection PrinterResolutions => new PrinterResolutionCollection(Get_PrinterResolutions());
public bool SupportsColor => DeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_COLORDEVICE, null, -1) == 1;
public int ToPage {
get {
return _toPage;
}
set {
if (value < 0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidLowBoundArgumentEx, "value", value, 0));
_toPage = value;
}
}
public PrinterSettings()
{
_defaultPageSettings = new PageSettings(this);
}
public bool IsDirectPrintingSupported(ImageFormat imageFormat)
{
if (imageFormat.Equals(ImageFormat.Jpeg) || imageFormat.Equals(ImageFormat.Png)) {
CreateDcScope scope = CreateInformationContext(DefaultPageSettings);
try {
int escapeFunction;
return IsDirectPrintingSupported((HDC)ref scope, imageFormat, out escapeFunction);
} finally {
scope.Dispose();
}
}
return false;
}
private unsafe static bool IsDirectPrintingSupported(HDC hdc, ImageFormat imageFormat, out int escapeFunction)
{
escapeFunction = (imageFormat.Equals(ImageFormat.Jpeg) ? 4119 : 4120);
fixed (int* ptr = &escapeFunction) {
int* ptr2 = ptr;
return PInvoke.ExtEscape(hdc, 8, 4, (PCSTR)(byte*)(&ptr2), 0, null) != 0;
}
}
public unsafe bool IsDirectPrintingSupported(Image image)
{
ImageFormat rawFormat = image.RawFormat;
if (rawFormat.Equals(ImageFormat.Jpeg) || rawFormat.Equals(ImageFormat.Png)) {
CreateDcScope scope = CreateInformationContext(DefaultPageSettings);
try {
if (IsDirectPrintingSupported((HDC)ref scope, rawFormat, out int escapeFunction)) {
using (MemoryStream memoryStream = new MemoryStream()) {
image.Save(memoryStream, image.RawFormat);
byte[] array = memoryStream.ToArray();
fixed (byte* value = array) {
uint num = default(uint);
return PInvoke.ExtEscape((HDC)ref scope, escapeFunction, array.Length, (PCSTR)value, 4, (byte*)(&num)) == 1;
}
}
}
return false;
} finally {
scope.Dispose();
}
}
return false;
}
public object Clone()
{
PrinterSettings obj = (PrinterSettings)MemberwiseClone();
obj.PrintDialogDisplayed = false;
return obj;
}
internal CreateDcScope CreateDeviceContext(PageSettings pageSettings)
{
HGLOBAL hdevmodeInternal = GetHdevmodeInternal();
try {
pageSettings.CopyToHdevmode(hdevmodeInternal);
return CreateDeviceContext(hdevmodeInternal);
} finally {
PInvokeCore.GlobalFree(hdevmodeInternal);
}
}
internal unsafe CreateDcScope CreateDeviceContext(HGLOBAL hdevmode)
{
DEVMODEW* lpInitData = (DEVMODEW*)PInvokeCore.GlobalLock(hdevmode);
CreateDcScope result = new CreateDcScope(DriverName, PrinterNameInternal, lpInitData, false);
PInvokeCore.GlobalUnlock(hdevmode);
return result;
}
internal CreateDcScope CreateInformationContext(PageSettings pageSettings)
{
HGLOBAL hdevmodeInternal = GetHdevmodeInternal();
try {
pageSettings.CopyToHdevmode(hdevmodeInternal);
return CreateInformationContext(hdevmodeInternal);
} finally {
PInvokeCore.GlobalFree(hdevmodeInternal);
}
}
internal unsafe CreateDcScope CreateInformationContext(HGLOBAL hdevmode)
{
void* lpInitData = PInvokeCore.GlobalLock(hdevmode);
CreateDcScope result = new CreateDcScope(DriverName, PrinterNameInternal, (DEVMODEW*)lpInitData, true);
PInvokeCore.GlobalUnlock(hdevmode);
return result;
}
public Graphics CreateMeasurementGraphics()
{
return CreateMeasurementGraphics(DefaultPageSettings);
}
public Graphics CreateMeasurementGraphics(bool honorOriginAtMargins)
{
Graphics graphics = CreateMeasurementGraphics();
if (honorOriginAtMargins) {
graphics.TranslateTransform(0 - _defaultPageSettings.HardMarginX, 0 - _defaultPageSettings.HardMarginY);
graphics.TranslateTransform((float)_defaultPageSettings.Margins.Left, (float)_defaultPageSettings.Margins.Top);
}
return graphics;
}
public Graphics CreateMeasurementGraphics(PageSettings pageSettings)
{
CreateDcScope scope = CreateDeviceContext(pageSettings);
Graphics graphics = Graphics.FromHdcInternal((IntPtr)ref scope);
graphics.PrintingHelper = new HdcHandle(scope);
return graphics;
}
public Graphics CreateMeasurementGraphics(PageSettings pageSettings, bool honorOriginAtMargins)
{
Graphics graphics = CreateMeasurementGraphics();
if (honorOriginAtMargins) {
graphics.TranslateTransform(0 - pageSettings.HardMarginX, 0 - pageSettings.HardMarginY);
graphics.TranslateTransform((float)pageSettings.Margins.Left, (float)pageSettings.Margins.Top);
}
return graphics;
}
[NullableContext(0)]
private unsafe int DeviceCapabilities(PRINTER_DEVICE_CAPABILITIES capability, void* output = default(void*), int defaultValue = -1)
{
return FastDeviceCapabilities(capability, PrinterName, output, defaultValue);
}
[NullableContext(0)]
private unsafe static int FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES capability, [Nullable(1)] string printerName, void* output = default(void*), int defaultValue = -1)
{
IntPtr value;
if (printerName == null)
value = (IntPtr)(void*)null;
else {
ref pinnableReference = ref printerName.GetPinnableReference();
value = (IntPtr)(&pinnableReference);
}
string outputPort = GetOutputPort();
IntPtr intPtr;
if (outputPort == null)
intPtr = (IntPtr)(void*)null;
else {
ref pinnableReference2 = ref outputPort.GetPinnableReference();
intPtr = (IntPtr)(&pinnableReference2);
}
char* value2 = (char*)(long)intPtr;
int num = PInvoke.DeviceCapabilities((char*)(long)value, value2, capability, (char*)output, null);
if (num != -1)
return num;
return defaultValue;
}
private static string GetDefaultPrinterName()
{
return GetDefaultName(1);
}
private static string GetOutputPort()
{
return GetDefaultName(2);
}
private unsafe static string GetDefaultName(int slot)
{
PRINTDLGEXW pRINTDLGEXW = default(PRINTDLGEXW);
pRINTDLGEXW.lStructSize = (uint)sizeof(PRINTDLGEXW);
pRINTDLGEXW.Flags = (PRINTDLGEX_FLAGS.PD_NOPAGENUMS | PRINTDLGEX_FLAGS.PD_RETURNDEFAULT);
pRINTDLGEXW.hwndOwner = PInvokeCore.GetDesktopWindow();
pRINTDLGEXW.nStartPage = uint.MaxValue;
PRINTDLGEXW pRINTDLGEXW2 = pRINTDLGEXW;
if (PInvokeCore.PrintDlgEx(&pRINTDLGEXW2).Failed)
return System.SR.NoDefaultPrinter;
HGLOBAL hDevNames = pRINTDLGEXW2.hDevNames;
DEVNAMES* ptr = (DEVNAMES*)PInvokeCore.GlobalLock(hDevNames);
if (ptr == null)
throw new Win32Exception();
string text;
switch (slot) {
case 1:
text = new string((char*)((byte*)ptr + (long)(int)ptr->wDeviceOffset * 2));
break;
case 2:
text = new string((char*)((byte*)ptr + (long)(int)ptr->wOutputOffset * 2));
break;
default:
throw new InvalidOperationException();
}
string result = text;
PInvokeCore.GlobalUnlock(hDevNames);
PInvokeCore.GlobalFree(pRINTDLGEXW2.hDevNames);
PInvokeCore.GlobalFree(pRINTDLGEXW2.hDevMode);
return result;
}
private int GetDeviceCaps(GET_DEVICE_CAPS_INDEX capability)
{
CreateDcScope scope = CreateInformationContext(DefaultPageSettings);
try {
return PInvokeCore.GetDeviceCaps((HDC)ref scope, capability);
} finally {
scope.Dispose();
}
}
public IntPtr GetHdevmode()
{
HGLOBAL hdevmodeInternal = GetHdevmodeInternal();
_defaultPageSettings.CopyToHdevmode(hdevmodeInternal);
return hdevmodeInternal;
}
internal unsafe HGLOBAL GetHdevmodeInternal()
{
string printerNameInternal = PrinterNameInternal;
IntPtr intPtr;
if (printerNameInternal == null)
intPtr = (IntPtr)(void*)null;
else {
ref pinnableReference = ref printerNameInternal.GetPinnableReference();
intPtr = (IntPtr)(&pinnableReference);
}
char* printerName = (char*)(long)intPtr;
return GetHdevmodeInternal(printerName);
}
[NullableContext(0)]
private unsafe HGLOBAL GetHdevmodeInternal(char* printerName)
{
int num = -1;
num = PInvoke.DocumentProperties(default(HWND), default(HANDLE), printerName, null, null, 0);
if (num < 1)
throw new InvalidPrinterException(this);
HGLOBAL hGLOBAL = PInvokeCore.GlobalAlloc(GLOBAL_ALLOC_FLAGS.GMEM_MOVEABLE, (UIntPtr)(uint)num);
DEVMODEW* ptr = (DEVMODEW*)PInvokeCore.GlobalLock(hGLOBAL);
if (_cachedDevmode != null)
Marshal.Copy(_cachedDevmode, 0, (IntPtr)ptr, _devmodeBytes);
else {
num = PInvoke.DocumentProperties(default(HWND), default(HANDLE), printerName, ptr, null, 2);
if (num < 0)
throw new Win32Exception();
}
if (_extraInfo != null && _extraBytes <= ptr->dmDriverExtra)
Marshal.Copy(_extraInfo, 0, (IntPtr)((byte*)ptr + (int)ptr->dmSize), _extraBytes);
if (ptr->dmFields.HasFlag(DEVMODE_FIELD_FLAGS.DM_COPIES) && _copies != -1)
ptr->Anonymous1.Anonymous1.dmCopies = _copies;
if (ptr->dmFields.HasFlag(DEVMODE_FIELD_FLAGS.DM_DUPLEX) && _duplex != Duplex.Default)
ptr->dmDuplex = (DEVMODE_DUPLEX)_duplex;
if (ptr->dmFields.HasFlag(DEVMODE_FIELD_FLAGS.DM_COLLATE) && _collate.IsNotDefault)
ptr->dmCollate = (_collate.IsTrue ? DEVMODE_COLLATE.DMCOLLATE_TRUE : DEVMODE_COLLATE.DMCOLLATE_FALSE);
num = PInvoke.DocumentProperties(default(HWND), default(HANDLE), printerName, ptr, ptr, 10);
if (num < 0) {
PInvokeCore.GlobalFree(hGLOBAL);
PInvokeCore.GlobalUnlock(hGLOBAL);
return default(HGLOBAL);
}
PInvokeCore.GlobalUnlock(hGLOBAL);
return hGLOBAL;
}
public IntPtr GetHdevmode(PageSettings pageSettings)
{
IntPtr intPtr = GetHdevmodeInternal();
pageSettings.CopyToHdevmode(intPtr);
return intPtr;
}
public unsafe IntPtr GetHdevnames()
{
string printerName = PrinterName;
string driverName = DriverName;
string outputPort = OutputPort;
int num = checked(4 + printerName.Length + driverName.Length + outputPort.Length);
int num2 = sizeof(DEVNAMES) / 2;
int num3 = checked(num2 + num);
HGLOBAL hGLOBAL = PInvokeCore.GlobalAlloc(GLOBAL_ALLOC_FLAGS.GHND, (UIntPtr)(uint)(2 * num3));
DEVNAMES* ptr = (DEVNAMES*)PInvokeCore.GlobalLock(hGLOBAL);
Span<char> span = new Span<char>(ptr, num3);
ptr->wDriverOffset = checked((ushort)num2);
ReadOnlySpan<char> readOnlySpan = driverName.AsSpan();
readOnlySpan.CopyTo(span.Slice(num2, driverName.Length));
num2 += (ushort)(driverName.Length + 1);
ptr->wDeviceOffset = checked((ushort)num2);
readOnlySpan = printerName.AsSpan();
readOnlySpan.CopyTo(span.Slice(num2, printerName.Length));
num2 += (ushort)(printerName.Length + 1);
ptr->wOutputOffset = checked((ushort)num2);
readOnlySpan = outputPort.AsSpan();
readOnlySpan.CopyTo(span.Slice(num2, outputPort.Length));
num2 += (ushort)(outputPort.Length + 1);
ptr->wDefault = checked((ushort)num2);
PInvokeCore.GlobalUnlock(hGLOBAL);
return hGLOBAL;
}
internal short GetModeField(ModeField field, short defaultValue)
{
return GetModeField(field, defaultValue, default(HGLOBAL));
}
internal unsafe short GetModeField(ModeField field, short defaultValue, HGLOBAL modeHandle)
{
bool flag = false;
try {
if ((long)(IntPtr)modeHandle == 0)
try {
modeHandle = GetHdevmodeInternal();
flag = true;
} catch (InvalidPrinterException) {
return defaultValue;
}
DEVMODEW* ptr = (DEVMODEW*)PInvokeCore.GlobalLock(modeHandle);
short result;
switch (field) {
case ModeField.Orientation:
result = ptr->dmOrientation;
break;
case ModeField.PaperSize:
result = ptr->dmPaperSize;
break;
case ModeField.PaperLength:
result = ptr->dmPaperLength;
break;
case ModeField.PaperWidth:
result = ptr->dmPaperWidth;
break;
case ModeField.Copies:
result = ptr->dmCopies;
break;
case ModeField.DefaultSource:
result = ptr->dmDefaultSource;
break;
case ModeField.PrintQuality:
result = ptr->dmPrintQuality;
break;
case ModeField.Color:
result = (short)ptr->dmColor;
break;
case ModeField.Duplex:
result = (short)ptr->dmDuplex;
break;
case ModeField.YResolution:
result = ptr->dmYResolution;
break;
case ModeField.TTOption:
result = (short)ptr->dmTTOption;
break;
case ModeField.Collate:
result = (short)ptr->dmCollate;
break;
default:
result = defaultValue;
break;
}
PInvokeCore.GlobalUnlock(modeHandle);
return result;
} finally {
if (flag)
PInvokeCore.GlobalFree(modeHandle);
}
}
internal unsafe PaperSize[] Get_PaperSizes()
{
string printerName = PrinterName;
int num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_PAPERNAMES, printerName, null, -1);
if (num != -1) {
int num2 = num;
BufferScope<char> bufferScope = new BufferScope<char>(64 * num2);
try {
fixed (char* output = &bufferScope.GetPinnableReference()) {
num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_PAPERNAMES, printerName, output, -1);
}
int num3 = num2;
Span<ushort> span = new Span<ushort>(stackalloc byte[(int)checked(unchecked((ulong)(uint)num3) * 2)], num3);
fixed (ushort* output2 = &span.GetPinnableReference()) {
num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_PAPERS, printerName, output2, -1);
}
num3 = num2;
Span<Size> span2 = new Span<Size>(stackalloc Size[num3], num3);
fixed (Size* output3 = &span2.GetPinnableReference()) {
num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_PAPERSIZE, printerName, output3, -1);
}
PaperSize[] array = new PaperSize[num2];
for (int i = 0; i < num2; i++) {
array[i] = new PaperSize((PaperKind)span[i], bufferScope.Slice(i * 64, 64).SliceAtFirstNull().ToString(), PrinterUnitConvert.Convert(span2[i].Width, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display), PrinterUnitConvert.Convert(span2[i].Height, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display));
}
return array;
} finally {
bufferScope.Dispose();
}
}
return Array.Empty<PaperSize>();
}
internal unsafe PaperSource[] Get_PaperSources()
{
string printerName = PrinterName;
int num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_BINNAMES, printerName, null, -1);
if (num != -1) {
int num2 = num;
BufferScope<char> bufferScope = new BufferScope<char>(24 * num2);
try {
fixed (char* output = &bufferScope.GetPinnableReference()) {
num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_BINNAMES, printerName, output, -1);
}
int num3 = num2;
Span<ushort> span = new Span<ushort>(stackalloc byte[(int)checked(unchecked((ulong)(uint)num3) * 2)], num3);
fixed (ushort* output2 = &span.GetPinnableReference()) {
FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_BINS, printerName, output2, -1);
}
PaperSource[] array = new PaperSource[num2];
for (int i = 0; i < num2; i++) {
array[i] = new PaperSource((PaperSourceKind)span[i], bufferScope.Slice(i * 24, 24).SliceAtFirstNull().ToString());
}
return array;
} finally {
bufferScope.Dispose();
}
}
return Array.Empty<PaperSource>();
}
internal unsafe PrinterResolution[] Get_PrinterResolutions()
{
string printerName = PrinterName;
int num = FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_ENUMRESOLUTIONS, printerName, null, -1);
if (num == -1)
return new PrinterResolution[4] {
new PrinterResolution(PrinterResolutionKind.High, -4, -1),
new PrinterResolution(PrinterResolutionKind.Medium, -3, -1),
new PrinterResolution(PrinterResolutionKind.Low, -2, -1),
new PrinterResolution(PrinterResolutionKind.Draft, -1, -1)
};
PrinterResolution[] array = new PrinterResolution[num + 4];
array[0] = new PrinterResolution(PrinterResolutionKind.High, -4, -1);
array[1] = new PrinterResolution(PrinterResolutionKind.Medium, -3, -1);
array[2] = new PrinterResolution(PrinterResolutionKind.Low, -2, -1);
array[3] = new PrinterResolution(PrinterResolutionKind.Draft, -1, -1);
int num2 = num;
Span<Point> span = new Span<Point>(stackalloc Point[num2], num2);
fixed (Point* output = &span.GetPinnableReference()) {
FastDeviceCapabilities(PRINTER_DEVICE_CAPABILITIES.DC_ENUMRESOLUTIONS, printerName, output, -1);
}
for (int i = 0; i < num; i++) {
Point point = span[i];
array[i + 4] = new PrinterResolution(PrinterResolutionKind.Custom, point.X, point.Y);
}
return array;
}
public unsafe void SetHdevmode(IntPtr hdevmode)
{
if (hdevmode == (IntPtr)0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidPrinterHandle, hdevmode));
DEVMODEW* ptr = (DEVMODEW*)PInvokeCore.GlobalLock((HGLOBAL)hdevmode);
_devmodeBytes = ptr->dmSize;
if (_devmodeBytes > 0) {
_cachedDevmode = new byte[_devmodeBytes];
Marshal.Copy((IntPtr)ptr, _cachedDevmode, 0, _devmodeBytes);
}
_extraBytes = ptr->dmDriverExtra;
if (_extraBytes > 0) {
_extraInfo = new byte[_extraBytes];
Marshal.Copy((IntPtr)((byte*)ptr + (int)ptr->dmSize), _extraInfo, 0, _extraBytes);
}
if (ptr->dmFields.HasFlag(DEVMODE_FIELD_FLAGS.DM_COPIES))
_copies = ptr->dmCopies;
if (ptr->dmFields.HasFlag(DEVMODE_FIELD_FLAGS.DM_DUPLEX))
_duplex = (Duplex)ptr->dmDuplex;
if (ptr->dmFields.HasFlag(DEVMODE_FIELD_FLAGS.DM_COLLATE))
_collate = (ptr->dmCollate == DEVMODE_COLLATE.DMCOLLATE_TRUE);
PInvokeCore.GlobalUnlock((HGLOBAL)hdevmode);
}
public unsafe void SetHdevnames(IntPtr hdevnames)
{
if (hdevnames == (IntPtr)0)
throw new ArgumentException(System.SR.Format(System.SR.InvalidPrinterHandle, hdevnames));
DEVNAMES* ptr = (DEVNAMES*)PInvokeCore.GlobalLock((HGLOBAL)hdevnames);
_driverName = new string((char*)((byte*)ptr + (long)(int)ptr->wDriverOffset * 2));
_printerName = new string((char*)((byte*)ptr + (long)(int)ptr->wDeviceOffset * 2));
OutputPort = new string((char*)((byte*)ptr + (long)(int)ptr->wOutputOffset * 2));
PrintDialogDisplayed = true;
PInvokeCore.GlobalUnlock((HGLOBAL)hdevnames);
}
public override string ToString()
{
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(104, 9);
defaultInterpolatedStringHandler.AppendLiteral("[PrinterSettings ");
defaultInterpolatedStringHandler.AppendFormatted(PrinterName);
defaultInterpolatedStringHandler.AppendLiteral(" Copies=");
defaultInterpolatedStringHandler.AppendFormatted(Copies);
defaultInterpolatedStringHandler.AppendLiteral(" Collate=");
defaultInterpolatedStringHandler.AppendFormatted(Collate);
defaultInterpolatedStringHandler.AppendLiteral(" Duplex=");
defaultInterpolatedStringHandler.AppendFormatted(Duplex);
defaultInterpolatedStringHandler.AppendLiteral(" FromPage=");
defaultInterpolatedStringHandler.AppendFormatted(FromPage);
defaultInterpolatedStringHandler.AppendLiteral(" LandscapeAngle=");
defaultInterpolatedStringHandler.AppendFormatted(LandscapeAngle);
defaultInterpolatedStringHandler.AppendLiteral(" MaximumCopies=");
defaultInterpolatedStringHandler.AppendFormatted(MaximumCopies);
defaultInterpolatedStringHandler.AppendLiteral(" OutputPort=");
defaultInterpolatedStringHandler.AppendFormatted(OutputPort);
defaultInterpolatedStringHandler.AppendLiteral(" ToPage=");
defaultInterpolatedStringHandler.AppendFormatted(ToPage);
defaultInterpolatedStringHandler.AppendLiteral("]");
return defaultInterpolatedStringHandler.ToStringAndClear();
}
}
}