Session D-MASK

Der Maskendesigner

Peter Herzog
ProLib Software GmbH


Dieser Beitrag besteht aus zwei Teilen. Der erste enthält Infos für die Version 3.0 Entwickler. Der zweite geht im Besonderen auf die neue Version 5.0 ein.

Teil 1: Grundlagen der Version 3.0

1. Der Formdesigner und dessen Verwendung
1.1 Formularen anlegen / ändern.
1.2 Formulare speichern.

2. Eigenschaften und Methoden
2.1 Properties (Eigenschaften)
2.2 Methoden (Prozeduren / Events)
2.3 Selbstdefinierte Properties und Methoden

3. Objekte und Daten
3.1 Datenumgebung
3.2 Datasessions
3.3 Optimistische / Pessimistische Sperren
3.4 Row- und Tablebuffering

4. Visual Custom eXtensions
4.1 Speichern eines Formulars, oder dessen Elemente
4.2 Hereinholen einer Visuellen Klasse

5. OLE-OBJEKTE einbinden
5.1 OLE Objekte im Formular plazieren und verwenden.
5.2 Datengebundene OLE Objekte

6. Eigene TOOLBARS erzeugen

7. Das Gridobjekt

8. Die Basisklassen

9. Die Formular Optionen

10. Error loading Form. .... Record number ...

Teil 2: Erweiterungen der Version 5.0

1. Der Formdesigner und dessen Verwendung

Der Formdesigner ist eine der zentralen Neuerungen von Visual FoxPro 3.0. Wie unter den Version 2.x haben Sie die Möglichkeit Ihr Maskendesign am Bildschirm zu gestalten. Der große Unterschied zur 2.x Version besteht allerdings darin, daß unter Visual FoxPro 3.0 die gesamte SCX-Datei sofort ausgeführt werden kann. Um dies zu verdeutlichen muß ich ein wenig weiter ausholen.

Bisher wurde eine Maske entweder handkodiert oder durch den Maskeneditor erstellt. Durch das visuelle Zusammenstellen von Elementen am Bildschirm wurde jedoch noch lange kein eigentlicher, ausführbarer Code generiert, sondern es wurden sogenannte „Metadaten" erstellt. Die Metadaten wurden in einer Datei mit der Endung .SCX abgelegt. Erst ein sogenannter Generator (GENSCRN.PRG) verwandelte aus den Metadaten echte Programme, die dann ausgeführt werden konnten. Die erzeugten Daten hatten die Endung *.SPR um sie von „normalen" Programmen unterscheiden zu können.

Im neuen Visual FoxPro ist man nun übergegangen, den Generationsprozess wegzulassen und es wurde möglich die Maske, heute Formular genannt, sofort wie ein Programm auszuführen.

1.1 Formulare anlegen / ändern.

Anlegen und Ändern eines Formulars geschieht durch die Befehle CREATE FORM <Formular> und MODIFY FORM <Formular>. Wenn CREATE FORM verwendet wird, so wird ein bereits bestehendes Formular überschrieben. Bei MODIFY FORM wird ein bestehendes Formular geöffnet oder es wird automatisch ein neues Formular angelegt. Sobald das Fenster am Bildschirm erscheint, haben Sie die Möglichkeit neue Elemente einzugeben, bzw. anzulegen. Zusätzlich zum Eingabefenster erscheinen, je nach Systemeinstellung, zusätzliche Fenster.

1.1.1 Die „Form Control" Toolbar

Gleichzeitig mit dem eigentlichem Fenster für das reine Editieren erscheint eine Toolbar, die bereits aus der Version 2.x bekannt ist, jedoch damals direkt im Editierfenster integriert war.


Die Toolbar zeigt nun Teils die gewohnten und Teils völlig neue Symbole, auf die ich hier näher eingehen möchte.


Der Pfeil zeigt an, daß Sie im Moment Objekte auf dem Fenster bewegen und verändern können.


Mit diesem Objekt können Sie selbstdefinierte „Visual Classes" zu Ihrer Maske zufügen, bzw. zwischen mehreren Form Controls wählen.


Diese drei Elemente entsprechen den @...SAY, @...GET und @...EDIT Befehlen und verhalten sich genauso wie unter der Version 2.x.


Dies entspricht einem 2.xer Pushbutton, wird jedoch nun CommandButton genannt.


Unter 2.x war es möglich mehrere PushButtons zu einer Reihe zusammenzufügen. Da diese Funktion bei einem CommandButton nicht mehr zur Verfügung steht, wurde die „Command Group" eingeführt. Dabei handelt es sich um ein Containerobjekt, welches mehrere CommandButtons beinhalten kann.


Der ehemalige Radiobutton ist nun zum Option Group geworden, reagiert jedoch genauso.


Die Checkbox oder Markierfeld hat sich ebenfalls nicht verändert. Es stellt nach wie vor einen Logischen Wert dar, der allerdings nun nicht mehr Ja oder Nein, sondern auch undefiniert beinhalten kann. Wie das obige Beispiel zeigt, ist die Checkbox an einen numerischen Wert gebunden, der im letzteren Falle eine 2 annimmt und somit undefiniert erscheint.


Die sogenannte Combobox ist ebenfalls aus der Version 2.x her bekannt, wurde jedoch um viele neue Features erweitert. Um nur ein einziges zu nennen, kann nun in dieser Combobox bereits editiert werden usw.


Dies ist die Listbox, die ebenfalls bereits bekannt ist, jedoch ebenfalls um eine Vielzahl an Möglichkeiten erweitert wurde. Unter anderem ist es nun möglich mehrere Spalten zu definieren usw.


Bei diesem Objekt handelt es sich um einen sogenannten Spinner, der eine Zahl hinauf oder hinunterzählen kann.


Dies ist das Symbol für ein Gridobjekt, welches weiter unten beschrieben wird.


Ein Bildsymbol, mit dem man beliebige BMP-Files einbinden kann.


Hierbei handelt es sich um ein Timerobjekt, welches zur Laufzeit selbst nicht sichtbar ist und beliebig auf dem Formular plaziert werden kann. Durch die Properties kann definiert werden, daß nach Ablauf einer definierten Zeit ein FoxPro-Programm gestartet wird.


Dies ist das Pageframe-Objekt. Es handelt sich dabei um ein Containerobjekt, welches wiederum andere Objekte in sich tragen kann. Jede Seite (Page) dieses Objektes wird durch einen Klick auf dessen Reiter aktiviert. Die Anzahl der Seiten usw. kann natürlich frei definiert werden. Es gibt auch noch eine Seite, welches sozusagen darunter liegt. Jedes Objekt, welches auf der untersten Seite liegt, wird durch alle anderen Seiten hindurch angezeigt und ist auch anwählbar.


Bei diesen Objekten handelt es sich einerseits um freie OLE2-Objekte, die z.B. wie Paint vorhanden sein können, andererseits können Sie damit „gebundene OLE-OBJEKTE" in Ihre Maske einbringen. Vereinfacht gesagt, können Sie ein WinWord oder Excel in Ihrer Applikation laufen lassen, wobei die Daten aus einer Datenbank kommen.


Hierbei handelt es sich um einfach Linien oder um grafische Elemente.


Dieses Objekt ist ein Separator, der bei der Definition einer Toolbar mehrere Objekte voneinander trennen kann, damit sie nicht zu sehr aufeinanderkleben.


Beim ersten Symbol handelt es sich um den Builder-Lock, beim zweiten um den Button-Lock. Wird der Button Lock gedrückt, dann bleibt z.B. ein CommandButton aktiv und kann mehrmals in der Maske plaziert werden.

1.1.2 Das Eigenschaften Fenster

Jedes Element beinhaltet Properties und Methoden.

Bei einem Property (Eigenschaft) handelt es sich um einen einstellbaren Wert, der z.B. das Aussehen eines Objektes beeinflußt. Oder z.B. einstellt, woher die Daten für dieses Objekt kommen sollen.

Bei Methoden handelt es sich um Aktionen die ausgelöst werden.

Eine Methode eines CommandButtons wäre z.B. der einfache Klick darauf. Aber bereits ein darüberfahren mit der Maus kann eine solche Methode „abfeuern". Man spricht hierbei um die Events.

Sollte das Eigenschaftenfenster nicht offen sein, so kann es geöffnet werden, in dem man mit der rechten Maustaste auf das Formular klickt und dann dementsprechend „Eigenschaften..." anklickt.

Das Eigenschaftenfenster besteht aus mehreren Elementen

1.1.2.1 Die Element-Combobox


Hier können Sie die gesamte Baumstruktur Ihrer Maske betrachten und sich ein spezielles Element auswählen.

1.1.2.2 Das Pinnadelsymbol


Das Pinnadelsymbol kann zwei verschiedene Zustände einnehmen. Das erste zeigt an, daß das Property sozusagen angesteckt ist. In diesem Falle bleibt das Fenster immer im Vordergrund. Diese Funktion entspricht dem „AlwaysOnTop" Property und kann natürlich auch selbst erzeugt werden.

1.1.2.3 Builder


Dieses Symbol startet einen Builder, der einem beim Erzeugen von Elementen unterstützt. Die Besonderheit an solchen Buildern ist, daß man sie selbst mit normalem FoxPro-Programmcode schreiben kann.

1.1.2.4 Die einzelnen Properties

Es wird hier nicht näher auf die einzelnen Properties eingegangen, da die Beschreibung in der Originaldokumentation bestens aufgelistet ist.

1.1.3 Andere Fenster

Es können noch diverse andere Fenster auftauchen, die meistens vom Property-Fenster aus geöffnet werden. Wenn man z.B. die Hintergrundfarbe einer Form verändern möchte, so muß man nicht die RGB-Kombination wissen, sondern kann in einem zusätzlichem Fenster aus einer Farbtafel auswählen.

1.2 Formulare speichern.

Hier steht Ihnen Sichern oder Sichern als... zur Verfügung. Dies funktioniert wie gewohnt.

Es gibt noch zusätzlich einen Punkt, der „Sichern als Klasse" heißt. Hier können Sie selbst VCX´e erstellen. Die in der Maske gemachten Definitionen können hier in wiederverwendbare Objekte verwandelt werden, deren Aussehen und Funktion in einer anderen Maske verwendet (vererbt) werden können.

Nebenbei noch ein Tip: Normalerweise wird ein, in einer Form eingegebener Code, beim Abspeichern automatisch compiliert. Wenn jedoch SCX-Dateien per Hand geändert werden, so muß mit COMPILE FORM der Code in den Forms neu übersetzt werden. Da VCX´en den selben Aufbau wie SCX´en haben, ist das COMPILE FORM auch auf VCX´en anzuwenden.

2. Eigenschaften und Methoden

Im ersten Teil haben wir kennengelernt, daß eine Vielzahl an Objekten gibt, die man in einem Formular plazieren kann. Sie haben auch gehört, daß jedes Objekt Eigenschaften und Methoden (Prozeduren oder Events) beinhalten kann.

2.1 Properties (Eigenschaften)

Als Eigenschaft kann z.B. die Position in der Form sein, oder dessen Größe und Farbe. Auch haben spezielle Objekte Ihre speziellen Eigenschaften. Eine besondere Eigenschaft des Timerobjektes ist z.B. der Intervall, der in Millisekunden angegeben wird. Wird diesem Property ein Wert ungleich 0 angegeben so wird nach Ablauf der eingegeben Zeit die Methode TimerEvent gestartet. Bei dieser Methode handelt es sich um ein normales FoxPro-Programm welches beliebige Aktionen ausführen kann; z.B.: kann es die Position eines anderen Objektes verändern usw.

2.2 Methoden (Prozeduren / Events)

Im Gegensatz zu den Properties handelt es sich bei den Methoden um Programme, welche gestartet „gefeuert" werden, wenn eine bestimmte Bedingung eintritt. Eine solche Bedingung kann z.B. eine Nachricht vom Betriebssystem sein, daß die Maus über ein Objekt bewegt wurde, oder ob auf das Objekt geklickt wurde. In diesem Falle spricht man von einem Event.

Andererseits kann eine solche Methode auch programmatisch aufgerufen werden. Es handelt sich ja dabei um ein normales Programm welches gleich einer Prozedur gestartet wird.

Als Beispiel soll hier der DRAG-Event angeführt werden, den Sie selbst starten können, wenn in eine Textbox geklickt wird. Nur so schaffen Sie es, eine Textbox auch wirklich an andere Stellen zu schieben.

2.3 Selbstdefinierte Properties und Methoden

Meistens kommt man mit den eingebauten Properties und Methoden aus, um einer Maske Leben einzuhauchen. Aber wenn es darum geht spezielle Code unterzubringen, oder Werte in der Maske abzuspeichern, so muß man sich selbst diese definieren.

Ein spezieller Tip nebenbei: Wenn Sie eine Variable brauchen, die von mehreren Methoden aus benötigt wird, so müssen Sie ein Property in der Form anlegen, da alle Variablen automatisch Privat deklariert sind, sobald diese in einer Methode verwendet werden. Dieses Property sprechen Sie nun über THISFORM.variable an und kann überall verwendet werden. Dazu gibt es unter dem Menüpunkt FORMS einen Punkt um neue Properties und Methoden anzulegen.

Jedes hier angelegte Property erscheint im Eigenschaftenfenster unter „Andere" am Ende der Liste. Wie normale Variablen werden auch Properties zuerst einmal mit .F. vorbelegt. Wenn Sie einen anderen Anfangswert haben möchten können Sie diesen sofort eintragen oder z.B.: im INIT-Event neu anlegen. Auch Arrays können eingetragen werden. Um dies zu bewerkstelligen müssen Sie in Klammern die Dimensionen andeuten. Also meinarray(1) für eindimensional, meinarray(1,1) für zweidimensional. Voreinstellen können Sie diese Arrays nur durch Zuweisung im INIT-Event.

3. Objekte und Daten

Eine Formular macht nur dann ordentlich Sinn, wenn damit Daten behandelt werden. Visual FoxPro 3.0 gibt uns nun Werkzeuge in die Hand, die Datenbearbeitung mit einem Formular zum Kinderspiel machen.

Speziell für die Datenbearbeitung stehen uns verschiedene Properties und Methoden zur Verfügung, die automatisch bei einem Objekt vorhanden sind. Außerdem haben wir die Möglichkeit Tabellen und Ansichten aus Datenbankcontainern der Maske zuzuordnen.

3.1 Datenumgebung

Sobald man ein Formular geöffnet hat, kann man unter dem Menüpunkt „Ansicht", die Datenumgebung öffnen.

In dem nun erscheinenden Fenster kann man beliebige für die Maske notwendige Tabellen und/oder Ansichten abspeichern. Wie fast überall in VFP3.0 ist die rechte Maustaste hier sehr behilflich. Man kann zwar auch über das Menü oder die ebenfalls erscheinende Toolbar eine Tabelle zufügen, jedoch mit der rechten Maustaste geht es am schnellsten. Sobald man eine Tabelle dem Formular zugefügt hat, kann man entweder ein Feld oder die gesamte Tabelle auf das Formular ziehen.

Es wird dann automatisch ein dementsprechendes Element im Formular angelegt. Wird die gesamte Tabelle hinübergezogen, so wird automatisch ein Gridobjekt erzeugt.

Diese Art des Feldanlegens ist die einfachste Art und Weise und erspart einem die Zuweisung der Properties. Allerdings hat es den Nachteil, daß die in VFP3.0 fest eingebauten „Basisklassen" verwendet werden, was ein nachträgliches Ändern schwierig macht.

3.2 Datasessions

Unter Visual FoxPro hat man die Möglichkeit, jede Maske mehrmals zu öffnen. Die zugeordneten Daten, bzw. die Tabellen und Ansichten müssen natürlich geöffnet werden um darauf zugreifen zu können. Wenn nun die Tabellen nur einmal geöffnet werden würden, dann würde sich der Satzzeiger jedesmal verändern, wenn man in einer anderen Maske einen anderen Datensatz in der selben Tabelle ansprechen würde. Um dies zu vermeiden hat man die Möglichkeit sogenannte „Private Sessions" zu definieren.

Hier werden die einzelnen Tabellen extra verwaltet und im Speicher verwaltet. Sobald man nun in seiner eigenen Privaten Datenumgebung den Satzzeiger verändert, so wird ein parallel dazu geöffnetes Formular nicht beeinflußt.

Dieses Verhalten kann man einstellen, indem man das Property „Datasession" von 1 (Default Datasession) auf 2 ( Private Datasession) stellt.

Hier gleich noch ein nützlicher Tip: Private Datasessions haben die Eigenheit alle SET-Einstellungen auf den amerikanischen Standard zurückzusetzen. Deshalb muß man die notwendigen Einstellungen im LOAD-EVENT der Maske erneut setzen.

3.3 Optimistische / Pessimistische Sperren

Die Datenumgebung ist dem gesamten Formular zugeordnet und in der Form gibt es nun ein spezielles Property, welches angibt, wie VFP3.0 sich beim Datenbearbeiten verhalten soll.

Dieses Property heißt „Buffermode" und kann die Zustände 0 none (default) 1 Pessimitic und 2 Optimistic annehmen.

3.3.1 None

bedeutet, daß keinerlei Netzwerksperren angewendet werden.

3.3.2 Pessimitic

bedeutet, daß der Datensatz gesperrt wird, sobald auch nur eins der Felder bearbeitet wird. Es ist wichtig zu wissen, daß die Sperre erst dann in Kraft tritt, wenn ein Feld bearbeitet wird und nicht, wenn der Datensatz gelesen wird. Dieses Verhalten ist das „Alte" aus FPW2.6. Sie werden beim Umstieg auf VFP3.0 mit diesem Sperrverhalten die wenigsten Probleme haben.

3.3.3 Optimistic

bedeutet, daß erst beim Verlassen oder expliziten Speichern mit TABLEUPDATE() der Datensatz gesperrt wird und erst dann die Daten weggeschrieben werden.

3.4 Row- und Tablebuffering

Neben dem Sperrverhalten kann nun auch Datenpufferung eingestellt werden. Dies wird durch das Property „Buffermode Override" aus der Datenumgebung heraus eingestellt. Zur Verfügung stehen folgende Einstellungen

3.4.1 0 Use Form Settings (default)

Dies ist defaultmäßig eingestellt und bedeutet, daß die Einstellungen der Form übernommen werden.

3.4.2 1 Pessimitic Row Buffering

Dies bedeutet, daß der einzelne Datensatz sofort gesperrt wird und die Daten in die Originaltabelle geschrieben werden, sobald der Datensatz gewechselt wird, oder TABLEUPDATE() durchgeführt wird. Sollte gewünscht werden, daß die Daten nicht weggeschrieben werden, so kann mit TABLEREVERT() der originale Zustand wiederhergestellt werden.

3.4.3 2 Optimistic Row Buffering

Hier wird ebenfalls nur ein Datensatz gesperrt, jedoch erst wenn der Datensatz verlassen wird, oder TABLEUPDATE() durchgeführt wird.

3.4.4 3 Pessimistic Table Buffering

Diese Einstellung funktioniert genauso wie das pessimistische Row Buffering, jedoch wird hier jeder angesprochene Datensatz gepuffert. Achten Sie darauf, daß in diesem Falle SET MULTILOCKS auf ON stehen muß.

3.4.5 4 Optimistic Table Buffering

Diese letzte Einstellung bezieht sich ebenfalls auf die gesamte Tabelle, verhält sich ansonsten genauso, wie das optimistische Row Buffering.

4. Visual Custom eXtensions

Die VCX´e sind die VFP3.0 eigenen Bausteine, ähnlich den OCX´en oder VBX´en.

Diese Dateien können mehrere Visuelle Klassen beinhalten. Also wie der Name bereits verrät, sichtbare Objekte mit Programmcode dahinter. Selbstverständlich können diese Objekte vererbt werden und fügen sich nahtlos in ein Formular ein.

Die VCX´e können aus allen Visuellen Basisklassen bestehen und jede beliebige Form annehmen. Eine einzige Klasse könnte ein ganzes Programm beinhalten. Mit VFP3.0 haben Sie bereits ein paar Demonstrationsklassen mitgeliefert bekommen, welche Sie frei verwenden können. (Siehe im Verzeichnis samples\controls )

4.1 Speichern eines Formulars, oder dessen Elemente

Es ist möglich mit dem Formulardesigner sich eigene VCX´e zu erstellen, indem man im Hauptmenü „Als Klasse speichern" wählt.

Sobald man diesem Menüpunkt gewählt hat, kann man auswählen, ob man die gesamte Maske oder nur die darin befindlichen Objekte als Klasse speichern möchte. Wählt man „Aktuelles Formular" so wird beim Wiederhereinholen der Klasse das aktuelle Formular überschrieben.

Wählt man „Ausgewählte Steuerelemente", so werden beim wiederhereinholen der Klasse diese Elemente in das aktuelle Formular eingefügt.

Beim Abspeichern muß man sich für einen Namen entscheiden, unter dem die Elemente in einer VCX-Datei gespeichert werden. Es können so beliebig viele Klassen in einer VCX untergebracht werden.

Letztendlich muß noch die physikalische VCX-Datei benannt werden in der die Klasse gespeichert wird.

Übernommen wird jedes gewählte Objekt mit dessen Properties und Methoden.

4.2 Hereinholen einer Visuellen Klasse

In der Form Control Toolbar steht uns folgendes Symbol zur Verfügung

Klassen anzeigen

Das dahinter verborgene Menü ermöglicht uns neue Klassen hinzuzufügen, die Standardklassen anzuzeigen oder OLE-Steuerobjekte einzufügen.

Sobald man eine VCX-Datei hinzufügt, werden die darin enthaltenen Klassen als kleine Icons in der Form Control Toolbar angezeigt.

Die neuen Klassen kann man nun genauso wie die Basisklassen frei auf der Form anordnen.

Die Properties werden dabei voll übernommen.

Die Methoden sind auf den ersten Blick nicht sichtbar, werden jedoch angewendet, wenn man diese nicht mit eigenem Code überschreibt. Eine Übernahme der Methoden erzwingt man mit folgender Schreibweise:

Klassenobjekt::Methode

wichtig sind dabei die zwei Doppelpunkte, die angeben, daß der Code aus der vererbten Klassen eingefügt werden soll.

5. OLE-OBJEKTE einbinden

Eine der wichtigsten Neuerungen stellt die Verwendung von OLE2 Objekten dar. Darunter versteht man fremde Programme, die nahtlos in die eigene Applikation eingefügt werden, wobei man die Umgebung des eigenen Programmes nicht verläßt.

OLE2 Objekte fügen sich nahtlos in bestehende Formulare ein und deren Funktionalität kann frei im eigenen Programm verwendet werden.

Am Beispiel eines eingebundenen Winword´s sieht man, daß beim „Betreten" des Objektes die Menüs und TOOLBARS gegen die des WinWord´s ausgetauscht werden und man sich sozusagen im WinWord befindet, ohne FoxPro verlassen zu haben.

5.1 OLE Objekte im Formular plazieren und verwenden.

Ein OLE Objekt wird durch

OLE-Container-Steuerelement

angelegt. Ein einfaches Ziehen eines Rahmens definiert die Position am Bildschirm, bzw. in Ihrem Formular.

Sobald man den Platz durch ziehen eines Rahmens definiert hat, kommt man in ein Dialogfenster „Einfügen Objekte". Hier hat man nun drei Möglichkeiten auszuwählen:

5.1.1 CREATE New

Aus einer Liste können Sie die in Ihrem System eingetragenen OLE-Server, sprich Programme die OLE2 fähig sind, auswählen. Als OLE2 Server gilt z.B. Paint oder WinWord, Excel usw.

Wählen Sie eines dieser Programme aus, so wird es im Hintergrund gestartet und erscheint bei jedem Klick darauf, als Fenster in Ihrer Maske.

5.1.2 CREATE FROM File

Hier haben Sie die Möglichkeit, eine Datei anzugeben deren Programm automatisch aufgerufen wird, welches es erzeugt hat. Eine XLS-Datei wird dann automatisch von Excel bearbeitet.

5.1.3 INSERT Control

Hier können Sie eines der neuen OCX´e einbinden. Zur Zeit stehen nur wenige solcher Programmteile zur Verfügung, aber viele Entwickler haben bereits angekündigt in absehbarer Zeit OCX´e zu entwickeln und anzubieten. Unter anderem wird es dann Textverarbeitungen usw. geben, die Sie hiermit auf einfachste Art und Weise einbinden können.

Zum sogenannten Ausprobieren wurde VFP3.0 z.B. das Outline-OCX mitgegeben. Dieses Objekt zeigt eine Baumstruktur an, die Sie als Programmierer selbst gestalten können.

Holen Sie sich dieses Objekt einmal in eine Ihrer Maske und Sie erkennen sofort eine Darstellung, wie sie uns vom Dateimanager her bekannt ist. Mit diversen Eigenschaften und Methoden können Sie nun von außen auf dieses Objekt einwirken.

5.2 Datengebundene OLE Objekte

So richtig Sinn, macht ein WinWord in Ihrer Maske, wenn Sie Ihr WinWord-Dokument aus einer Datenbank beziehen können. Zu diesem Zweck gibt es

gebundene OLE Steuerelemente.

Dieses Objekt verhält sich im Grunde genauso wie ein normales OLE2 Objekt. Die Daten die es benötigt bekommt es jedoch direkt von FoxPro.

Das General-Feld in einer Datenbank können Sie verwenden um einerseits WinWord-Dokumente, andererseits Paintbrush-Bilder zu bearbeiten.

Die nette Eigenheit dieses Objektes ist die Tatsache, daß jeweils das benötigte Programm geladen wird, wenn es sich um unterschiedliche OLE-Datentypen handelt.

Es ist auch möglich OLE1 Objekte zu verwalten, allerdings können dann die Programme nicht mehr in Ihrer Maske erscheinen, sondern werden als einzelne selbständige Programm aufgerufen.

6. Eigene TOOLBARS erzeugen

Als eine der neuen „Schönheiten" kann man die TOOLBARS bezeichnen. Es handelt sich dabei eigentlich um normale Fenster, die verschiedene Knöpfe oder Symbole beherbergen. VFP selbst weiß was es zu tun hat, wenn man eine solche Toolbar mit der Maus verschiebt und z.B. am Bildschirmrand „andockt".

Das Toolbar-Objekt selbst ist ein Containerobjekt und kann mittels CREATE class angelegt werden. Ein einzelnes „CREATE class" öffnet ein Dialogfenster, in dem Sie angeben können, wie die Klasse heißt, von welcher Basisklasse sie abstammt und in welcher VCX sie gespeichert werden soll.

Als Basisklasse verwenden Sie hier natürlich „Toolbar".

Nun bekommen Sie eine kleine Toolbar gezeigt, die zuerst noch leer ist. In diese Toolbar können Sie nun Objekte plazieren, wie Sie es für notwendig erhalten. Die Objekte haben nun wieder Eigenschaften und Methoden, die Sie nach Ihren Wünschen definieren können.

Sobald Sie die Klasse abspeichern, können Sie sich die Toolbar nun frei verwenden.

Zuerst müssen Sie die Klassen dem System bekannt geben. Am einfachsten geschieht das durch den Befehl:

SET CLASSLIB TO <name.VCX>

Nun müssen Sie das Objekt Toolbar erzeugen. In der VCX steht ja nur die Beschreibung der Toolbar. Dies geschieht durch:

x=CREATEOBJ(„Klassenname")

x ist dabei eine beliebige Variable, unter deren Name wir unser Objekt wiederfinden können.

Klassenname ist nun der Name der Toolbar unter der sie in der VCX-Datei gespeichert wurde.

Mit x.show erscheint die Toolbar auf dem Bildschirm und kann ganz normal verwendet werden.

x.release läßt die Toolbar wieder verschwinden und entfernt sie auch noch gleichzeitig aus dem Speicher.

7. Das Gridobjekt

Das Gridobjekt ist eines der mächtigsten und auch kompliziertesten Objekte, die VFP3.0 zu bieten hat.

Grundsätzlich handelt es sich um ein Containerobjekt welches wiederum andere Objekte in sich beherbergen kann. Standardmäßig ist ein Header-Objekt, also die Überschrift, und ein Textobjekt eingebunden. Diese Zusammenstellung entspricht einem normalen Browse-Window wie wir es aus der 2.x Zeit her kennen.

Das Gridobjekt ist jedoch weitaus mehr. Sie können nahezu alles damit machen solange es sich dabei auf eine Tabelle oder Cursor handelt.

Die einzelnen Eigenschaften aufzuzählen und zu beschreiben würde den Rahmen dieses Dokumentes sprengen, aber einige Spezialitäten möchte ich hier doch aufführen.

Natürlich gibt es hier wieder die Möglichkeit durch die Angabe einer „Recordsource" anzugeben, woher die Daten stammen, die angezeigt werden sollen. Weiters haben Sie die Möglichkeit durch die Eigenschaft „Linkmaster" anzugeben, wie die Tabelle in Relation zu einer anderen steht. Auch kann der Index bestimmt werden, nachdem die Tabelle gereiht werden soll. Dies geschieht durch die Eigenschaft „Childorder".

Die Anzahl der Spalten wird durch „ColumnCount" angegeben. Wenn diese -1 darstellt, so wird automatisch die volle Tabelle hereingeholt. Sobald Sie die Zahl erhöhen, so wird das Gridobjekt sozusagen erweitert und es stehen pro Spalte ein Headerobjekt und ein Textobjekt zur Verfügung.

Zur Veranschaulichung:

GRID
Columne 1
Header 1
Text 1
Columne 2
Header 1
Text 1

Anstelle eines Textobjektes kann nun jedes andere Element eingesetzt werden, solange es fähig ist, in einem Containerobjekt Platz zu nehmen. (Ausnahmen sind hier Form und Formset)

Zum Beispiel kann hier ein Commandbutton stehen, der wenn er gedrückt wird z.B. eine Telefonnummer wählt.

8. Die Basisklassen

Um von Klassen sprechen zu können, muß ich zuerst einmal weiter ausholen und Objekte, an sich, erklären.

Unter VFP3.0 ist alles ein Objekt und jedes Objekt liegt in einem Container. Selbst VFP3.0 ist ein Objekt und liegt in Windows eingepackt im Speicher. Genaugenommen wird jedes VFP-Object selbst von VFP gemalt. Ausnahmen sind hier die Windows selbst, die vom „echten" Windows gezeichnet werden.

VFP3.0 selbst wird über die Systemvariable _screen angesprochen. Vermeiden Sie bei DEFINE WINDOW Anweisungen den Namen SCREEN oder ähnliches. Es könnte intern zu Konflikten kommen. Wenn Sie nun ein Formular oder eine Toolbox auf den Bildschirm bringen, so wird in VFP3.0 dazu ein Speicherbereich reserviert und mit einem Namen versehen, damit man diesen Speicherbereich jederzeit beeinflussen kann.

Ein Formular liegt dann sozusagen in dem Vaterobjekt „_screen" eingebettet. In VFP3.0 wurden mehrere Platzhalter eingeführt, die indirekt auf andere Objekte zeigen. „parent" ist z.B. ein Zeiger auf das in der Hierarchie darüberliegende Objekt. Liegt ein Formular am Bildschirm, so ist _screen sein „parent".

Auch kann das aktuelle Objekt angesprochen werden, ohne dessen Name selbst zu kennen. (Dies ist notwendig, wenn Klassen ihren Namen ändern)

Um auf ein FORMSET (ein Zusammenschluß mehrerer Formulare) zugreifen zu können, so können Sie entweder dessen Name verwenden, oder eben einen Platzhalter mit der Bezeichnung THISFORMSET.

Eine Form wird mit THISFORM referenziert und das einzelne Objekt ist durch THIS zu erreichen.

Beispiel: Auf dem Bildschirm liegt ein Formular mit einem einzelnen Commandbutton. Wenn Sie nun die Schriftart des Commandbuttons verändern möchten, dann haben Sie die Möglichkeit dies mit THIS.FontName=„Curier New" zu erledigen. In diesem Falle wird die Änderung auch sofort ausgeführt. Es gibt auch noch andere Eigenschaften, wo ein Refresh der Maske notwendig wird, damit Daten am Schirm auch angezeigt werden.

Wenn Sie nun in der Click Methode des Commandbuttons, THISFORM.Release hinterlegen, so wird das Formular released, also aus dem Speicher entfernt. Dies hat natürlich auch die Folge, daß das Fenster vom Schirm verschwindet und das Programm beendet wird.

Visual FoxPro 3.0 ist nun mit den wichtigsten Klassen bereits ausgestattet, damit man ordentliche Windowsprogramme erzeugen kann. Diese Klassen nennt man Basisklassen, da von diesen alle VFP-Klassen abgeleitet werden.

Man muß bei den einzelnen Basisklassen aber noch unterscheiden, ob es sich dabei um ein Containerobjekt handelt oder ob es z.B. ein Objekt ist, welches nur in einem bestimmten Containerobjekt liegen kann. (Beispiel: Header kann nur in einem Grid vorkommen)

Hier eine Aufstellung der Klassen:
Container kann beinhalten
  • FormSet
  • Form
  • PageFrame
  • PageFrame
  • CommandButtonGroup
  • OptionButtonGroup
  • Grid
  • Column
  • Selbstdefinierte Objekte

Form
PageFrame und jede andere Klasse darunter
Page
Jede Klasse darunter
CommandButton
OptionButton
Column
Header, CheckBox, ComboBox, CommandButton, EditBox, ListBox, OptionBox, Spinner, TextBox, Grid
Alle Klassen

Da eine komplette Aufzählung aller Möglichkeiten, Eigenschaften und Methoden alle Grenzen sprengen würde, so darf ich Sie auf die Hilfedatei verweisen, in der Sie unter „The Visual FoxPro Base Classes" eine vollständige Auflistung erhalten.

9. Die Formular Optionen

Im Menüpunkt Extras können die Optionen angezeigt werden. Speziell für die Formulare und den Formdesigner gibt es hier eine eigene Seite, bei der verschiedene Standardeinstellungen gemacht werden können.

Unter anderem kann man für das FormSet und die einzelne Form eine sogenannte Klassenvorlage (im Englischen Templates) bestimmen. Es handelt sich dabei um normale VCX´e, deren Inhalt beim Neuanlegen eines Formulars hereingeholt wird.

Hier können Sie z.B. bereits die Hintergrundfarbe festlegen usw. Ein besonderer Vorteil ist dabei, daß Sie beim Verändern der Klassenvorlage automatisch alle damit erstellten Formulare ebenfalls verändern, ohne irgend etwas neu generieren oder kompilieren zu müssen.

10. Error loading Form. .... Record number ...

Es wird Ihnen garantiert einmal passieren, daß Sie diese Meldung am Schirm sehen und eventuell schaffen Sie es nicht mehr die Form mit MODI FORM formname aufzumachen. Jetzt heißt es, „nicht verzagen". Wie immer und überall liegen uns die Metadaten der Form zu Füßen und wir müssen diese nur in die Hand nehmen und überarbeiten. Im Falle einer Form ist dies eben die SCX-Datei. Ein einfaches USE meineform.SCX und dann ein BROWSE zeigt uns den Inhalt der Datei. Passen Sie jedoch auf, was Sie machen. Ein „ungeschultes" Eingreifen hat schon so manche Form für immer verschwinden lassen. Auf alle Fälle ist bei der oben genannten Fehlermeldung die Datensatznummer dieser SCX gemeint. Meistens „happerts" beim Datenevironment. Leider läßt sich hier nicht genau ermitteln, welche Datei gemeint ist. Also hilft nur noch suchen. Aber auf alle Fälle sollten Sie sich folgende Felder genauer ansehen.
  • CLASS
Die Klasse des Objectes.
  • CLASSLOC
Der Pfad einer eventuellen VCX-Datei von der das Object abstammt.
  • BASECLASS
Der Name der Basisklasse.
  • OBJNAME
Der Name des Objectes
  • PARENT
Das darüberliegende Object welches das Object beinhaltet.
  • PROPERTIES
Die Properties, die gegenüber der Superclass geändert wurden.
  • METHODS

Der Code, der dahinter liegt.

  • OBJCODE
Der Code in kompilierter Form. (Nicht verändern)

Dies war der erste Streich und er zweite folgt zugleich.

Teil 2: Erweiterungen der Version 5.0

In der Version 5.0 sind die Grundlagen die gleichen geblieben. Sie Öffnen eine Maske mit MODIFY FORM und erhalten ebenfalls die gewohnte Toolbar.

Wenn Sie genau nachsehen, bemerken Sie, daß ein Containerelement nun ebenfalls über diese Toolbar eingefügt werden kann, ohne eine Klasse bemühen zu müssen.

Unter dem Klassen-Symbol verbirgt sich nun ein neues Wort. „AktiveX Controls“

Aber keine Angst. Nur der Name ist neu. Ansonsten sind hier wie zuvor die OCX´e zu laden.

Etwas generell Neues erleben Sie, wenn Sie eine Maske die über den RUN-Knopf gestartet wurde wieder schliessen. Die Maske wird sofort wieder zum Editieren geöffnet. Ein Luxus, den ich schon lange vermisst hatte. Dazugehörig wurde auch ein Button in der Toolbar untergebracht, der eine laufende Form abbricht und in den Editiermodus übergeht.

Im Propertiefenster hat sich ebenfalls einiges getan. Mit der rechten Maustaste auf den Rahmen geklickt läßt ein Menü aufgehen.

Sie können nun die Beschreibungen am Fußende ein und ausschalten. Das Pinnadelsmbol ist verschwunden und anstelle dessen gibt es in dem Menü einen Eintrag.

Neu ist ebenfalls, daß Sie die Anzeige auf die geänderten Bestandteile beschränken können. Zu allerletzt ein hilfreiches Tool für die Redner der Konferenz: Der Font ist einstellbar.

An der Klasse „Form“ selbst hat sich auch einiges getan. Eine neue Form erscheint sofort in der richtigen Hintergrundfarbe, es werden dabei automatisch die Systemsettings gelesen. (Coloursource-Propertie)

Auch neu ist die Möglichkeit eine Maske als SDI-Form zu deklarieren. (ShowWindow-Propertie)

SDI bedeutet, daß die Form sich frei am Desktop bewegen läßt, ohne im Hauptfenster gefangen zu sein. Es kann sogar noch unterschieden werden, ob es „AS Top Level Form“ oder „IN Top Level Form“ laufen soll. Ersteres bedeuted, daß es sich wie ein neues Programm verhält. Dies gilt auch für den minimierten Zustand. Es erscheint dann sogar in der Startleiste von Windows95.

IN Top Level Form bedeuted, daß es sich in der Maske einnisted, welche als die Oberste anzusehen ist.

Jede Maske kann nun auch mit dem Fragezeichen in der rechten oberen Ecke versehen werden. Dieses „ShowWhatThis“ Verhalten bezahlt man allerdings mit verschiedenen anderen Einstellungen. Als Beispiel darf die Maske nicht mehr verkleinert, vergrößert, minimiert und maximiert werden. Modal muß sie außerdem noch sein und ShowWhatThis muß aktiviert sein. Erst dann erscheint dieses Fragezeichen und Sie können damit jedes beliebige Objekt anklicken, welches dann mit der Anzeige des Hilfetextes antworten soll.

Auch bei den einzelnen Basisklassen wurden vereinzelt neue Properties und Methoden eingeführt. Hier einige herausragende Beispiele:

Jedes textanzeigende Objekt hat nun das Property „IntegralHeight“. Dies ist dafür zuständig, daß das Object sich in der Größe ausrichtet, um den Inhalt ordentlich anzeigen zu können. Eine Fontänderung wirkt sich dann natürlich sofort auf das gesamte Objekt aus.

Die Combobox besitzt nun endlich ein Format und InputMask Property. Außerdem kann nun als Controlsource ein numerisches Feld verwendet werden, ohne daß der Listindex zurückgeliefert werden. Man hat auch endlich entdeckt, daß es sich bei der Combobox um mehrere Elemente in einem handelt und kann nun eigene Click-Ereignisse abfangen, wenn unterschiedliche Elemente angeklickt werden.

Entscheidend haben sich die Pages einer Pageframe geändert. Diese erscheinen nun nicht mehr gleichmäßig auf die gleiche Länge getrimmt, sondern sind einmal kürzer, einmal länger, je nach dem, wie lange der Text ist, der auf der Page als Caption gespeichert wurde.

Sollte Ihnen dieses Verhalten nicht gefallen, so können Sie dies durch das Tabstyle-Propertiy ändern.

Komplett neu erscheint einem das Verhalten des Dataenvironments. Wenn man eine Tabelle zufügt und keine Datenbank geöffnet ist, erscheint automatisch der Dateiöffnen-Dialog. Nachdem man eine Datei ausgewählt hat, bleibt der Dialog geöffnet usw. Lauter Kleinigkeiten, die das Leben leichter machen.

Wenn Sie aus dem Dataenvironment eine Tabelle in die Maske ziehen, wird automatisch ein komplettes Grid erzeugt, als ob Sie den Builder zu Hilfe genommen hätten.

In der Version 3.0 wurden leider immer wieder VFP-Basisklassen verwendet, wenn man ein Feld aus einem Cursor in die Maske fallen ließ. Jetzt haben Sie die Möglichkeit selbstdefinierte Klassen zu hinterlegen, welche verwendet werden, wenn Sie ein Feld in die Maske fallen lassen.

Man bemerkt, daß die Entwicklungsabteilung selbst mit dem Produkt gearbeitet hat, anders sind diese Neuerungen scheinbar nicht erklärbar. <g>

Nun eine etwas genauere Erklärung des DO FORM Befehls:

Wenn man eine VFP-Form unter dem Gesichtspunkt der Objektorientierten Programmierung ansieht, so stellt Sie einen glatten Verstoß gegen diese dar. Ein normales Objekt muß mit x=createobject() erzeugt werden. Eine Form hingegen wird mit einem Befehl gestartet: DO FORM.

Dieser Befehl erzeugt in einem Atemzug ein Objekt „Form“, hängt ein Dataenvironment dazu, öffnet Dateien und zeigt die Maske auch noch an. Die Maske macht auch noch etwas OOP-Unübliches. Es werden eine Vielzahl von Methoden zuerst abgefeuert, bevor das eigentliche INIT durchlaufen wird. Im Dataenvironment ist der BeforeOpenTables-Event der erste Platz, in dem Sie in einer Maske Selbstprogrammiertes unterbringen können. Direkt vor der eigentlichen Maske wird der LOAD-Event durchgeführt. Erst dann werden die einzelnen Objekte auf der Form eingebaut und deren INIT´s durchlaufen. Ganz zum Schluß läuft das INIT der Form ab. Parameter können jedoch erst hier übergeben werden. Beachten Sie dies wenn Sie Aufgrund von Parametern einzelne Objekte beinflussen wollen.

Wenn Sie eine Form einfach mit DO FORM myform.scx starten, so wird intern in VFP eine unsichtbare Referenz erzeugt, die verhindert, daß die Maske wieder verschwindet. Diese Referenz können Sie so nicht ansprechen, ohne über _screen.activeform oder _screen.forms(x) zu gehen.

Wenn Sie aber doch auf die Form zugreifen wollen, so können Sie eine Referenz mit der NAME-Klausel erzeugen.

DO FORM myform.scx NAME Referenz

Wollen Sie mehrere Instanzen der gleichen Form erzeugen, so müssen Sie natürlich den Namen der Referenz immer wieder wechseln. Es bietet sich an, ein Array dafür zu verwenden.

Mit der NAME-Klausel wird jedoch nur ein Weg aufgezeigt, wie man an die Form rankommt. Will man auch noch, daß sich die Form zerstört, wenn die Referenz aufgelöst wird, so muß auch noch LINKED angehängt werden.

DO FORM myform.scx NAME Referenz LINKED

Wenn Sie der Form Parameter übergeben wollen, so können Sie dies mit der WITH-Klausel erledigen.

DO FORM myform.scx WITH par1, par2

Im Init der Form muß dann natürlich eine PARAMETERS oder LPARAMETERS Anweisung stehen.

Wollen Sie aus der Form auch Daten empfangen, so ist dies möglich, wenn die Maske Modal eingestellt wird. In der Unload-Methode muß dann ein RETURN Wert Statement untergebracht sein. Den Rückgabewert erhalten Sie durch die TO-Klausel.

DO FORM myform.scx TO returnvariable

Ich hoffe, daß Sie nun wesentlich leichter mit dem Maskendesigner umgehen können und genügend Tips erhalten haben, um schöne, funktionelle Windows-Programme erstellen können.