using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Gdi32
{
/// Enable color optimization.
public const uint EMF_PP_COLOR_OPTIMIZATION = 0x01;
/// The GdiDeleteSpoolFileHandle function releases a spool file handle.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE.
///
///
/// The GdiDeleteSpoolFileHandle function is exported by Gdi32.dll for use within a print processor's
/// PrintDocumentOnPrintProcessor function.
///
///
/// Print processors should call GdiDeleteSpoolFileHandle after calling GdiEndDocEMF, when processing a print job's EMF data
/// stream has been completed. The function calls ClosePrinter (described in the Microsoft Window SDK documentation) to close the
/// printer connection.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdideletespoolfilehandle BOOL
// GdiDeleteSpoolFileHandle( HANDLE SpoolFileHandle );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "ff22498e-404f-42f6-82fd-f0178f6c7789")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiDeleteSpoolFileHandle(HSPOOLFILE SpoolFileHandle);
/// The GdiEndDocEMF function ends EMF playback operations for an EMF-formatted print job.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
///
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE, and an error code can
/// be obtained by calling GetLastError.
///
///
///
/// The GdiEndDocEMF function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// The function performs operations that must be performed after a print job's EMF records have been played. The function calls the
/// spooler's EndDoc function (described in the Microsoft Window SDK documentation), which in turn calls the printer driver's
/// DrvEndDoc function.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdienddocemf BOOL GdiEndDocEMF( HANDLE
// SpoolFileHandle );
[DllImport(Lib.Gdi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "e58403d4-aacc-4d22-98e5-86db1a69c54a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiEndDocEMF(HSPOOLFILE SpoolFileHandle);
/// The GdiEndPageEMF function ends EMF playback operations for a physical page of an EMF-formatted print job.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
///
/// Caller-supplied flags. The following flag is defined:
/// EMF_PP_COLOR_OPTIMIZATION
/// Enable color optimization. For more information, see Remarks.
///
///
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE, and an error code can
/// be obtained by calling GetLastError.
///
///
///
/// The GdiEndPageEMF function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// The GdiEndPageEMF function ends the processing of a physical page and causes it to be ejected from the printer. A print
/// processor should call GdiEndPageEMF at the following times:
///
///
/// -
///
/// After the appropriate number of document pages have been placed on the physical page by making calls to GdiPlayPageEMF. Note
/// that GdiPlayPageEMF does not actually print on the device context, but instead prepares a data structure that describes
/// the text and graphics that are to be printed on the physical page(s). The text and graphics are printed to the device context
/// when GdiEndPageEMF is called.
///
///
/// -
///
/// Whenever a call to GdiGetDevmodeForPage indicates a document page's DEVMODEW structure is different from the previous page's
/// DEVMODE structure.
///
///
///
///
/// If this function is called with the dwOptimization parameter set to EMF_PP_COLOR_OPTIMIZATION, color optimization is enabled. If
/// dwOptimization is set to 0, no optimization is performed. When color optimization is enabled, the presence of color in the spool
/// file causes the spool file to be played in color; the lack of color in the spool file causes the spool file to be played in monochrome.
///
///
/// If you are creating a Unidrv rendering plug-in to generate color watermarks, be advised that color optimization causes color
/// watermarks to be printed in black and white when they are printed on black-and-white documents. To ensure that color watermarks
/// print correctly with color and black-and-white documents, disable color optimization.
///
///
/// The color optimization controlled by the dwOptimization parameter can also be controlled by setting the
/// dwColorOptimization member of the ATTRIBUTE_INFO_2 or ATTRIBUTE_INFO_3 structures. This optimization also can be
/// controlled by the Unidrv * ChangeColorModeOnDoc? color attribute (see Color Attributes).
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdiendpageemf BOOL GdiEndPageEMF( HANDLE
// SpoolFileHandle, DWORD dwOptimization );
[DllImport(Lib.Gdi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "e15344a5-32ed-43a8-93c2-d5201617d595")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiEndPageEMF(HSPOOLFILE SpoolFileHandle, uint dwOptimization);
/// The GdiGetDC function returns a handle to a printer's device context.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
/// If the operation succeeds, the function returns a device context handle. Otherwise the function returns NULL.
///
///
/// The GdiGetDC function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// A print processor can call GdiGetDC to obtain a printer's device context handle anytime after calling
/// GdiGetSpoolFileHandle. The print processor can use the context handle to call Win32 device context functions, in order to
/// perform such operations as applying transformations on the print image.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdigetdc HDC GdiGetDC( HANDLE SpoolFileHandle );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "f8aacb6d-4e8a-4fdb-902c-3d0efbc40f08")]
public static extern HDC GdiGetDC(HSPOOLFILE SpoolFileHandle);
///
/// The GdiGetDevmodeForPage function returns DEVMODEW structures for the specified and previous pages of a print job.
///
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
/// Caller-supplied number of the page for which DEVMODEW contents are to be returned.
/// Caller-supplied location to receive a pointer to a DEVMODE structure for the page specified by dwPageNumber.
///
/// Caller-supplied location to receive a pointer to a DEVMODE structure for the page previous to the one specified by dwPageNumber.
///
/// If the operation succeeds, the function returns TRUE. Otherwise it returns FALSE.
///
///
/// The GdiGetDevmodeForPage function is exported by Gdi32.dll for use within a print processor's
/// PrintDocumentOnPrintProcessor function.
///
///
/// Before calling GdiPlayPageEMF to execute a page's EMF instructions, a print processor must call GdiGetDevmodeForPage to
/// determine if the DEVMODE structure associated with the page to be printed is the same as that of the last page printed. If the
/// two returned DEVMODE structures are not identical, the print processor must perform the following steps, in order, before
/// calling GdiPlayPageEMF for the page:
///
///
/// -
/// Call GdiEndPageEMF.
///
/// -
/// Call GdiResetDCEMF, specifying the DEVMODE pointed to by pCurrDM.
///
/// -
/// Call GdiStartPageEMF.
///
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdigetdevmodeforpage BOOL GdiGetDevmodeForPage(
// HANDLE SpoolFileHandle, DWORD dwPageNumber, PDEVMODEW *pCurrDM, PDEVMODEW *pLastDM );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("winppi.h", MSDNShortId = "3410e8b1-820f-4892-8d26-d803e3f943da")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiGetDevmodeForPage(HSPOOLFILE SpoolFileHandle, uint dwPageNumber, out IntPtr pCurrDM, out IntPtr pLastDM);
/// The GdiGetPageCount function returns the number of pages in a print job.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
///
/// If the operation succeeds, the function returns the number of pages in the current print job. Otherwise the function returns zero.
///
///
///
/// The GdiGetPageCount function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// Note The GdiGetPageCount function does not return until all pages have been spooled, even if the print server
/// administrator has specified that print jobs should be printed during spooling. Therefore, this function should not be used
/// unless it is necessary to obtain the total page count before document processing can begin, such as for printing pages in
/// reverse order.Usually, a better method for determining the page count is to count the number of calls made to GdiGetPageHandle.
///
/// For additional information about this set of functions, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdigetpagecount DWORD GdiGetPageCount( HANDLE
// SpoolFileHandle );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "0a101b59-c610-4158-97a8-002222a94309")]
public static extern uint GdiGetPageCount(HSPOOLFILE SpoolFileHandle);
/// The GdiGetPageHandle function returns a handle to the specified page within a print job.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
/// Caller-supplied page number.
///
///
/// Caller-supplied pointer to a location that receives the page type. The possible page types are shown in the following table:
///
///
///
/// Page Type
/// Meaning
///
/// -
/// EMF_PP_FORM
/// The page is a form or has a watermark. (Not currently supported.)
///
/// -
/// EMF_PP_NORMAL
/// The page is a normal page.
///
///
///
///
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE, and an error code can
/// be obtained by calling GetLastError.
///
///
///
/// The GdiGetPageHandle function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// Print processors must obtain a page handle before calling GdiPlayPageEMF to draw a page. If a Page value is specified that is
/// too large, the function returns ERROR_NO_MORE_ITEMS.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdigetpagehandle HANDLE GdiGetPageHandle( HANDLE
// SpoolFileHandle, DWORD Page, LPDWORD pdwPageType );
[DllImport(Lib.Gdi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "7eaed9d2-20fa-4cf1-b924-fbe1443535e9")]
public static extern HANDLE GdiGetPageHandle(HSPOOLFILE SpoolFileHandle, uint Page, out uint pdwPageType);
/// The GdiGetSpoolFileHandle function returns a handle to a print job's EMF file.
///
/// Caller-supplied pointer to a string representing the name of the target printer. See the following Remarks section.
///
/// Caller-supplied pointer to a DEVMODEW structure. See the following Remarks section.
/// Caller-supplied pointer to the print job's document name. See the following Remarks section.
/// If the operation succeeds, the function returns a spool file handle. Otherwise the function returns NULL.
///
///
/// The GdiGetSpoolFileHandle function is exported by Gdi32.dll for use within a print processor's
/// PrintDocumentOnPrintProcessor function.
///
///
/// When a print processor calls GdiGetSpoolFileHandle, it should supply arguments as illustrated in the following table.
///
///
///
/// Parameter
/// Argument
///
/// -
/// pwszPrinterName
/// Pointer to the printer name received by the print processor's OpenPrintProcessor function.
///
/// -
/// pDevmode
///
/// Pointer to the DEVMODEW structure contained in the PRINTPROCESSOROPENDATA structure, received by the print processor's
/// OpenPrintProcessor function.
///
///
/// -
/// pwszDocName
/// Document name pointer received by the print processor's PrintDocumentOnPrintProcessor function.
///
///
///
/// A print processor must call the GdiGetSpoolFileHandle function before calling any other GDI printing functions, because
/// the returned handle must be passed to the other functions. The function calls OpenPrinter to open a connection to the printer,
/// and CreateDC to create a device context for drawing. The print processor can obtain the device context's handle by calling GdiGetDC.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdigetspoolfilehandle HANDLE
// GdiGetSpoolFileHandle( LPWSTR pwszPrinterName, LPDEVMODEW pDevmode, LPWSTR pwszDocName );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("winppi.h", MSDNShortId = "c820ee94-29c2-4478-884c-49dd68cd713a")]
public static extern SafeHSPOOLFILE GdiGetSpoolFileHandle([MarshalAs(UnmanagedType.LPWStr)] string pwszPrinterName, in DEVMODE pDevmode, [MarshalAs(UnmanagedType.LPWStr)] string pwszDocName);
///
/// The GdiPlayPageEMF function plays the EMF records within a specified rectangle for one document page of a spooled print job.
///
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
///
/// Caller-supplied page handle, obtained by calling GdiGetPageHandle, identifying the page for which records are to be played.
///
///
/// Caller-supplied pointer to a RECT structure specifying the rectangle into which the page is to be drawn.
///
///
/// Caller-supplied pointer to a RECT structure specifying the page's border rectangle (if any). Can be NULL.
///
///
/// Caller-supplied pointer to a RECT structure specifying the coordinates of the page's clip region (if any). Can be NULL.
///
///
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE, and an error code can
/// be obtained by calling GetLastError.
///
///
///
/// The GdiPlayPageEMF function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// The GdiPlayPageEMF function is the means by which a print processor positions a document page or a specified rectangular
/// region of a document page on a physical page. Note that GdiPlayPageEMF does not actually print on the device context, but
/// instead prepares a data structure that describes the text and graphics that are to be printed on the physical page(s). The text
/// and graphics are printed to the device context when GdiEndPageEMF is called.
///
///
/// The print processor uses prectClip to describe the rectangular region to be printed, and prectDocument to describe a rectangle
/// into which the document page (or clipped region) must fit. If prectClip is NULL, the entire document page will be
/// printed. For non- NULL values of prectClip, only the portion of the document page within the clip region will be printed.
/// The GdiPlayPageEMF function then performs the scaling and translation operations required to make the document page (or
/// selected portion) fit into the rectangle.
///
///
/// The prectBorder parameter, if it is non- NULL, describes a solid-line border rectangle to be drawn around the document
/// page. If prectBorder is NULL, no such border will be drawn.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdiplaypageemf BOOL GdiPlayPageEMF( HANDLE
// SpoolFileHandle, HANDLE hemf, RECT *prectDocument, RECT *prectBorder, RECT *prectClip );
[DllImport(Lib.Gdi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "e0122858-0c9d-4aa8-a394-89d65fb98fda")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiPlayPageEMF(HSPOOLFILE SpoolFileHandle, HANDLE hemf, in RECT prectDocument, in RECT prectBorder, in RECT prectClip);
/// The GdiResetDCEMF function resets a printer's device context during playback of a spooled EMF print job.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
/// Caller-supplied pointer to a DEVMODEW structure, obtained by a previous call to GdiGetDevmodeForPage.
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE.
///
///
/// The GdiResetDCEMF function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// Print processors must call GdiResetDCEMF whenever it is necessary to reset the printer's device context. The function
/// must be called whenever the GdiGetDevmodeForPage function indicates that the current document page's DEVMODEW structure is not
/// identical to that of the previous document page.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdiresetdcemf BOOL GdiResetDCEMF( HANDLE
// SpoolFileHandle, PDEVMODEW pCurrDM );
[DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("winppi.h", MSDNShortId = "ea97cc22-6057-427d-90c1-4f23ced932aa")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiResetDCEMF(HSPOOLFILE SpoolFileHandle, IntPtr pCurrDM);
/// The GdiStartDocEMF function performs initialization operations for an EMF-formatted print job.
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
/// Caller-supplied pointer to a DOCINFOW structure (described in the Microsoft Window SDK documentation).
///
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE, and an error code can
/// be obtained by calling GetLastError.
///
///
///
/// The GdiStartDocEMF function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// The function performs initializations that must take place before a print job's EMF records can be played. The function calls
/// the spooler's StartDoc function (described in the Window SDK documentation), which in turn calls the printer driver's
/// DrvStartDoc function.
///
///
/// The print processor must set the lpszOutput member of the DOCINFOW structure to the output file name contained in the
/// PRINTPROCESSOROPENDATA structure, previously received by the OpenPrintProcessor function.
///
///
/// The print processor must set the lpszDocName member of the DOCINFOW structure to the document name pointer, previously
/// received by the PrintDocumentOnPrintProcessor function.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdistartdocemf BOOL GdiStartDocEMF( HANDLE
// SpoolFileHandle, DOCINFOW *pDocInfo );
[DllImport(Lib.Gdi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("winppi.h", MSDNShortId = "aca4534a-871e-4d86-b329-cb4f84611a29")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiStartDocEMF(HSPOOLFILE SpoolFileHandle, in DOCINFO pDocInfo);
///
/// The GdiStartPageEMF function performs initialization operations for a physical page of an EMF-formatted print job.
///
/// Caller-supplied spool file handle, obtained by a previous call to GdiGetSpoolFileHandle.
///
/// If the operation succeeds, the function returns TRUE. Otherwise the function returns FALSE, and an error code can
/// be obtained by calling GetLastError.
///
///
///
/// The GdiStartPageEMF function is exported by Gdi32.dll for use within a print processor's PrintDocumentOnPrintProcessor function.
///
///
/// A print processor must call the GdiStartPageEMF function each time a new physical page is to be created. It can then call
/// GdiPlayPageEMF for each document page that is to be placed on the physical page.
///
/// For additional information, see Using GDI Functions in Print Processors.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/winppi/nf-winppi-gdistartpageemf BOOL GdiStartPageEMF( HANDLE
// SpoolFileHandle );
[DllImport(Lib.Gdi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winppi.h", MSDNShortId = "963c809f-da89-4f27-ba8b-3de8cdcec179")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GdiStartPageEMF(HSPOOLFILE SpoolFileHandle);
/// Provides a handle to a spool file.
[StructLayout(LayoutKind.Sequential)]
public struct HSPOOLFILE : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HSPOOLFILE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HSPOOLFILE NULL => new HSPOOLFILE(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HSPOOLFILE h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HSPOOLFILE(IntPtr h) => new HSPOOLFILE(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HSPOOLFILE h1, HSPOOLFILE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HSPOOLFILE h1, HSPOOLFILE h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HSPOOLFILE h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a for that is disposed using .
public class SafeHSPOOLFILE : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHSPOOLFILE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHSPOOLFILE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HSPOOLFILE(SafeHSPOOLFILE h) => h.handle;
///
protected override bool InternalReleaseHandle() => GdiDeleteSpoolFileHandle(handle);
}
}
}