CÓMO: Determinar el estado de la impresora y del trabajo de impresión desde Visual Basic

Resumen

En este artículo se describe cómo utilizar las funciones de la interfaz de programación de aplicaciones (API) de Windows en Visual Basic para determinar mediante programación el estado de la impresora o de los trabajos de impresión. Aunque una aplicación normalmente no tiene que comprobar el estado de una impresora antes de imprimir, puede ser útil determinar mediante programación el estado de una impresora o de un trabajo de impresión.

Descripción de la técnica

El término "impresora" puede hacer referencia a un dispositivo de hardware, una cola, un controlador o incluso un puerto. En este artículo, el término "impresora" se define como una cola de impresión local. El ejemplo de código de este artículo devuelve los estados que el sistema operativo notifica. Éste es el mismo estado que el administrador de trabajos de impresión notifica, que puede comprobar observando la cola de impresión local.

Por ejemplo, para ver la cola en un equipo que ejecuta Microsoft Windows 98, haga clic en Inicio, seleccione Configuración, haga clic en Impresoras y, a continuación, haga doble clic en el icono de la impresora cuya cola desee ver.

NOTA: no puede comunicarse directamente con la impresora física. No debería tener que hacerlo porque el sistema operativo debe arbitrar el acceso al hardware.

El código de ejemplo de este artículo examina la cola de impresión local, que obtiene información del monitor del puerto, que a su vez se comunica con el dispositivo físico. Para obtener una descripción más detallada de cómo funciona esto, consulte los artículos que se enumeran en la sección "Referencias" de este artículo.

Este ejemplo notifica el estado de la impresora y de los trabajos, pero observe que la información del estado de los trabajos es generalmente más confiable para las aplicaciones. En teoría, debería examinar los estados de la impresora y de los trabajos por separado, y el código debería deducir el estado "meta" de la cola. Sin embargo, en la mayor parte de las ocasiones, el código puede confiar en los estados de los trabajos. Además, este ejemplo recorre los trabajos y comprueba y notifica el estado de cada uno. Esto se debe a que un trabajo puede seguir a otro que notifique un problema, por ejemplo, que se ha quedado sin papel o se ha bloqueado.

NOTA: el sistema sólo comprueba el estado cuando tiene un trabajo que poner en cola. De lo contrario, la cola se considera "preparada" porque puede aceptar trabajos, aun cuando el hardware esté en estado de error. Por ejemplo, si el último trabajo que se imprimió usó la última página de papel, el sistema operativo no lo sabe hasta que el sistema intente imprimir de nuevo.

Además, aunque hay muchos estados que se pueden notificar, muchos no se admiten en la práctica. El hardware de la impresora y el monitor del puerto determinan qué estados notificar. Por ejemplo, si la impresora se ha quedado sin papel y está apagada, el estado puede notificarse como "Imprimiendo" porque eso es lo que el trabajo está intentando hacer. Por consiguiente, una cola que indique "Preparada" no garantiza que el trabajo de impresión se vaya a completar correctamente.

Este ejemplo de código examina sólo la cola local, lo que debería bastar para la mayoría de las aplicaciones. Sin embargo, conectarse a impresoras remotas puede llegar a ser bastante complejo. Puede haber colas encadenadas, en las que el puerto de la cola local esté realmente en otra cola. Puede tener colas de impresión, en las que varias impresoras trabajan desde una súper cola común. Cuando la arquitectura se vuelve más compleja, el código para recuperar un estado significativo también se complica y se reduce la utilidad del estado.

Sólo en Microsoft Windows 95, Microsoft Windows 98 y Microsoft Windows Millennium Edition puede examinar también el campo PrinterInfo.Attributes y consultar el bit PRINTER_ATTRIBUTE_WORK_OFFLINE. Este estado normalmente se produce debido a la acción del usuario (por ejemplo, si el usuario hace clic con el botón secundario del mouse en un icono de impresora y, a continuación, hace clic en Trabajar sin conexión). Este estado no se debe al cambio de estado de un trabajo de impresión, aunque el sistema operativo puede forzar el estado si la impresora no se puede conectar para sacar de la cola un trabajo. En ese caso, el estado que se notifica suele ser USER_INERVENTION_REQUIRED.

Ejemplo paso a paso:

  1. Cree un nuevo proyecto estándar EXE en Visual Basic. Se creará Form1 de forma predeterminada.
  2. En el menú Proyecto, haga clic en Agregar módulo y, a continuación, agregue el código siguiente:
    Option Explicit

    Public Declare Function lstrcpy Lib "kernel32" _
    Alias "lstrcpyA" _
    (ByVal lpString1 As String, _
    ByVal lpString2 As String) _
    As Long

    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, 256

    'Strip any trailing nulls from string.
    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
    Dim 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

    Public Function CheckPrinterStatus(PI2Status As Long) As String
    Dim tempStr As String

    If PI2Status = 0 Then ' Return "Ready"
    CheckPrinterStatus = "Printer Status = Ready" & vbCrLf
    Else
    tempStr = "" ' Clear
    If (PI2Status And PRINTER_STATUS_BUSY) Then
    tempStr = tempStr & "Busy "
    End If

    If (PI2Status And PRINTER_STATUS_DOOR_OPEN) Then
    tempStr = tempStr & "Printer Door Open "
    End If

    If (PI2Status And PRINTER_STATUS_ERROR) Then
    tempStr = tempStr & "Printer Error "
    End If

    If (PI2Status And PRINTER_STATUS_INITIALIZING) Then
    tempStr = tempStr & "Initializing "
    End If

    If (PI2Status And PRINTER_STATUS_IO_ACTIVE) Then
    tempStr = tempStr & "I/O Active "
    End If

    If (PI2Status And PRINTER_STATUS_MANUAL_FEED) Then
    tempStr = tempStr & "Manual Feed "
    End If

    If (PI2Status And PRINTER_STATUS_NO_TONER) Then
    tempStr = tempStr & "No Toner "
    End If

    If (PI2Status And PRINTER_STATUS_NOT_AVAILABLE) Then
    tempStr = tempStr & "Not Available "
    End If

    If (PI2Status And PRINTER_STATUS_OFFLINE) Then
    tempStr = tempStr & "Off Line "
    End If

    If (PI2Status And PRINTER_STATUS_OUT_OF_MEMORY) Then
    tempStr = tempStr & "Out of Memory "
    End If

    If (PI2Status And PRINTER_STATUS_OUTPUT_BIN_FULL) Then
    tempStr = tempStr & "Output Bin Full "
    End If

    If (PI2Status And PRINTER_STATUS_PAGE_PUNT) Then
    tempStr = tempStr & "Page Punt "
    End If

    If (PI2Status And PRINTER_STATUS_PAPER_JAM) Then
    tempStr = tempStr & "Paper Jam "
    End If

    If (PI2Status And PRINTER_STATUS_PAPER_OUT) Then
    tempStr = tempStr & "Paper Out "
    End If

    If (PI2Status And PRINTER_STATUS_OUTPUT_BIN_FULL) Then
    tempStr = tempStr & "Output Bin Full "
    End If

    If (PI2Status And PRINTER_STATUS_PAPER_PROBLEM) Then
    tempStr = tempStr & "Page Problem "
    End If

    If (PI2Status And PRINTER_STATUS_PAUSED) Then
    tempStr = tempStr & "Paused "
    End If

    If (PI2Status And PRINTER_STATUS_PENDING_DELETION) Then
    tempStr = tempStr & "Pending Deletion "
    End If

    If (PI2Status And PRINTER_STATUS_PRINTING) Then
    tempStr = tempStr & "Printing "
    End If

    If (PI2Status And PRINTER_STATUS_PROCESSING) Then
    tempStr = tempStr & "Processing "
    End If

    If (PI2Status And PRINTER_STATUS_TONER_LOW) Then
    tempStr = tempStr & "Toner Low "
    End If

    If (PI2Status And PRINTER_STATUS_USER_INTERVENTION) Then
    tempStr = tempStr & "User Intervention "
    End If

    If (PI2Status And PRINTER_STATUS_WAITING) Then
    tempStr = tempStr & "Waiting "
    End If

    If (PI2Status And PRINTER_STATUS_WARMING_UP) Then
    tempStr = tempStr & "Warming Up "
    End If

    'Did you find a known status?
    If Len(tempStr) = 0 Then
    tempStr = "Unknown Status of " & PI2Status
    End If

    'Return the Status
    CheckPrinterStatus = "Printer Status = " & tempStr & vbCrLf
    End If
    End Function
  3. Agregue tres controles CommandButton.
  4. Agregue tres controles TextBox a Form1 y, a continuación, configure los controles TextBox como sigue:
    1. Establezca la propiedad MultiLine de cada control TextBox en True.
    2. Establezca el tamaño de cada control TextBox aproximadamente en 12 cm de ancho y 7 de largo.
    3. Establezca la propiedad ScrollBars de cada control TextBox en 2 - Vertical.
  5. Agregue un control Timer a Form1.
  6. Agregue el código siguiente al módulo del formulario:
    Option Explicit

    Private Sub Command1_Click()
    'Enable the timer to begin printer status checks.
    Timer1.Enabled = True

    'Enable and disable start and stop buttons.
    Command1.Enabled = False
    Command2.Enabled = True
    Command3.Enabled = True
    End Sub

    Private Sub Command2_Click()
    'Disable timer to stop further printer checks.
    Timer1.Enabled = False

    'Enable and disable start and stop buttons.
    Command1.Enabled = True
    Command2.Enabled = False
    Command3.Enabled = True
    End Sub

    Private Sub Command3_Click()
    'Clear the status info.
    Text1.Text = ""
    Text2.Text = ""
    Text3.Text = ""
    End Sub

    Private Sub Form_Load()
    'Initialize captions for control buttons.
    Command1.Caption = "Start"
    Command2.Caption = "Stop"
    Command3.Caption = "Clear"

    'Clear the status info.
    Text1.Text = ""
    Text2.Text = ""
    Text3.Text = ""

    Command1.Enabled = True
    'Disable stop and clear buttons.
    Command2.Enabled = False
    Command3.Enabled = False

    'Set interval for printer status checking to 1/2 second.
    Timer1.Enabled = False
    Timer1.Interval = 500
    End Sub

    Private Sub Timer1_Timer()
    Dim PrinterStatus As String
    Dim JobStatus As String
    Dim ErrorInfo As String

    'Clear the status info for new info/status.
    Text1.Text = ""
    Text2.Text = ""
    Text3.Text = ""

    'Call sub to perform check.
    Text1.Text = CheckPrinter(PrinterStatus, JobStatus)
    Text2.Text = PrinterStatus
    Text3.Text = JobStatus
    End Sub

    Public Function CheckPrinter(PrinterStr As String, JobStr As String) As String
    Dim hPrinter As Long
    Dim ByteBuf As Long
    Dim 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
    Dim LastError As Long
    Dim PrinterName As String
    Dim 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.
    'This is typically, but not always, the system default printer.
    PrinterName = Printer.DeviceName

    '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 occurred, 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 that is 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

    'Note that in Charles Petzold's book "Programming Windows 95," he
    'states that because of a problem with GetPrinter on Windows 95 only, you
    'must allocate a buffer as much as three times larger than the value
    'returned by the initial call to GetPrinter. This is not done here.
    ReDim PrinterInfo(1 To BytesNeeded)

    ByteBuf = BytesNeeded

    'Call GetPrinter to get the status.
    result = GetPrinter(hPrinter, 2, PrinterInfo(1), ByteBuf, _
    BytesNeeded)

    'Check for errors.
    If result = 0 Then
    'Determine the error that occurred.
    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.
    PrinterStr = CheckPrinterStatus(PI2.Status)

    '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 that is needed.
    result = EnumJobs(hPrinter, 0&, &HFFFFFFFF, 2, ByVal 0&, 0&, _
    BytesNeeded, NumJI2)

    'Check if there are no current jobs, and then 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)

    'Call API to get print job info.
    result = EnumJobs(hPrinter, 0&, &HFFFFFFFF, 2, JobInfo(0), _
    BytesNeeded, 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
    'Because of a bug in Windows NT 3.51, the time member is not set correctly.
    'Therefore, do not use the time member on Windows 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
  7. Vaya a la cola de impresión y, a continuación, pause la impresora. Tenga en cuenta que puede que necesite una impresora local en lugar de una impresora de red para pausar la cola de impresión.
  8. Ejecute el proyecto de ejemplo y, a continuación, haga clic en Iniciar.
  9. Realice una o varias operaciones de impresión desde otra aplicación, por ejemplo, desde el Bloc de notas. La información de la impresora se muestra en los cuadros de texto. Observe que los detalles del trabajo aparecen en la ventana Inmediata.
  10. Si es necesario, haga clic en Detener en el formulario para desplazarse a través de los cuadros de texto y la ventana Inmediata, y ver la información de esta impresora.

Solucionar problemas

  • Sólo un control de dispositivo concreto puede obtener información de estado de la impresora precisa en tiempo real. Este código obtiene el mismo estado que el Administrador de trabajos de impresión de Windows notifica.
  • El estado exacto que se notifica puede variar con las diferentes impresoras y controladores.

Referencias

Para obtener información adicional sobre cómo se establecen el estado de la impresora y de los trabajos de impresión, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

160129 CÓMO: Obtener el estado de una impresora y un trabajo de impresión
Para obtener información adicional acerca de cómo utilizar la función de la API EnumPrinters, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

166008 ACC: Enumerar las impresoras locales y de red
Para obtener información adicional sobre cómo recuperar información del trabajo de impresión en Microsoft Visual C++, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:

228769 CÓMO: Recuperar información del trabajo de impresión
158828 Cómo llamar adecuadamente a las API de enumeración de Win32 Spooler
Propiedades

Id. de artículo: 202480 - Última revisión: 27 dic. 2007 - Revisión: 1

Comentarios