Link to home
Start Free TrialLog in
Avatar of Eric Sherman
Eric ShermanFlag for United States of America

asked on

Detect Windows Printer Status Using Visual Basic

I have an Access 2k / VB application that loops through a list of customers and prints to WinFax Fax Driver (basically another printer). I am looking for some VB code that can basically check the status of this printer and if Spooling or Printing then suspend the VB application until finished.  There should only be one print job in the print que.  Once finished, the VB application will send the next print job until it cycles through the entire recordset based on customer number.

Kind of like ...  

While WinFax Printer Status = "Spooling" OR WinFax Printer Status = "Printing"
  Do Somtheing
Wend

Any help will be appreciated.

Thanks,

ET
ASKER CERTIFIED SOLUTION
Avatar of JesterToo
JesterToo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Eric Sherman

ASKER

Thanks Jester for the responses.  Looks like the GetPrinter API should be able to accomplish what I am trying to do.  I reviewed the link you provided and I'm not that familiar with the GetPrinter API so I need a little help to get started.

I have a printer named "WinFax (Photo Quality)".   All I need to find out is if the JobsCount for this printer is greater than 1 then I will supspend the application running in VB.  In other words ...

While "WinFax (Photo Quality)" JobsCount > 1 Then
  Do Something
Wend

I need help with the structure of the code to reference the GetPrinter API in order to read the JobsCount for the printer.
I will probably have the declare the following fuction but where/how do you reference the printer you are trying to get the JobsCount for???


Private Declare Function GetPrinterApi Lib "winspool.drv" Alias _
       "GetPrinterA" (ByVal hPrinter As Long, _
         ByVal Level As Long, _
         buffer As Long, _
         ByVal pbSize As Long, _
         pbSizeNeeded As Long) As Long

Private Type PRINTER_INFO_2
   JobsCount As Long


Thanks,

ET


Ok, I searched around and put this together from a couple of other posts.  This seems to work and it find out how many print jobs are in the printer que.  I have a question if anyone can answer, please.  In the Function below HowMany() the following code is included and I'm not sure how to understand what it's doing.

    If pcbNeed > 0 Then
        ReDim pJob(pcbNeed - 1)
        retval = EnumJobs(hPrinter, 0, 99, 1, pJob(0), pcbNeed, pcbNeed, pcRet)
    End If

When I tested the contents of the variables it would look something like this ... I'm not sure how the ReDim pJob got to 66.

    If 176 > 0 Then
        ReDim pJob(176 - 1)
        retval = EnumJobs(155667028, 0, 99, 1, 66, 176, 176, 1)
    End If


Public Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" _
    (ByVal pPrinterName As String, phPrinter As Long, pDefault As Any) 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 Any, ByVal cdBuf As Long, _
    pcbNeed As Long, pcReturned As Long) As Long

Public Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long

'Function
Function HowMany()
Dim hPrinter As Long
Dim pcbNeed As Long, pcRet As Long
Dim pJob() As Byte
Dim lngJobsCount As Long
Dim retval As Long
Dim strPrinter As String

    'Set your printer name here
    strPrinter = "WinFax (photo quality)"
   
    retval = OpenPrinter(strPrinter, hPrinter, ByVal vbNullString)
   
    retval = EnumJobs(hPrinter, 0, 99, 1, ByVal vbNullString, 0, pcbNeed, pcRet)
   
    If pcbNeed > 0 Then
        ReDim pJob(pcbNeed - 1)
        retval = EnumJobs(hPrinter, 0, 99, 1, pJob(0), pcbNeed, pcbNeed, pcRet)
    End If
   
    retval = ClosePrinter(hPrinter)
   
    HowMany = pcRet
    MsgBox pcbNeed - 1
End Function