StandardPrintController
Specifies a print controller that sends information to a printer.
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.Storage.Xps;
namespace System.Drawing.Printing
{
[NullableContext(1)]
[Nullable(0)]
public class StandardPrintController : PrintController, IHandle<HDC>
{
[Nullable(2)]
private HdcHandle _hdc;
[Nullable(2)]
private Graphics _graphics;
HDC IHandle<HDC>.Handle {
get {
return _hdc?.Handle ?? HDC.Null;
}
}
public unsafe override void OnStartPrint(PrintDocument document, PrintEventArgs e)
{
base.OnStartPrint(document, e);
if (!document.PrinterSettings.IsValid)
throw new InvalidPrinterException(document.PrinterSettings);
_hdc = new HdcHandle(document.PrinterSettings.CreateDeviceContext(_modeHandle));
string documentName = document.DocumentName;
IntPtr intPtr;
if (documentName == null)
intPtr = (IntPtr)(void*)null;
else {
ref reference = ref documentName.GetPinnableReference();
intPtr = (IntPtr)(&reference);
}
char* value = (char*)(long)intPtr;
string outputPort = document.PrinterSettings.OutputPort;
IntPtr intPtr2;
if (outputPort == null)
intPtr2 = (IntPtr)(void*)null;
else {
ref reference2 = ref outputPort.GetPinnableReference();
intPtr2 = (IntPtr)(&reference2);
}
char* ptr = (char*)(long)intPtr2;
DOCINFOW dOCINFOW = default(DOCINFOW);
dOCINFOW.cbSize = sizeof(DOCINFOW);
dOCINFOW.lpszDocName = value;
dOCINFOW.lpszDatatype = null;
dOCINFOW.fwType = 0;
dOCINFOW.lpszOutput = (char*)(long)(document.PrinterSettings.PrintToFile ? ((IntPtr)ptr) : ((IntPtr)(void*)null));
DOCINFOW lpdi = dOCINFOW;
if (PInvoke.StartDoc(this, ref lpdi) <= 0) {
WIN32_ERROR wIN32_ERROR = (WIN32_ERROR)Marshal.GetLastPInvokeError();
if (wIN32_ERROR == WIN32_ERROR.NO_ERROR)
wIN32_ERROR = GetLastError();
if (wIN32_ERROR != WIN32_ERROR.ERROR_CANCELLED)
throw new Win32Exception((int)wIN32_ERROR);
e.Cancel = true;
}
ref reference2 = ref *(char*)null;
ref reference = ref *(char*)null;
}
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern WIN32_ERROR GetLastError();
public unsafe override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e)
{
base.OnStartPage(document, e);
e.PageSettings.CopyToHdevmode(_modeHandle);
DEVMODEW* lpdm = (DEVMODEW*)PInvokeCore.GlobalLock(_modeHandle);
try {
PInvoke.ResetDCW((HDC)ref _hdc, lpdm);
} finally {
PInvokeCore.GlobalUnlock(_modeHandle);
}
_graphics = Graphics.FromHdcInternal((IntPtr)ref _hdc);
if (document.OriginAtMargins) {
int deviceCaps = PInvokeCore.GetDeviceCaps((HDC)ref _hdc, GET_DEVICE_CAPS_INDEX.LOGPIXELSX);
int deviceCaps2 = PInvokeCore.GetDeviceCaps((HDC)ref _hdc, GET_DEVICE_CAPS_INDEX.LOGPIXELSY);
int deviceCaps3 = PInvokeCore.GetDeviceCaps((HDC)ref _hdc, GET_DEVICE_CAPS_INDEX.PHYSICALOFFSETX);
int deviceCaps4 = PInvokeCore.GetDeviceCaps((HDC)ref _hdc, GET_DEVICE_CAPS_INDEX.PHYSICALOFFSETY);
float num = (float)(deviceCaps3 * 100 / deviceCaps);
float num2 = (float)(deviceCaps4 * 100 / deviceCaps2);
_graphics.TranslateTransform(0 - num, 0 - num2);
_graphics.TranslateTransform((float)document.DefaultPageSettings.Margins.Left, (float)document.DefaultPageSettings.Margins.Top);
}
if (PInvoke.StartPage(this) > 0)
return _graphics;
throw new Win32Exception();
}
public override void OnEndPage(PrintDocument document, PrintPageEventArgs e)
{
try {
if (PInvoke.EndPage(this) <= 0)
throw new Win32Exception();
} finally {
_graphics.Dispose();
_graphics = null;
}
base.OnEndPage(document, e);
}
public override void OnEndPrint(PrintDocument document, PrintEventArgs e)
{
if (_hdc != null)
try {
if ((e.Cancel ? PInvoke.AbortDoc(this) : PInvoke.EndDoc(this)) <= 0)
throw new Win32Exception();
} finally {
_hdc.Dispose();
_hdc = null;
}
base.OnEndPrint(document, e);
}
}
}