Posts mit dem Label Drucker werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Drucker werden angezeigt. Alle Posts anzeigen

Donnerstag, 4. November 2010

Druckerinformationen mit VFP Bordmitteln / Display printer infos with native VFP functions

Vor einiger Zeit hatte ich bereits in zwei Einträgen über die Anzeige des aktuellen Druckerstatus (Teil1 , Teil2 )geschrieben. Die dort vorgestellten Funktionen arbeiten auf Basis der Windows Management Instrumentation (WMI).
Die heutige Funktion kommt ohne WMI aus. Sie greift auf zwei native VFP Funktionen zu: GETPRINTER() und PRTINFO().

Die Funktion PRTINFO() kennt insgesamt 13 verschiedene Parameterwerte die uns über die aktuellen Einstellungen des zuvor mit GETPRINTER() ausgewählten Druckers Auskunft geben. Dummerweise gibt es aber in fast allen Rückmeldungen wiederum nur einfache Zahlenwerte die wir dann mühselig über die Hilfe nachschlagen müssen.

Die folgende Funktion AnalyzePrtInfo() schlüsselt diese Daten in Textinformationen auf. Liefert ein Drucker keine Kenndaten zu einem bestimmten Abfragewert zurück, dann wird dies mit 'n.v.' (=nicht verfügbar) quittiert.

* // Funktionstest START
CLEAR 
lcPrinter = GETPRINTER()
?lcPrinter
FOR i = 1 TO 13
    ? AnalyzePrtInfo( i , PRTINFO( i , lcPrinter ) )
ENDFOR 
* // Funktionstest ENDE 

FUNCTION AnalyzePrtInfo as String
LPARAMETERS vParam as Integer , vValue as Integer
    LOCAL lcTitel as String , lcReturn as String
    STORE [] TO lcTitel , lcReturn
    DO CASE 
    *!*    1    Paper orientation
    CASE vParam = 1
        lcTitel = [Papierausrichtung]
        DO CASE
        CASE vValue = 0
            lcReturn = [Portrait (Hoch)]
        CASE vValue = 1
            lcReturn = [Landscape (Quer)]
        OTHERWISE
            lcReturn = [n.v.]
        ENDCASE
    *!*    2    Paper size 
    CASE vParam = 2
        lcTitel = [Papierformat]
        DO CASE 
        CASE vValue = 1
            lcReturn = [Letter, 8 1/2 x 11 inch]
        CASE vValue = 2
            lcReturn = [Letter Small, 8 1/2 x 11 inch]
        CASE vValue = 3
            lcReturn = [Tabloid, 11 x 17 inch]
        CASE vValue = 4
            lcReturn = [Ledger, 17 x 11 inch]
        CASE vValue = 5
            lcReturn = [Legal, 8 1/2 x 14 inch]
        CASE vValue = 6
            lcReturn = [Statement, 5 1/2 x 8 1/2 inch]
        CASE vValue = 7
            lcReturn = [Executive, 7 1/4 x 10 1/2 inch]
        CASE vValue = 8
            lcReturn = [A3, 297 x 420 mm]
        CASE vValue = 9
            lcReturn = [A4, 210 x 297 mm]
        CASE vValue = 10
            lcReturn = [A4, Small 210 x 297 mm]
        CASE vValue = 11
            lcReturn = [A5, 148 x 210 mm]
        CASE vValue = 12
            lcReturn = [B4, 250 x 354 mm]
        CASE vValue = 13
            lcReturn = [B5, 182 x 257 mm]
        CASE vValue = 14
            lcReturn = [Folio, 8 1/2 x 13 inch]
        CASE vValue = 15
            lcReturn = [Quarto, 215 x 275 mm]
        CASE vValue = 16
            lcReturn = [10 x 14 inch]
        CASE vValue = 17
            lcReturn = [11 x 17 inch]
        CASE vValue = 18
            lcReturn = [Note, 8 1/2 x 11 inch]
        CASE vValue = 19
            lcReturn = [Envelope #9, 3 7/8 x 8 7/8 inch]
        CASE vValue = 20
            lcReturn = [Envelope #10, 4 1/8 x 9 1/2 inch]
        CASE vValue = 21
            lcReturn = [Envelope #11, 4 1/2 x 10 3/8 inch]
        CASE vValue = 22
            lcReturn = [Envelope #12, 4 1/2 x 11 inch]
        CASE vValue = 23
            lcReturn = [Envelope #14, 5 x 11 1/2 inch]
        CASE vValue = 24
            lcReturn = [C size sheet]
        CASE vValue = 25
            lcReturn = [D size sheet]
        CASE vValue = 26
            lcReturn = [E size sheet]
        CASE vValue = 27
            lcReturn = [Envelope DL, 110 x 220 mm]
        CASE vValue = 28
            lcReturn = [Envelope C5, 162 x 229 mm]
        CASE vValue = 29
            lcReturn = [Envelope C3, 324 x 458 mm]
        CASE vValue = 30
            lcReturn = [Envelope C4, 229 x 324 mm]
        CASE vValue = 31
            lcReturn = [Envelope C6, 114 x 162 mm]
        CASE vValue = 32
            lcReturn = [Envelope C65, 114 x 229 mm]
        CASE vValue = 33
            lcReturn = [Envelope B4, 250 x 353 mm]
        CASE vValue = 34
            lcReturn = [Envelope B5, 176 x 250 mm]
        CASE vValue = 35
            lcReturn = [Envelope B6, 176 x 125 mm]
        CASE vValue = 36
            lcReturn = [Envelope, 110 x 230 mm]
        CASE vValue = 37
            lcReturn = [Envelope Monarch, 3 7/8 x 7.5 inch]
        CASE vValue = 38
            lcReturn = [6 3/4 Envelope, 3 5/8 x 6 1/2 inch]
        CASE vValue = 39
            lcReturn = [US Std Fanfold, 14 7/8 x 11 inch]
        CASE vValue = 40
            lcReturn = [German Std Fanfold, 8 1/2 x 12 inch]
        CASE vValue = 41
            lcReturn = [German Legal Fanfold, 8 1/2 x 13 inch]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    3    Paper length in .1 millimeter increments
    CASE vParam = 3
        lcTitel = [Papierlänge]
        DO CASE 
        CASE vValue >= 0
            lcReturn = TRANSFORM( vValue ) +  [ .1 mm]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    4    Paper width in .1 millimeter increments
    CASE vParam = 4
        lcTitel = [Papierbreite]
        DO CASE 
        CASE vValue >= 0
            lcReturn = TRANSFORM( vValue ) +  [ .1 mm]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    5    Factor by which printer output is scaled
    CASE vParam = 5
        lcTitel  = [Skalierung]
        DO CASE 
        CASE vValue >= 0
            lcReturn = TRANSFORM( vValue ) + [ %]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    6    Number of copies to print
    CASE vParam = 6
        lcTitel  = [Anzahl Kopien]
        DO CASE 
        CASE vValue >= 0
            lcReturn = TRANSFORM( vValue )
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    7    Default paper source
    CASE vParam = 7
        lcTitel  = [Schacht]
        DO CASE 
        CASE vValue = 1
            lcReturn = [Oberer Schacht]
        CASE vValue = 2
            lcReturn = [Unterer Schacht]
        CASE vValue = 3
            lcReturn = [Mittlerer Schacht]
        CASE vValue = 4
            lcReturn = [Manueller Einzug]
        CASE vValue = 5
            lcReturn = [Briefumschlag Einzug]
        CASE vValue = 6
            lcReturn = [Manueller Briefumschlag Einzug]
        CASE vValue = 7
            lcReturn = [Automatischer Einzug]
        CASE vValue = 8
            lcReturn = [Traktoreinzug]
        CASE vValue = 9
            lcReturn = [Kleinformat]
        CASE vValue = 10
            lcReturn = [Großformat]
        CASE vValue = 11
            lcReturn = [Große Kapazität]
        CASE vValue = 14
            lcReturn = [Kassette]
        CASE vValue = 15
            lcReturn = [Standardeinzug (automatisch)]
         OTHERWISE 
            lcReturn = [n.v.]
         ENDCASE 
    *!*    8    A positive value that indicates the horizontal resolution
    *!*        in dots per inch (DPI) or a negative value that indicates
    *!*        the print quality.
    CASE vParam = 8
        lcTitel  = [Auflösung]
        DO CASE 
        CASE vValue = -1
            lcReturn = [Draft]
        CASE vValue = -2
            lcReturn = [Niedrig]
        CASE vValue = -3
            lcReturn = [Mittel]
        CASE vValue = -4
            lcReturn = [Hoch]
        OTHERWISE 
            lcReturn = TRANSFORM( vValue ) + [ DPI]
        ENDCASE         
    *!*    9    A value that indicates if a color printer rends color or
    *!*        monochrome output
    CASE vParam = 9
        lcTitel  = [Ausgabe]
        DO CASE 
        CASE vValue = 1
            lcReturn = [monochrome]
        CASE vValue = 2
            lcReturn = [farbig]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    10    Duplex mode
    CASE vParam = 10
        lcTitel  = [Druckausgabe]
        DO CASE 
        CASE vValue = 1
            lcReturn = [Simplex Druck]
        CASE vValue = 2
            lcReturn = [Vertikaler Duplexdruck]
        CASE vValue = 3
            lcReturn = [Horizontaler Duplexdruck]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    11    The vertical resolution in dots per inch (DPI). If not
    *!*        available, a value of -1 is returned.
    CASE vParam = 11
        lcTitel  = [vertik. Auslösung]
        DO CASE 
        CASE vValue >= 0
            lcReturn = TRANSFORM( vValue ) + [ DPI]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    *!*    12    A value that indicates how TrueType® fonts are printed
    CASE vParam = 12
        lcTitel  = [Truetype Schriften]
        DO CASE 
        CASE vValue = 1
            lcReturn = [Druck als Bitmap Grafik]
        CASE vValue = 2
            lcReturn = [Druck über Softfonts]
        CASE vValue = 3
            lcReturn = [Druck über Ersatzfonts]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE  
    *!*    13    A value that indicates if output is collated
    CASE vParam = 13
        lcTitel  = [Sammeldruck]
        DO CASE 
        CASE vValue = 0
            lcReturn = [nein]
        CASE vValue = 1
            lcReturn = [ja]
        OTHERWISE 
            lcReturn = [n.v.]
        ENDCASE 
    ENDCASE 
    RETURN PADR( lcTitel , 20 , [ ] ) + [: ] + lcReturn
ENDFUNC 

Dienstag, 6. April 2010

Druckerstatus abfragen - Teil 2 / Query printer status - Part 2

Im Dezember hatte ich einen Eintrag verfasst, in dem es darum ging, den Status der vorhandenen Drucker abzufragen. Im folgenden Codebeispiel habe ich diese Funktionalität dahingehend erweitert, dass nun auch der Standarddrucker des aktuellen Benutzers gefunden und gekennzeichnet wird.

Ermöglicht wird dies durch eine Abfrage des Windows-Spoolertreibers (winspool.drv) der sich üblicherweise im Windows System- und/oder System32-Verzeichnis befindet.

Der u.a. Code baut auf den bereits im Dezember Posting gezeigten Funktionen GetPrinterStatus() und GetPrinterStatusAsText() auf. Neu hinzugekommen sind die Funktionen DisplayPrinterInfos() sowie GetDefaultPrinter() welche innerhalb von GetPrinterStatus() direkt aufgerufen wird. Ebenfalls neu ist, dass nun sämtliche Daten in einem Cursor vorgehalten werden.

DisplayPrinterInfos() erweitert die _SCREEN-Ausgabe um Druckerstandort und Kommentar. GetDefaultPrinter() greift auf die API-Funktion 'GetDefaultPrinter' aus winspool.drv zurück. Hierbei habe ich den API-Funktionsnamen mit einem Alias ( -> MyDefaultPrinter) versehen, damit meine identische interne Funktionsbenamung keine Rekursion verursacht.

LOCAL liFlag as Integer

* // installierte Drucker überprüfen und entsprechenden Cursor erzeugen    
=APRINTERS(laPrn,1)

* // Leeren Cursor erzeugen 
CREATE CURSOR crsprinters ( ;
    prn_type        C(  1), ;
    prn_default     C(  1), ;
    prn_printer     C(250), ;
    prn_port        C( 50), ;
    prn_driver      C(100), ;
    prn_comment     C(250), ;
    prn_location    C(250), ;
    prn_status      C( 30) ;
    )

* // Wurden installierte Drucker gefunden, dann wird nun der Inhalt        
* // des Arrays in einer Schleife verarbeitet und an 'crsPrinters'         
* // übergeben. 
IF !EMPTY(laPrn(1,1))
    FOR liFlag = 1 TO ALEN(laPrn,1)
        IF SUBSTR(laPrn(liFlag,1),1,2) = [\\]
            m.prn_type       = [n]
            m.prn_printer    = [ ] + laPrn(liFlag,1)
        ELSE 
            m.prn_type       = [l]
            m.prn_printer    = laPrn(liFlag,1)
        ENDIF
        m.prn_port      = laPrn(liFlag,2)
        m.prn_driver    = laPrn(liFlag,3)
        m.prn_comment   = laPrn(liFlag,4)
        m.prn_location  = laPrn(liFlag,5)
        m.prn_default   = [ ]
        m.prn_status    = [ ]
        INSERT INTO crsPrinters FROM MEMVAR 
    ENDFOR 
    * // Nun die noch fehlenden Statusinformationen im Cursor            
    * // hinterlegen und die Ausgaberoutine aufrufen. 
    GetPrinterStatus()
    DisplayPrinterInfos()
    USE IN SELECT([crsPrinters])
ELSE 
    * // Ab und an soll es tatsächlich vorkommen, dass überhaupt kein    
    * // Drucker im System vorhanden ist. Dies sollten wir dem Anwender    
    * // natürlich nicht vorenthalten.
    LOCAL lcString as String
    TEXT TO lcString NOSHOW ADDITIVE TEXTMERGE PRETEXT 2
        A C H T U N G ! ! !
        Für Ihr Login sind noch keine Drucker installiert!
        Zum Ausdrucken von Daten werden diese jedoch zwingend
        benötigt. Bitte installieren Sie über
        
        [Start] - [Einstellungen] - [Drucker] - [Neuer Drucker]
        
        einen oder mehrere Drucker!
    ENDTEXT 
    MESSAGEBOX(lcString,0+64+0,[Kein Drucker installiert])
    RELEASE lcString
ENDIF 

RELEASE laPrn

* // ----------------------------------------- DisplayDefaultPrinter
FUNCTION GetDefaultPrinter as String

    * // Wichtig bei dieser Funktion ist, dass der als Referenz        
    * // übergebene String mit CHR(0) Zeichen vorbesetzt wird.        
    LOCAL liBuffSize as Integer, lcPrinter as String
    liBufsize = 250
    lcPrinter = REPLICATE( CHR( 0 ), liBufsize )
    
    * // Über winspool.drv können wir den aktuellen Standarddrucker    
    * // abfragen. Das Ergebnis liefern wir als String zurück, um    
    * // in der nachfolgenden Verarbeitung einen direkten Namens-    
    * // vergleich durchführen zu können.
    TRY 
        DECLARE INTEGER GetDefaultPrinter IN winspool.drv AS MyDefaultPrinter ;
                STRING  @ pszBuffer,;
                INTEGER @ pcchBuffer

        * // Da die API-Funktion genauso heisst, wie die VFP-Funktion
        * // war eine Umbenennung der API-Funktion mit Hilfe eines    
        * // ALIAS notwendig. Somit wurde aus GetDefaultPrinter() die 
        * // Funktion MyDefaultPrinter.
        = MyDefaultPrinter( @lcPrinter, @liBufsize )
        lcPrinter = SUBSTR(lcPrinter, 1, AT( CHR( 0 ), lcPrinter ) - 1 )
    CATCH 
        lcPrinter = [ ]
    ENDTRY 
    
    RETURN lcPrinter

ENDFUNC 

* // ------------------------------------------- DisplayPrinterInfos
FUNCTION DisplayPrinterInfos
    
    * // Diese Funktion zeigt den Inhalt des Druckercursors an.        
    * // hierbei erfolgt die Kennzeichnung des Standarddruckers über
    * // ein kleines 'x' vor dem Druckernamen.
    
    LOCAL lcFont as String, lcDisplay as String
    
    * // VFP Screen vorbereiten                                        
    lcFont              = _screen.Fontname
    _screen.FontName    = [Courier New]
    CLEAR 
    
    SELECT crsPrinters
    GO TOP 
    ??[Status                   Drucker (x=Standarddrucker)              Standort                            Kommentar                                                             ]
     ?[---------------------------------------------------------------------------------------------------------------------------------------------------------------------------]
    DO WHILE !EOF()
        TEXT TO lcDisplay TEXTMERGE NOSHOW PRETEXT 1+2+4+8
            <<SUBSTR( crsPrinters.prn_status,1,20 )>>
            <<IIF(EMPTY(crsPrinters.prn_default),[   ],[ x ])>>
            <<SUBSTR( crsPrinters.prn_printer,1,40 )>>
            <<SUBSTR( crsPrinters.prn_location,1,35 )>>
            <<SUBSTR( crsPrinters.prn_comment,1,70 )>>
        ENDTEXT 
        ? lcDisplay
        SKIP IN ([crsPrinters])
    ENDDO 
         
    * // VFP Screen zurücksetzen            
    _screen.FontName = lcFont
    
ENDFUNC 

* // ---------------------------------------------- GetPrinterStatus
FUNCTION GetPrinterStatus as String

    LOCAL lcComputer as String, loWMIService as Object, ;
          loInstalledPrinters as Object, lcStatus as String, ;
          lcFont as String, lcDefPrn as String

    * // Arbeitsvariablen initialisieren    
    lcComputer          = [.]
    loWMIService        = GETOBJECT([winmgmts:] + [{impersonationLevel=impersonate}!\\] + lcComputer + [\root\cimv2])
    loInstalledPrinters = loWMIService.ExecQuery([SELECT * FROM Win32_Printer])
    lcFont              = _screen.FontName 
    lcDefPrn            = GetDefaultPrinter()

    * // Druckerobjekt auslesen                
    FOR EACH loPrinter IN loInstalledPrinters

        lcStatus = GetPrinterStatusAsText(loPrinter)

        SELECT crsPrinters
        GO TOP 
        LOCATE FOR prn_printer = loPrinter.Name
        IF FOUND()
            IF LEN(ALLTRIM(lcStatus)) > 15
                REPLACE prn_status WITH SUBSTR(lcStatus,16)   IN crsPrinters
            ELSE 
                REPLACE prn_status WITH SUBSTR(lcStatus,1,15) IN crsPrinters
            ENDIF 
            * // Standarddrucker im Cursor kennzeichnen.
            IF ALLTRIM(crsPrinters.prn_printer) == lcDefPrn
                REPLACE prn_default WITH [x] IN crsPrinters
            ENDIF 
        ENDIF 
        
    NEXT 
ENDFUNC 

* // ---------------------------------------- GetPrinterStatusAsText
FUNCTION GetPrinterStatusAsText as String
LPARAMETERS oPrinter as Object

    LOCAL lcReturn as String
    lcReturn = []
    
    DO CASE 
    CASE oPrinter.PrinterStatus = 1
        lcReturn = [anderes        ]    && Other
    CASE oPrinter.PrinterStatus = 2
        lcReturn = [unbekannt      ]    && Unknown
    CASE oPrinter.PrinterStatus = 3
        lcReturn = [bereit         ]    && Idle
    CASE oPrinter.PrinterStatus = 4
        lcReturn = [druckt         ]    && Printing
    CASE oPrinter.PrinterStatus = 5
        lcReturn = [aufwärmen      ]    && Warming Up
    CASE oPrinter.PrinterStatus = 6
        lcReturn = [gestoppt       ]    && Stopped Printing
    CASE oPrinter.PrinterStatus = 7
        lcReturn = [Offline        ]    && Offline
    CASE oPrinter.PrinterStatus = 8
        lcReturn = [pausierend     ]    && Paused
    CASE oPrinter.PrinterStatus = 9
        lcReturn = [Fehler         ]    && Error
    CASE oPrinter.PrinterStatus = 10
        lcReturn = [beschäftigt    ]    && Busy
    CASE oPrinter.PrinterStatus = 11
        lcReturn = [nicht verfügbar]    && Not Available
    CASE oPrinter.PrinterStatus = 12
        lcReturn = [wartend        ]    && Waiting
    CASE oPrinter.PrinterStatus = 13
        lcReturn = [verarbeiten    ]    && Processing
    CASE oPrinter.PrinterStatus = 14
        lcReturn = [initialisieren ]    && Initialization
    CASE oPrinter.PrinterStatus = 15
        lcReturn = [Stromsparmodus ]    && Power Save
    CASE oPrinter.PrinterStatus = 16
        lcReturn = [löscht Druckjob]    && Pending Deletion
    CASE oPrinter.PrinterStatus = 17
        lcReturn = [E/A aktiv      ]    && I/O Active
    CASE oPrinter.PrinterStatus = 18
        lcReturn = [manuelle Zufuhr]    && Manual Feed
    ENDCASE 
    * // Die Liste ggf. nach Bedarf erweitern
    IF INLIST(oPrinter.PrinterStatus,1,9)
        lcReturn = lcReturn + GetDetectedErrorStateAsText(oPrinter.DetectedErrorState)
    ENDIF 
    RETURN lcReturn
    
ENDFUNC 

* // ----------------------------------- GetDetectedErrorStateAsText
FUNCTION GetDetectedErrorStateAsText as String
LPARAMETERS vErrorstate as Integer 

    LOCAL lcReturn as String 
    
    DO CASE
    CASE m.vErrorState = 0
        lcReturn = [Unbekannter Fehler]                 && Unknown
    CASE m.vErrorState = 1
        lcReturn = [Anderer Fehler]                     && Other
    CASE m.vErrorState = 2
        lcReturn = [kein Fehler]                        && No Error
    CASE m.vErrorState = 3
        lcReturn = [zu wenig Papier]                    && Low Paper
    CASE m.vErrorState = 4
        lcReturn = [kein Papier]                        && No Paper
    CASE m.vErrorState = 5
        lcReturn = [zu wenig Toner]                     && Low Toner
    CASE m.vErrorState = 6
        lcReturn = [kein Toner]                         && No Toner
    CASE m.vErrorState = 7
        lcReturn = [Gehäuse geöffnet]                   && Door Open
    CASE m.vErrorState = 8
        lcReturn = [Papierstau]                         && Jammed
    CASE m.vErrorState = 9
        lcReturn = [Kundendienst erforderlich]          && Service Requested
    CASE m.vErrorState = 10
        lcReturn = [Ausgabeschacht ist voll]            && Output Bin Full
    CASE m.vErrorState = 11
        lcReturn = [Papier Problem]                     && Paper Problem
    CASE m.vErrorState = 12
        lcReturn = [Seite kann nicht gedruckt werden]   && Cannot Print Page
    CASE m.vErrorState = 13
        lcReturn = [Benutzereingriff notwendig]         && User Intervention Required
    CASE m.vErrorState = 14
        lcReturn = [Arbeitsspeicher voll]               && Out Of Memory
    CASE m.vErrorState = 15
        lcReturn = [unbekannter Server]                 && Server Unknown
    OTHERWISE
        lcReturn = [Unbekannt]    
    ENDCASE
    RETURN     [(] + ALLTRIM(STR(m.vErrorState)) + [) ] + lcReturn
    
ENDFUNC 

Donnerstag, 3. Dezember 2009

Druckerstatus abfragen / Query printer status

Die Anzeige des aktuellen Zustands der verfügbaren Drucker kann für so manchen Anwender von essentieller Bedeutung sein, wenn es darum geht einen Ausdruck möglichst schnell in den Händen zu halten. Andererseits kann es nur von Vorteil sein, wenn bei einer Druckausgabe bereits im Vorfeld erkennbar ist, daß ein spezieller Drucker bspw. einen Papierstau hat, oder nur wenig Papier im Einzugschacht verfügbar ist.

Die Funktion APRINTER(myPrinterArray[,1]) liefert uns in einem Array den Druckernamen, den Anschluss, den Treiber, den Kommentar und den Standort.

APRINTER(laPrinters,1)
CLEAR
DISPLAY MEMORY LIKE laPrinters

Was fehlt ist die Information, ob der oder die Drucker auch tatsächlich verfügbar sind, oder ob gerade ein Druckjob abgearbeitet wird, oder ob der Drucker überhaupt verfügbar ist. Solche Informationen können wir jedoch über den Windows Management Service recht einfach abrufen.Detaillierte Infos zur Win32_Printer Klasse (Bestandteil der Windows Management Instrumentation) gibt es auf MSDN:

http://msdn.microsoft.com/en-us/library/aa394363(VS.85).aspx

Dort finden wir u.a. auch die Aufschlüsselung der Fehlernummern auf die wir gezielt reagieren können, wenn der Druckerstatus bspw. eine 1 (=Other) oder 9 (=Error) liefert. Im folgenden ein wenig Mustercode der über den Zugriff auf die WMI auskunft gibt:

LOCAL lcComputer as String, loWMIService as Object, ;
      loInstalledPrinters as Object, lcStatus as String, ;
      lcFont as String

* // Arbeitsvariablen initialisieren und WMI Objekt erzeugen
lcComputer          = [.]
loWMIService        = GETOBJECT([winmgmts:] + [{impersonationLevel=impersonate}!\\] + lcComputer + [\root\cimv2])
loInstalledPrinters = loWMIService.ExecQuery([SELECT * FROM Win32_Printer])
lcFont              = _screen.FontName
* // VFP Screen vorbereiten            
_screen.FontName    = [Courier New]
CLEAR 
?[Name] + SPACE(40) + [Status]
?REPLICATE([-],50)

* // Druckerobjekt auslesen            
FOR EACH loPrinter IN loInstalledPrinters

    ?PADR(loPrinter.Name,44,[ ])
    lcStatus = GetPrinterStatusAsText(loPrinter)
    ?? lcStatus

NEXT
* // VFP Screen zurücksetzen        
_screen.FontName = lcFont


FUNCTION GetPrinterStatusAsText as String
LPARAMETERS oPrinter as Object

    LOCAL lcReturn as String
    lcReturn = []

    DO CASE
    CASE oPrinter.PrinterStatus = 1
        * // Other
        lcReturn = [anderes        ]
    CASE oPrinter.PrinterStatus = 2
        * // Unknown
        lcReturn = [unbekannt      ]
    CASE oPrinter.PrinterStatus = 3
        * // Idle
        lcReturn = [bereit         ]
    CASE oPrinter.PrinterStatus = 4
        * // Printing
        lcReturn = [druckt         ]
    CASE oPrinter.PrinterStatus = 5
        * // Warming Up
        lcReturn = [aufwärmen      ]
    CASE oPrinter.PrinterStatus = 6
        * // Stopped Printing
        lcReturn = [gestoppt       ]
    CASE oPrinter.PrinterStatus = 7
        * // Offline
        lcReturn = [Offline        ]
    CASE oPrinter.PrinterStatus = 8
        * // Paused
        lcReturn = [pausierend     ]
    CASE oPrinter.PrinterStatus = 9
        * // Error
        lcReturn = [Fehler         ]
    CASE oPrinter.PrinterStatus = 10
        * // Busy
        lcReturn = [beschäftigt    ]
    CASE oPrinter.PrinterStatus = 11
        * // Not Available
        lcReturn = [nicht verfügbar]
    CASE oPrinter.PrinterStatus = 12
        * // Waiting
        lcReturn = [wartend        ]
    CASE oPrinter.PrinterStatus = 13
        * // Processing
        lcReturn = [verarbeiten    ]
    CASE oPrinter.PrinterStatus = 14
        * // Initialization
        lcReturn = [initialisieren ]
    CASE oPrinter.PrinterStatus = 15
        * // Power Save
        lcReturn = [Stromsparmodus ]
    CASE oPrinter.PrinterStatus = 16
        * // Pending Deletion
        lcReturn = [löscht Druckjob]
    CASE oPrinter.PrinterStatus = 17
        * // I/O Active
        lcReturn = [E/A aktiv      ]
    CASE oPrinter.PrinterStatus = 18
        * // Manual Feed
        lcReturn = [manuelle Zufuhr]
    ENDCASE
    * // Die Liste ggf. nach Bedarf erweitern
    IF INLIST(oPrinter.PrinterStatus,1,9)
        lcReturn = lcReturn + GetDetectedErrorStateAsText(oPrinter.DetectedErrorState)
    ENDIF
    RETURN lcReturn

ENDFUNC


FUNCTION GetDetectedErrorStateAsText as String
LPARAMETERS vErrorstate as Integer

    LOCAL lcReturn as String

    DO CASE
    CASE m.vErrorState = 0
        * // Unknown
        lcReturn = [Unbekannter Fehler]
    CASE m.vErrorState = 1
        * // Other
        lcReturn = [Anderer Fehler]
    CASE m.vErrorState = 2
        * // No Error
        lcReturn = [kein Fehler]
    CASE m.vErrorState = 3
        * // Low Paper
        lcReturn = [zu wenig Papier]
    CASE m.vErrorState = 4
        * // No Paper
        lcReturn = [kein Papier]
    CASE m.vErrorState = 5
        * // Low Toner
        lcReturn = [zu wenig Toner]
    CASE m.vErrorState = 6
        * // No Toner
        lcReturn = [kein Toner]
    CASE m.vErrorState = 7
        * // Door Open
        lcReturn = [Gehäuse geöffnet]
    CASE m.vErrorState = 8
        * // Jammed
        lcReturn = [Papierstau]
    CASE m.vErrorState = 9
        * // Service Requested
        lcReturn = [Kundendienst erforderlich]
    CASE m.vErrorState = 10
        * // Output Bin Full
        lcReturn = [Ausgabeschacht ist voll]
    CASE m.vErrorState = 11
        * // Paper Problem
        lcReturn = [Papier Problem]
    CASE m.vErrorState = 12
        * // Cannot Print Page
        lcReturn = [Seite kann nicht gedruckt werden]
    CASE m.vErrorState = 13
        * // User Intervention Required
        lcReturn = [Benutzereingriff notwendig]
    CASE m.vErrorState = 14
        * // Out Of Memory
        lcReturn = [Arbeitsspeicher voll]
    CASE m.vErrorState = 15
        * // Server Unknown
        lcReturn = [unbekannter Server]
    OTHERWISE
        lcReturn = [Unbekannt]
    ENDCASE
    RETURN     [(] + ALLTRIM(STR(m.vErrorState)) + [) ] + lcReturn

ENDFUNC