Atari-Insider: Magische Knöpfe

Guten Tag, liebe Leserin und lieber Leser! Aufmerksamen Besuchern der Atari-Messe in Neuss dürfte es nicht entgangen sein, daß das Milan-TOS einer Oberflächenpolitur unterzogen wurde. Zumindest in einer Betaversion konnten bereits moderne Buttons im 3D-Look besichtigt werden (siehe Bild 1), die bis dahin nur von anderen Betriebssystemen bekannt waren oder von vielen Applikationen "von Hand" und nur für die jeweilige Applikation nachgerüstet wurden.

Erfreulicherweise haben die Milan-Entwickler dabei das Rad nicht neu erfunden, sondern haben die Programmierung der Objekte MagiC-kompatibel gehalten. Das Programm aus Bild 1 sieht also ohne Änderungen unter MagiC folgendermaßen aus:

Man sieht also, daß das Aussehen der Objekte nicht identisch ist, aber - und das ist das Entscheidende - die Programmierung dahinter ist absolut gleich. Man muß als Programmierer also nicht mehr die verschiedenen Betriebssysteme testen und das Aussehen der Objekte in seinen Programmen irgendwie daran anpassen, sondern man kann die Darstellung getrost dem Betriebssystem überlassen genau so, wie es die ursprüngliche Idee von GEM vorsieht, nur leider war das Erscheinungsbild von GEM irgendwann nicht mehr ganz zeitgemäß, und passende Erweiterungen wurden seitens Atari nicht vorgenommen. Spät, aber für den Milan noch rechtzeitig, kommt nun also diese erfreuliche Korrektur und Verbesserung des Betriebssystems.

Warum sollte man als Programmierer diese Objekttypen unterstützen? Neue Applikationen, die sich ganz auf das Erscheinungsbild des Betriebssystems verlassen, haben natürlich eine geringere Größe, da sie eigene Routinen zur Objektdarstellung nicht mehr mitbringen müssen. Aber auch bei älteren, bereits vorhandenen Applikationen, die spezielle USERDEF-Routinen zur Objektdarstellung meistens eingebaut haben, ist eine Anpassung sinnvoll. Hier zählt vor allem das einheitliche Aussehen aller Applikationen, die unter einem bestimmten Betriebssystem verwendet werden. Selbst wenn zwei Betriebssysteme ein unterschiedliches Aussehen mitbringen (siehe Bilder 1 und 2), sollte das Erscheinungsbild der Programme innerhalb eines Betriebssystems gleich sein - und dies kann nur mit vom Betriebssystem bereitgestellten Objekt-Zeichenroutinen erreicht werden.

Leider stehen MagiC-kompatible AES-Objekte nicht unter allen Betriebssystemen zur Verfügung. Wie also erfahrt ein Programm, ob es diese Objekte verwenden darf? Die Lösung ist eigentlich recht einfach, denn Atari hat mit MultiTOS die AES-Funktion appl_getinfo() eingeführt, mit der man Eigenschaften des Systems abfragen kann. Allerdings haben die Entwickler bei Atari offenbar nicht besonders gut nachgedacht, denn sie vergaßen leider die Möglichkeit festzustellen, ob appl_getinfo() überhaupt aufgerufen werden darf... Findige Programmierer entwickelten daraufhin die sogenannte ?AGI-Methode appl_getinfo() ist demnach genau dann vorhanden, wenn appl_find("?AGI") einen Wert größer gleich Null zurückliefert. Man beachte, daß die an appl_find() übergebene Zeichenkette ausnahmsweise nicht mit Leerzeichen auf acht Stellen aufgefüllt wird! Die ?AGI-Methode wird auch von der aktuellen Betaversion des Milan-TOS unterstützt. Für sehr alte MagiC-Versionen und N.AES testen wir trotzdem noch zusätzlich auf die AES-Version, damit wir eine möglichst breite Basis an erkannten Betriebssystemen bekommen. Anstelle der ursprünglichen appl_getinfo()-Routine ruft man also ganz einfach folgende Routine auf, die automatisch beachtet, ob das System den Aufruf überhaupt verträgt:

# Listing 1
int appl_xgetinfo(int type, int *out1, int *out2, int *out3, int *out4)
{
static int has_agi = ((_GemParBlk.global[0] == 0x0399 
			&& get_cookie('MagX',NULL))
		|| (_GemParBlk.global[0] >~ 0x0400)
		|| (appl_find("?AGI") >= 0));

return(has_agi ? appl_getinfo(type,out1,out2,out3,out4) : 0);
}

Wenn appl_xgetinfo() Null zurückgibt, ist die von uns gewünschte (in type übergebene) Unterfunktion nicht (!) verfügbar. Man sollte allerdings niemals vom Nicht-Vorhandensein einer Unterfunktion auf andere Unterfunktionen schließen, sondern alle benötigten Unterfunktionen aufiufen und die Rückgabe korrekt testen. Die Werte in out1..out4 dürfen also genau dann ausgewertet werden, wenn appl_xgetinfo() einen Wert ungleich Null liefert.

# Listing 2
int out1,out2,out3,out4; 
int has_magic_objects =0;

if (appl_xgetinfo(13,&out1,&out2,&out3,&out4)) 
{
	has_magic_objects = (out4 & 0x0004);
}
if (has_magic_objects)
{
	/* MagiC-korapatible Objekte vorhanden *,
}

Wann dürfen MagiC-kompatible Objekte nun benutzt werden?Dazu müssen wir noch wissen, daß - wie wir weiter unten noch sehen werden - die MagiC-Objekte mit dem Flag WHITEBAK im Feld obstate der AESOBJECT-Struktur gesteuert werden. Da WHITEBAK vom GEM-Erfinder aber ursprünglich für etwas ganz anderes vorgesehen war (wenn auchnur für PC-GEM), steuert laut MagiC-Dokumentation WHITEBAK das Aussehen der Objekte genau dann, wenn appl_xgetinfo(13) in Word 4 das Bit 2 (entspricht der Hexadezimalzahl 0x0004) gesetzt hat. Oder als C-Code: Wie wird aus einem normalen Dialog, wie er in Bild 3 dargestellt ist, ein "moderner" Dialog mit 3D-Effekten? Die meisten neuen Objekte sind erweiterte G_BUTTON-Objekte. Beispielsweise wird aus einem Button ein Gruppenrahmen, indem das Bit WHITEBAK (0x40) im unteren Byte von obstate und das gesamte obere Byte von obstate auf 0xfe gesetzt wird. Der Titel des Gruppenrahmens ist dann der normale Buttontext. Mit WHITEBAK werden die neuen Objekttypen also eingeschaltet, und mit dem oberen Byte von ob state wird bestimmt, was für ein Typ dabei herauskommt. Beispiel Kontrollkästchen (Checkbox):

Dieser Typ wird durch 0xff im oberen Byte von ob_state gekennzeichnet. Moderne Radiobuttons können auf dieselbe Art erzeugt werden. Überschriften (unterstrichene Titeltexte) werden auf ähnliche Art und Weise erzeugt, basieren aber auf dem AES-Typ GSTRING. Für alle diese Objekte können auch Tastaturkürzel (Shortcuts) festgelegt werden, die mit einem Strich unter dem entsprechenden Buchstaben angezeigt werden. Wenn Shortcuts eingesetzt werden, sollte nach Möglichkeit die Höhe eines jeden Objekts um ein Pixel vergrößert werden, damit die Unterstreichungen auf jeden Fall innerhalb des Objekts dargestellt werden können.

An dieser Stelle möchte ich nicht weiter auf die einzelnen Möglichkeiten im Detail eingehen, da man dies in der MagiC6-Programmierdoku in der Datei OBTYPES.TXT ausführlich nachlesen kann. Die Betaversion vom Milan-TOS hält sich -soweit die darin beschriebenen Objekte unterstützt werden - an diese Dokumentation.

Ein weiteres Problem moderner, "verschönter" Applikationen betrifft die Menüs. Viele Programme haben die Trennstriche in den Menüs, die normalerweise nur aus Minuszeichen bestehen, durch eigene, meistens durchgezogene graue Trennstriche ersetzt. Ein Problem wird daraus in dem Moment, wenn ein Betriebssystem den Menühintergrund nicht mehr weiß, sondern ebenfalls grau darstellt. Je nach Implementation der Trennstriche sieht man dann entweder gar nichts mehr oder aber optisch nicht unbedingt ansprechende Teilstriche. Auch hierfür gibt es eine Lösung. MagiC hat vor einiger Zeit die Unterfunktion MENUCOL (11) bei der AES-Funktion objc_sysvar() eingeführt, mit der man den Farbindex der Menü-Hintergrundfarbe abfragen und seine eigenen Trennstriche - bei Gleichheit der Farben - in einer anderen Farbe darstellen kann. Das künftige Milan-TOS unterstützt diese Unterfunktion ebenfalls.

# Listing 3
int out1,out2;
if (objc_sysvar(0, MENUCOL,0,0, &out1,&out2))
{
	/* in out1 steht der Farbindex *
		* der Menü-Hintergrundfarbe */
}

Bei MENUCOL sollte man davon ausgehen, daß nur der Lesemodus unterstützt wird (allein schon, um den Benutzer nicht mit häßlichen Hintergrundfarben zu quälen), d.h. der erste Parameter bei objc_sysvar() sollte bei dieser Unterfunktion stets Null sein. objc_sysvar() ist übrigens genau dann vorhanden, wenn appl_xgetinfo(13) in Word 2 einen Wert ungleich Null zurückgibt.

Zum Schluß möchte ich noch auf eine Erweiterung eingehen, die derzeit nur MagiC betrifft. Seit Version 6 bietet MagiC die Verwendung eines proportionalen Systemfonts an. Wenn ein proportionaler Systemfont verwendet wird, kann man nicht mehr davon ausgehen, daß Zeichenketten, die links- und rechtsbündigen Text gleichzeitig enthalten (das sind normalerweise alle Menüeinträge, deren Shortcuts durch eine passende Anzahl von Leerzeichen rechtsbündig gemacht werden), nach wie vor die gleiche Breite besitzen - im allgemeinen wird dies dann nicht mehr der Fall sein. Bei der Menüleiste setzt MagiC von sich aus einen speziellen Algorithmus ein, um den Text des Menüeintrags vom Kürzel zu trennen und den Text dann links-, das Kürzel dagegen rechtsbündig auszugeben. Dies geschieht vollautomatisch, ohne daß man als Programmierer spezielle Vorkehrungen treffen müßte. Bei selbstprogrammierten Menüs (meistens Popup-Menüs) weiß MagiC aber nicht, welche Zeichenketten einen Shortcut enthalten können, so daß hier ein bißchen Mitarbeit seitens der Programmierer gefordert ist. Programmierer, die dies betrifft, sollten sich einmal den Objekttyp GSHORTCUT (38) in der bereits erwähnten Datei OBTYPES.TXT ansehen. Wenn man in den selbstprogrammierten Menüs bei allen G STRING-Objekten den Objekttyp ganz einfach auf G SHORTCUT ändert, kümmert sich MagiC auch hier um die korrekte Darstellung. Ob GSHORTCUT verwendet werden darf, kann natürlich auch mit appl_xgetinfo() abgefragt werden.

Links zu den besprochenen Programmen befinden sich im World Wide Web unter der Adresse http://www.snailshell.de/insi-der.html. Dort ist auch der Quelltext der Pascal-Bibliothek ObjectGEM und dabei insbesondere die Datei OWINDOWS.PAS vorhanden, an der man genauer studieren kann, wie die Objekte in der Praxis eingesetzt werden.

Bis zum nächsten Monat!


Thomas Much
Aus: ST-Computer 12 / 1998, Seite 43

Links

Copyright-Bestimmungen: siehe Über diese Seite