Computer & Technik
Clipper
Fenster umrahmen
Auch das Umrahmen von Fenstern kann man Clipper anvertrauen. Die Funktion
void _SBOX(int, int, int, int, char *);
erledigt alles notwendige. Übergeben werden der Funktion die Koordinaten des Fensters, das umrahmt werden soll, sowie ein Zeiger auf einen String, der die Rahmenzeichen enthält. Die Syntax entspricht der des Clipper BOX-Befehls.
Das Löschen von Bildschirmbereichen erfolgt je nach Anforderungen über drei verschiedene Funktionen:
void _CLREOL(void); /* Löscht bis zum Bildschirmzeilenende */
void _CLREOS(void); /* Löscht bis Spalten- und Zeilenende */
void _CLRALL(void); /* Löscht aktuelles Fenster */
Eine ordentliche Fensterverwaltung muß aber mehr leisten, als Fenster setzen und beschreiben. Fenster bzw. Bildschirme müssen auch gesichert und restauriert werden können. Glücklicherweise bietet Clipper auch dazu einige interne Funktionen an:
void _WINSAVE(int, int, int, int, char *);
void _WINREST(int, int, int, int, char *);
void _SCRSAVE(char *);
void _SCRREST(char *);
Die Funktionen _SCRSAVE() und _SCRREST() sichern bzw. restaurieren jeweils einen Bildschirm, dessen Ziel- bzw. Quelladresse als Zeiger übergeben wird.
Die Funktionen _WINSAVE() und _WINREST() leisten im Prinzip das gleiche. Zusätzlich berücksichtigen sie jedoch die als Parameter übergebenen Fenstergrenzen. Dadurch ergibt sich eine kleine Speicherplatzersparnis, weil nur der wirklich benötigte Speicherplatz angefordert werden muß.
Bleibt die Frage, wohin mit dem gesicherten Bildschirmen? Denn der Funktion muß die Adresse eines Speicherbereiches mitgeteilt werden. Grundsätzlich kann natürlich mit _exmgrab() Speicherplatz angefordert werden. Doch das bedeuted eine nicht unerhebliche Verschwendung der ohnehin beschränkten Clipper-Ressourcen. Um dies zu umgehen, behelfen wir uns mit einem hardwarenahen Trick. Clipper schreibt standardmäßig lediglich auf die erste Bildschirmseite. Der CGA kann aber insgesamt 8 Bildschirmseiten verwalten; die Herculeskarte derer sogar 16. Da jeweils die erste Seite von den Programmausgaben verwendet wird, verbleiben 7 bzw. 15 ungenutzte Seiten, für die kein Speicher allokiert werden muß, weil dieser bereits seitens der Hardware vorhanden ist.
Problematisch ist allerdings das Verwalten der intenern Zeiger auf den Speicher. Denn es liegt in der Verantwortung des Programmiers, die korrekten Speicheradressen an die internen Funktionen zu übergeben.
Das Erkennen der Grafikkarte übernimmt Clipper. In der internen Variablen
int _COLORD;
steht eine "1", wenn eine Farbgrafikkarte gefunden wurde. Es ist sinnvoll, sich auf diese Variable zu verlassen und Clipper-konform zu bleiben, auch wenn sich Clipper - was hoffentlich nie vorkommt? - einmal irren sollte.
Je nach Grafikkarte stehen also 7 bzw. 15 freie Seiten für die Sicherung zur Verfügung. Für jeden Bildschirm werden 4000 Bytes benötigt. Dies ergibt sich aus der Auflösung von 25x80 Zeichen, für die jeweils ein Zeichencode und ein Attribut-Byte gespeichert werden muß. Alle Zeiger auf die gesicherten Seiten ergeben sich daher als Vielfaches von 4000 auf die Basisadresse, die von der installierten Hardware abhängig ist. Für CGA, EGA und VGA beginnt der (Text-) Bildschirmspeicher auf B8000h; der der Herculeskarte auf B0000h.
Aus der Hardware ergibt sich somit die maximale Anzahl der auf diese Weise verwaltbaren Fenster. Obwohl die Zahl 7 auf den ersten Blick etwas klein aussieht, dürfte sie im allgemeinen ausreichen. Denn mehr als 7 Fenster gleichzeitig zu öffnen, dürfte selten sinnvoll sein. In diesem Beitrag wird der Speicherplatzersparnis jedenfalls eindeutig der Vorzug gegeben.
Die noch verbleibende Arbeit zur Verwaltung der Fenster beschränkt sich auf das Adressieren der Fensterpuffer. In dieser Bibliothek wird als Datenstruktur der STACK eingesetzt. Dies erspart eine Listenverwaltung, indem immer der zuletzt gesicherte Bildschirm als erster wieder restauriert wird. Spezialfunktionen erlauben natürlich das Überspringen mehrerer Fenster, indem die übrigen vom System einfach "vergessen" werden.
Als weiteres Zuckerstückchen erlaubt diese Library das Schreiben auf verdeckte Bildschirme. Natürlich kann dies nur über eine Spezialfunktion erfolgen. Denn für Clipper-Befehle wie SAY oder GET sind die verdeckten Bildschirme nicht erreichbar.
Eine Hiobsbotschaft gibt es zum Schluß noch zu vermelden. In Clipper 5.0 existiert das Modul DRIVERSD nicht mehr. Statt dessen gibt es ein Modul namens GT, in dem die meisten Bildschirmfunktionen enthalten sind. Allerdings wurde dieser Teil der Clipper-Laufzeitbibliothek komplett überarbeitet, so daß die Ausführungen und die Library nur für Clipper '87 gelten.