MultiTOS für Einsteiger Teil 3

Diesmal wollen wir ein wenig vom reinen Einsteigerpfad abweichen, aber nur, um Ihnen die Arbeit mit MINIWIN zu erleichtern. Keine Panik, alles, was Sie brauchen, ist ein Editor!

Wie schon in den vorherigen Teilen unseres Kurses erwähnt, erlaubt es MINIWIN, TOS- bzw. TTP-Programme unter MultiTOS in einem eigenen Fenster auszuführen. Im Prinzip müssen Sie sich darum überhaupt nicht kümmern (vorausgesetzt, MultiTOS ist richtig installiert), ein Doppelklick auf ein TOS-/TTP-Programm aus dem Desktop heraus genügt, MultiTOS erkennt Ihr Ansinnen selbständig und startet MINIWIN, das wiederum Ihr gewünschtes Programm in einem Fenster zum Leben erweckt. Zwar können Sie in der standardmäßig auftauchenden Menüleiste diverse Einstellungen für MINIWIN vornehmen, Ihr TOS-/TTP-Programm wird dadurch allerdings immer noch nicht komfortabler. Vor den Komfort haben die Götter den Schweiß gesetzt.

MINIWIN hat die „allerliebste“ Fähigkeit, ein wenig Unterstützung Ihrerseits vorausgesetzt, ein TOS-/TTP-Programm mit einer eigenen Menüleiste und, darin integriert, mit diversen Makros zu versehen. Da bisher noch niemand den Weg gefunden hat, einen Computer mit hellseherischen Fähigkeiten auszustatten, liegt es an Ihnen, eine passende Menüleiste zu entwerfen. Beim Start eines TOS-/TTP-Programmes sucht MINIWIN eine Datei gleichen Namens mit der Endung MNU. Sie wollen zum Beispiel das Programm GETKEY.TOS mit einer selbstdefinierten Menüzeile versehen, dann sollte sich

die Datei GETKEY.MNU im gleichen Verzeichnis befinden. Natürlich kann MINIWIN Ihr TOS-/TTP-Programm auch nicht mit dem MNU-File in ein GEM-Programm mit Menüzeile verwandeln, aber es zieht sich geschickt aus dieser Affäre, indem es dem TOS-/TTP-Programm einfach Tastatureingaben vorspielt. Reagiert Ihr Programm zum Beispiel auf die Tastenkombination Control+A, Control+Wmit dem Spielen einer Melodie, können Sie sich via MINIWIN ein Menü mit dem Eintrag Musike definieren. Das Anwählen dieses Eintrags würde nun MINIWIN dazu veranlassen, die Tastenkombination Control+A, Control+W an das TOS-/TTP-Programm im Fenster zu schicken.

Die *.MNU-Datei

Der Aufbau einer MNU-Datei ist im Prinzip recht einfach, es handelt sich um einen einfachen Text mit entsprechenden Befehlen. daher genügt zum Erstellen einer MNU-Datei ein ASCII-Editor, bzw. Sie sollten auch nur einen solchen für diese Arbeit verwenden, da MINIWIN auf die Verdauung der Steuerzeichen von 1st Word oder ähnlichem garantiert mit einem „bombigen“ Schluckauf reagiert. Allerdings sollten Sie auch sonst bei der Erstellung und dem Austesten der MNU-Dateien nach Möglichkeit keine wichtigen Programme im Hintergrund laufen lassen, da MINIWIN sich, was die Syntax angeht, mitunter recht kleinlich zeigt und bei Fehlern zur Strafe das gesamte System in die ewigen Jagdgründe schickt. Wahrscheinlich ist dies auch der Grund, warum ATARI dieses Feature wenig bzw. überhaupt nicht dokumentiert hat.

Die Befehle

Wie zu alten Fortran-/Cobol-Zeiten (ja,ja, alles kommt wieder) ist in den MNU-Files die Stellung eines Befehls im Verhältnis zum Zeilenanfang von Bedeutung, ebenso muß ein Befehl in eine Zeile passen. Ein Beispiel:

Datei
"Das ist ein Eintrag“ 0065 3b00

Der Titel eines Menüs (hier: Datei) muß immer ganz am Anfang einer Zeile stehen. Besteht er aus mehreren Wörtern, muß er auch noch in Anführungszeichen gesetzt werden. Die einzelnen Einträge unter einem Titel sind durch Einrücken um ein oder mehrere Leerzeichen gekennzeichnet. Auch ein Eintrag braucht einen Namen (hier: “Das ist ein Eintrag “) und für den gilt das gleiche wie für den Titel, bei mehreren Wörtern in Anführungszeichen setzen! Durch ein oder mehrere Leerzeichen bzw. Tabs getrennt folgt der. Code einer Taste oder ein kompletter Text in Anführungszeichen, der bei der An wähl des Eintrags an das TOS-Programm geschickt wird. Optional kann man auch noch ein Tastaturkürzel für den Eintrag, wiederum durch Blank(s) getrennt, angeben. Verwirrt? Zerpflücken wir das Beispiel:

Datei -> Das ist der Menütitel:
“Das ist ein Eintrag“ -> Der erste Eintrag.
0065  -> Der Hex-Code für ein „e“, dieses 
         wird an das Programm gesendet. 
         Hex-Codes müssen immer vierstellig 
         angegeben werden.
3b00  -> Der Hex-Code für die F1-Taste, 
         quasi ein Minimakro. Wird das 
         Makro nicht gewünscht, sollte man 
         0000 schreiben!

Anstelle von 0065 könnte z.B. auch “Juchu", also ein Text in Anführungsstrichen stehen. Beide Methoden können beliebig gemischt Verwendung finden, z.B. mit “Juchu“000d folgt dem Text ein Return. ACHTUNG! Das gilt nicht für das Tastaturkürzel (3b00), hier muß immer ein vierstelliger Hex-Code stehen. Wichtigste Regel: Wenn Leerzeichen in einer Definition Vorkommen, muß der Text in Anführungsstrichen stehen!

Was ist nun eigentlich dieser ominöse vierstellige Hex-Code? Er setzt sich zusammen aus dem Scan-Code (die ersten zwei Stellen) und dem ASCII-Code (die letzten zwei Stellen) einer Taste. Aha, sehr schön. Und was sind Scan- bzw. ASCII-Code? Ääähm, also der Scan-Code ist praktisch die Nummer der Taste, „Esc“ z.B. beginnt den Reigen mit der Nummer 1 gefolgt von der Taste „1/!“ mit der Nummer 2 usw. Der ASCII-Code wiederum gibt praktisch die Aufschrift der (Buchstaben-)Tasten als Zahl wieder. Die Taste „A“ z.B. hat den Scan-Code 1e und den ASCII-Code 61. Beide Codes hintereinander geschrieben ergeben 1e61, den von MINIWIN gewünschten Hex-Code. Einfach, nicht? Als Besonderheit haben die Sondertasten (F1-F10, Help, Undo usw.) keinen ASCII-Code, also sind die letzten zwei Stellen bei Ihnen 00 (z.B. Undo hat den Code 6100). Um die Verwirrung komplett zu machen, können Sie sich bei den Zeichentasten (1234.., ABCDEF..., !$% &... usw.) wiederum den Scan-Code schenken, in diesem Falle sind die ersten zwei Stellen 00. Ein A kann also als 1e61 oder 0061 angegeben werden, ganz nach Belieben.

Damit Sie sich nun nicht mehr den Kopf über diese Codes zerbrechen müssen, finden Sie in den Listings 2 und 3 das Programm GETKEY in zwei Ausführungen, einmal in C (GETKEY.C) und einmal in GFA-BASIC (GETKEY.LST), selbstflüsternd sind beide Versionen von den Funktionen her identisch. Dieses einfache Machwerk gibt nach einem beliebigen Tastendruck den entsprechend Hex-Code aus, diesen können Sie direkt in Ihre MNU-Datei übernehmen. Auch zum Testen von Menüs hat es sich als nützlich erwiesen, da es unter MINIWIN auch die „simulierten“ Eingaben anzeigt.

Am besten, Sie werfen nun Ihren Rechner an, starten MultiTOS und „gewöhnen“ sich zuerst an diese „einfachen“ Menüs, denn es geht auch noch deutlich komplizierter.

Für noch mehr Komfort bietet MINIWIN auch noch Alert- und Fileselect-Boxen! Die Zeile

Quit ?“[2][Wirklich beenden?] [ Ja | Nein ]“:011b:! 001b

zum Beispiel erzeugt den Menüeintrag „ Quit Esc“ und stellt nach der Anwahl von „Quit“ eine Alert-Box mit einem Fragezeichen, dem Text „Wirklich beenden?“ und den zwei Buttons „Ja“ und „Nein“ dar. Nach dem Anklicken von „Ja“ wird die Taste 011b (Esc) an das TOS-/TTP-Programm gesendet. Ein Klick auf „Nein“ bleibt dagegen ohne Folgen (dafür sorgt das „!“). Der prinzipielle Syntax sieht also so aus: Eine Alert-Box beginnt immer mit einem Fragezeichen, gefolgt von ihrer Definition im normalen AES-Format in Anführungszeichen. Es folgt ein Doppelpunkt, und danach kommen Tasten oder Texte getrennt durch weitere Doppelpunkte, entsprechend der Anzahl von Buttons. Soll auf einen Button nicht mit einet Taste oder einem Text reagiert werden,'kömmt das Ausrufungszeichen zum Einsatz, es dient also als Dummy.

Damit Sie Ihre Dateinamen nicht immer von Hand einhacken müssen, stellt MINIWIN auch noch Fileselect-Boxen zur Verfügung. Ein Beispiel:

“Voller Pfad“ @“Bitte wählen“&P 0000

Hiermit wird der Menüeintrag „Voller Pfad“ ohne Makro generiert. Nach dessen Anwahl gibt MINIWIN eine Fileselect-Box mit der Überschrift „Bitte wählen“ aus.,Folgen Sie dieser Aufforderung und wählen eine Datei an, sendet die Variable &P den vollen Pfadnamen an das TOS-/ TTP-Programm. Wird nur der Dateiname gebraucht, verwenden Sie anstelle von &P die Variable &F. Natürlich können auch Alert- und Fileselect-Boxen kombiniert werden:

“Mit Frage“ @“Bitte wählen“?“[2][Voller Pfad?][Ja|Nein|Abbruch]“:&P:&F:!

Dieser Bandwurm stellt eine Fileselect-Box, gefolgt von einer Alert-Box dar! Dieses und weitere Beispiele finden Sie in „funktionsfähiger“ Form im Listing 1 (GETKEY.MNU). Am besten lernen Sie die Fähigkeiten von MINIWIN kennen, wenn Sie mit GETKEY und diesem MNU-File ein wenig „hemmexperimentieren“. In diesem Sinne, viel Spaß bis nächsten Monat...


Datei
 Quit ?"[2][Wirklich beenden?][ Ja | Nein ]":011b:!001b

Tasten
 "Pfeil nach oben"      4800 4800
 "Pfeil nach unten"     5000 5000
 "Pfeil nach links"     4b00 4b00
 "Pfeil nach rechts"    4d00 4d00
---
Help 6200 6200
Undo 6100 6100
---
Alternate+A 1e00 1e00
Alternate+B 3000 3000
---
Control+Y 0019 0019
Control+V 0016 0016
---
"Ein Macro" 00010006 3200
---
"Ein ganzer Satz + Return" "Dies ist ein Test"000d 1f00

Fragen
 "1 Button"  ?"[1][1 Button Test][ OK ]":"O" 7800 
 "2 Buttons" ?”[1][2 Buttons Test][ A | B ]":"a":"b" 7900
 "3 Buttons" ?"[1][3 Buttons Test][ 1. | 2. | 3.]":"1":"2"s"3" 7a00
 Ja/Nein ?"[3][Ja oder Nein?|Das ist...][ Ja | Nein ]":"ja":! 2400

Dateiauswahl
 "Voller Pfad" @"Bitte wählen"&P 
 "Nur Filename" @"Bitte wahlen"&F 
 "Mit Frage" @"Bitte wählen"?"[2][Voller Pfad?][Ja|Nein|Abbruch]":&P:&F;!

Listing 1: GETKEY.MNU


/* GETKEY.C, Pure C
 *
 * Gibt die für MINIWIN nötigen
 * Tastaturcodes aus!
 * Autor: Richard Kurz
 * (c) 1993 by MAXON 
 */

#include <stdio.h>
#include <screen.h>
#include <string.h>

#define TRUE 1 
#define FALSE 0

#define MAX_TAST 53

/* Daten für die Sondertasten */ 
static struct 
{
    int sc; 
    int as; 
    char t[30];
}stasten[MAX_TAST]=
{
    {0x1c,0x0d,"Return"},
    {0x72,0x0d,"Enter"},
    [0x01,0x1b,"Escape"},
    {0x53,0x7f,"Delete"},
    {0x0e,0x08,"Backspace"},
    {0x0f,0x09,“Tab"},
    {0x39,0x20,"Space"},
    {0x3b,0x00,"F1"},
    {0x3c,0x00,"F2"},
    {0x3d,0x00,"F3"},
    {0x3e,0x00,"F4"},
    {0x3f,0x00,“F5"},
    {0x40,0x00,"F6"},
    {0x41,0x00,"F7"},
    {0x42,0x00,"F8"},
    {0x43,0x00,"F9"},
    {0x44,0x00,"F10"},
    {0x54,0x00,"Shift+F1"},
    {0x55,0x00,"Shift+F2"},
    {0x56,0x00,"Shift+F3"},
    {0x57,0x00,"Shift+F4"},
    {0x58,0x00,"Shift+F5"},
    {0x59,0x00,"Shift+F6"},
    {0x5a,0x00,"Shift+F7"},
    {0x5b,0x00,"Shift+F8"},
    {0x5c,0x00,"Shift+F9"},
    {0x5d,0x00,"Shift+F10"},
    {0x62,0x00,"Help"},
    {0x61,0x00,"Undo"},
    {0x52,0x00,"Insert"},
    {0x47,0x00,"Clr/Home"},
    {0x48,0x00,"Pfeil nach oben"},
    {0x50,0x00,"Pfeil nach unten"},
    {0x4b,0x00,"Pfeil nach links"},
    {0x4d,0x00,"Pfeil nach rechts"},
    {0x48,0x38,"Shift+Pfeil nach oben"},
    {0x50,0x32,"Shift+Pfeil nach unten"},
    {0x4b,0x34,"Shift+Pfeil nach links"},
    {0x4d,0x36,"Shift+Pfeil nach rechts"},
    {0x73,0x00,"Control+Pfeil nach links"},
    {0x74,0x00,"Control+Pfeil nach rechts“},
    {0x78,0x00,"Alternate+1"},
    {0x79,0x00,"Alternate+2"},
    {0x7a,0x00,"Alternate+3"},
    {0x7b,0x00,"Alternate+4"},
    {0x7c,0x00,"Alternate+5"},
    {0x7d,0x00,"Alternate+6"},
    {0x7e,0x00,"Alternate+7"},
    {0x7f,0x00,"Alternate+8"},
    {0x80,0x00, "Altemate+9"},
    {0x81,0x00,"Alternate+0"},
    {0x82,0x00,"Alternate+ß"},
    {0x83,0x00,"Alternate+'"},
};

char *get_name(int scan, int ascii)
/* Erzeugt den Namen für eine Taste */
{
    static char t[30];
    KEYTAB *keys; 
    int i;

    for(i = 0;i<MAX_TAST;i++)
    {
        if(stasten[i].as==ascii && stasten[i].sc==scan)
        {
            strcpy(t,stasten[i].t); 
            return t;
        }
    }

    if(!ascii && scan<128)
    {
        keys=Keytbl((char *)-1,(char *)-1,(char *)-1); 
        sprintf(t,"Alternate+%c",keys->shift[scan]);
    }
    else if(ascii<32)
        sprintf(t,"Control+%c\n",ascii+64); 
    else if(ascii)
        sprintf (t, "%c", ascii); 
    else
        strcpy(t,"Sondertaste???\n"); 
    return t;
}/* get_name */

char *to_hex(int scan, int ascii)
/* Generiert den Hexcode */
{
    static char t[30]; 
    int i;

    sprintf(t,"%4X",(scan<<8)+ascii);
    for(i=0;t[i];i++)if(t[i]==' ')t[i]='0’;
    return t;
}/* to_hex */

int main(void)
/* Hier spielt die Musik */
{ 
    long taste; 
    int scan,ascii;

    Clear_home();
    puts("Taste drücken,"); 
    puts("Abbrechen mit Esc\n");

    do
    {
        taste=Crawcin();
        ascii=((unsigned char *)&taste)[3]; 
        scan=((unsigned char *)&taste)[1]; 
        printf("%s, ",to_hex( scan, ascii)); 
        printf("%s\n",get_name(scan,ascii)); 
    } while (ascii!=27);

    return 0;
}/* main */

Listing 2: GETKEY.C


; Pure C Projekt-Datei für GETKEY

getkey.tos
=
pcstart.o 
getkey.c 
pcstdlib.lib 
pctoslib.lib

Listing 3: GETKEY.PRJ


' GETKEY.LST, GFA-BASIC 3.5
'
' Gibt die für MINIWIN nötigen 
' Tastaturcodes aus!
' Autor; Richard Kurz
' (c) 1993 by MAXON
'
DEFINT "a-z"
@main
END
'
' Daten für die Sondertasten
'
sondertasten:
DATA $1c,$0d,"Return"
DATA $72,$0d,"Enter"
DATA $01,$1b,"Escape"
DATA $53,$7f,"Delete"
DATA $0e,$08,"Backspace"
DATA $0f,$09,"Tab"
DATA $39,$20,"Space"
DATA $3b,$00,"F1"
DATA $3c,$00,"F2"
DATA $3d,$00,"F3"
DATA $3e,$00,"F4"
DATA $3f,$00,"F5"
DATA $40,$00,"F6"
DATA $41,$00,“F7"
DATA $42,$00,"F8"
DATA $43,$00,"F9"
DATA $44,$00,"F10"
DATA $54,$00,"Shift+F1"
DATA $55,$00,"Shift+F2"
DATA $56,$00,"Shift+F3"
DATA $57,$00,"Shift+F4"
DATA $58,$00,"Shift+F5"
DATA $59,$00,"Shift+F6"
DATA $5a,$00,"Shift+F7"
DATA $5b,$00,"Shift+F8"
DATA $5c,$00,"Shift+F9"
DATA $5d,$00,"Shift+F10"
DATA $62,$00,"Help"
DATA $61,$00,"Undo"
DATA $52,$00,"Insert"
DATA $47,$00,"Clr/Home"
DATA $48,$00,"Pfeil nach oben"
DATA $50,$00,"Pfeil nach unten"
DATA $4b,$00,"Pfeil nach links"
DATA $4d,$00,"Pfeil nach rechts" 
DATA $48,$38,"Shift+Pfeil nach oben"
DATA $50,$32,"Shift+Pfeil nach unten" 
DATA $4b,$34,"Shift+Pfeil nach links" 
DATA $4d,$36,"Shift+Pfeil nach rechts" 
DATA $73,$00,"Control+Pfeil nach links" 
DATA $74,$00,"Control+Pfeil nach rechts" 
DATA $78,$00,"Alternate+1"
DATA $79,$00,"Alternate+2"
DATA $7a,$00,"Alternate+3"
DATA $7b,$00,"Alternate+4"
DATA $7c,$00,"Alternate+5"
DATA $7d,$00,"Alternate+6"
DATA $7e,$00,"Alternate+7"
DATA $7f,$00,"Alternate+8"
DATA $80,$00,"Alternate+9"
DATA $81,$00,"Alternate+0"
DATA $82,$00,"Alternate+ß"
DATA $83,$00,"Alternate+'"
DATA $00,$00,"Ende"
'
' Erzeugt den Namen zu einer Taste
'
FUNCTION get_name$(scan,ascii)
    LOCAL s,a,keys,t$
    RESTORE sondertasten
    DO
        READ s,a,t$
        EXIT IF t$="Ende"
        IF s=scan AND a=ascii 
            RETURN t$
        ENDIF
    LOOP
    '
    IF ascii=0 AND scan<128 
        ' XBIOS Keytab
        keye=XBIOS(16,L:-1,L:-1,L:-1) 
        keys=LPEEK(keys+4)
        t$="Alternate+"+CHR$(PEEK(keys+scan)) 
    ELSE IF ascii<32
        t$="Control+"+CHR$(ascii+64)
    ELSE IF ascii 
        t$=CHR$(ascii)
    ELSE
        t$="Sondertaste???"
    ENDIF
    '
    RETURN t$
ENDFUNC
'
' Generiert den Miniwin-Hexcode
'
FUNCTION to_hex$(scan, ascii)
    LOCAL i,wert,t$
    '
    wert=SHL(scan,8)+ascii 
    t$=HEX$(wert) 
    i=LEN(t$)
    WHILE i<4 
        t$="0"+t$
        INC i 
    WEND
    RETURN t$
ENDFUNC
'
' Die Haupt-Procedure
'
PROCEDURE main
    LOCAL taste,scan,ascii
    '
    CLS
    PRINT "Taste drücken"
    PRINT "Abbrechen mit Esc"
    REPEAT
        ' GEMDOS Crawcin 
        taste=GEMDOS(7) 
        ascii=BYTE(taste) 
        scan=BYTE(SHR(taste,16))
        PRINT @to_hex$(scan,ascii);", ";
        PRINT @get_name$(scan,ascii)
    UNTIL ascii=27 
RETURN

Listing 4: GETKEY.LST


Richard Kurz
Aus: ST-Computer 10 / 1993, Seite 104

Links

Copyright-Bestimmungen: siehe Über diese Seite