Druckertreiber unter GFA-BASIC

Bei meinem Programm handelt es sich um Routinen, die die Anpassung eines Programms an verschiedene Drucker ermöglichen. Diese Routinen werden in ein Programm eingebunden und können dann über eine Prozedur LPRINT() angesprochen werden. Somit müssen Sie in bestehenden Programmen eigentlich nur die entsprechenden LPRINT-Anweisungen (GFA-BASIC) durch die Procedure-Aufrufe ersetzen. Die Routinen entstammen einem meiner Programme und sind somit schon in der Praxis erprobt.

Alt... Neu...
LPRINT HALLO"; lprint( "HALLO".FALSE)
LPRINT " DU DA" lprint(" DU DA".TRUE)
LPRINT "IM RADIO" lprint("IM RADIO",TRUE)

Da ich in der Anfangsphase der Programmierung auch besondere Probleme mit den Druckern hatte, möchte ich es den Einsteigern erleichtern, universelle Druckerausgaben auf verschiedenen Druckern realisieren zu können.

Druck dem Drucker

Viele Programmierer haben Probleme mit der Ansteuerung der verschiedenen Druckertypen. Da auch ich eines Tages vor dem Problem der Druckeranpassung stand, produzierte ich zwei kleine Programme, die es erlauben, einen Druckertreiber zu erstellen bzw. diesen Treiber anzusteuern.

Ein großes Augenmerk habe ich dabei auf möglichste 'Kompatibilität' mit dem bestehenden GFA-BASIC-Befehl LPRINT gelegt. Folgerichtig heißt auch die Prozedur, die die Ansteuerung des Druckers übernimmt, schlicht lprint(). Als Parameter für diese Prozedur werden als erstes der Text-String übergeben und anschließend ein Flag (Boolsche Variable), das angibt, ob nach der Zeile ein Wagenrücklauf (CR) und Papiervorschub (LF) durchgeführt werden soll. Anhand der folgenden Zeilen werden Sie die Notwendigkeit dieser Regelung erkennen:

Das Semikolon am Ende einer (L-)PRINT-Anweisung bedeutet, daß kein CR+LF ausgeführt werden soll. Bei der nächsten (L-)PRINT-Anweisung schreibt der Drucker/Bildschirm an derselben Position weiter, wo er das letzte Zeichen gedruckt hat. Da sich diese Regelung bei einem Prozedur-Aufruf nicht praktizieren läßt, bietet es sich an, ein Flag zu übergeben, das anzeigt, ob ein CR+LF ausgeführt werden soll. Wenn der Prozedur also ein TRUE (=-1) übergeben wird, wird der CR+LF ausgeführt, bei einem FALSE (=0) nicht.

Aus der Tatsache. daß an die Prozedur nur (Text-)Strings übergeben werden können, folgt, daß sich der USING-Befehl nicht wie bisher anwenden läßt. Doch auch hier gibt es eine einfache Lösung, indem einfach konsequent Texte über lprint() und Zahlen über USING ausgegeben werden. wie folgendes Beispiel illustrieren soll:

Die Kombination

lprint("Mineralölsteuer:", FALSE) 
LPRINT USING "#####.##",msteuer

entspricht dem alten

LPRINT USING "Mineralölsteuer: #####.##", msteuer

Das Wie

Als erstes möchte ich nun das Erstellen eines Treibers erläutern. Dazu existiert das Programm (1) (MAKE_ TRB.LST).

In der erscheinenden Fileselectbox geben Sie einen Namen für den zu erstellenden Treiber an. Sie sollten einen möglichst sprechenden Namen angeben. z.B. STARNB10.PRN, damit Sie später schnell den gewünschten Treiber wiederfinden. Nach dem Verschwinden der Fileselectbox werden Sie aufgefordert, eine bis zu 20 Zeichen umfassende Erklärung bzw. eine genaue Spezifizierung für den Treiber anzugeben. In dieser Zeile läßt sich z.B. auch der Druckername ausführlich eingeben. damit sich auch jeder Anwender zurechtfindet. Der eingegebene String wird ggf. auf eine Länge von 20 Stellen erweitert und in die Anpassungs-Datei geschrieben. Nun kommen wir zur eigentlichen Anpassung. Sie geben nun ein Zeichen, das Ihr Drucker nicht ohne weiteres drucken kann, an. Um Ihnen ein Beispiel geben zu können, nehme ich nun an, Sie hätten einen STAR NB24-10, und das anzupassende Zeichen sei ein "Ä". Dann geben Sie natürlich zunächst das “Ä" ein. Danach geben Sie die Codes an. die Ihren Drucker zum Ausgeben des Zeichens veranlassen. Für unser Beispiel wären das folgende Codes: 27 82 2 91 27 82 0. Um dem Programm zu sagen. daß nun keine Codes mehr für das "Ä" folgen, geben Sie eine negative Zahl. z.B. -1 an. Anschließend werden Sie nach einem weiteren Zeichen gefragt. daß der Anpassung bedarf: wenn Sie alle Ihre Problemzeichen angepaßt haben, drücken Sie einfach RETURN. Die Treiberdatei wird dann angelegt und steht für eine spätere Verwendung zur Verfügung.

Um die Treiberdatei in eigenen Programmen einsetzen zu können, existieren zwei Routinen. die sich im Programm (2) (USE_TRB.LST) versteckt halten.

Die erste Routine, load_printer(), erlaubt es, einen angefertigten Druckertreiber einzulesen. Dazu übergeben Sie den Pfad und den Namen des Treibers. z.B. \DRUCKER\NB2410.PRT. Von dieser Prozedur werden einige Variablen belegt, die in Ihrem Programm dann nicht mehr Vorkommen dürfen (s. Tabelle).

Wenn der Druckertreiber nicht gefunden wird bzw. es sich um keinen Druckertreiber handelt. gibt die Prozedur load_printer() eine entsprechende Meldung aus.

drucker_type_$ => Name/Bezeichnung des Druckers umlaute_$ => Tabelle der anzupassenden Zeichen zeichen_$ => Tabelle der Ersatz-Codes

Die andere Prozedur lprint() habe ich ja schon zuvor erwähnt: durch sie wird der Befehl LPRINT ersetzt. Das Vorgehen ist recht einfach: es wird untersucht, ob ein Zeichen des Text-Strings (a$) in dem unlaute_$ enthalten ist. Wenn nun z.B. unser "Ä" im Text-String enthalten ist. wird, ausgehend von der Position des "Ä" im umlaute_$, auf die Position der Anpassungszeichens im zeichen_$ geschlossen. Dann wird nachgesehen, wieviele Zeichen ausgegeben werden müssen, um den Umlaut zu ersetzen. Der Umlaut in a$ wird dann ersetzt durch die Zeichenfolge in umlaut_$. Anschließend wird das nächste Zeichen in a$ untersucht, wobei natürlich der Zählen, der angibt, welches Zeichen von a$ gerade untersucht wird. um die Anzahl der Anpassungscodes erhöht werden muß. damit nicht eventuell die Anpassungscodes noch einmal angepaßt werden. Nachdem dann aS ganz durchsucht worden ist. erfolgt die Ausgabe an den Drucker, entweder mit oder ohne CR+LF.

Außer den oben genannten Ausnahmen sind alle Variablen lokal definiert, so daß sich keine Überschneidungen ergeben sollten. In dieser Anpassung ist es noch nicht möglich. z.B. Fettdruck zu realisieren, es sei denn, man verwendet z.B. bestimmte griechische Zeichen zur Kennung für solche Textattribute. Die Erweiterung sollte Ihnen jedoch nicht besonders schwerfallen.

' *** Drucker-Treiber erzeugen ***
'
' 1989 Martin Fangmeyer
'
'
' (c) 1990 MAXON Computer GmbH

FILESELECT "\*.PRN","DRUCKER.PRN",file$ ! Datei auswählen
'
IF file$<>""
    OPEN "O",#1,file$ ! Zum Schreiben öffnen
    '
    PRINT #1,"Treiber"; ! Kennung für Treiber schreiben
    '
    PRINT "Name des Treibers (Druckertype...)   : ";
    FORM INPUT 20,drucker_type_$ ! Name des Druckers abfragen...
    PRINT #1,LEFT$(drucker_type_$+SPACE$(20),20); ! ...und in die Datei schreiben
    '
    REPEAT
        PRINT
        PRINT "Zu ersetzendes Zeichen [RETURN]=Ende:        ";
        FORM INPUT 1,char$      ! Umlaut einlesen
        ascii%=ASC(char$)
        IF ascii%>0             ! Schon fertig ?
            PRINT               ! Nein
            umlaute_$=umlaute_$+char$ ! Umlaut an die Liste anhängen 
            PRINT "Ersetzen des Zeichens '";char$;"''   durch die folgenden,"
            PRINT "Codes (Werte <0=ENDE):"  ! ...ein wenig Text auf den Schirm
            CLR a%,code_neu$    ! Variablen löschen
            REPEAT
                PRINT USING "##",a%+1;
                INPUT ". Code: ",code% ! code% abfragen 
                IF code%=>0     ! code% ok (=>0)?
                    code_neu$=code_neu$+CHR$(code%) ! Ja, an die Liste anhängen 
                    INC a%
                ENDIF
            UNTIL a%=>10 OR code%<0 ! Max. 10 Codes einiesen 
            IF a%>0             ! War was da ?
                ' zeichen_$ auf gültiges Format 
                zeichen_$=zeichen_$+CHR$(a%)+LEFTS(code_neu$+STRING$(10,0),10)
            ELSE                ! Keine Codes eingegeben
                umlaute_$=LEFT$(umlaute_$,LEN(umlaute_$)-1) ! => umlaute_$ kürzen
            ENDIF
        ENDIF
    UNTIL ascii%=0              ! [RETURN] für Ende?
    '
    OUT #1,LEN(umlaute_$)       ! Anzahl der umlaute_$ schreiben...
    '
    PRINT #1,umlaute_$;         ! ...Umlaute selbst
    '
    PRINT #1,zeichen_$;         ! ...Anpassungen...
    '
    CLOSE #1                    ! Ende der Unterhaltung
ENDIF
' *** Drucker-Treiber ***
'
'   1989 Martin Fangmeyer
'
'
' (c) 1990 MAXON Computer GmbH
' *** Treiber einlesen ***
'
PROCEDURE load_printer(a$)      ! Treiber laden 
    LOCAL a%
    IF EXIST(a$)                ! Datei da ?
        OPEN "I",#1,a$          ! ja, öffnen
        IF INPUTS(7,#1)<>"Treiber" ! Treiber-Kennung vorhanden ?
            ALERT 2,"Kein Drucker-Treiber !",1, "Weiter",a% ! Nein => Fehler
        ELSE                    ! Treiber o.k.
            drucker_type_$*INPUT$(20,#1) ! Bezeichnung für den Treiber 
            a%=LEN(drucker_type_$)       ! SPACE-Zeichen am Ende entfernen 
            WHILE MID$(drucker_type_$,a%,1)=" " AND a%>0
                DEC a%
            WEND
            drucker_type_$=LEFT$(drucker_type_$,a%)
            '
            a%=INP(#1)          ! Länge des Umlaute-Strings
            IF a%>0             ! Überhaupt was da ?
                umlaute_$=INPUT$(a%,#1) ! Ja, lesen
                '
                zeichen_$=INPUT$(a%*11,#1) ! Code-Tabellen lesen
            ENDIF 
        ENDIF
        CLOSE #1                ! Datei schließen
    ELSE
        ALERT 2,"Drucker-Treiber|nicht gefunden !",1, "Weiter",a% ! Datei nicht da!
    ENDIF
RETURN
'
' *** Ersetzen der Umlaute durch die entsprechenden Codes ***
'
PROCEDURE lprint(a$,flag!)
    LOCAL a%,b%,c%
    IF umlaute_$<>""            ! Treiber definiert ?
        a%=1                        ! Ja, a$ vom ersten...
        WHILE a%<=LEN(a$)           ! ...bis zum letzten
            b%=INSTR(umlaute_$,MID$(a$,a%,1)) ! Aktuelles Zeichen in Tabelle ?
            IF b%>0                 ! Und ob!
                MUL b%,11           ! Position der Ersatz-Codes 
                SUB b%,10           ! in zeichen_$ berechnen..
                c%=ASC(MID$(zeichen_$,b%)) ! Anzahl der Ersatz-Codes 
                IF c%>0             ! Was zu ersetzen ?
                    INC b%          ! Ja
                    '
                    ' Nun die Codes in den Original-String hineinpacken...
                    '
                    a$=LEFT$(a$,a%-1)+MID$(zeichen_$,b%,c%)+MID$(a$,a%+1)
                    ADD a%,c%       ! Suchposition in a$ erhöhen
                ELSE                ! Kein Ersatz-Code definiert
                    a$=LEFT$(a$,a%-1)+MID$(a$,a%+1) ! => Zeichen löschen
                ENDIF
            ELSE                    ! Kein Umlaut
                INC a%              ! => nächstes Zeichen prüfen
            ENDIF 
        WEND 
    ENDIF
    IF flag!                        ! Ausgabe mit Line-Feed ?
        LPRINT a$                   ! Nein!
    ELSE
        LPRINT a$;                  ! Doch
    ENDIF
RETURN                              ! That's all...

Martin Fangmeyer
Aus: ST-Computer 05 / 1990, Seite 89

Links

Copyright-Bestimmungen: siehe Über diese Seite