Session D-APP

Wie baue ich eine
VFP3.0-Applikation

Peter Herzog
Peter Herzog System & Organisation


EINFÜHRUNG


RÜCKBLICK

Zuerst mal ein kleiner Rückblick auf die gute alte FoxPro 2.xer Zeit, als es noch keine Objekte gab und man sich von Maske zu Maske geschwungen hat, bis der Endeknopf gedrückt wurde.

Ein „normales" Programm bestand aus einem Projekt welches folgende Komponenten enthielt:
• ein INIT-Programm in dem diverse Einstellungen gemacht wurden.
• ein Hauptmenü Irgendwie sollte unter Windows das Programm
  wie „Windows" aussehen.

In den meisten Hauptmenüs waren dann die Aufrufe der einzelnen Masken, die dann die verschiedenen Funktionen übernahmen. Andere wiederum ließen zuerst noch eine Hauptmaske erscheinen, in der man mittels Klick auf einen Button, die einzelnen Aktionen auslöst.


Gleich einmal vorweggenommen: Alles beim Alten !

Wenn Sie mit VFP arbeiten wollen, dann muß natürlich das Layout nicht anders gestaltet werden und der Aufruf der Programme geschieht nun genauso wie früher. Ein entscheidender Punkt wird Ihnen allerdings sofort auffallen, wenn Sie einmal eine Form starten, die Sie in der Entwicklungsumgebung erstellt haben. Der Klick auf das rote Rufzeichen läßt die Maske erscheinen, aber was am Bildschirm bleibt, daß ist das Command-Fenster. Oh ja, jetzt fällts einem auf. Ist eine tolle Sache und muß auch bedacht werden, wenn man Programme schreibt. Früher wurde eine Maskendefinition in mehrere einzelne Befehle übersetzt, die Grob dargestellt so aussahen:

Dieses Progrämmchen hat uns damals der GENSCRN erzeugt und wenn Sie diesen Code ablaufen lassen, dann wird sich auch VFP wie FoxPro 2.6 verhalten. In diesem Falle wird das Command-Window verschwinden und das Fenster läuft sozusagen alleine im Hintergrundfenster.

Etwas anders sieht es mit der Form aus, die mit DO FORM <Formname> aufgerufen wird. Gleich einer Blase schwimmt die Form nun am Hintergrund und das Command-Fenster ist für andere Befehle frei.

Ein neuerlicher Befehl könnte nun wiederum der selbe Aufruf der selben Form sein. Und schon haben wir zwei Masken am Schirm. Unter FoxPro 2.x nahezu ein Horror, wenn man an das „Foundation Read" denkt, welches für 90% der Fox-Programmierer zwar vom Namen bekannt war aber nicht verwendet wurde.

Schon haben wir DAS neue Thema von Visual FoxPro 3.0 erlebt, welches so wahnsinnig viel Möglichkeiten bietet.


Objekt Orientiertes Programmieren.

Wollen wir uns mal an ein Projekt ranmachen, um zu zeigen, wie es heutzutage mit VFP3.0 zu verwirklichen ist. Also munter drauf los und ein MODI PROJ TEST hineingetippt.

Was uns nun erwartet, ist das Kontrollzentrum unserer Applikation. Wie in guter alter Zeit schreiben wir uns zuerst mal ein INIT-Programm. Einzutragen ist es in der Projektpage Code. Dort ein „Neu" angeklickt und schon geht’s los. Wenn Sie bereits unter FoxPro 2.x programmiert haben, so haben Sie sicherlich bereits solch ein Programm vorrätig. Hier sollten folgende Bestandteile vorhanden sein:

Die PUBLIC-Variablen

Tip: Schreiben Sie vor den Variablennamen immer Ihre Bedeutung.

Beispiel:

Globale Character Variablen: gcVariable
Globale Nummerische: gnVariable
Globale Datum: gdVariable

...

Locale Character Variablen: lcVariable, lnVariable, ...
Parameter variablen: tcVariable, tnVariable, ...

Alle notwendigen Settings

Anmerkung: schreiben Sie auch die länderspezifischen Settings hinein, damit Sie auf anderen Rechnern / Windowsversionen nicht unangenehme Überraschungen erleben.

Eine Abfangroutine für den QUIT

Eine Fehlerbehandlungsroutine

Einstellungen des Hintergrundschirmes

Tip: Früher wurde mit MODI WINDOW SCREEN gearbeitet. Diese Befehle sind nun „OUT". Auch die Befehle WONTOP(), WTITEL() usw. sollten nicht mehr verwendet werden. An diese Stelle ist der Objekt-Alias-Name „_SCREEN" getreten, der den Hauptschirm von VFP anspricht.

Unser Hauptmenü

Anmerkung: Am Menü hat sich zur Zeit noch nicht getan, was eventuell mit Objektorientiert zu tun hätte. Also bleibt alles beim Alten.

Wenn Sie an dieser Stelle das Programm abspeichern würden und eine Applikation daraus erstellen würden, dann würde das Programm sich sofort wieder beenden. Aus der 2.xer Zeit wissen wir, daß ein Foundation Read fehlt, daß das Programm am Leben hält.

Früher wurde hier einfach READ VALID <variable> an die letzte Position nach dem Menüaufruf geschrieben und schon konnte man das Menü bedienen und seine Programme aufrufen. Auch heute wird noch ein READ benötigt. Jedoch ein Spezielles READ, welches das System nicht mehr komplett in Anspruch nimmt sondern anderen Teilen des Systems erlaubt, nebenher zu existieren.


READ EVENTS

Events deutet bereits darauf hin, daß es sich dabei um etwas Objektorientiertes handeln könnte. Zumindest bedeutet dies, daß andere „Ereignisse" nebenher erlaubt sind, was beim normalen READ nicht möglich ist.

Also schreiben wir in unser INIT-Programm das READ EVENTS hinein.

Nun fehlt noch ein eventuelles Aufräumen. Also SET Einstellungen zurückstellen usw.

Es wird Ihnen aufgefallen sein, daß ich keine Dateioperationen aufgeführt habe. Dies liegt daran, daß es grundsätzlich möglich ist, daß Öffnen und Schließen von Dateien den einzelnen Masken zu überlassen.

Wenn Sie dennoch zuallererst die Dateien öffnen wollen, so verwenden Sie unbedingt die Klausel ALIAS und AGAIN. Ansonsten wird eine mit „privat Datasession" ausgestattete Form Ihren Dienst versagen.


OPEN DATABASE

Auch sollte bei Verwendung von Datenbanken immer ein OPEN DATABASE <Datenbank> geschrieben werden. Dies hat den Vorteil, daß man beim USE der einzelnen Tabellen keinen Pfad mehr angeben muß.

Nun haben wir das Hauptgerüst, um ordentlich anzufangen. Das Menü sollte noch mit einem „Ausstiegspunkt" versehen werden. Also ein „BEENDEN"-Eintrag mit dem Hotkey ALT+F4, der folgenden Befehl ausführt: „CLEAR EVENTS".

Wir müssen uns nun vorstellen, daß nach Start des Programmes, alle Befehlszeilen ohne anzuhalten durchlaufen werden, bis das Programm beim READ EVENTS angelangt ist. Dort bleibt es stehen, bis ein CLEAR EVENTS ausgeführt wird. Alles was in der Zwischenzeit geschieht, wird sozusagen als Event - Ereignis ausgeführt.

Alle zwischendurch gestarteten Masken werden wie „Objektblasen„ behandelt und schwimmen auf der Oberfläche wie Fettaugen auf der Suppe.


Modale Masken

Man kann jedoch jede Maske dazu veranlassen statisch auf der Oberfläche zu verweilen. Dies nennt man dann Modale Masken und dies kann durch das WindowType-Property erreichen.

In diesem Zustand wird intern ein hartes READ eingeschaltet und diese Maske bleibt hartnäckig am „OnTop" des Bildschirmes, bis sie beendet wird.

Dieses Verhalten ist notwendig, wenn man einen Returnwert einer Maske erhalten möchte. Dem Aufruf einer Maske kann die Klausel „TO <variable> „ angehängt werden. Genau dann ist es notwendig, daß man die Maske Modal macht, da ansonsten die Maske sozusagen nicht stehenbleiben würde und der Returnwert im falschen Moment zurückgegeben werden würde.

Nun haben wir das Grundgerüst einer normalen Applikation besprochen. Als nächstes wollen wir den Hauptteil jeder Applikation ergründen. Es handelt sich dabei natürlich um die einzelnen Masken. Ohne Masken natürlich keine Eingabe. Wenn wir schon bei der Eingabe sind, sollten wir uns entscheiden wie wir die Daten in die DBF-Tabellen bekommen.

Unter FoxPro 2.x hatten wir grundsätzlich zwei Möglichkeiten die Felder zu füllen.

Der erste Weg war das direkte Bearbeiten der Tabellenfelder. Dies hatte den Vorteil, daß der Datensatz automatisch gesperrt wurde, sobald man im Feld eine Taste gedrückt hatte. Der Nachteil war das direkte Verändern der Daten, was ein „Undo" relativ kompliziert machte.

Der andere Weg war das Speichern der Daten in Memoryvariablen. Meisten wurden die Variablen mit SCATTER MEMVAR MEMO zuerst mit den Daten gefüllt und dann mit GATHER MEMVAR MEMO wieder weggeschrieben. Zwischendurch mußte selbst dafür gesorgt werden, daß man den Datensatz sperrt (Pessimistisch). Oder es wurde vor dem GATHER nachgesehen, welche Felder sich in der Zwischenzeit geändert hatten und es wurde dementsprechend darauf reagiert (Optimistisch).

Ein kleines Problem trat auf, wenn man in mehreren Tabellen gleiche Feldnamen vergeben hatte. Da nun durch einen SCATTER diese Variablen überschrieben wurden.


Buffering

Unter VFP3.0 hat man sich dem Problem angenommen und ein Verfahren eingeführt, welches man „Buffering" nennt.

Bei dieser Verarbeitungsart wird direkt auf der Tabelle bzw. direkt in die Felder geschrieben. Das sogenannte Buffering verwaltet nun das Schreiben und Sperren der einzelnen Datensätze. Wird Buffering eingeschaltet wird sozusagen nicht physikalisch auf der Festplatte geschrieben sondern temporär im Speicher, der mit der Funktion TABLEUPDATE() weggeschrieben, oder mit dem Befehl TABLEREVERT() wieder restauriert werden kann.

Hier gibt es nun auch wieder Unterscheidungsarten. Einerseits kann nur ein Datensatz Zwischengespeichert werden oder jeder Datensatz der bearbeitet wird / wurde. (Rowbuffering / Tablebuffering). Jede Zwischenbufferung kann nun auch noch beeinflußt werden, wie die Satzsperre funktionieren soll. Auf der einen Seite kann beim Bearbeiten (Pessimistisch) oder erst beim Speichern (Optimistisch) gesperrt werden. Ich persönlich bevorzuge die Pessimistische Art, da dies erstens wesentlich einfach zu handhaben ist und außerdem der alten FoxPro 2.x - Denke am nähesten kommt. Auf alle Fälle sollte man keine Mischungen der Bufferung machen, da ansonsten die Probleme im Netzwerk explodieren können. Die Einstellung in der Form können durch das Property BUFFERMODE eingestellt werden.


Datasession

Nun zur weiter oben bereits erwähnten Datasession: Wenn Sie mehrere Formen aufgerufen haben dann haben diese standardmäßig die Datasession 0 (Default) eingestellt. Das bedeutet, daß jede dieser Formen auf den selben Tabellen arbeitet. Wird nun der Satzzeiger in der einen Form verschoben (SKIP) dann wird natürlich in der anderen Form ebenfalls der Satzzeiger verschoben, was das Arbeiten mit beiden Masken nahezu unmöglich machen würde.

In VFP3.0 haben wir die Möglichkeit jeder Maske eine Private Datasession zu verpassen. Einzustellen ist dies in der Form mit dem Property DATASESSION.

Hat man dieses Property auf 2 (Privat) gestellt, so wird jede Tabelle eigens AGAIN geöffnet. Dies kann man durch das View-Window kontrollieren (Eingabe von SET im Command-Window). Dort findet man eine Combobox mit der Bezeichnung „Current Session"

Gegenüber FoxPro 2.6, welches bereits 225 Selectebenen hatte, wurde die Zahl der Selectebenen auf Übertriebene 32767 erhöht. Wenn man nun bedenkt, daß jede Form eine Private Datasession haben kann, und die Anzahl der Formen auf über 100 geschraubt werden kann, dann sollte dies für die nächsten Jahre reichen. Einzig allein die Anzahl der Filehandles ist noch auf 255 beschränkt. Aber dies wird in einer der nächsten Versionen geändert werden.

Nun noch die Frage, wie man Tabellen zur Form dazubekommt.


DATAENVIRONMENT

Wenn man auf die Form mit der rechten Maustaste klickt oder im Menüpunkt View/Dataenvironment anklickt, so erscheint die Datenumgebung als freies Fenster. Hier wiederum mit der rechten Maustaste geklickt, erlaubt uns eine Tabelle dazuaddieren.

Jede hier eingetragene Tabelle wird nun automatisch beim Start der Form geöffnet und natürlich auch wieder geschlossen. Im Propertiefenster können auch noch weitere Einstellungen vorgenommen werden, die das Öffnen der Tabellen beeinflußt. (Order / Filter setzen usw.)

Es verleitet nun einfach ein Feld der Tabelle zu nehmen und in die Form fallen zu lassen. Dies ist zwar eine feine Sache, da automatisch das Feld erzeugt wird, jedoch wird standardmäßig nur die Basisklasse des Feldes erzeugt und außerdem ist die Feldlänge generell auf zehn Stellen eingestellt.

Hier ist natürlich der beste Zeitpunkt über Klassen und Vererbung zu sprechen.

Jedes Objekt welches wir auf die Form ziehen können (Siehe Toolbar) ist im VFP fest hineinprogrammiert und entspricht im großen und ganzen den Microsoft Foundation Classes, was das Layout angeht. Deshalb wird jede Form mit weißem Hintergrund, jeder Commandbutton mit Arial 10 erscheinen. Usw.

Wenn wir nun jede unserer Formen in einer anderen Farbe darstellen wollen, so müssen wir jede Maske „angreifen" und händisch verändern. Daß dies nicht unbedingt der schönste Weg ist, leuchtet ein.


Die eigene Basisklasse

Aus diesem Grund ist es empfehlenswert zuerst einmal seine eigenen „Basisklassen" zu definieren. Dies kann mit dem Klassendesigner erledigt werden, der genau den selben Aufbau hat wie der Formdesigner.

Dort kann man ich eine Klasse aufbauen, die ein oder mehrere Objekte beinhaltet. Diese Klasse kann nun in einer VCX abgespeichert werden. Natürlich kann eine VCX mehrere Klassen beinhalten.

Wenn man nun jedes Objekt von der eigenen VCX ableitet, und wenn es nur die Form alleine ist, dann kann man später die VCX verändern und die Änderungen werden automatisch in allen Masken nachgezogen.

Auf den Begleitdisketten finden Sie eine BCLASS.VCX, die bereits alle relevanten Objekte beinhaltet, die man in der täglichen Arbeit gebrauchen kann.

Als erstes müssen wir sicherstellen, daß bereits ein CREATE FORM von dieser BCLASS abgeleitet wird. Dazu gibt es unter TOOLS / OPTIONS / FORMS einen Punkt der sich Templates nennt. Diese Templates oder auch Vorlagen basieren auf eine Klasse in einer VCX.

Wird hier die eigene Basisklasse eingetragen, so wird in Zukunft jede Maske, die wir erstellen die Einstellungen erben, die in der Klasse eingetragen sind.


Vererbung

Manchmal ist es jedoch sinnvoll, wenn die Vererbung nicht durchgeführt wird. Soll zum Beispiel eine Maske Rot erscheinen, und nicht das Standardgrau aufweisen, so muß explizit ein Rot in der jeweiligen Maske eingetragen werden.

Genau zu diesem Zeitpunkt wird die Vererbung unterbrochen. Zurückholen kann man diese durch einen rechten Mausklick im Propertiefenster.

Bei Methoden / Events ergibt sich eine besondere Situation.

Wenn man in einer Form eine Methode füllt, so wird generell die Vererbung unterbrochen. Sollte man also in seiner eigenen Basisklasse Code hinterlegt haben, so wird dieser nicht mehr ausgeführt. Manchmal ist es jedoch sinnvoll, wenn sowohl der Code der Basisklasse, als auch der soeben eingegebene ausgeführt wird.


Scope Resolution Operator

Zu diesem Zweck gibt es den sogenannten „Scope Resolution Operator". Ein heftiges Wort, welches sich aber in zwei nachfolgenden Doppelpunkten niederschlägt.

Beispiel:

Eine INIT-Methode beinhaltet in der eigenen Basisklasse (FORMB) Code, der bestimmte Objekte positioniert. In der eigenen Form möchte man nun noch ein WAIT WINDOW zu Testzwecken eintragen. Folgender Code ermöglicht, daß beide Teile ausgeführt werden.

Abhängig davon, wo bzw. an welcher Stelle das <CLASS>::<Methode> geschrieben wird, wird es zur Laufzeit sozusagen hineinkopiert.

Nun haben wir im groben die Möglichkeiten der Form angeschnitten. Weiters möchte ich noch einige Tips geben, die die Arbeit erleichtern bzw. das Arbeiten erst möglich machen.


Includefile in der Form und der Class

Wenn Sie #INCLUDE Anweisungen verwenden, dann können Sie diese in einem Headerfile (*.h) hinterlegen. Um diese Headerfiles auch in Formen und Klassen verwenden können, müssen diese unter dem Menüpunkten Form / Class / Headerfile eingetragen werden.


Eigene Properties und Methoden von Objekten

Im Form- und Klassendesigner können Sie zu jedem Containerobjekt (das Objekt in dem alle anderen liegen) eigene Properties und Methoden anlegen. Die Properties werden dabei, wie Variablen behandelt und sind nach dem Anlegen auf .F. gesetzt. Methoden sind Anfangs leer. Sie können beides für Ihre eigenen Zwecke gebrauchen, wie es Ihnen gefällt. Es sei anzumerken, daß eine in einer Methode angelegte Variable per Definition Privat deklariert wird. Wenn Sie die Methode wieder verlassen, dann ist die Variable natürlich wieder verschwunden. Wollen Sie jedoch eine Variable dauerhaft für die gesamte Form gültig machen, so legen Sie sich am besten ein Property an, welches den Zweck der Variable erfüllt.

Genauso geht es mit Methoden. Brauchen Sie für die Form einen Codeteil, der mehrmals aufgerufen wird, so können Sie diesen als Methode der Form abspeichern und mit THISFORM.<Methode> immer wieder aufrufen.


Das Dataenvironment zur Laufzeit bearbeiten

Das Dataenvironment ist zur Laufzeit unter dem Namen:

anwählbar. Damit können Sie zum Beispiel im INIT einer Form Filter setzen usw.


Database Property im Dataenvironment der Form

VFP3.0 speichert in der Form die Location der Datenbank ab, wenn Tabellen aus einer Datenbank in der Form verankert werden.

Wenn die Datenbank in einem anderen Unterverzeichnis steht, so wird der relative Pfad zur Form mit abgespeichert. Sollte sich der DBC auf einem anderen Laufwerk befinden, so wird der harte Pfad mit abgespeichert.

Dies wirkt sich beim Kunden natürlich etwas störend aus, da beim Hochstarten der Form nach dem Pfad der Datenbank gefragt wird. Ich muß also davon abraten, Form und Datenbank getrennt zu halten, wenn die Form abgespeichert wird. Im Notfall hilft da nur noch ein USE <Form>.SCX und ein Durchsuchen der einzelnen Datensätze nach dem Property „DATABASE" dort steht dieser Pfad der Datenbank. Wenn ein relativer Pfad angegeben wurde, dann wird es ein Problem, wenn man die Form in ein anderes Verzeichnis verschiebt. Dann muß die Form unbedingt mit MODI FORM noch einmal geöffnet werden. Dann läßt Sie VFP nach der Datenbank suchen und die Welt ist wieder in Ordnung.


Gleichzeitiges Arbeiten im Netz (Entwickeln)

Das Projekt unter VFP ist leider noch nicht Multiuserfähig. Deshalb muß jeder Entwickler im Netz sich seine eigene Kopie der Datenbank und der gesamten Verzeichnisstruktur lokal anlegen. Es muß unbedingt immer der selbe Pfadaufbau verwendet werden, denn ansonsten wird derjenige, der die Teile zusammenfügt seines Lebens nicht mehr glücklich. Dann treten die oben beschrieben Probleme mit den Masken und Datenbanken auf.


Toolbars

Toolbars können nur mit dem Klassendesigner angelegt werden.

Ansonsten ist es ein leichtes sich die Objekte zusammenzustecken, wie man es gerade braucht.

Der Aufruf einer Toolbar wird über die Funktion CREATEOBJECT() erledigt. Dazu muß VFP die VCX bekanntgegeben werden, in der die Toolbar abgelegt wurde.

Nun kann das Objekt Toolbar erzeugt werden.

Beachten Sie, daß die Variable, in der Sie die Referenz zu der Toolbar speichern auch bestehen bleibt. Also keine Privat Variable verwenden, wenn Sie dies in einer Methode einer Form machen. Sie können aber auch ein Property einer Form für die Toolbar verwenden. Dies hat den besonderen Nebeneffekt, daß die Toolbar verschwindet, wenn die Form geschlossen wird, da dann alle Properties released werden und somit auch die Toolbar als Objekt aus dem Speicher entfernt wird.

Nun müssen Sie die Toolbar nur noch anzeigen.


Weitere Tips zur Toolbar

Wenn Sie die Toolbar an irgendeine Ecke des Bildschirmes hängen wollen, so können Sie dies durch die Methode oToolbar.DOCK(x) verwirklichen. Das x ist dabei eine Zahl zwischen -1 und 3, wobei -1 den „undocked" Status widerspiegelt.

Beim release einer Toolbar sieht es nicht besonders gut aus, wenn alle Buttons einzeln verschwinden. Um diesen Effekt zu unterbinden, brauchen Sie nur die Toolbar vorher zu verstecken, welches Sie mit oToolbar.HIDE erledigen können.

Wenn Sie aus einer Toolbar heraus, die gerade aktive Form beeinflussen wollen, so müssen Sie diese über _screen.activeform ansprechen.

Wollen Sie die Toolbar nur dann anzeigen, wenn die Form auch aktiv ist, so können Sie in der Activate, bzw. Deactivate-Methode der Form die Toolbar mit oToolbar.HIDE verstecken und mit oToolbar.SHOW wieder anzeigen. Beachten Sie jedoch, daß dabei der Bildschirm flackern kann, wenn der Platz der Toolbar am oberen Bildschirmrand freigegeben wird.


Geschwindigkeit

Ein großes Thema ist die Geschwindigkeit der Applikation, besonders dann, wenn Sie entweder sehr groß ist, sehr viele Elemente in ihr vorhanden sind oder wenig Speicher zur Verfügung steht.

Besonders schlecht ist die Performance des Gridobjektes, wenn der SET FILTER Befehl angewendet wird. Rushmore greift leider bei diesem Objekt nicht mehr.

Sehr gute Abhilfe können Sie durch den SET KEY Befehl erhalten. Dieser zwingt zwar zu einer Ordersetzung, ist jedoch so extrem schnell, daß Rushmore in diesem Falle viel länger braucht.

Wenn ein Index verwendet wird, in dem eine FOR-Klausel enthalten ist, so wird auch dieser extrem schnell, da ja Rushmore gar nicht verwendet wird.


SEEK vs. LOCATE FOR

In vielen Fällen ist man verleitet, den Locate-Befehl zu verwenden, da dieser über mehrere Indizes geht und man sich keine Gedanken machen muß, welche Order gerade gesetzt wurde usw. Bei einer Programmschleife, die sehr viele Locates ausführen muß, sind Sie jedoch besser beraten, wenn Sie etwas Tabellendesign aufwenden und sich einen ordentlichen Index aufbauen. Die Geschwindigkeitssteigerungen können bis zu 100% erreichen.


SET ORDER-SKIP vs. SELECT

Vielfach wird der Selectbefehl verwendet um irgendwelche Daten zusammenzusammeln. Tests haben jedoch ergeben, daß ein ordentlich gestylter Index mit einer DO WHILE Schleife und SKIPS wesentlich schneller sein kann.

Überhaupt sollte man das mengenmäßige Denken manchmal vermeiden, um Performance aus der Applikation herauszuholen. Gerade diese Möglichkeit des satzorientierten Zugriffes in Verbindung mit mengenorientierten Befehlen machen VFP zu einem einmaligen Tool. Denn die richtige Anwendung der Befehle und das Know How über Optimierung am richtigen Platz läßt andere Programmiersprachen regelrecht verblassen. (Keineswegs eine Übertreibung)


Wenn eine Form beim Aufruf viel zu lange braucht

Manchmal übertreibt man es mit diversen Masken und lädt viel zu viele Objekte darauf ab. Naturgemäß benötigen diese Masken beim Aufruf wesentlich länger. Besonders dann, wenn viele Dateien geöffnet werden und oder mengenmäßig viele Objekte und Klassen verwendet werden.

Man kann die Ladezeit solcher Masken in die Hauptladezeit der Applikation verlegen in dem man diese auf „visible=.f." setzt. Dies vergrößert zwar die Ladezeit der gesamten Applikation, aber das hat meistens weniger Gewicht, als das „hochkommen" einer Maske. Solche Masken dürfen natürlich nicht modal gemacht werden, da ansonsten beim Start der APP alles stehenbleibt. Ein Aufruf der Maske wird jedoch dann nur Sekundenbruchteile brauchen, da ja alle Objekte bereits im Speicher liegen.

Nun wünsche ich Ihnen noch viel Spaß beim Programmieren.

Die VFP3.0 Programmierer warnen

Objektorientierung unter VFP3.0 macht süchtig