Click here to Skip to main content
15,900,907 members
Articles / Programming Languages / Visual Basic

Monitoring a Printer Queue from VB.NET

Rate me:
Please Sign up or sign in to vote.
4.61/5 (67 votes)
2 May 2014CPOL4 min read 1.6M   18.1K   188   518
How to monitor a printer queue from Visual Basic .NET

Introduction

Some of the API calls used in this example are only supported on Windows NT, 2000, XP and .NET server. Therefore this technique does not apply to Windows 95, Windows 98 or Windows ME.

Although VB.NET printer handling has improved immeasurably over that offered by Visual Basic 6 and the new extensions to System.Drawing.Printing have also helped, there is still a need to turn to the Windows API in order to monitor a print queue.

Get a Handle to the Printer You Want to Monitor

All of the API calls that access the printer or spooler need a printer handle. This is obtained by passing the unique printer device name to the OpenPrinter API call and must be released by the ClosePrinter API call when it is no longer needed.

VB.NET
<DllImport("winspool.drv", EntryPoint:="OpenPrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=False, _
CallingConvention:=CallingConvention.StdCall)> _
    Public Function OpenPrinter(<InAttribute()> ByVal pPrinterName As String, _
                            <OutAttribute()> ByRef phPrinter As IntPtr, _
                               <InAttribute(), MarshalAs(UnmanagedType.LPStruct)> ByVal pDefault As PRINTER_DEFAULTS _
                               ) As Boolean

    End Function

<DllImport("winspool.drv", EntryPoint:="ClosePrinter", _
SetLastError:=True, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
    Public Function ClosePrinter(<InAttribute()> ByVal hPrinter As IntPtr) As Boolean

    End Function

Ask for the Notifications You are Interested in

To minimise the impact of a printer watch on system performance, we can specify precisely which printer events we are interested in. This is done by passing a parameter to FindFirstPrinterChangeNotification using one or more of the following values:

VB.NET
Public Enum Printer_Change_Notification_General_Flags 
    PRINTER_CHANGE_FORM = &H70000 
    PRINTER_CHANGE_PORT = &H700000 
    PRINTER_CHANGE_JOB = &HFF00 
    PRINTER_CHANGE_PRINTER = &HFF 
    PRINTER_CHANGE_PRINT_PROCESSOR = &H7000000 
    PRINTER_CHANGE_PRINTER_DRIVER = &H70000000 
End Enum 

Public Enum Printer_Change_Notification_Form_Flags 
    PRINTER_CHANGE_ADD_FORM = &H10000 
    PRINTER_CHANGE_SET_FORM = &H20000 
    PRINTER_CHANGE_DELETE_FORM = &H40000 
End Enum 

Public Enum Printer_Change_Notification_Port_Flags 
    PRINTER_CHANGE_ADD_PORT = &H100000 
    PRINTER_CHANGE_CONFIGURE_PORT = &H200000 
    PRINTER_CHANGE_DELETE_PORT = &H400000 
End Enum 

Public Enum Printer_Change_Notification_Job_Flags 
    PRINTER_CHANGE_ADD_JOB = &H100 
    PRINTER_CHANGE_SET_JOB = &H200 
    PRINTER_CHANGE_DELETE_JOB = &H400 
    PRINTER_CHANGE_WRITE_JOB = &H800 
End Enum 

Public Enum Printer_Change_Notification_Printer_Flags 
    PRINTER_CHANGE_ADD_PRINTER = &H1 
    PRINTER_CHANGE_SET_PRINTER = &H2 
    PRINTER_CHANGE_DELETE_PRINTER = &H4 
    PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = &H8 
End Enum 

Public Enum Printer_Change_Notification_Processor_Flags 
    PRINTER_CHANGE_ADD_PRINT_PROCESSOR = &H1000000 
    PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = &H4000000 
End Enum 

Public Enum Printer_Change_Notification_Driver_Flags 
    PRINTER_CHANGE_ADD_PRINTER_DRIVER = &H10000000 
    PRINTER_CHANGE_SET_PRINTER_DRIVER = &H20000000 
    PRINTER_CHANGE_DELETE_PRINTER_DRIVER = &H40000000
End Enum

Specify the Information You want Returned for the Event

When an event occurs -- for example, if a job is added to the print queue -- you will probably want to get information about the job that caused that event. Again, in order to minimise the impact on the system, you specify exactly which fields you want information from. For a print job event, the possible fields are:

VB.NET
 Public Enum Job_Notify_Field_Indexes 
    JOB_NOTIFY_FIELD_PRINTER_NAME = &H0 
    JOB_NOTIFY_FIELD_MACHINE_NAME = &H1 
    JOB_NOTIFY_FIELD_PORT_NAME = &H2 
    JOB_NOTIFY_FIELD_USER_NAME = &H3 
    JOB_NOTIFY_FIELD_NOTIFY_NAME = &H4 
    JOB_NOTIFY_FIELD_DATATYPE = &H5 
    JOB_NOTIFY_FIELD_PRINT_PROCESSOR = &H6 
    JOB_NOTIFY_FIELD_PARAMETERS = &H7 
    JOB_NOTIFY_FIELD_DRIVER_NAME = &H8 
    JOB_NOTIFY_FIELD_DEVMODE = &H9 
    JOB_NOTIFY_FIELD_STATUS = &HA 
    JOB_NOTIFY_FIELD_STATUS_STRING = &HB 
    JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR = &HC 
    JOB_NOTIFY_FIELD_DOCUMENT = &HD 
    JOB_NOTIFY_FIELD_PRIORITY = &HE 
    JOB_NOTIFY_FIELD_POSITION = &HF 
    JOB_NOTIFY_FIELD_SUBMITTED = &H10 
    JOB_NOTIFY_FIELD_START_TIME = &H11 
    JOB_NOTIFY_FIELD_UNTIL_TIME = &H12 
    JOB_NOTIFY_FIELD_TIME = &H13 
    JOB_NOTIFY_FIELD_TOTAL_PAGES = &H14 
    JOB_NOTIFY_FIELD_PAGES_PRINTED = &H15 
    JOB_NOTIFY_FIELD_TOTAL_BYTES = &H16 
    JOB_NOTIFY_FIELD_BYTES_PRINTED = &H17 
End Enum 

To inform the print spooler that you want information on these fields, you create a PRINTER_NOTIFY_OPTIONS structure that is passed to FindFirstPrinterChangeNotification and which holds a pointer to an array of PRINTER_NOTIFY_OPTIONS_TYPE, one for each of the above fields that you require. These structures are documented on MSDN.

In VB.NET, it is easy to translate these structures into classes that can be passed to the API, by being marshaled as if they were structures:

VB.NET
<StructLayout(LayoutKind.Sequential)> _ 
Public Class PrinterNotifyOptionsType 
    Public wType As Int16 
    Public wReserved0 As Int16 
    Public dwReserved1 As Int32 
    Public dwReserved2 As Int32 
    Public FieldCount As Int32 
    Public pFields As IntPtr 

    Private Sub SetupFields() 

        '\\ Free up the global memory 
        If pFields.ToInt32 <> 0 Then 
            Marshal.FreeHGlobal(pFields) 
        End If 

        If wType = Printer_Notification_Types.JOB_NOTIFY_TYPE Then 
            FieldCount = JOB_FIELDS_COUNT 
            pFields = Marshal.AllocHGlobal((JOB_FIELDS_COUNT * 2) - 1) 
            
            '\\ Put the field indexes in the unmanaged array
            Marshal.WriteInt16(pFields, 0, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_PRINTER_NAME)) 
            Marshal.WriteInt16(pFields, 2, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_MACHINE_NAME)) 
            Marshal.WriteInt16(pFields, 4, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_PORT_NAME)) 
            Marshal.WriteInt16(pFields, 6, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_USER_NAME)) 
            Marshal.WriteInt16(pFields, 8, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_NOTIFY_NAME)) 
            Marshal.WriteInt16(pFields, 10, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_DATATYPE)) 
            Marshal.WriteInt16(pFields, 12, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_PRINT_PROCESSOR)) 
            Marshal.WriteInt16(pFields, 14, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_PARAMETERS)) 
            Marshal.WriteInt16(pFields, 16, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_DRIVER_NAME)) 
            Marshal.WriteInt16(pFields, 18, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_DEVMODE)) 
            Marshal.WriteInt16(pFields, 20, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_STATUS)) 
            Marshal.WriteInt16(pFields, 22, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_STATUS_STRING)) 
            Marshal.WriteInt16(pFields, 24, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR)) 
            Marshal.WriteInt16(pFields, 26, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_DOCUMENT)) 
            Marshal.WriteInt16(pFields, 28, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_PRIORITY)) 
            Marshal.WriteInt16(pFields, 30, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_POSITION)) 
            Marshal.WriteInt16(pFields, 32, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_SUBMITTED)) 
            Marshal.WriteInt16(pFields, 34, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_START_TIME)) 
            Marshal.WriteInt16(pFields, 36, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_UNTIL_TIME)) 
            Marshal.WriteInt16(pFields, 38, 
                CShort(Job_Notify_Field_Indexes.JOB_NOTIFY_FIELD_TIME)) 
            Marshal.WriteInt16(pFields, 40, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_TOTAL_PAGES)) 
            Marshal.WriteInt16(pFields, 42, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_PAGES_PRINTED)) 
            Marshal.WriteInt16(pFields, 44, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_TOTAL_BYTES)) 
            Marshal.WriteInt16(pFields, 46, 
                CShort(Job_Notify_Field_Indexes.
                JOB_NOTIFY_FIELD_BYTES_PRINTED)) 
        End If 
    End Sub 

    Public Sub New(ByVal value As Printer_Notification_Types) 
        wType = value 
        Call SetupFields() 
    End Sub
  
End Class   

Starting the Watch

To start the printer watch, you need to pass the printer handle to FindFirstPrinterChangeNotification:

VB.NET
<DllImport("winspool.drv", EntryPoint:="FindFirstPrinterChangeNotification", _
 SetLastError:=True, CharSet:=CharSet.Unicode, _
 ExactSpelling:=False, _
 CallingConvention:=CallingConvention.StdCall)> _
Public Function FindFirstPrinterChangeNotification _
                (<InAttribute()> ByVal hPrinter As IntPtr, _
                 <InAttribute()> ByVal fwFlags As Int32, _
                 <InAttribute()> ByVal fwOptions As Int32, _
                 <InAttribute(), MarshalAs(UnmanagedType.LPStruct)> ByVal pPrinterNotifyOptions As PrinterNotifyOptions _
                    ) As Microsoft.Win32.SafeHandles.SafeWaitHandle

End Function

Waiting for a Notification

In the Visual Basic 6 implementation of this, a great deal of complexity was added by the fact that it is a single-threaded system. Thus, when the program was waiting for the printer notification, it was effectively locked up. In Visual Basic .NET, this is no longer necessary because it supports asynchronous events and threading.

The FindFirstPrinterChangeNotification API call returns a Windows synchronization wait handle. This can be used by the VB.NET Common Language Runtime to trigger a particular subroutine whenever that synchronisation object is signalled. This is done with the Threading.RegisteredWaitHandle object:

VB.NET
Private Shared _mhPrinterChangeNotification As RegisteredWaitHandle 

    Dim wh As New ManualResetEvent(False) 
    wh.Handle = mhWait 
    _mhPrinterChangeNotification = 
        ThreadPool.RegisterWaitForSingleObject(wh, 
        New WaitOrTimerCallback(AddressOf PrinterNotifyWaitCallback), 
        wh, -1, True)

Here, PrinterNotifyWaitCallback is a public subroutine that has the correct signature for WaitOrTimerCallback:

VB.NET
Public Sub PrinterNotifyWaitCallback( _ 
    ByVal state As Object, _ 
    ByVal timedOut As Boolean) 

Getting Information About the Event that Occurred

When the wait object is triggered, you have to call FindNextPrinterChangeNotification to find out what event triggered it and get the details.

VB.NET
<DllImport("winspool.drv", EntryPoint:="FindNextPrinterChangeNotification", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=False, _
CallingConvention:=CallingConvention.StdCall)> _
    Public Function FindNextPrinterChangeNotification _
                        (<InAttribute()> ByVal hChangeObject As Microsoft.Win32.SafeHandles.SafeWaitHandle, _
                         <OutAttribute()> ByRef pdwChange As Int32, _
                         <InAttribute(), MarshalAs(UnmanagedType.LPStruct)> ByVal pPrinterNotifyOptions As PrinterNotifyOptions, _
                         <OutAttribute()> ByRef lppPrinterNotifyInfo As IntPtr _
                             ) As Boolean
    End Function

This returns a 32-bit number in pdwChange that indicates what event has occurred. For example, this will contain PRINTER_CHANGE_ADD_JOB when a job is added to the print queue. Additionally, it returns a pointer to data allocated by the spooler in lppPrinterNotifyInfo, which contains a PRINTER_NOTIFY_INFO structure, followed by an array of PRINTER_NOTIFY_INFO_DATA structures. Again, in VB.NET these can be represented by classes:

VB.NET
<StructLayout(LayoutKind.Sequential)> _ 
Public Class PRINTER_NOTIFY_INFO 
    Public Version As Int32 
    Public Flags As Int32 
    Public Count As Int32 
End Class 

You can populate these classes from a pointer, using Marshal.PtrToStructure:

VB.NET
Private msInfo As New PRINTER_NOTIFY_INFO() 
    '\\ Read the data of this printer notification event 
    Marshal.PtrToStructure(lpAddress, msInfo)

Using the code

The printer monitor code attached is implemented as a user control. This means you must compile the control project before Visual Studio can use it in the form designer or toolbox.

History

  • 16 Aug 2006
    • Release 2.0.3 of the component. Allows monitoring multiple printers and gives more detail on the print job events raised. The code is migrated to .NET 2.0.
  • 6 Nov 2006
    • Added new status TonerLow and properties Colour, Collate and PrintQuality to the PrinterInformation class
  • 15 August 2007
    • Updated source code: now uses the SafeWaitHandle class
  • 29 May 2009
    • New source code which is converted to .NET 2 and also uses the Unicode versions of the API calls for international support
  • 02 May 2014
    • Converted all code to be 32 and 64 bit compatible, and added a lot of new printer api calls

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Ireland Ireland
C# / SQL Server developer
Microsoft MVP (Azure) 2017
Microsoft MVP (Visual Basic) 2006, 2007

Comments and Discussions

 
AnswerRe: How to monitor a printer queue from VB.NET Pin
Duncan Edwards Jones11-Jun-05 10:50
professionalDuncan Edwards Jones11-Jun-05 10:50 
AnswerRe: How to monitor a printer queue from VB.NET Pin
CodeCypher7-Jul-05 17:50
CodeCypher7-Jul-05 17:50 
AnswerRe: How to monitor a printer queue from VB.NET Pin
Duncan Edwards Jones9-Nov-05 11:22
professionalDuncan Edwards Jones9-Nov-05 11:22 
Generalaid with FindFirstPrinterChangeNotification Pin
Member 153323226-May-05 9:38
Member 153323226-May-05 9:38 
GeneralHave problem with Network Printers connect to Print Server Pin
Member 188602524-May-05 5:21
Member 188602524-May-05 5:21 
GeneralRe: Have problem with Network Printers connect to Print Server Pin
Duncan Edwards Jones11-Jun-05 10:52
professionalDuncan Edwards Jones11-Jun-05 10:52 
QuestionHow to get Paper Size info from each Print Job? Pin
Member 188602517-May-05 16:16
Member 188602517-May-05 16:16 
AnswerRe: How to get Paper Size info from each Print Job? Pin
Duncan Edwards Jones17-May-05 22:26
professionalDuncan Edwards Jones17-May-05 22:26 
From the structure JOB_INFO_2 you have a pointer to a DEVMODE struicture:

Private Type JOB_INFO_2
JobId As Long
lpPrinterName As String
lpMachinename As String
lpUserName As String
lpDocumentName As String
lpNotifyName As String
lpDataType As String
lpPrintProcessor As String
lpParameters As String
lpDriverName As String
lpDevMode As Long '<---- Pointer to DevMode
lpStatus As String
lpSecurityDescriptor As Long 'Pointer to SECURITY_DESCRIPTOR
Status As Long
Priority As Long
Position As Long
StartTime As Long
UntilTime As Long
TotalPages As Long
JobSize As Long
Submitted As SYSTEMTIME
time As Long
PagesPrinted As Long
End Type

So you need to get this pointer and marshal a DevMode structure from it:-

Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32

Private Type DEVMODE
dmDeviceName As String * CCHDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * CCHFORMNAME
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type

And use it's dmPaperSize member. It can be one of:-

' ##ENUMERATION_DESCRIPTION PrinterPaperSizes are the predefined paper types. Typically a printer will only support a very small subset of these.
Public Enum PrinterPaperSizes
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTER Letter 8 1/2 x 11 in
DMPAPER_LETTER = 1
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTERSMALL Letter Small 8 1/2 x 11 in
DMPAPER_LETTERSMALL = 2
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_TABLOID Tabloid 11 x 17 in
DMPAPER_TABLOID = 3
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LEDGER Ledger 17 x 11 in
DMPAPER_LEDGER = 4
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LEGAL Legal 8 1/2 x 14 in
DMPAPER_LEGAL = 5
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_STATEMENT Statement 5 1/2 x 8 1/2 in
DMPAPER_STATEMENT = 6
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_EXECUTIVE Executive 7 1/4 x 10 1/2 in
DMPAPER_EXECUTIVE = 7
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A3 A3 297 x 420 mm
DMPAPER_A3 = 8
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A4 A4 210 x 297 mm
DMPAPER_A4 = 9
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A4SMALL A4 Small 210 x 297 mm
DMPAPER_A4SMALL = 10
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A5 A5 148 x 210 mm
DMPAPER_A5 = 11
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B4 B4 (JIS) 250 x 354
DMPAPER_B4 = 12
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B5 B5 (JIS) 182 x 257 mm
DMPAPER_B5 = 13
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_FOLIO Folio 8 1/2 x 13 in
DMPAPER_FOLIO = 14
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_QUARTO Quarto 215 x 275 mm
DMPAPER_QUARTO = 15
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_10X14 10x14 in
DMPAPER_10X14 = 16
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_11X17 11x17 in
DMPAPER_11X17 = 17
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_NOTE Note 8 1/2 x 11 in
DMPAPER_NOTE = 18
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_9 Envelope #9 3 7/8 x 8 7/8
DMPAPER_ENV_9 = 19
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_10 Envelope #10 4 1/8 x 9 1/2
DMPAPER_ENV_10 = 20
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_11 Envelope #11 4 1/2 x 10 3/8
DMPAPER_ENV_11 = 21
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_12 Envelope #12 4 \276 x 11
DMPAPER_ENV_12 = 22
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_14 Envelope #14 5 x 11 1/2
DMPAPER_ENV_14 = 23
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_CSHEET C size sheet
DMPAPER_CSHEET = 24
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_DSHEET D size sheet
DMPAPER_DSHEET = 25
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ESHEET E size sheet
DMPAPER_ESHEET = 26
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_DL Envelope DL 110 x 220mm
DMPAPER_ENV_DL = 27
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_C5 Envelope C5 162 x 229 mm
DMPAPER_ENV_C5 = 28
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_C3 Envelope C3 324 x 458 mm
DMPAPER_ENV_C3 = 29
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_C4 Envelope C4 229 x 324 mm
DMPAPER_ENV_C4 = 30
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_C6 Envelope C6 114 x 162 mm
DMPAPER_ENV_C6 = 31
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_C65 Envelope C65 114 x 229 mm
DMPAPER_ENV_C65 = 32
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_B4 Envelope B4 250 x 353 mm
DMPAPER_ENV_B4 = 33
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_B5 Envelope B5 176 x 250 mm
DMPAPER_ENV_B5 = 34
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_B6 Envelope B6 176 x 125 mm
DMPAPER_ENV_B6 = 35
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_ITALY Envelope 110 x 230 mm
DMPAPER_ENV_ITALY = 36
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_MONARCH Envelope Monarch 3.875 x 7.5 in
DMPAPER_ENV_MONARCH = 37
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_PERSONAL 6 3/4 Envelope 3 5/8 x 6 1/2 in
DMPAPER_ENV_PERSONAL = 38
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_FANFOLD_US US Std Fanfold 14 7/8 x 11 in
DMPAPER_FANFOLD_US = 39
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_FANFOLD_STD_GERMAN German Std Fanfold 8 1/2 x 12 in
DMPAPER_FANFOLD_STD_GERMAN = 40
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_FANFOLD_LGL_GERMAN German Legal Fanfold 8 1/2 x 13 in
DMPAPER_FANFOLD_LGL_GERMAN = 41
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ISO_B4 B4 (ISO) 250 x 353 mm
DMPAPER_ISO_B4 = 42
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JAPANESE_POSTCARD Japanese Postcard 100 x 148 mm
DMPAPER_JAPANESE_POSTCARD = 43
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_9X11 9 x 11 in
DMPAPER_9X11 = 44
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_10X11 10 x 11 in
DMPAPER_10X11 = 45
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_15X11 15 x 11 in
DMPAPER_15X11 = 46
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_ENV_INVITE Envelope Invite 220 x 220 mm
DMPAPER_ENV_INVITE = 47
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTER_EXTRA Letter Extra 9 \275 x 12 in
DMPAPER_LETTER_EXTRA = 50
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LEGAL_EXTRA Legal Extra 9 \275 x 15 in
DMPAPER_LEGAL_EXTRA = 51
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_TABLOID_EXTRA Tabloid Extra 11.69 x 18 in
DMPAPER_TABLOID_EXTRA = 52
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A4_EXTRA A4 Extra 9.27 x 12.69 in
DMPAPER_A4_EXTRA = 53
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTER_TRANSVERSE Letter Transverse 8 \275 x 11 in
DMPAPER_LETTER_TRANSVERSE = 54
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A4_TRANSVERSE A4 Transverse 210 x 297 mm
DMPAPER_A4_TRANSVERSE = 55
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTER_EXTRA_TRANSVERSE Letter Extra Transverse 9\275 x 12 in
DMPAPER_LETTER_EXTRA_TRANSVERSE = 56
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A_PLUS SuperA/SuperA/A4 227 x 356 mm
DMPAPER_A_PLUS = 57
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B_PLUS SuperB/SuperB/A3 305 x 487 mm
DMPAPER_B_PLUS = 58
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTER_PLUS Letter Plus 8.5 x 12.69 in
DMPAPER_LETTER_PLUS = 59
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A4_PLUS A4 Plus 210 x 330 mm
DMPAPER_A4_PLUS = 60
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A5_TRANSVERSE A5 Transverse 148 x 210 mm
DMPAPER_A5_TRANSVERSE = 61
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B5_TRANSVERSE B5 (JIS) Transverse 182 x 257 mm
DMPAPER_B5_TRANSVERSE = 62
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A3_EXTRA A3 Extra 322 x 445 mm
DMPAPER_A3_EXTRA = 63
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A5_EXTRA A5 Extra 174 x 235 mm
DMPAPER_A5_EXTRA = 64
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B5_EXTRA B5 (ISO) Extra 201 x 276 mm
DMPAPER_B5_EXTRA = 65
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A2 A2 420 x 594 mm
DMPAPER_A2 = 66
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A3_TRANSVERSE A3 Transverse 297 x 420 mm
DMPAPER_A3_TRANSVERSE = 67
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A3_EXTRA_TRANSVERSE A3 Extra Transverse 322 x 445 mm
DMPAPER_A3_EXTRA_TRANSVERSE = 68
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_DBL_JAPANESE_POSTCARD Japanese Double Postcard 200 x 148 mm
DMPAPER_DBL_JAPANESE_POSTCARD = 69
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A6 A6 105 x 148 mm
DMPAPER_A6 = 70
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_KAKU2 Japanese Envelope Kaku #2
DMPAPER_JENV_KAKU2 = 71
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_KAKU3 Japanese Envelope Kaku #3
DMPAPER_JENV_KAKU3 = 72
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_CHOU3 Japanese Envelope Chou #3
DMPAPER_JENV_CHOU3 = 73
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_CHOU4 Japanese Envelope Chou #4
DMPAPER_JENV_CHOU4 = 74
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_LETTER_ROTATED Letter Rotated 11 x 8 1/2 11 in
DMPAPER_LETTER_ROTATED = 75
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A3_ROTATED A3 Rotated 420 x 297 mm
DMPAPER_A3_ROTATED = 76
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A4_ROTATED A4 Rotated 297 x 210 mm
DMPAPER_A4_ROTATED = 77
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A5_ROTATED A5 Rotated 210 x 148 mm
DMPAPER_A5_ROTATED = 78
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B4_JIS_ROTATED B4 (JIS) Rotated 364 x 257 mm
DMPAPER_B4_JIS_ROTATED = 79
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B5_JIS_ROTATED B5 (JIS) Rotated 257 x 182 mm
DMPAPER_B5_JIS_ROTATED = 80
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JAPANESE_POSTCARD_ROTATED Japanese Postcard Rotated 148 x 100 mm
DMPAPER_JAPANESE_POSTCARD_ROTATED = 81
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED Double Japanese Postcard Rotated 148 x 200 mm
DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED = 82
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_A6_ROTATED A6 Rotated 148 x 105 mm
DMPAPER_A6_ROTATED = 83
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_KAKU2_ROTATED Japanese Envelope Kaku #2 Rotated
DMPAPER_JENV_KAKU2_ROTATED = 84
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_KAKU3_ROTATED Japanese Envelope Kaku #3 Rotated
DMPAPER_JENV_KAKU3_ROTATED = 85
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_CHOU3_ROTATED Japanese Envelope Chou #3 Rotated
DMPAPER_JENV_CHOU3_ROTATED = 86
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_CHOU4_ROTATED Japanese Envelope Chou #4 Rotated
DMPAPER_JENV_CHOU4_ROTATED = 87
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B6_JIS B6 (JIS) 128 x 182 mm
DMPAPER_B6_JIS = 88
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_B6_JIS_ROTATED B6 (JIS) Rotated 182 x 128 mm
DMPAPER_B6_JIS_ROTATED = 89
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_12X11 12 x 11 in
DMPAPER_12X11 = 90
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_YOU4 Japanese Envelope You #4
DMPAPER_JENV_YOU4 = 91
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_JENV_YOU4_ROTATED Japanese Envelope You #4 Rotated
DMPAPER_JENV_YOU4_ROTATED = 92
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_P16K PRC 16K 146 x 215 mm
DMPAPER_P16K = 93
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_P32K PRC 32K 97 x 151 mm
DMPAPER_P32K = 94
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_P32KBIG PRC 32K(Big) 97 x 151 mm
DMPAPER_P32KBIG = 95
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_1 PRC Envelope #1 102 x 165 mm
DMPAPER_PENV_1 = 96
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_2 PRC Envelope #2 102 x 176 mm
DMPAPER_PENV_2 = 97
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_3 PRC Envelope #3 125 x 176 mm
DMPAPER_PENV_3 = 98
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_4 PRC Envelope #4 110 x 208 mm
DMPAPER_PENV_4 = 99
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_5 PRC Envelope #5 110 x 220 mm
DMPAPER_PENV_5 = 100
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_6 PRC Envelope #6 120 x 230 mm
DMPAPER_PENV_6 = 101
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_7 PRC Envelope #7 160 x 230 mm
DMPAPER_PENV_7 = 102
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_8 PRC Envelope #8 120 x 309 mm
DMPAPER_PENV_8 = 103
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_9 PRC Envelope #9 229 x 324 mm
DMPAPER_PENV_9 = 104
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_10 PRC Envelope #10 324 x 458 mm
DMPAPER_PENV_10 = 105
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_P16K_ROTATED PRC 16K Rotated
DMPAPER_P16K_ROTATED = 106
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_P32K_ROTATED PRC 32K Rotated
DMPAPER_P32K_ROTATED = 107
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_P32KBIG_ROTATED PRC 32K(Big) Rotated
DMPAPER_P32KBIG_ROTATED = 108
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_1_ROTATED PRC Envelope #1 Rotated 165 x 102 mm
DMPAPER_PENV_1_ROTATED = 109
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_2_ROTATED PRC Envelope #2 Rotated 176 x 102 mm
DMPAPER_PENV_2_ROTATED = 110
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_3_ROTATED PRC Envelope #3 Rotated 176 x 125 mm
DMPAPER_PENV_3_ROTATED = 111
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_4_ROTATED PRC Envelope #4 Rotated 208 x 110 mm
DMPAPER_PENV_4_ROTATED = 112
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_5_ROTATED PRC Envelope #5 Rotated 220 x 110 mm
DMPAPER_PENV_5_ROTATED = 113
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_6_ROTATED PRC Envelope #6 Rotated 230 x 120 mm
DMPAPER_PENV_6_ROTATED = 114
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_7_ROTATED PRC Envelope #7 Rotated 230 x 160 mm
DMPAPER_PENV_7_ROTATED = 115
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_8_ROTATED PRC Envelope #8 Rotated 309 x 120 mm
DMPAPER_PENV_8_ROTATED = 116
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_9_ROTATED PRC Envelope #9 Rotated 324 x 229 mm
DMPAPER_PENV_9_ROTATED = 117
' ##ENUMERATION_MEMBER_DESCRIPTION DMPAPER_PENV_10_ROTATED PRC Envelope #10 Rotated 458 x 324 mm
DMPAPER_PENV_10_ROTATED = 118
End Enum

Or it can be >= 256 in which case it is an unknown paper size and the dimensions are in dmPaperLength and dmPaperWidth...


'--8<------------------------
Ex Datis:
Duncan Jones
Merrion Computing Ltd
GeneralRe: How to get Paper Size info from each Print Job? Pin
Member 188602523-May-05 17:13
Member 188602523-May-05 17:13 
GeneralRe: How to get Paper Size info from each Print Job? Pin
joprinz12-Mar-06 7:54
joprinz12-Mar-06 7:54 
GeneralProblems With Some Printers Pin
djb7014-Mar-05 5:42
djb7014-Mar-05 5:42 
GeneralRe: Problems With Some Printers Pin
Duncan Edwards Jones14-Mar-05 6:11
professionalDuncan Edwards Jones14-Mar-05 6:11 
GeneralRe: Problems With Some Printers Pin
djb7014-Mar-05 8:57
djb7014-Mar-05 8:57 
GeneralRe: Problems With Some Printers Pin
Duncan Edwards Jones14-Mar-05 22:31
professionalDuncan Edwards Jones14-Mar-05 22:31 
GeneralRe: Problems With Some Printers Pin
djb7015-Mar-05 7:50
djb7015-Mar-05 7:50 
GeneralRe: Problems With Some Printers Pin
Duncan Edwards Jones15-Mar-05 8:14
professionalDuncan Edwards Jones15-Mar-05 8:14 
GeneralRe: Problems With Some Printers Pin
Stephen Morris17-May-05 5:44
Stephen Morris17-May-05 5:44 
GeneralRe: Problems With Some Printers Pin
Duncan Edwards Jones17-May-05 6:05
professionalDuncan Edwards Jones17-May-05 6:05 
GeneralRe: Problems With Some Printers Pin
Stephen Morris17-May-05 7:08
Stephen Morris17-May-05 7:08 
GeneralRe: Problems With Some Printers Pin
The_Mega_ZZTer3-Nov-05 7:10
The_Mega_ZZTer3-Nov-05 7:10 
QuestionHow to get the path of the document? Pin
santy_r2-Mar-05 0:05
santy_r2-Mar-05 0:05 
AnswerRe: How to get the path of the document? Pin
Anonymous2-Mar-05 0:35
Anonymous2-Mar-05 0:35 
GeneralRe: How to get the path of the document? Pin
santy_r2-Mar-05 1:00
santy_r2-Mar-05 1:00 
GeneralRe: How to get the path of the document? Pin
Anonymous2-Mar-05 1:48
Anonymous2-Mar-05 1:48 
GeneralMissing Project Can Anybody Give a Full Version Of This Project Pin
fitpm19-Jan-05 10:00
fitpm19-Jan-05 10:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.