Session D-TIPS

Programmier-Tricks für VFP

Sebastian Flucke
ASCI Consulting GmbH


Vorbetrachtung

Session-Notes zu einer Tips- & Tricks-Session sind mit das schwierigste, was einem so passieren kann, denn wollte man all die vielen Kleinigkeiten notieren, würde das bei weitem den hier möglichen Rahmen sprengen.

Aus diesem Grunde finden Sie auf den folgenden Seiten die Dokumentation von diversen Hilfsklassen sowie einige weitere Aspekte der Interna von Visual FoxPro.

Und ansonsten gilt für diese Session der olympische Gedanke "Dabei sein ist alles" <vbg>!

Dokumentation diverser Hilfs-Klassen

Alle im folgenden beschriebenen Klassen nebst deren Basisklassen finden Sie auf der Begleitdiskette.

Klasse cmbQuickFill

Combobox mit QuickFill-Eigenschaft à la “Quicken“. Bei der Eingabe jedes Buchstaben in das Editierfeld der Combobox wird sofort nach einem Satz gesucht, der in einem einstellbaren Suchbegriff mit den bisher eingegebenen Buchstaben übereinstimmt.

Basisklasse: ComboBox
Elternklasse: basComboBox

Beschreibung:

cmbQuickFill ermöglicht ein schnelles, interaktives Aufsetzen auf einem Suchbegriff in einer Tabelle, zum Beispiel einem Kundennamen. Die Tabelle muß dazu nach dem Suchbegriff indiziert sein. Bei der Eingabe eines neuen Buchstaben wird eine erneute Suche durchgeführt. Alle bisher eingetragenen Buchstaben werden für die Suche verwendet. Mit der Backspace-Taste können eingetragene Buchstaben zurückgenommen werden. Ist die Suche erfolgreich, wird der gefundene Suchbegriff im Textfeld der ComboBox ausgegeben. Der gesamte gefundene Suchbegriff wird dargestellt, wobei der eingegebene Teil des Suchbegriffs normal und der ergänzte Teil hinterlegt dargestellt wird. Ist die Suche nicht erfolgreich, wird der eingegebene Buchstabe zurückgewiesen (siehe dazu auch: lAllowNew Eigenschaft). Die ComboBox kann jederzeit normal aufgeklappt werden. Außerdem ist bei leerem Textfeld (also vor der Eingabe des ersten Buchstaben) ein Aufklappen mit der Leertaste möglich. Mit der Eigenschaft “lAllowNew“ kann festgelegt werden, ob die Eingabe neuer Werte erlaubt ist oder nicht. Neue Werte können gespeichert werden, wenn die Eigenschaft “nAutoSave“ 1 oder 2 enthält.

Einbau:

cmbQuickFill kann in jede FORM eingebaut werden. Die zu durchsuchende Tabelle muß geöffnet sein. Da die Suche mit SEEK() durchgeführt wird, muß als steuernder Index der Index auf dem Feld des Suchbegriffs aktiv sein. Der Index kann pur oder mit UPPER() bzw. LOWER() gebildet sein.

Der RowSourceType von cmbQuickFill ist fix auf 6 = Fields voreingestellt. Tragen Sie in RowSource den Feldnamen des Suchbegriffs mit vorangestelltem Alias ein. Wenn sichergestellt ist, daß beim Init der ComboBox bereits der richtige Arbeitsbereich angewählt ist, kann auf die Angabe des Alias verzichtet werden. Die Requery-Methode der ComboBox wird unterstützt. Sie können also die RowSource vom cmbQuickFill zur Laufzeit umsetzen. Nach einem Aufruf der REQUERY()-Methode arbeitet cmbQuickFill dann auf der neuen Tabelle mit dem neuen Suchbegriff.

Eigenschaften:
lAllowNew legt fest, ob neue Werte eingegeben werden dürfen
nAutoSave gibt an, ob neu eingegebene Werte gespeichert werden sollen:
0 = nicht speichern
1 = nach Abfrage speichern
3 = immer speichern
cAlias Alias der ControlSource, wird in der ReInit-Methode ermittelt
cDefaultKeys Liste von INKEY-Werten, für die ein Default-Verhalten benötigt wird. Werte in Backslashes einschließen, z.B. \24\5\ für Down- und Up-Arrow
cEscapeKeys Liste von INKEY-Werten für die eine Sonderbehandlung erforderlich ist. Wenn ein solcher Escape-Key eingegeben wird, wird die Methode EscapeKeyPressed (siehe unten) aufgerufen. Werte in Backslashes einschließen, z.B. \22\7\ für INS und DEL Key.
cField intern, Feldname für Liste, wird im ReInit ermittelt
cUpperLower intern, speichert Form des Indexausdruck  (Upper,Lower oder Proper), wird im ReInit ermittelt
lInGrid intern, hält fest, ob QuickFill in einem Grid verwender wird
cKeyTag Bezeichnung des Schlüssels, über den gesucht werden soll, Leer = voreingestellter Schlüssel
lFound intern, Merker für Begriff gefunden
cRowAlias intern, Alias der RowSource, wird im ReInit ermittelt
CrowField intern, erster Feldname der RowSource, wird im ReInit ermittelt
RowSourceType fix auf 6 = Fields
RowSource Name des Tabellenfeldes, das den Suchbegriff bildet, mit vorangestelltem Alias
Style fix auf 0 = DropdownCombo

Methoden:
AfterPositioning Nach dem Positionieren auf einem neuen Satz. Hier können Sie Methodencode hinterlegen, der nach dem Positionieren auf einem neuen Satz durchgeführt werden soll.
EscapeKeyPressed ObjektEvent: Wird aufgerufen, wenn eine der unter cEscapeKeys angegebenen Tasten gedrückt wurde. Der Tastencode wird übergeben.
NewValueQuestion ObjektMethode: gibt den Text der Frage zurück, die abfragt, ob ein neuer Wert gespeichert werden soll. Wenn ein Leerstring zurückgegeben wird, wird ohne Abfrage immer gespeichert.
_ReInit wird intern zur Neuinitialisierung nach einem Requery() benutzt.
_SaveValue intern, Methode zum Abspeichern des neuen Wertes

Klasse Commalist

Kommagetrennte Liste von Werten mit Navigationsmethoden

Basisklasse: Label
Elternklasse:  BasLabel

Eigenschaften:
cItemList Geben Sie die Liste von Ausdrücken mit Komma getrennt ein, die von diesem Objekt verwaltet werden sollen.
_ncount Interner Zähler
_npoint Zeigt auf den aktuellen Ausdruck der Liste. Nicht verändern!!!
_avalues[1,0] Array mit den einzelnen Ausdrücken

Methoden:
Recent Verwenden Sie Recent(), um den aktuellen Ausdruck aufzurufen. Der aktuelle Ausdruck ist der Ausdruck, auf der der Listenpointer gerade zeigt.
First First() ermittelt den ersten Ausdruck in der Liste
getpos Getpos() gibt die aktuelle Position des Listen-Pointers zurück.
Last Last() ermittelt den letzten Ausdruck in der Liste
Next Next() ermittelt den nächsten Ausdruck in der Liste
Previous Previous()ermittelt den vorherigen Ausdruck in der Liste
Requery Rufen Sie Requery() auf, nachdem Sie den Inhalt der Eigenschaft „Liste„ geändert haben.
Setpos Setpos(n) setzt den Listenpointer auf die n-te Position in der Liste

Klasse FormSizerH / FormSizerV

Dient zum Einstellen der wirklichen Form-Height bzw. Form-Width, wenn mit vielen zur Laufzeit unsichtbaren Klassen auf einer Form gearbeitet wird. In diesem Fall ziehen Sie die Form einfach größer, legen alle unsichtbaren Klassen am Boden der Form ab, und markieren die echte Form-Größe mit der FormSizerH-Linie. Dadurch sind die Forms wesentlich übersichtlicher, und die unsichtbaren Klassen werden zur Designzeit nicht durch andere Objekte verdeckt. Die Linie wird zur Laufzeit NICHT instanziiert, sondern setzt im INIT nur die Height der Form, um dann mittels RETURN .F. aus dem Leben zu scheiden...

Basisklasse: Line
Elternklasse: BasLine

Klasse Command

Führt einen Befehl aus, gibt Fehler-Code oder 0 zurück

Basisklasse: Label
Elternklasse: Complabel

Eigenschaften:
ccommand Letzte Befehlszeile, die den Fehler verursacht hatte
_nerror Letzte Fehlernummer
cmessage Fehlermeldung (Message()) des letzten Fehlers

Methoden:
Do Verwenden Sie DO(“cCommandLine“), um die Befehlszeile cCommandline auszuführen. Wenn cCommandLine einen Fehler verursacht, gibt Do() die Fehlernummer zurück, anderenfalls 0.

Klasse NamedCounter

Stellt benannte Zähler zur Verfügung

Basisklasse: Label
Elternklasse: CompLabel

Eigenschaften:
_aNames[1,0] Namen-Array
_aValues[1,0] Werte-Array
_nPointer Zeigt auf den aktuellen Zähler

Methoden:
Decrement Verwenden Sie Decrement (cName), um den in cName angegebenen Zähler herabzusetzen
GetValue Mit GetValue (cName) erhalten Sie den Wert des Zählers cName.
Increment Verwenden Sie Increment (cName), um den in cName angegebenen Zähler zu erhöhen.
Setvalue SetValue (cName,nValue) setzt den Zähler cName auf den Wert nValue. Wenn nValue .NULL. ist, wird der Zähler cName gelöscht.
isEmpty Intern, gibt .T. zurück, wenn kein Zähler definiert ist.
_new Intern, erstellt einen neuen Zähler
Search Intern, sucht einen Namen

Klasse NamedStack

Stellt einen Stack mit Methoden für die Navigation und Suchen zur Verfügung

Basisklasse: Label
Elternklasse: CompLabel

Eigenschaften:
_aNames[1,0] Namen-Array
_aValues[1,0] Werte-Array
_nPointer Intern, zeigt auf die aktuelle Stapelposition.

Methoden:
appendvalue Verwenden Sie Appendvalue(cName,uValue), um einen Wert zum Stapel hinzu­zufügen. Sie können diesen Wert wiederfinden, indem Sie cName an die Search-Methode übergeben.
deletevalue DeleteValue() löscht die aktuelle Stapelposition.
InitStack InitStack initialisiert den Stapel. Alle bisher gespeicherten Werte gehen verloren.
insertvalue InsertValue(cName,uValue) fügt einen Wert vor der aktuellen Position in den Stapel ein. Verwenden Sie cName mit der Search-Methode, um den Wert wiederzufinden.
IsEmpty IsEmpty() gibt .T. zurück, wenn der Stapel leer ist, anderenfalls .F.
IsFirst Verwenden Sie IsFirst(), um herauszufinden, ob die aktuelle Stapelposition die erste Position im Stapel ist. In diesem Fall gibt IsFirst() .T. zurück, anderenfalls .F.
IsLast Verwenden Sie IsLast(), um herauszufinden, ob die aktuelle Stapelposition die letzte Position im Stapel ist. In diesem Fall gibt IsLast() .T. zurück, anderenfalls .F.
First First() gibt den ersten Stapelwert zurück.
Last Last() gibt den letzten Stapelwert zurück.
Next Next() gibt den nächsten Stapelwert zurück.
Previous Previous() gibt den vorherigen Stapelwert zurück.
Search Mit Search(cName) können Sie den Wert der Stapelposition cName ermitteln.

Klasse Note_It

Anzeige eines beliebigen Textes bzw Anmerkung auf der Form. Nur zur Entwicklungszeit sichtbar, es wird zur Laufzeit nicht instanziiert. Klein und praktisch, um anderen Kollegen Hinweise zu einem bestimmten Objekt zu geben, oder auf bestimmte Einstellungen hinzuweisen.

Das Label hat die Eigenschaften Autosize und WordWrap auf .T., daher kann das Erscheinungsbild der Anmerkung flexibel angepaßt werden.

Basisklasse: Label
Elternklasse: BasLabel

Klasse Saver

Speicherung und Wiederherstellung des Status eines beliebigen Objekts

 
Basisklasse: Label
Elternklasse: Complabel

Eigenschaften:
cDefaultProps Geben Sie eine mit Kommas getrennte Liste von Eigenschaften ein, die als Vorein­stellung für dieses Objekt gespeichert werden sollen. Die meisten Eigenschaften für FORMs, TOOLBARs und GRIDs sind voreingestellt und müssen hier nicht berücksichtigt werden.
_lHideErrors Intern, sagt dem ErrorHandler, daß er jeden Fehler ignorieren soll.
_nLastErrNo Intern, Nummer des letzten Fehlers, dies wird immer unterstützt, auch wenn HideErrors gesetzt ist.

Methoden:
_doRestore Intern, wickelt das Wiederherstellen ab.
_dosave Intern, die eigentliche Save-Methode. Diese wird von der Save-Methode mit speziellen Parametern aufgerufen.
GetStoredValue Rufen Sie GetStoredValue(cProName) auf, um den gespeichert Wert für eine einzelne Eigenschaft cPropName zu ermitteln. Der Wert wird als Zeichenkette zurückgegeben.
_ObjSearch Intern, sucht den Datensatz für ein bestimmtes Objekt.
_OpenDBF Intern, öffnet die OBJSTORE.DBF für Speichern und Wiederhestellen.
Restore Restore(oRef[,cPropList]) stellt die gespeicherten Werte von oRef wieder her. Wenn eine Liste von Eigenschaften vorhanden ist, werden nur die Eigenschaften in der Liste wiederhergestellt.
Save Save(oRef[,cPropList]) speichert das Objekt, auf das mit oRef referenziert wird. Die Werte der Eigenschaften , die in DefaultProps stehen werden gespeichert, wenn keine PropList als zweiter Parameter mitgegeben wird. Anderenfalls werden nur die Werte der Eigenschaften der PropList gespeichert.

Klasse NumBox

Textbox für numerische Ein- und Ausgabe

 
Basisklasse: Textbox
Elternklasse: Bastextboxl

Beschreibung:

Wenn Sie mit der Maus in eine Textbox für numerische Eingabe klicken, passiert es häufig, daß die Zeichenanzahl bis zum Komma nicht ausreicht, um die Vorkommastellen einzugeben. NumBox ist eine TextBox-Klasse, mit der Sie dieses leidige Problem der Mauspositionierung ad acta legen können. Kern der Klasse ist die Ausgestaltung des KeyPress-Events.

Klasse ShowWhatsThis

ShowWhatsThis ist eine grafische CheckBox analog dem Hilfe-Button der WinWord-Standard-Symbolleiste. Wenn dieser Button gedrückt wird und man dann mit der Maus auf ein Control klickt, so wird bei Vorhandensein einer zugehörigen Hilfe-Datei ein erläuternder Mega-Tooltip angezeigt. In den auf diese Weise angeklickten Controls müssen keinerlei Vorbereitungen getroffen werden mit Ausnahme des Eintragens der jeweiligen WhatsThisHelpId!

Basisklasse: Checkbox
Elternklasse: bascheckboxl

Eigenschaften:
cHelpFile Name und ggf. Pfad des zu benutzenden Help-Files
cOklLeftMouse speichert die aktuelle ON KEY LABEL LEFTMOUSE - Einstellung
cPublic beinhaltet den Namen der temporären Public-Variablen, unter der der OKL die DoShow-Methode erreichen kann

Methoden:
Click hier befindet sich die Aktivierung des ShowWhatsThis-Modus
DoShow diese Methode wird aufgerufen, wenn bei aktiviertem ShowWhatsThis-Modus mit der Maus geklickt wurde
NoHelpAvailable diese Methode generiert die Ausgabe "Kein Hilfeeintrag vorhanden!"

Datenübergabe an DLLs

Die API-Programmierung gehört mit zu den schwierigeren Programmiertechniken unter FoxPro - und Strukturen gehören zu den Leckerbissen der API-Programmierung. Um das Handling mit Strukturen einfach zu gestalten, entstand die STRUCTURE-Komponente, die auf der Begleitdiskette als Pre-Release beiliegt.

Was sind Strukturen eigentlich? Man muß sich Strukturen als eine Art von Objekten vorstellen. Ähnlich wie Objekte bestehen auch Strukturen aus einer Reihe von Eigenschaften (Strukturvariablen genannt), auf die man über ihre Namen zugreifen kann, es fehlen allerdings die Methoden. Tatsächlich handelt es sich bei den Strukturen um die Vorläufer der Objekte.

Problematisch sind Strukturen vor allem deswegen, weil sie in einem binären Format codiert werden, das typischerweise von C++ Programmen verwendet wird und eine 1:1 Abbildung des vom Prozessor verwendeten Formates darstellt. Die Zahl 258 wird zum Beispiel als Chr(1)+Chr(2) kodiert. Grundsätzlich können Strukturen an API-Funktionen übergeben werden, wenn man sie zuvor in einen String umwandelt, der eben diese binäre Codierung enthält.

Die STRUCTURE-Komponente ist eine VFP-Klasse, die diese Thematik kapselt. Die Bestandteile der Struktur, die Strukturvariablen, werden als ganz normale Eigenschaften angesprochen.

Die Arbeit mit der Komponente läuft in den folgenden Schritten ab:

(1) Definieren der Klasse für die konkrete Struktur

Eine typische Struct-Definition sieht also wie folgt aus:

Define Class myStruct as cusStruct

  cDocument = ""

  nLen = 0

  cMember = "l:nLen, n:cDocument "

Enddefine

Diese Struktur enthält zwei Elemente: cDocument und nLen. Ersteres ist ein beliebig langer sogenannter nullterminierter String (n), letzeres ein LONG (l). In der Variable cMember ist die Reihenfolge der Elemente sowie der jeweilige C-Datentyp definiert. Eine Auflistung aller möglichen Typen kann den Quelltext-Kommentaren entnommen werde4n.

(2) Instanzieren dieser Klasse

oStruct = CreateObject( "myStruct" )   && Struktur erzeugen

(3) bei Bedarf Zuweisung von Werten zu einzelnen Struktur-Bestandteilen

oStruct.cDocument = "MYFILE.TXT"

(4) Abrufen des binär codierten Strings

cStruct = oStruct.GetString()

(5) Aufrufen der benötigten DLL-Funktion
Zu beachten ist, daß die Struktur bei der Deklaration der API-Funktion als "C" und falls Rückgaben nötig sind, "per reference" angegeben werden muß!

= ApiGetFileLength( @cStruct )

(6) bei Bedarf Übergabe der von der API-Funktion zurückgegebenen binär codierten Struktur an die Struktur-Klasse

oStruct.SetStruct( cStruct )

(7) bei Bedarf Abrufen von einzelnen Strukturvariablen

* Ausgabe der Dateilänge

? oStruct.nLen

Durch diese STRUCTURE-Komponente ist kein Detailwissen über die Interna von Strukturen und die Probleme bei ihrem Einsatz in Visual FoxPro notwendig. Mit dieser Komponente können komplexe API-Strukturen fast wie eine normale VFP-Klasse gehandhabt werden. In Vorbereitung ist eine Erweiterung dieser Komponente für dem Umgang mit Pointern, Arrays und Arrays von Pointern. Testkandidaten können gerne mit dem Autor Kontakt aufnehmen.

Cascading Destroy

Wenn man einige Vorteile der objektorientierten Programmierung nutzen will, wird man häufig Objekt-Referenzen in Variablen, Arrays, Properties usw. speichern (siehe auch Session D-EINS). Dabei muß man um eine Besonderheit wissen, die im folgenden beschrieben wird. Dabei wird ein "Bild" verwendet, welches schon seit geraumer Zeit die Runde durch die FoxPro-Gemeinde macht, um den etwas verzwickten Tatbestand zu beschreiben

Soweit, so gut! Die Probleme beginnen dann, wenn irgendwelche Object References auf das Objekt belegt werden.

Eine ärgerliche Geschichte. Noch schlimmer wird die Sache allerdings, wenn man das Bild auf die Objekte in der Form erweitert und diese als einzelne Arme des Kronleuchters betrachtet.

Dieses sehr problematische Verhalten passiert leider auch dann, wenn alle Object References sich als Properties innerhalb der freizugebenden Form befinden und sowieso gelöscht werden würden.

Aus diesem Dilemma gibt es zwei Auswege:

Letztendlich bleibt aber unklar, weshalb ein solches Verhalten in der Version 5.0 nicht abgestellt wurde.

VCX intern

Visuell erstellte Klassen werden in Visual FoxPro in VCX/VCT-Dateien abgespeichert. Eine solche Klassenbibliothek ist physisch betrachtet eine DBF-Datei mit der Extension VCX mit dazugehöriger Memodatei VCT. Eine visuelle Klassenbibliothek kann also mit den ganz normalen FoxPro-Befehlen geöffnet und bearbeitet werden, solange man die interne Integrität nicht verletzt. Die zum Lieferumfang von Visual FoxPro gehörende Dokumentation ist leider sehr unzureichend, deshalb sollen die wichtigsten Aspekte hier erläutert werden.

Die Struktur einer visuellen Klassenbibliothek sieht wie folgt aus:

Field   Field Name     Type  Width    Dec Index Collate Nulls
1
PLATFORM
Character
8
   
No
2
UNIQUEID 
Character
10
   
No
3
TIMESTAMP
Numeric
10
   
No
4
CLASS
Memo
4
   
No
5
CLASSLOC
Memo
4
   
No
6
BASECLASS
Memo
4
   
No
7
OBJNAME
Memo
4
   
No
8
PARENT
Memo
4
   
No
9
PROPERTIES
Memo
4
   
No
10
PROTECTED
Memo
4
   
No
11
METHODS
Memo
4
   
No
12
OBJCODE 
Memo (binary)
4
   
No
13
OLE
Memo
4
   
No
14
OLE2 
Memo
4
   
No
15
RESERVED1
Memo
4
   
No
16
RESERVED2 
Memo
4
   
No
17
RESERVED3
Memo
4
   
No
18
RESERVED4
Memo
4
   
No
19
RESERVED5
Memo
4
   
No
20
RESERVED6
Memo
4
   
No
21
RESERVED7
Memo
4
   
No
22
RESERVED8
Memo
4
   
No
23
USER
Memo
4
   
No
** Total **
 
Memo
109
   

Wie leicht zu erkennen ist, besteht diese Datei im wesentlichen aus Memofeldern, in denen verschiedene Informationen abgelegt sind. Kennt man sich in den internen Zusammenhängen dieser Datei etwas aus, kann man auf sehr effektive Weise schnell bestimmte Veränderungen vornehmen (z.B. mit dem REPLACE-Befehl).

ACHTUNG!
Vor jeglichen Experimenten mit VCX-Dateien immer eine Sicherungskopie erstellen! Auch nach jedem Änderungs-Schritt des VCX-Hackings sollten Sie immer eine Kopie anlegen, damit Sie nicht durch eine Unachtsamkeit alles wieder verderben!

Die folgende Tabelle beschreibt alle Felder, die Informationen zur Vererbungshierarchie enthalten:
Feld Bemerkungen
Parent
  • ist dieses Feld leer, so ist der aktuelle Datensatz der Kopfsatz einer Klasse
  • ist dieses Feld nicht leer, so beschreibt der aktuelle Datensatz ein zur Designzeit in einen Container aggregiertes Objekt und Parent enthält den Namen des übergeordneten Objektes
ObjName
  • Name der Klasse (wenn das Feld Parent leer ist)
  • ansonsten Name, unter dem das Objekt in das Parent-Objekt aggregiert ist
BaseClass
  • VFP-Basisklasse des aktuellen Objektes
Class
  • Parent-Klasse des aktuellen Objektes
  • gilt Class = BaseClass, so liegt eine direkte Ableitung von einer VFP-Basisklasse vor

ClassLoc

  • enthält Namen und ggf. Pfad der Klassenbibliothek, in der sich die Parent-Klasse befindet
  • befindet sich die Parentklasse in der gleichen VCX-Datei, enthält ClassLoc den Namen der VCX-Datei (siehe auch nächster Tip)
  • befindet sich die VCX-Datei der Parentklasse in einem anderen Verzeichnis auf dem gleichen Laufwerk, enthält ClassLoc außer dem Namen der Quell-VCX-Datei auch den relativen Pfad zu dieser Datei ausgehend von der Klassen­bibliothek mit der abgeleiteten Klasse
    ACHTUNG! Die ClassLocation, die Projektmanager bzw. ClassBrowser in ihren Statuszeilen anzeigen, sind auf die aktuell gültigen absoluten Pfade erweitert und entsprechen demnach nicht 1:1 dem Inhalt von ClassLoc!
  • befindet sich die VCX-Datei der Parentklasse auf einem anderen Laufwerk, so ist in ClassLoc der absolute Zugriffspfad gespeichert (diese Konstellation sollte man vermeiden!)

Achtung!
Benennen Sie keine VCX-Dateien um, denn damit werden die internen ClassLoc-Verweise nicht mit angepaßt, ganz zu schweigen von den externen Referenzen aus anderen Klassenbibliotheken!
Ein Tool zum Umbenennen von VCX-Dateien finden Sie auf der Begleitdiskette!

Weitere Felder enthalten die Informationen zu den Methoden und Eigenschaften eines Objektes:
Feld Bemerkungen
Reserved3
  • enthält je selbstdefiniertem Property und je selbstdefinierter Methode eine Zeile mit dem jeweiligen Namen sowie dem zugehörigen Kommentar
    ACHTUNG! Die Zeilen in den Memofeldern der VCX-Dateien müssen durch die Kombination CHR(13)+CHR(10), sonst kommt es zu undefinierten Zuständen, meist GPF!
  • ist dem Namen ein "*" vorangestellt, handelt es sich um eine Methode, ansonsten um ein Property
  • durch ein Leerzeichen getrennt folgt dem Namen dann der zugehörige Kommentar
  • Reserved3 wird nur bei dem Kopfsatz einer Klasse benutzt (aggregierte Objekte haben keine selbstdefinierten Methoden und Properties, es sei denn aus ihrer eigenen zugrunde­liegenden Klassendefinitio
Protected
  • enthält im Kopfsatz einer Klasse die Namen aller auf "protected" oder "hidden" gesetzten Methoden und Properties
  • "hidden" gesetzte Properties oder Methoden werden mit einem nachfolgenden "^" gekennzeichnet
  • in Sätzen von aggregierten Objekten kann Protected das Schlüsselwort TRUE enthalten, wenn das betreffende Unterobjekt als "protected" deklariert wurde ("hidden" ist hier nicht möglich)
Properties
  • dieses Feld enthält je Property, dessen Einstellung von der Elternklasse abweicht, eine Zeile mit der Zuweisung für das jeweilige Property im Format "Property = irgendwas"
    (gilt sowohl für VFP-Properties als auch für selbstdefinierte Properties)
Methods
  • enthält den Quelltext aller Methoden, die gegenüber der Elternklasse verändert wurden
ObjCode
  • in diesem Feld wird der P-Code gespeichert, der duch das Kompilieren von Methods entsteht
  • bei normalem CREATE / MODIFY CLASS passiert dieses Kompilieren beim Schließen des entsprechenden Quelltextfensters
  • haben Sie auf externem Wege Veränderungen im Feld Methods vorgenommen, muß die betreffende VCX-Datei mit dem Befehl COMPILE CLASSLIB neu kompiliert werden
Reserved6
  • speichert den ScaleMode der Klasse
Reserved7
  • hier ist der Klassenkommentar abgelegt

Reserved8

  • beinhaltet im Kopfsatz den Verweis auf eine Header-Datei
    ACHTUNG! Auf die hier gespeicherte Datei wird immer beim Kompileren der Klasse zugegriffen. Ein eventuell in Reserved8 eingetragener relativer Pfad wird nicht ausgehend von der Lage der VCX-Datei, sondern ausgehend vom aktuellen Arbeitsverzeichnis aus interpretiert!
  • in Sätzen von aggregierten Objekten enthält Reserved8 das Schlüsselwort NOINIT, falls diese Einstellung zugeordnet wurde

Die nachfolgende Tabelle behandelt die restlichen Felder:
Feld Bemerkungen
PlatForm
  • diente bei der CrossPlattform-Programmierung der Unterscheidung der verschiedenen Betriebssystem-Plattformen
  • da Visual FoxPro mittlerweile ein reines Windows-Produkt ist, hat dieses Feld nur noch historische Bedeutung
UniqueId
  • für VFP-interne Zwecke
TimeStamp
  • für VFP-interne
Ole
  • für ActiveX-bezogene Informationen
Ole2
  • für ActiveX-bezogene Informationen
Reserved1

Reserved2

Reserved4

Reserved5

  • diese Felder werden für weitere verschiedene Zwecke benutzt, auf die hier nicht näher eingegangen werden soll

User

  • dieses Feld kann für eigene Ergänzungen genutzt werden

Wenn Sie VCX-Dateien per "VCX-Hacking" bearbeiten wollen, beachten Sie unbedingt die nachfolgenden Punkte:

Ein wichtiges Tool zur Maintenance von VCX-Dateien ist der ClassBrowser, der in der Visual FoxPro Programmiersprache geschrieben ist.

Mit dem ClassBrowser können Sie Klassen umbenennen und auf andere Parentklassen umdefinieren (innerhalb der gleichen Basisklasse) sowie Klassen per Drag&Drop in eine andere VCX-Datei verschieben.

Ein entscheidendes Merkmal dabei ist die Tatsache, daß eine derartige Änderung automatisch an alle Klassen und SCX-Dateien weitergeleitet wird, die im Moment des Umdefinierens im Classbrowser geöffnet sind!

ACHTUNG: Dieser Umdefinitions-Mechanismus funktioniert fehlerhaft, wenn die beteiligten Klassenbibliotheken bzw. SCX-Dateien nicht alle aus dem aktuellen Verzeichnis stammen (was häufig bei auf Unterverzeichnisse verteilten Projekten der Fall ist!). Auf der Begleitdiskette finden Sie ein Tool, womit über Unterverzeichnisse verteilte Klassen und SCX-Dateien auf ein gemeinsames Verzeichnis umdefiniert werden, dann fehlerfrei mit dem ClassBrowser behandelt werden können und anschließend wieder zurückverteilt werden!