FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour ¿Verificar el estado de la impresora?
Posts: 8523
Joined: Tue Dec 20, 2005 07:36 PM

¿Verificar el estado de la impresora?

Posted: Mon Mar 23, 2026 05:49 PM

Buenas tardes, ¿es correcta esta lógica para comprobar el ESTADO de la impresora predeterminada?

// C:\FWH\SAMPLES\PRNATIVA.PRG

#include "fivewin.ch"

STATIC oWnd, oPrn

FUNCTION Main()

   DEFINE WINDOW oWnd FROM 1, 1 TO 20, 60 TITLE "Printing a Window"

   @ 3, 3 BUTTON "&Print me" OF oWnd SIZE 80, 20 ;
      ACTION IMPR_ATIVA()

   ACTIVATE WINDOW oWnd

RETURN NIL

FUNCTION IMPR_ATIVA()

   PRINT oPrn NAME "Teste"

  IF oPrn:hDC == 0

      MsgStop("Impressora desligada ou não encontrada!")

      RETURN NIL

  ELSEIF oPrn:hDC == 4

      MsgStop("Impressora em Estado de Imprimindo!")

      RETURN NIL

  ELSEIF oPrn:hDC == 3

      MsgStop("Impressora em Estado de IDLE!")

      RETURN NIL

  ELSEIF oPrn:hDC == 2

      MsgStop("Impressora em Estado Desconhecido!")

      RETURN NIL

  ELSEIF oPrn:hDC == 1

      MsgStop("Impressora em Estado de Out Of Paper!")

      RETURN NIL

  ENDIF

  PAGE

     oWnd:Print( oPrn, 1, 1, 2 ) // Scale factor 2

  ENDPAGE

   ENDPRINT

RETURN NIL

// FIN / END - kapiabafwh@gmail.com

Gracias, tks.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM

Re: ¿Verificar el estado de la impresora?

Posted: Mon Mar 23, 2026 07:16 PM

Estimado Joao,

No, la lógica no es correcta. Hay varios problemas:

  1. oPrn:hDC no es un código de estado de impresora

    hDC es el Device Context handle de Windows. Después de PRINT oPrn, su valor será:

  2. 0 → falló la creación (impresora no disponible)

  3. Un número grande (ej. 0xA10045B2) → handle válido, la impresora está lista

    Nunca será 1, 2, 3 o 4 como códigos de estado. Esas comparaciones nunca se cumplirán.

  4. La estructura PRINT...ENDPRINT está rota

    PAGE/ENDPAGE queda fuera del flujo cuando haces RETURN NIL dentro del bloque PRINT...ENDPRINT. Si hDC != 0, el código
    nunca llega a PAGE porque siempre entra en algún ELSEIF.

    Versión corregida (simple):

  FUNCTION IMPR_ATIVA()

 PRINT oPrn NAME "Teste"

    IF oPrn:hDC == 0
       MsgStop( "Impressora desligada ou não encontrada!" )
       RETURN NIL
    ENDIF

    PAGE
       oWnd:Print( oPrn, 1, 1, 2 )
    ENDPAGE

 ENDPRINT

  RETURN NIL

Si necesitas el estado real de la impresora, usa la API de Windows GetPrinter() o en FiveWin:

  FUNCTION IMPR_ATIVA()
     LOCAL cPrinter := GetDefaultPrinter()
     LOCAL nStatus  := GetPrinterStatus( cPrinter )  // necesitas implementar via API

 // Los códigos reales de Windows (PRINTER_STATUS_*) son:
 // PRINTER_STATUS_PAUSED       := 0x00000001
 // PRINTER_STATUS_ERROR        := 0x00000002
 // PRINTER_STATUS_PAPER_OUT    := 0x00000010
 // PRINTER_STATUS_OFFLINE      := 0x00000080
 // PRINTER_STATUS_PRINTING     := 0x00000400

 IF nStatus == 0
    // Status OK, imprimir
    PRINT oPrn NAME "Teste"
       PAGE
          oWnd:Print( oPrn, 1, 1, 2 )
       ENDPAGE
    ENDPRINT
 ELSE
    MsgStop( "Impressora com problema! Status: " + Str(nStatus) )
 ENDIF

  RETURN NIL

Resumen: Para una verificación básica, basta comprobar oPrn:hDC == 0 (fallo) vs. distinto de cero (OK). Los valores
1-4 como estado de impresora no tienen relación con hDC.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 8523
Joined: Tue Dec 20, 2005 07:36 PM

Re: ¿Verificar el estado de la impresora?

Posted: Mon Mar 23, 2026 08:41 PM

Querido Maestro, este ejemplo está correcto?

// C:\FWH\SAMPLES\PRNATIVA.PRG

#Include "FiveWin.ch"

#define PRINTER_STATUS_OK                       0
#define PRINTER_STATUS_PAUSED                   1
#define PRINTER_STATUS_ERROR                    2
#define PRINTER_STATUS_PENDING_DELETION         4
#define PRINTER_STATUS_PAPER_JAM                8
#define PRINTER_STATUS_PAPER_OUT               16
#define PRINTER_STATUS_MANUAL_FEED             32
#define PRINTER_STATUS_PAPER_PROBLEM           64
#define PRINTER_STATUS_OFFLINE                128
#define PRINTER_STATUS_IO_ACTIVE              256
#define PRINTER_STATUS_BUSY                   512
#define PRINTER_STATUS_PRINTING              1024
#define PRINTER_STATUS_OUTPUT_BIN_FULL       2048
#define PRINTER_STATUS_NOT_AVAILABLE         4096
#define PRINTER_STATUS_WAITING               8192
#define PRINTER_STATUS_PROCESSING           16384
#define PRINTER_STATUS_INITIALIZING         32768
#define PRINTER_STATUS_WARMING_UP           65536
#define PRINTER_STATUS_TONER_LOW           131072
#define PRINTER_STATUS_NO_TONER            262144
#define PRINTER_STATUS_PAGE_PUNT           524288
#define PRINTER_STATUS_USER_INTERVENTION  1048576
#define PRINTER_STATUS_OUT_OF_MEMORY      2097152
#define PRINTER_STATUS_DOOR_OPEN          4194304

STATIC oWnd, oPrn

FUNCTION Main()

   DEFINE WINDOW oWnd FROM 1, 1 TO 20, 60 TITLE "Printing a Test"

   @ 3, 3 BUTTON "&Print me" OF oWnd SIZE 80, 20 ;
      ACTION IMPR_ATIVA()

   ACTIVATE WINDOW oWnd

RETURN NIL

FUNCTION IMPR_ATIVA()

   LOCAL oFont, nRowStep, nColStep, nRow := 0, nCol := 0, n, m

   LOCAL cPrinter := GetDefaultPrinter()
   // GetPrinterStatus( cPrinter ) // necesitas implementar via API
   LOCAL nStatus  := PrnStatus( cPrinter )  

   IF nStatus == 0

  IF PrnStatus( cPrinter ) == 4096

     // Verifica se SPOOLER esta desligado e tenta liga-lo
     MsgRun( cPrinter + ": " + isprint( GetDefaultPrinter() ) + ;
        " ou Spooler Desligado.", "Status da Impressora",                 ;
        {|| WinExec( "NET START SPOOLER", 7 ) } )

  ENDIF

   // Status OK, imprimir
   ELSE

  MsgStop( "Impressora com problema! Status: " + Str(nStatus) )

  RETURN NIL

   ENDIF

   // TODO OK, PUEDE IMPRIMIR.
   PRINT oPrn NAME "Testing the printer object from FiveWin" PREVIEW MODAL

  if Empty( oPrn:hDC )
     return nil  // Printer was not installed or ready
  endif

  DEFINE FONT oFont NAME "Ms Sans Serif" SIZE 0, -12 OF oPrn

  nRowStep = oPrn:nVertRes() / 20   // We want 20 rows
  nColStep = oPrn:nHorzRes() / 15   // We want 15 cols

  PAGE

     oPrn:SayBitmap( 1, 1, "..\bitmaps\fivewin.bmp" )

     for n = 1 to 20  // rows

         nCol = 0

         oPrn:Say( nRow, nCol, Str( n, 2 ), oFont )

         nCol += nColStep

         for m = 1 to 15

            oPrn:Say( nRow, nCol, "+", oFont )

            nCol += nColStep

         next

         nRow += nRowStep

     next

     oPrn:Line( 0, 0, nRow, nCol )

  ENDPAGE

   ENDPRINT

   oFont:End()      // Destroy the font object

RETURN NIL

// FIN / END - kapiabafwh@gmail.com

Gracias, tks.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM

Re: ¿Verificar el estado de la impresora?

Posted: Mon Mar 23, 2026 08:50 PM

Estimado Joao,

Revisado con Claude code:

1. IF invertido → ahora verifica nStatus != 0 para detectar problemas, y solo imprime si todo está OK

  1. == reemplazado por lAnd() → los status son bitmask, se deben comprobar con AND de bits
  2. PrnStatus() llamada una sola vez → el resultado se guarda en nStatus
  3. isprint() eliminada → no es función estándar de FiveWin
  4. Más estados cubiertos → paper jam, paused, no toner, toner low, door open, user intervention
  5. Flujo limpio → primero valida, si hay problema sale con RETURN NIL, si no continúa a imprimir

prnativa.prg

// C:\FWH\SAMPLES\PRNATIVA.PRG
// Exemplo: Verificar estado da impressora antes de imprimir

#include "FiveWin.ch"

#define PRINTER_STATUS_OK                       0
#define PRINTER_STATUS_PAUSED                   1
#define PRINTER_STATUS_ERROR                    2
#define PRINTER_STATUS_PENDING_DELETION         4
#define PRINTER_STATUS_PAPER_JAM                8
#define PRINTER_STATUS_PAPER_OUT               16
#define PRINTER_STATUS_MANUAL_FEED             32
#define PRINTER_STATUS_PAPER_PROBLEM           64
#define PRINTER_STATUS_OFFLINE                128
#define PRINTER_STATUS_IO_ACTIVE              256
#define PRINTER_STATUS_BUSY                   512
#define PRINTER_STATUS_PRINTING              1024
#define PRINTER_STATUS_OUTPUT_BIN_FULL       2048
#define PRINTER_STATUS_NOT_AVAILABLE         4096
#define PRINTER_STATUS_WAITING               8192
#define PRINTER_STATUS_PROCESSING           16384
#define PRINTER_STATUS_INITIALIZING         32768
#define PRINTER_STATUS_WARMING_UP           65536
#define PRINTER_STATUS_TONER_LOW           131072
#define PRINTER_STATUS_NO_TONER            262144
#define PRINTER_STATUS_PAGE_PUNT           524288
#define PRINTER_STATUS_USER_INTERVENTION  1048576
#define PRINTER_STATUS_OUT_OF_MEMORY      2097152
#define PRINTER_STATUS_DOOR_OPEN          4194304

STATIC oWnd, oPrn

FUNCTION Main()

   DEFINE WINDOW oWnd FROM 1, 1 TO 20, 60 TITLE "Printing a Test"

   @ 3, 3 BUTTON "&Print me" OF oWnd SIZE 80, 20 ;
      ACTION IMPR_ATIVA()

   ACTIVATE WINDOW oWnd

RETURN NIL

FUNCTION IMPR_ATIVA()

   LOCAL oFont, nRowStep, nColStep, nRow := 0, nCol := 0, n, m
   LOCAL cPrinter := GetDefaultPrinter()
   LOCAL nStatus  := PrnStatus( cPrinter )

   // Verificar estado da impressora (status sao flags de bits)
   IF nStatus != PRINTER_STATUS_OK

  DO CASE
  CASE lAnd( nStatus, PRINTER_STATUS_NOT_AVAILABLE )
     MsgRun( cPrinter + " nao disponivel. Iniciando Spooler...", ;
             "Status da Impressora", ;
             {|| WinExec( "NET START SPOOLER", 7 ) } )

  CASE lAnd( nStatus, PRINTER_STATUS_OFFLINE )
     MsgStop( "Impressora offline!" )

  CASE lAnd( nStatus, PRINTER_STATUS_PAPER_OUT )
     MsgStop( "Sem papel!" )

  CASE lAnd( nStatus, PRINTER_STATUS_PAPER_JAM )
     MsgStop( "Papel atolado!" )

  CASE lAnd( nStatus, PRINTER_STATUS_ERROR )
     MsgStop( "Erro na impressora!" )

  CASE lAnd( nStatus, PRINTER_STATUS_PAUSED )
     MsgStop( "Impressora pausada!" )

  CASE lAnd( nStatus, PRINTER_STATUS_NO_TONER )
     MsgStop( "Sem toner!" )

  CASE lAnd( nStatus, PRINTER_STATUS_TONER_LOW )
     MsgStop( "Toner baixo!" )

  CASE lAnd( nStatus, PRINTER_STATUS_DOOR_OPEN )
     MsgStop( "Porta da impressora aberta!" )

  CASE lAnd( nStatus, PRINTER_STATUS_USER_INTERVENTION )
     MsgStop( "Impressora requer intervencao do usuario!" )

  OTHERWISE
     MsgStop( "Problema na impressora! Status: " + LTrim( Str( nStatus ) ) )

  ENDCASE

  RETURN NIL

   ENDIF

   // Impressora OK, imprimir
   PRINT oPrn NAME "Testing the printer object from FiveWin" PREVIEW MODAL

  IF Empty( oPrn:hDC )
     RETURN NIL
  ENDIF

  DEFINE FONT oFont NAME "Ms Sans Serif" SIZE 0, -12 OF oPrn

  nRowStep := oPrn:nVertRes() / 20
  nColStep := oPrn:nHorzRes() / 15

  PAGE

     oPrn:SayBitmap( 1, 1, "..\bitmaps\fivewin.bmp" )

     FOR n := 1 TO 20
        nCol := 0
        oPrn:Say( nRow, nCol, Str( n, 2 ), oFont )
        nCol += nColStep
        FOR m := 1 TO 15
           oPrn:Say( nRow, nCol, "+", oFont )
           nCol += nColStep
        NEXT
        nRow += nRowStep
     NEXT

     oPrn:Line( 0, 0, nRow, nCol )

  ENDPAGE

   ENDPRINT

   oFont:End()

RETURN NIL

// FIN / END - kapiabafwh@gmail.com
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 8523
Joined: Tue Dec 20, 2005 07:36 PM

Re: ¿Verificar el estado de la impresora?

Posted: Tue Mar 24, 2026 05:37 PM

Super many thanks querido Maestro. Versión completa, Creo no haber olvidado nada. Implementaré los cambios según me los comuniquen los usuarios.

// C:\FWH\SAMPLES\PRNATIVA.PRG

// Exemplo: Verificar estado da impressora antes de imprimir

#include "FiveWin.ch"

#define PRINTER_STATUS_OK                       0
#define PRINTER_STATUS_PAUSED                   1
#define PRINTER_STATUS_ERROR                    2
#define PRINTER_STATUS_PENDING_DELETION         4
#define PRINTER_STATUS_PAPER_JAM                8
#define PRINTER_STATUS_PAPER_OUT               16
#define PRINTER_STATUS_MANUAL_FEED             32
#define PRINTER_STATUS_PAPER_PROBLEM           64
#define PRINTER_STATUS_OFFLINE                128
#define PRINTER_STATUS_IO_ACTIVE              256
#define PRINTER_STATUS_BUSY                   512
#define PRINTER_STATUS_PRINTING              1024
#define PRINTER_STATUS_OUTPUT_BIN_FULL       2048
#define PRINTER_STATUS_NOT_AVAILABLE         4096
#define PRINTER_STATUS_WAITING               8192
#define PRINTER_STATUS_PROCESSING           16384
#define PRINTER_STATUS_INITIALIZING         32768
#define PRINTER_STATUS_WARMING_UP           65536
#define PRINTER_STATUS_TONER_LOW           131072
#define PRINTER_STATUS_NO_TONER            262144
#define PRINTER_STATUS_PAGE_PUNT           524288
#define PRINTER_STATUS_USER_INTERVENTION  1048576
#define PRINTER_STATUS_OUT_OF_MEMORY      2097152
#define PRINTER_STATUS_DOOR_OPEN          4194304
#define PRINTER_STATUS_SERVER_UNKNOWN     8388608
#define PRINTER_STATUS_POWER_SAVE        16777216

STATIC oWnd, oPrn

FUNCTION Main()

   DEFINE WINDOW oWnd FROM 1, 1 TO 20, 60 TITLE "Printing a Test"

   @ 3, 3 BUTTON "&Print me" OF oWnd SIZE 80, 20 ;
      ACTION IMPR_ATIVA()

   @ 3, 25 BUTTON "&Exit" OF oWnd SIZE 80, 20 ;
      ACTION( oWnd:End() )

   ACTIVATE WINDOW oWnd CENTERED

RETURN NIL

FUNCTION IMPR_ATIVA()

   LOCAL oFont, nRowStep, nColStep, nRow := 0, nCol := 0, n, m
   LOCAL cPrinter := GetDefaultPrinter()
   LOCAL nStatus  := PrnStatus( cPrinter )

   // Verificar estado da impressora (status sao flags de bits)
   IF nStatus != PRINTER_STATUS_OK // tem problemas na impressora.

  DO CASE
  CASE lAnd( nStatus, PRINTER_STATUS_NOT_AVAILABLE )

     MsgRun( cPrinter + " nao disponivel. Iniciando Spooler...", ;
                        "Status da Impressora", ;
             {|| WinExec( "NET START SPOOLER", 7 ) } )

  CASE lAnd( nStatus, PRINTER_STATUS_OFFLINE )

     MsgStop( "Impressora offline!", , "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_PAPER_OUT )

     MsgStop( "Impressora: Sem papel!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_PAPER_JAM )

     MsgStop( "Impressora: Papel atolado(Modo Bandeja)", "Atenção" )

 CASE lAnd( nStatus, PRINTER_STATUS_ERROR )

    MsgStop( "Erro na impressora!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_PAUSED )

     MsgStop( "Impressora pausada!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_NO_TONER )

     MsgStop( "Impressora: Sem toner!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_TONER_LOW )

     MsgStop( "Impressora: Toner baixo!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_DOOR_OPEN )

     MsgStop( "Porta(ou tampa) da impressora aberta!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_USER_INTERVENTION )

     MsgStop( "Impressora requer Intervenção do usuário!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_OUTPUT_BIN_FULL )

     MsgStop( "Impressora: O compartimento de saída está cheio!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_MANUAL_FEED )

     MsgStop( "Impressora: em Modo Manual!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_OUT_OF_MEMORY )

     MsgStop( "Impressora: Sem Memória suficiente!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_IO_ACTIVE )

     MsgStop( "Impressora: com input/output(I/O) Ativo!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_BUSY )

     MsgStop( "Impressora: Ocupada(Lotada)!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_WARMING_UP )

     MsgStop( "Impressora: em Atenção(Cuidado)!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_SERVER_UNKNOWN )

     MsgStop( "Impressora: Servidor Desconhecido!", "Atenção" )

  CASE lAnd( nStatus, PRINTER_STATUS_POWER_SAVE )

     MsgStop( "Impressora: em Modo POWER_SAVE(Economia de Energia)!", "Atenção" )

  OTHERWISE // outros problemas:

     MsgStop( "Problema na impressora! Status: " + LTrim( Str( nStatus ) ), "Reporte ao Técnico" )

  ENDCASE

  RETURN NIL

   ENDIF

   // Impressora OK, imprimir
   PRINT oPrn NAME "Testing the printer object from FiveWin" PREVIEW MODAL

  IF Empty( oPrn:hDC )
     RETURN NIL
  ENDIF

  DEFINE FONT oFont NAME "Ms Sans Serif" SIZE 0, -12 OF oPrn

  nRowStep := oPrn:nVertRes() / 20
  nColStep := oPrn:nHorzRes() / 15

  PAGE

     oPrn:SayBitmap( 1, 1, "..\bitmaps\fivewin.bmp" )

     FOR n := 1 TO 20

        nCol := 0

        oPrn:Say( nRow, nCol, Str( n, 2 ), oFont )

        nCol += nColStep

        FOR m := 1 TO 15

           oPrn:Say( nRow, nCol, "+", oFont )

           nCol += nColStep

        NEXT

        nRow += nRowStep

     NEXT

     oPrn:Line( 0, 0, nRow, nCol )

  ENDPAGE

   ENDPRINT

   oFont:End()

RETURN NIL

// FIN / END - kapiabafwh@gmail.com

Gracias, tks.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341

Continue the discussion