Konsole-Programme (RootCRT)
Textmodus, nicht mehr
Für Clipper-Migranten bietet sich ein Programm an, dass auf einem Objekt der RootCRT()-Klasse basiert. Leider gibt die Dokumentation gar nichts über diese Klasse preis, und man erfährt von ihrer Existenz nur durch einen Blick in die mitgelieferte Quelle der AppSys.prg:
oCrt := RootCrt():New()
RootCRT() stellt ein Text-Modus-Fenster zur Verfügung.
Entscheidend hierfür ist - bei Verwendung der Standard-AppSys.prg die Projekt-Definitionsdatei. Es gibt dort zwei Stellen, an denen die Weichen für ein RootCRT()-Programm gestellt werden:
GUI = no LINKFLAGS =
Beide Anweisungen verhindern in dieser Form, dass ein Presentation Manager Programm erzeugt wird.
In der Standard-AppSys.prg findet sich folgender Code:
nAppType := AppType() DO CASE CASE nAppType == APPTYPE_PM // wird in unserem Fall nicht ausgewählt, verwendet entweder XbpDialog() oder XbpCRT() CASE nAppType == APPTYPE_VIO .OR. nAppType == APPTYPE_NOVIO // entspricht den Alternativen, die auf RootCRT() aufbauen
Hierzu ein kleines Demo-Programm:
FUNCTION Main() Local cName := Space(30) ? MaxRow() ? MaxCol() @ 10, 10 GET cName READ RETURN (.T.)
Dies sieht - zusammen mit dem Bildschirm-Output - schon recht Clipper-like aus.
Die Einschränkung
Versuchen wir es jetzt mit diesem kleinen Programm:
FUNCTION Main() Local aPos, aSize, oXbp aPos := {1,1} aSize := {20,3} oXbp := XbpPushButton():new(SetAppWindow(), SetAppWindow(), aPos, aSize) RETURN(.T.)
Mehr Code brauchen wir für dieses Beispiel nicht, denn beim Erstellen eines XbpPushButton() bricht das Programm ab mit dem Hinweis, dass wir es ohne das Link-Flag /PM:PM erstellt haben.
Ohne /PM:PM stehen die Elemente, die wir für ein GUI-Programm benötigen, nicht zur Verfügung. Und: die Fehlermeldung lässt sich nicht mit der Maus beantworten, da in unserem kleinen Beispiel kein Aufruf von SetMouse() vorkommt, und ohne den gibt es keine Mausunterstützung.
Tastatur-Aktivitäten
Bestimmte Methodiken aus Clipper-Zeiten passen nicht nach Windows, dazu gehört der Funktionsaufruf InKey() in genau dieser Form. InKey() pollt den Tastaturpuffer (bzw. die Event-Warteschlange) und wartet auf eine Tastatureingabe. Unter DOS war das akzeptabel, unter Windows treibt eine solche Schleife die CPU-Lastung auf Maximalniveau:
nKey := 0 WHILE nKey <> K_ESC nKey := InKey() END
Das Windows-Paradigma sieht so aus, dass ein Programm auf ein Ereignis wartet (das Programm ist passiv, bis das Ereignis eintritt), während das Code-Beispiel dazu führt, dass das Programm permanent aktiv nachfragt, ob nun endlich eine Taste gedrückt wurde. Spätestens beim Vergleich der CPU-Auslastung wird der Unterschied deutlich.
Immer in Abhängigkeit vom jeweiligen Programm-Code könnte die Schleife dann auch so aussehen:
nKey := 0 WHILE nKey <> K_ESC nKey := InKey(0) END
Und plötzlich fällt die CPU-Auslastung auf Normal-Niveau.
noch schnell die Maus hinzugefügt
Mag man sich denken, aber auch hier ist Vorsicht angesagt. Zwar erlaubt ein SetMouse(.T.) das Aktivieren der Maus, doch kann man mit dieser Anweisung seine Programmlogik sehr schnell "zerbrechen".
Ein Clipper-Paradigma lautet, dass man alle Felder einer Eingabemaske nur in der vorgegebenen Reihenfolge abarbeiten kann (und auch muss) (und damit auch die entsprechenden Prüfungen je Feld):
@ 01, 10 GET Feld1 VALID Pruefe1() @ 02, 10 GET Feld2 VALID Pruefe2() @ 03, 10 GET Feld3 VALID Pruefe3() READ
Wenn in einem Clipper-Programm in Feld2 ein ungültiger Wert eingegeben wird, kann der Anwender das Feld nicht normal verlassen (nur durch Abbruch des READ).
In unserem Xbase-Programm aktivieren wir jetzt die Maussteuerung, und nach der Eingabe in Feld1 klickt der Anwender auf Feld3, ohne dass Feld2 in diesem Zusammenhang angesprochen wurde. Die Eingabe in Feld3 erfüllt die Prüfung durch Pruefe3(), die Prüfung von Feld2 wurde jedoch nicht ausgeführt.
Wenn jetzt ANGENOMMEN wird, dass alle drei Felder geprüft wurden, so wurde diese eiserne Logik (die in reinem Clipper NIE zu umgehen war) jetzt durch die Maus ausgehebelt.
Werden alle Felder nach dem READ nachgängig nochmals den entsprechenden Prüfungen unterzogen, dann besteht keine Gefahr. Aber ein solches Programm-Verhalten ist doch recht selten anzutreffen. Ansonsten kann es passieren, dass spätere Verarbeitungsschritte abbrechen, weil Feld2 ungültige oder unerwartete Werte enthält.