Tips und Tricks für Programmierer

Hilfesystem mit Form-Alert

Damit Sie Ihr Programm noch anwenderfreundlicher gestalten, sollten Sie dem Anwender ein Hilfesystem zur Verfügung stellen. Dazu bieten die »form_alert«-Boxen des GEM eine einfache Lösung. In diese Boxen passen fünf Zeilen Text - natürlich ist eine Hilfe in der Regel länger. Aus diesem Grund verteilen wir den Text auf mehrere Dialogboxen. Auf der TOS-Diskette finden Sie die C-Routine »helpsystem(char *helptext)«, die einen Hilfetext darstellt und dabei dem Anwender erlaubt, den Text seitenweise vor- und zurück zu blättern. Folgt in der Hilfe noch mindestens eine weitere Seite, so erscheint neben dem »OK«-Knopf zusätzlich der »VOR«-Knopf. Zum Zurückblättern dient der »ZURÜCK«-Knopf. Der Aufbau des Hilfetextes für die »helpsystem«-Funktion ist äußerst einfach: Sie trennen Zeilen mit »\« und Seiten mit einem Klammeraffen (»@«). Die letzte Seite besitzt dieses Symbol jedoch nicht. Beachten Sie allerdings, daß jede Seite maximal fünf Zeilen und jede Zeile maximal 30 Zeichen umfassen darf. Außerdem ist es empfehlenswert, in jeder Seite die jeweils längste Zeile mit einem Leerzeichen zu beenden. Dadurch stellen Sie sicher, daß zwischen Text und der rechten Rahmenseite wenigstens ein Zeichen Platz ist. (ba)

Ein Mausbeschleuniger für eigene Programme

Damit auch Ihre Programme stets eine beschleunigte Maus aufweisen, verwenden Sie den Mausbeschleuniger aus Listing 1 . Er ist sehr kurz (ca. 100 Byte), läßt sich jederzeit ein- und ausschalten und verwendet das XBRA-Protokoll zum Verbiegen der Systemvektoren. Außerdem arbeitet er unabhängig von Ihrem Programm und ist - sofern Sie ihn nicht vorher ausschalten - auch noch im Desktop und in anderen Programmen aktiv. Da der Mausbeschleuniger in Assembler programmiert ist, läßt er sich von nahezu jeder Programmiersprache aufrufen. Dazu verwenden Sie die Routine »on_mspeeder«. Sie installiert den Beschleuniger in dem sicheren RAM-Bereich ab $600 (»target«). Zum Ausschalten rufen Sie die Routine »off_mspeeder« auf. Hinweise zum Aufruf von Assembler-Routinen, beziehungsweise der Einbindung finden Sie in der dazugehörigen Bedienungsanleitung. (ba)

; Mausbeschleuniger von Martin Backschat
target:	equ	$0600
off_mspeeder:		; Mausbeschl. ausschalten
	movem.l	d1-a6, -(sp)
	lea	deinit, a4
	bsr	call
	movem.l	(sp)+, d1-a6
	rts
on_mspeeder:		; Mausbeschl. einschalten
	bsr	off_mspeeder
	movem.l	d1-a6, -(sp)
	lea	init, a4
	bsr	call
	movem.l	(sp)+ ,d1-a6
	rts
call:
	move.w	#34, -(sp)	; vektorliste von
	trap	#14	; Tastaturproz-
	movea.l	d0, a3	; Interrupts holen
	move.l	a4, -(sp)
	move.w	#38, -(sp)
	trap	#14
	addq.l	#8, sp
	rts
deinit:
	cmpi.l	#‘TOSm‘, target+4
	bne	exit
	move.l	target+8, d0
	beq	exit
	move.l	d0, 16(a3)
exit:
	clr.l	target+4
	rtsinit:
	lea	start(pc), a0
	lea	end(pc), a1
	lea	target, a2
copyarea:
	move.w	(a0)+, (a2)+
	cmpa.l	a0, a1
	bne	copyarea
	movea.l	16(a3), a1	; alter Mausvektor
	move.l	a1, target+8	; alter Inhalt retten
	move.l	#target+12, 16(a3)	; Vektor setzen
	rts		; fertig
start:
	dc.l	‚XBRA‘,‘TOSM‘	; FCopy MouseSpeeder
old:	dc.l	0
turbo:
	movem.l	d0-d2/a0, -(sp)	; benötigte Register retten
	cmpi.b	#$f8, (a0)	; ist es ein Mausinterrupt
	bcs	msend	; nein
	cmpi.b	#$fc, (a0)+
	bce	msend	; nein

	move.b	(a0)+, d0	; x-Bewegung
	move.b	(a0)+, d1	; y-Bewegung
	cmpi.b	#2, d0
	bls.s	l01
	move.b	d0, d2
	bpl.s	l00
	neg.b	d2
l00:	mulu	d2, d0
l01:	cmnpi.b	#2, a1
	bls.s	l03
	move.b	d1, d2
	bpl.s	l02
	neg.b	d2
l02:	mulu	d2, d1
l03:	move.b	d1, -(a0)	; Werte zurückschreiben
	move.b	d0, -(a0)
insend:
	movem.l	(sp)+, d0-d2/a0	; Register
	move.l	old(pc), -(sp)
	rts
end

Wer bin ich?

GEM-Programme können ihren eigenen Namen ermitteln - ab TOS 1.4 auch den Ordner, in dem sie liegen. Dazu dient die AES-Funktion »shel_read«:

#include <stdio.h>
#include <aes.h>
void main()
{
	char name[128];
	char args[128];
	appl_init();
	shel_read (name, args);
	printf ("Programmname: "%s\n", name);
	printf ("Argumentzeile: "%s\n", args);
	(void) getchar ();
	appl_exit();
}

Beachten Sie, daß die beiden an »shel_read« übergebenen String-Variablen mindestens 128 Byte umfassen müssen, um etwaige Fehler zu vermeiden. (Thomas Tempelmann /ah)

Auf Dateiensuche

Haben Sie schon bemerkt, daß die AES-Funktion »rsrc_load« »RSC«-Dateien auch findet, wenn diese nicht im aktuellen Verzeichnis, sondern beispielsweise im Wurzelverzeichnis stehen? Wenn Sie eine alternative Benutzeroberfläche wie »Gemini« benutzen, können Sie sogar alle RSC-Dateien in einen beliebigen Ordner packen und diesen Pfad in der Environment-Variable »PATH« angeben. Im Grunde stützt sich »rsrc_load« auf die Funktion »shel_find«, die beliebige Dateien suchen kann. Sie erhält einen Dateinamen und sucht diesen dann im aktuellen Verzeichnis und im Wurzelverzeichnis des Bootlaufwerks. Betriebssysteme ab TOS-Version 1.4 durchforsten zusätzlich das Inhaltsverzeichnis, von dem das Programm gestartet wurde (in der Regel identisch mit dem aktuellen Verzeichnis). Sie sollten diese Funktion auch selbst benutzen, wenn Sie noch weitere zu Ihrem Programm gehörende Dateien laden, beispielsweise eine ».INF«-Datei. (Thomas Tempelmann /ah)

#include <stdio.h>
#include <aes.h>
void main()
{
	char name [128];
	appl_init();
	printf ("In Welcher Datei suchen?");
	scanf ( "&s", name);
	shel_find (name);
	printf ("\n Gefunden: %s\n", name);
	(void) getchar();
	appl_exit();
}

Fehlermeldungen über das Desktop

Wenn ein Programm noch in der Initialisierungsphase einen Fehler feststellt, der nur einen Programmabbruch zuläßt (Datei nicht gefunden oder akuter Speicherplatzmangel), ist eine Fehlermeldung erforderlich. Handelt es sich uni eine GEM-Anwendung, ist der Aufruf von »form_alert« blockiert, falls GEM zu diesem Zeitpunkt noch nicht initialisiert ist. Terminieren Sie daher Ihr Programm Über die GEMDOS-Funktion »Pterm«. Dort geben Sie einen der folgenden Werte an. Im Desktop erscheint eine entsprechende Fehlermeldung. (Thomas Tempelmann/ah)

Fehlernummer Meldung
-33, -34: Diese Anwendung kann das angegebene Objekt nicht finden
-35: Kein Speicherplatz um Dokument zu öffnen, Bitte anderes Dokument schließen
-39: Für diese Anwendung steht nicht genügend Speicherplatz zur Verfügung
-46: Laufwerk mit dieser Kennung unbekannt

Tabelle 1. Die Fehlernummern des GEMDOS

Diskette voll und keine Fehlermeldung?

In der Regel liefern die GEMDOS-Funktionen negative Werte, um Fehler mitzuteilen. »Fwrite« liefert zum Beispiel im Fall einer defekten Diskette den Wert -6. Allerdings liefert diese Funktion keinen negativen Wert, falls die Diskette voll ist und so die Daten nicht mehr gespeichert wurden. Stattdessen erhalten Sie dann, wie auch bei erfolgreichem Zugriff, die Anzahl der wirklich gespeicherten Bytes zurück. Viele Programme beachten dies leider nicht und lassen auf diese Weise kommentarlos Daten bei einer vollen Diskette verschwinden. Um ein erfolgreiches Speichern zu erkennen, müssen Sie also bei »Fwrite« den erhaltenen Wert mit dem Sollwert der zu schreibenden Daten vergleichen. Dazu ein Beispiellisting in C: (Thomas Tempelmann/ah)

anzahl = 100;	/* 100 Byte schreiben */
if (Fwrite (handle, anzahl, puffer) != anzahl)
	/*Fehler-Routine! */
	...
else
	/* Speichern war erfolgreich */

...Von sichtbaren und unsichtbaren Mäusen

Viele GEM-Programme schalten gelegentlich die Maus ein oder aus. Doch mit welcher Funktion? Da gibt es »graf_mouse« im AES, »v_hide_c« im VDI‚ und die Line A-Routinen erwähnen wir besser erst gar nicht. Von diesen Routinen sollte jeder GEM-Programmierer die Finger lassen, wenn er keine Inkompatibilitäten mit späteren TOS-Versionen oder neuen Grafikkarten riskieren will. Nun scheinen die VDI-Funktionen etwas bequemer zu sein, zumindest entscheiden sich viele Programmierer für diese Funktion. Das ist aber grundlegend falsch. Finger weg von den VDI-Funktionen »v_show_c« und »v_hide_c«. Denn AES und VDI merken sich von unabhängig voneinander, ob die Maus sichtbar ist. Wenn Sie nun über das VDI die Maus abschalten, merkt das AES nichts von alledem. Bei einem nachfolgenden AES-Aufruf von »form_alert« bleibt die Maus unsichtbar - ein sogar bei so manchem kommerziellen Programm zu beobachtender, unliebsamer Effekt. Nur wenn Sie mit »graf_mouse« die Maus abschalten, schaltet »form_alert« diese, falls nötig, wieder an. (Thomas Tempelmann /ah)

Tastenklick abschalten ohne Control-Accessory

Stört Sie der Klickton beim Drücken jeder Taste, wollen Sie aber sonstige Laute Ihres Atari vernehmen? Dann haben Sie vielleicht extra das aufwendige »CONTROL.ACC« installiert, um den Tastenklick abzuschalten? Einen einfacheren Weg zum ruhigeren Atari finden Sie in der Systemvariable »conterm« (Adresse $484, Tabelle 2). Bit 1 wacht über den Tastaturklick. Übersetzen und linken Sie einfach das folgende Turbo-C-Programm und kopieren es in Ihren AUTO-Ordner. Gegenüber dem Control-Accessory ist dieses Programm nicht resident und verschwendet so keinen freien Speicherplatz. (Thomas Tempelmann/ah)

#include <tos.h>
void main()
{
	long oldsp;
	oldsp = Super (0L);
	*(char *) 0x484  = 1;
	(void) Super (oldsp);
}
Bit Bedeutung
0 Tastaturklick ein/aus
1 Tastatur-Repeat ein/aus
2 Glocke nach <Control+G> ein/aus
3 Bei gesetztem Bit liefert die BIOS-Funktion »conin« in den Bits 24-31 »kbshift«

Tabelle 2. Die Bitbelegung von »conterm« ($484)



Aus: TOS 06 / 1991, Seite 107

Links

Copyright-Bestimmungen: siehe Über diese Seite