MartyConnelly
martyconnelly at shaw.ca
Mon Feb 13 15:44:00 CST 2006
Some alternate code using winSpool to list status of printer and it's jobs in the queue Option Compare Database Option Explicit Public Declare Function OpenPrinter Lib "winspool.drv" _ Alias "OpenPrinterA" _ (ByVal pPrinterName As String, _ phPrinter As Long, _ pDefault As PRINTER_DEFAULTS) _ As Long Public Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" _ (ByVal hPrinter As Long, _ ByVal Level As Long, _ pPrinter As Byte, _ ByVal cbBuf As Long, _ pcbNeeded As Long) _ As Long Public Declare Function ClosePrinter Lib "winspool.drv" _ (ByVal hPrinter As Long) _ As Long Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, _ Source As Any, _ ByVal Length As Long) Public Declare Function EnumJobs Lib "winspool.drv" Alias "EnumJobsA" _ (ByVal hPrinter As Long, _ ByVal FirstJob As Long, _ ByVal NoJobs As Long, _ ByVal Level As Long, _ pJob As Byte, _ ByVal cdBuf As Long, _ pcbNeeded As Long, _ pcReturned As Long) _ As Long ' constants for PRINTER_DEFAULTS structure Public Const PRINTER_ACCESS_USE = &H8 Public Const PRINTER_ACCESS_ADMINISTER = &H4 ' constants for DEVMODE structure Public Const CCHDEVICENAME = 32 Public Const CCHFORMNAME = 32 Public Type PRINTER_DEFAULTS pDatatype As String pDevMode As Long DesiredAccess As Long End Type Public 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 dmLogPixels As Integer dmBitsPerPel As Long dmPelsWidth As Long dmPelsHeight As Long dmDisplayFlags As Long dmDisplayFrequency As Long End Type Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type Type JOB_INFO_2 JobId As Long pPrinterName As Long pMachineName As Long pUserName As Long pDocument As Long pNotifyName As Long pDatatype As Long pPrintProcessor As Long pParameters As Long pDriverName As Long pDevMode As Long pStatus As Long pSecurityDescriptor As Long Status As Long Priority As Long Position As Long StartTime As Long UntilTime As Long TotalPages As Long Size As Long Submitted As SYSTEMTIME time As Long PagesPrinted As Long End Type Type PRINTER_INFO_2 pServerName As Long pPrinterName As Long pShareName As Long pPortName As Long pDriverName As Long pComment As Long pLocation As Long pDevMode As Long pSepFile As Long pPrintProcessor As Long pDatatype As Long pParameters As Long pSecurityDescriptor As Long Attributes As Long Priority As Long DefaultPriority As Long StartTime As Long UntilTime As Long Status As Long cJobs As Long AveragePPM As Long End Type Public Const ERROR_INSUFFICIENT_BUFFER = 122 Public Const PRINTER_STATUS_BUSY = &H200 Public Const PRINTER_STATUS_DOOR_OPEN = &H400000 Public Const PRINTER_STATUS_ERROR = &H2 Public Const PRINTER_STATUS_INITIALIZING = &H8000 Public Const PRINTER_STATUS_IO_ACTIVE = &H100 Public Const PRINTER_STATUS_MANUAL_FEED = &H20 Public Const PRINTER_STATUS_NO_TONER = &H40000 Public Const PRINTER_STATUS_NOT_AVAILABLE = &H1000 Public Const PRINTER_STATUS_OFFLINE = &H80 Public Const PRINTER_STATUS_OUT_OF_MEMORY = &H200000 Public Const PRINTER_STATUS_OUTPUT_BIN_FULL = &H800 Public Const PRINTER_STATUS_PAGE_PUNT = &H80000 Public Const PRINTER_STATUS_PAPER_JAM = &H8 Public Const PRINTER_STATUS_PAPER_OUT = &H10 Public Const PRINTER_STATUS_PAPER_PROBLEM = &H40 Public Const PRINTER_STATUS_PAUSED = &H1 Public Const PRINTER_STATUS_PENDING_DELETION = &H4 Public Const PRINTER_STATUS_PRINTING = &H400 Public Const PRINTER_STATUS_PROCESSING = &H4000 Public Const PRINTER_STATUS_TONER_LOW = &H20000 Public Const PRINTER_STATUS_USER_INTERVENTION = &H100000 Public Const PRINTER_STATUS_WAITING = &H2000 Public Const PRINTER_STATUS_WARMING_UP = &H10000 Public Const JOB_STATUS_PAUSED = &H1 Public Const JOB_STATUS_ERROR = &H2 Public Const JOB_STATUS_DELETING = &H4 Public Const JOB_STATUS_SPOOLING = &H8 Public Const JOB_STATUS_PRINTING = &H10 Public Const JOB_STATUS_OFFLINE = &H20 Public Const JOB_STATUS_PAPEROUT = &H40 Public Const JOB_STATUS_PRINTED = &H80 Public Const JOB_STATUS_DELETED = &H100 Public Const JOB_STATUS_BLOCKED_DEVQ = &H200 Public Const JOB_STATUS_USER_INTERVENTION = &H400 Public Const JOB_STATUS_RESTART = &H800 Public Function GetString(ByVal PtrStr As Long) As String Dim StrBuff As String * 256 'Check for zero address If PtrStr = 0 Then GetString = " " Exit Function End If 'Copy data from PtrStr to buffer CopyMemory ByVal StrBuff, ByVal PtrStr, 64 'Strp any trailing nulls from sting GetString = StripNulls(StrBuff) End Function Public Function StripNulls(OriginalStr As String) As String 'Strip any trailing nulls from input string If (InStr(OriginalStr, Chr(0)) > 0) Then OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1) End If 'Return modified string StripNulls = OriginalStr End Function Public Function PtrCtoVbString(Add As Long) As String Dim sTemp As String * 512, x As Long x = lstrcpy(sTemp, Add) If (InStr(1, sTemp, Chr(0)) = 0) Then PtrCtoVbString = "" Else PtrCtoVbString = Left(sTemp, InStr(1, sTemp, Chr(0)) - 1) End If End Function 'Amyuni PDF Converter 'HP Deskjet 3840 Series 'CheckPrinter("Amyuni PDF Converter","01") Public Function CheckPrinter(PrinterStr As String, JobStr As String) As String Dim hPrinter As Long Dim ByteBuf As Long, BytesNeeded As Long Dim PI2 As PRINTER_INFO_2 Dim JI2 As JOB_INFO_2 Dim PrinterInfo() As Byte Dim JobInfo() As Byte Dim result As Long, LastError As Long Dim PrinterName As String, tempStr As String Dim NumJI2 As Long Dim pDefaults As PRINTER_DEFAULTS Dim I As Integer 'Set a default return value if no errors occur CheckPrinter = "Printer info retrieved" 'NOTE: You can pick a printer from the Printers Collection 'or use the EnumPrinters() API to select a printer name. 'Use the default printer of Printers collection PrinterName = Printer.DeviceName ' or from parameter above PrinterName = PrinterStr 'Set desired access security setting pDefaults.DesiredAccess = PRINTER_ACCESS_USE 'Call API to get a handle to the printer result = OpenPrinter(PrinterName, hPrinter, pDefaults) If result = 0 Then 'If an error occured, display an error and exit sub CheckPrinter = "Cannot open printer " & PrinterName & _ ", Error: " & Err.LastDllError Exit Function End If 'Init BytesNeeded BytesNeeded = 0 'Clear the error object of any errors Err.Clear 'Determine the buffer size needed to get printer info result = GetPrinter(hPrinter, 2, 0&, 0&, BytesNeeded) 'Check for error calling GetPrinter If Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER Then 'Display an error message, close printer, and exit sub CheckPrinter = " > GetPrinter Failed on initial call! <" ClosePrinter hPrinter Exit Function End If 'Due to a problem with GetPrinter on Windows 95, we must allocate 'a buffer as much as 3 times larger than the value returned by the 'initial call to GetPrinter. See page 790 of Charles Petzold's 'book "Programming Windows 95" for additional information. ReDim PrinterInfo(1 To BytesNeeded * 3) ByteBuf = BytesNeeded 'Call GetPrinter to get the status result = GetPrinter(hPrinter, 2, PrinterInfo(1), ByteBuf, _ BytesNeeded * 3) 'Check for errors If result = 0 Then 'Determine the error that occured LastError = Err.LastDllError() 'Display error message, close printer, and exit sub CheckPrinter = "Couldn't get Printer Status! Error = " _ & LastError ClosePrinter hPrinter Exit Function End If 'Copy contents of printer status byte array into a 'PRINTER_INFO_2 structure to separate the individual elements CopyMemory PI2, PrinterInfo(1), Len(PI2) 'Check if printer is in ready state If PI2.Status = 0 Then PrinterStr = "Printer Status = Ready" & vbCrLf Else tempStr = "" ' Clear If (PI2.Status And PRINTER_STATUS_BUSY) Then tempStr = tempStr & "Busy " End If If (PI2.Status And PRINTER_STATUS_DOOR_OPEN) Then tempStr = tempStr & "Printer Door Open " End If If (PI2.Status And PRINTER_STATUS_ERROR) Then tempStr = tempStr & "Printer Error " End If If (PI2.Status And PRINTER_STATUS_INITIALIZING) Then tempStr = tempStr & "Initializing " End If If (PI2.Status And PRINTER_STATUS_IO_ACTIVE) Then tempStr = tempStr & "I/O Active " End If If (PI2.Status And PRINTER_STATUS_MANUAL_FEED) Then tempStr = tempStr & "Manual Feed " End If If (PI2.Status And PRINTER_STATUS_NO_TONER) Then tempStr = tempStr & "No Toner " End If If (PI2.Status And PRINTER_STATUS_NOT_AVAILABLE) Then tempStr = tempStr & "Not Available " End If If (PI2.Status And PRINTER_STATUS_OFFLINE) Then tempStr = tempStr & "Off Line " End If If (PI2.Status And PRINTER_STATUS_OUT_OF_MEMORY) Then tempStr = tempStr & "Out of Memory " End If If (PI2.Status And PRINTER_STATUS_OUTPUT_BIN_FULL) Then tempStr = tempStr & "Output Bin Full " End If If (PI2.Status And PRINTER_STATUS_PAGE_PUNT) Then tempStr = tempStr & "Page Punt " End If If (PI2.Status And PRINTER_STATUS_PAPER_JAM) Then tempStr = tempStr & "Paper Jam " End If If (PI2.Status And PRINTER_STATUS_PAPER_OUT) Then tempStr = tempStr & "Paper Out " End If If (PI2.Status And PRINTER_STATUS_OUTPUT_BIN_FULL) Then tempStr = tempStr & "Output Bin Full " End If If (PI2.Status And PRINTER_STATUS_PAPER_PROBLEM) Then tempStr = tempStr & "Page Problem " End If If (PI2.Status And PRINTER_STATUS_PAUSED) Then tempStr = tempStr & "Paused " End If If (PI2.Status And PRINTER_STATUS_PENDING_DELETION) Then tempStr = tempStr & "Pending Deletion " End If If (PI2.Status And PRINTER_STATUS_PRINTING) Then tempStr = tempStr & "Printing " End If If (PI2.Status And PRINTER_STATUS_PROCESSING) Then tempStr = tempStr & "Processing " End If If (PI2.Status And PRINTER_STATUS_TONER_LOW) Then tempStr = tempStr & "Toner Low " End If If (PI2.Status And PRINTER_STATUS_USER_INTERVENTION) Then tempStr = tempStr & "User Intervention " End If If (PI2.Status And PRINTER_STATUS_WAITING) Then tempStr = tempStr & "Waiting " End If If (PI2.Status And PRINTER_STATUS_WARMING_UP) Then tempStr = tempStr & "Warming Up " End If If Len(tempStr) = 0 Then tempStr = "Unknown Status of " & PI2.Status End If PrinterStr = "Printer Status = " & tempStr & vbCrLf End If 'Add printer name, driver, and port to list PrinterStr = PrinterStr & "Printer Name = " & _ GetString(PI2.pPrinterName) & vbCrLf PrinterStr = PrinterStr & "Printer Driver Name = " & _ GetString(PI2.pDriverName) & vbCrLf PrinterStr = PrinterStr & "Printer Port Name = " & _ GetString(PI2.pPortName) & vbCrLf 'Call API to get size of buffer needed result = EnumJobs(hPrinter, 0&, &HFFFFFFFF, 2, ByVal 0&, 0&, _ BytesNeeded, NumJI2) 'Check if there are no current jobs and display appropriate message If BytesNeeded = 0 Then JobStr = "No Print Jobs!" Else 'Redim byte array to hold info about print job ReDim JobInfo(0 To BytesNeeded * 3) 'Call API to get print job info result = EnumJobs(hPrinter, 0&, &HFFFFFFFF, 2, JobInfo(0), _ BytesNeeded * 3, ByteBuf, NumJI2) 'Check for errors If result = 0 Then 'Get and display error, close printer, and exit sub LastError = Err.LastDllError CheckPrinter = " > EnumJobs Failed on second call! < Error = " _ & LastError ClosePrinter hPrinter Exit Function End If 'Copy contents of print job info byte array into a 'JOB_INFO_2 structure to separate the individual elements For I = 0 To NumJI2 - 1 ' Loop through jobs and walk the buffer CopyMemory JI2, JobInfo(I * Len(JI2)), Len(JI2) ' List info available on Jobs Debug.Print "Job ID" & vbTab & JI2.JobId Debug.Print "Name Of Printer" & vbTab & _ GetString(JI2.pPrinterName) Debug.Print "Name Of Machine That Created Job" & vbTab & _ GetString(JI2.pMachineName) Debug.Print "Print Job Owner's Name" & vbTab & _ GetString(JI2.pUserName) Debug.Print "Name Of Document" & vbTab & GetString(JI2.pDocument) Debug.Print "Name Of User To Notify" & vbTab & _ GetString(JI2.pNotifyName) Debug.Print "Type Of Data" & vbTab & GetString(JI2.pDatatype) Debug.Print "Print Processor" & vbTab & _ GetString(JI2.pPrintProcessor) Debug.Print "Print Processor Parameters" & vbTab & _ GetString(JI2.pParameters) Debug.Print "Print Driver Name" & vbTab & _ GetString(JI2.pDriverName) Debug.Print "Print Job 'P' Status" & vbTab & _ GetString(JI2.pStatus) Debug.Print "Print Job Status" & vbTab & JI2.Status Debug.Print "Print Job Priority" & vbTab & JI2.Priority Debug.Print "Position in Queue" & vbTab & JI2.Position Debug.Print "Earliest Time Job Can Be Printed" & vbTab & _ JI2.StartTime Debug.Print "Latest Time Job Will Be Printed" & vbTab & _ JI2.UntilTime Debug.Print "Total Pages For Entire Job" & vbTab & JI2.TotalPages Debug.Print "Size of Job In Bytes" & vbTab & JI2.Size 'Due to a bug since NT 3.51, the time member is not set correctly 'so don't use it on NT 3.51. Debug.Print "Elapsed Print Time" & vbTab & JI2.time Debug.Print "Pages Printed So Far" & vbTab & JI2.PagesPrinted 'Display basic job status info JobStr = JobStr & "Job ID = " & JI2.JobId & _ vbCrLf & "Total Pages = " & JI2.TotalPages & vbCrLf tempStr = "" 'Clear 'Check for a ready state If JI2.pStatus = 0& Then ' If pStatus is Null, check Status If JI2.Status = 0 Then tempStr = tempStr & "Ready! " & vbCrLf Else 'Check for the various print job states If (JI2.Status And JOB_STATUS_SPOOLING) Then tempStr = tempStr & "Spooling " End If If (JI2.Status And JOB_STATUS_OFFLINE) Then tempStr = tempStr & "Off line " End If If (JI2.Status And JOB_STATUS_PAUSED) Then tempStr = tempStr & "Paused " End If If (JI2.Status And JOB_STATUS_ERROR) Then tempStr = tempStr & "Error " End If If (JI2.Status And JOB_STATUS_PAPEROUT) Then tempStr = tempStr & "Paper Out " End If If (JI2.Status And JOB_STATUS_PRINTING) Then tempStr = tempStr & "Printing " End If If (JI2.Status And JOB_STATUS_USER_INTERVENTION) Then tempStr = tempStr & "User Intervention Needed " End If If Len(tempStr) = 0 Then tempStr = "Unknown Status of " & JI2.Status End If End If Else ' Dereference pStatus tempStr = PtrCtoVbString(JI2.pStatus) End If 'Report the Job status JobStr = JobStr & tempStr & vbCrLf Debug.Print JobStr & tempStr Next I End If 'Close the printer handle ClosePrinter hPrinter End Function Johncliviger at aol.com wrote: >Hi all >I'm printing documents from AXP using cmd_Onclick to drive a report and all >is fine. That is until the printer elsewhere in the building cocks it up and >we need a re-print. How can I know sat at my AXP workstation that the document >has fails to print? > >TIA > >john c > > -- Marty Connelly Victoria, B.C. Canada