Computer & Technik
Clipper
Fenster für Clipper
Die Entwicklung kommerzieller Software verlangt mehr oder weniger aufwendige Benutzeroberflächen. SAA ist in aller Munde und als Verkaufsargument von nicht zu unterschätzender Wirkung. Doch leider enthält Clipper in seinen Bibliotheken keine Funktionen für eine Fensterverwaltung. Man muß also in die eigene Trickkiste greifen.
Doch gerade bei Clipper ist es schwer eine gute Fensterverwaltung zu implementieren. Denn auf den gewohnten Komfort von Funktionen wie beispielsweise SAY und GET möchte kein Clipper-Programmierer verzichten wollen. Vielmehr muß eine Fensterverwaltung implementiert werden, die sich nahtlos in die Clipper-eigenen Routinen einfügt.
Die Analyse der Clipper-Laufzeitblibliothek, die augenscheinlich von Quick-C abstammt, zeigt einige Routinen und Variable, die für die Fensterverwaltung genutzt werden können. Alle Zugriffe auf den Bildschirm wurden für Clipper '87 im Modul DRIVERSD zusammengefaßt.
Beim Zugriff auf den Bildschirm verläßt sich Clipper vollständig auf vier Variable, die den jeweils aktiven Bildschirmbereich markieren:
int _ROWOFF; /* erste Bildschirmzeile des aktiven Fensters */
int _COLOFF; /* erste Bildschirmspalte des aktiven Fensters */
int _MAXROW; /* maximale Anzahl der Bildschirmzeilen */
int _MAXCOL; /* maximale Anzahl der Bildschirmspalten */
Mit Hilfe dieser vier Variablen, deren Werte immer absolut zu interpretieren sind, ist es Clipper möglich, alle SAYs und GETs korrekt zu steuern. Als Startwert gilt immer:
_ROWOFF == 0;
_COLOFF == 0;
_MAXROW == 24;
_MAXCOL == 79;
Damit steht ein Fenster mit 25 Zeilen und 80 Spalten zur Verfügung. Werden den Variablen andere Werte zugewiesen, arbeitet Clipper mit diesen Werten. Um beispielsweise ein Fenster mit der linken oberen Ecke in Zeile 10, Spalte 20 und der rechten unteren Ecke in Zeile 60, Spalte 20 zu setzen, müssen den Variablen lediglich folgende Werte zugewiesen werden:
_ROWOFF = 10;
_COLOFF = 20;
_MAXROW = 20;
_MAXCOL = 60;
Für Clipper steht jetzt nur noch ein Fenster mit 10 Zeilen und 40 Spalten zur Verfügung. Dankenswerterweise erledigt Clipper den gesamten Rest der Arbeit. Alle Clipper-Befehle wie SAY, Get oder ? erkennen den verkleinerten Bildschirmbereich. Doch leider nicht nur diese. Auch ERRORSYS und ALTERR kennen nur noch den verkleinerten Bildschirmbereich. Es ist also ratsam, ERRORSYS und ALTERR so zu modifizieren, daß sie im Fehlerfall als erstes den vollen Bildschirm wieder herstellen und erst dann terminieren.
Um die Fenster-Variablen leichter setzen zu können, existiert eine interne Funktion namens _SETWIN(), mit der ein Fenster festgelegt werden kann. Doch auch hier ist Vorsicht geboten! Denn _SETWIN() berücksichtigt ebenfalls die Vorgaben der Fenster-Variablen.
Der Aufruf
_SETWIN(10, 5, 20, 15);
würde unter Verwendung der Beispieldaten zu folgendem Ergebnis führen:
_ROWOFF = 10 + 5 == 15;
_COLOFF = 20 + 10 == 30;
_MAXROW = 20 + 15 == 35 ==> Kappen auf _MAXROW == 20;
_MAXCOL = 60 + 20 == 80 ==> Kappen auf _MAXCOL == 60;
Als Fenster ergibt sich also:
Linke obere Ecke: Zeile 15, Spalte 30
Rechte untere Ecke: Zeile 20, Spalte 60.
Gewünscht war aber
Linke obere Ecke: Zeile 5, Spalte 10
Rechte untere Ecke: Zeile 15, Spalte 20.
Um solche Mißverständnisse zu vermeiden, empfiehlt es sich, vor dem Definieren eines neuen Fensters, zunächst das alte zu schließen, bzw. die internen Variablen auf die Defaultwerte zurückzusetzen. Dies geht ganz einfach, indem man _SETWIN() mit vier Nullen aufruft, also
_SETWIN(0, 0, 0, 0);