IntelliSense in Visual FoxPro 7.0

Von Daryl Moore und Andy Kramek

Dieser Artikel erklärt die Implementierung von IntelliSense in Visual FoxPro 7.0 und zeigt auf,
wie Entwickler sich durch die offene Architektur ihr Leben erleichtern und ihre Produktivität steigern können.

*
Auf dieser Seite
Konfigurieren von IntelliSense Konfigurieren von IntelliSense
Die Tabelle FoxCode Die Tabelle FoxCode
Erstellen und Einsetzen von Skripts Erstellen und Einsetzen von Skripts

Konfigurieren von IntelliSense

Es gibt in Visual FoxPro 7.0 zwei Möglichkeiten, IntelliSense zu konfigurieren.
Die erste Möglichkeit besteht in der Einstellung des Werts und der neuen Eigenschaft EditorOptions des Anwendungsobjekts von VFP. Die Vorgabeeinstellung ist "LQKR", obwohl es zur Zeit fünf Möglichkeiten gibt, die durch diese Eigenschaft gesteuert werden können:

Hyperlinks (K oder k): entscheidet, wie Links aktiviert werden. Die Einstellung "k" erfordert lediglich einen einfachen Mausklick, während "K" ein CTRL-Click erfordert. Dies ist die Vorgabeeinstellung. Ist nichts angegeben, werden Hyperlinks im Editor und Befehls-Fenster als normaler Text betrachtet.

Word Drag 'n Drop (W): wenn eingeschaltet kann Text nur in eine Position unmittelbar hinter einem Leerzeichen verschoben werden. Dies schützt Sie vor dem unbeabsichtigten Einfügen im bestehenden Text, wenn Sie im Editor oder im Befehls-Fenster mit Drag-and-Drop arbeiten. Als Vorgabewert ist dieses Verhalten deaktiviert.

Designer Value Tips (T): damit wird gesteuert, ob Elemente, die in Listen angezeigt werden, auch ihren Tooltipp anzeigen. Als Vorgabewert werden die Tooltipps angezeigt.

List Member (L oder l): damit wird gesteuert, ob und wann die Elementlisten angezeigt werden. Als Vorgabe werden Listen automatisch angezeigt (L). Sie könnten es jedoch bevorzugen, das kleine l anzugeben, um die automatische Anzeige zu unterdrücken. Dennoch verfügen Sie dann über die Möglichkeit, die Liste mit CTRL-3 aufzurufen (oder im Menü "Bearbeiten" von FoxPro den Menüpunkt "Elemente anzeigen" zu wählen).

Quick Info (Q oder q): damit wird gesteuert, ob und wann die unterschiedlichen Arten der QuickInfos angezeigt werden. Als Vorgabewert werden sie automatisch angezeigt (Q), obwohl Sie es bevorzugen könnten, die Option "q" zu wählen, um die automatische Anzeige zu unterdrücken, aber noch über die Möglichkeit zu verfügen, das QuickInfo mit CTRL+I aufzurufen (oder im Menü "Bearbeiten" von FoxPro den Menüpunkt "QuickInfo" zu wählen).

Um alle Features von IntelliSense zu aktivieren (einschließlich der Kontrolle des Drag-and-Drop von Text), geben Sie im Befehls-Fenster einfach die folgende Zeile ein:

_VFP.EditorOptions = "LQKTW"

Die zweite Möglichkeit besteht darin, den neuen IntelliSense-Manager einzusetzen, den Sie über das Menü Extras -> IntelliSense-Manager aufrufen. Dieses Formular verfügt über vier Seiten und eröffnet Ihnen nicht nur Zugriff auf die eben beschriebenen Konfigurationsmöglichkeiten, sondern über die Tabelle FoxCode, durch die IntelliSense gesteuert wird, auch auf andere Funktionalitäten von IntelliSense.
Die erste Seite (Abbildung 17) bietet Ihnen eine interaktive Möglichkeit, die Eigenschaft _VFP.EditorOptions für die Elementliste und das QuickInfo einzustellen. Dort wird auch definiert, wie IntelliSense die Groß- und Kleinschreibung für Befehle und Funktionen behandeln soll, sowie ein Vorgabewert der immer dann verwendet werden soll, wenn keine spezielle Anweisung vorliegt. Die Checkbox entscheidet, ob die definierten Einstellungen nur für die nativen Befehle und Funktionen, oder auch für benutzerdefinierte Befehle und Funktionen gelten sollen. Schaltflächen aktivieren ein Fenster mit Tipps und zeigen den Inhalt der Tabelle FoxCode an, in der die Informationen gespeichert sind, die von IntelliSense genutzt werden.

Bild01

Abbildung 1. Die Konfigurationsseite des IntelliSense-Managers

Die zweite Seite Typen (Abbildung 18) steuert die Einträge, die in der Typenliste angezeigt werden, wenn die Klausel AS eingesetzt wird. Visual FoxPro 7.0 wird mit einem Grundset ausgeliefert, das alle Basisklassen von Visual FoxPro, sowie alle Standard-Datentypen umfasst. Dies geschieht unabhängig davon, ob sie im Moment in Visual FoxPro verfügbar sind oder nicht. Wird eine Checkbox deaktiviert, wird dieses Element in den Typenlisten nicht mehr angezeigt.

Bild02

Abbildung 2. Die Typenliste von IntelliSense

Mit den Schaltflächen dieser Seite können die verfügbaren Typen erweitert werden.

Die Schaltfläche Bearbeiten öffnet ein Fenster, das die Einträge der aktuell ausgewählten Elemente in der Tabelle FoxCode anzeigt. Diese Möglichkeit wird in der Regel genutzt, um die Anzeige für ein Element zu ändern.

Die Schaltfläche Typbibliotheken öffnet einen Dialog, der die registrierten COM-Server, ActiveX-Steuerelemente oder beides auflistet und es ermöglicht, diese der Typliste hinzuzufügen.

Bild03

Abbildung 3. Der Typliste von IntelliSense eine Typbibliothek hinzufügen

Die Schaltfläche Klassen öffnet Visual FoxPros Standarddialog visueller Klassen und ermöglicht es, benutzerdefinierte Klassen der Typliste von IntelliSense hinzuzufügen (Abbildung 20).

Bild04

Abbildung 4. Der Typliste von IntelliSense eine benutzerdefinierte Klasse hinzufügen

Beachten Sie, dass Klassen, die in Programmdateien definiert wurden, in die Typliste aufgenommen werden können, dass aber der entsprechende Datensatz der Tabelle FoxCode manuell hinzugefügt werden muss.

Die Schaltfläche Webdienste ruft den Assistenten "Registrierung der Visual FoxPro Webdienste" auf und fügt der Typliste den angegebenen Webdienst hinzu (Abbildung 21).

Bild05

Abbildung 5. Der Typliste von IntelliSense einen Webdienst hinzufügen

Die dritte Seite des IntelliSense-Managers, Benutzerdefiniert, stellt eine filterbare Ansicht bereit, die zum Hinzufügen, Ändern oder Löschen benutzerdefinierter Einträge in der Tabelle FoxCode dient (Abbildung 22).

Bild06

Abbildung 6. Der FoxCode-Tabelleneditor

Der nächste Abschnitt dieses Artikels behandelt detailliert die Tabelle FoxCode.
Die letzte Seite, Erweitert, ermöglicht Ihnen den Zugriff auf zwei zusätzliche Elemente, "Eigenschaften bearbeiten" und "Bereinigen" (Abbildung 23). Auf diese Eigenschaften gehen wir im nächsten Abschnitt dieses Artikels im Detail ein.

Bild07

Abbildung 7. Die erweiterten Optionen des IntelliSense-Managers

Die Schaltfläche Bereinigen ruft einen Verwaltungsdialog für die Tabelle FoxCode sowie für die MRU-Listen auf (Abbildung 24).

Bild08

Abbildung 8. Der Wartungsdialog für die Tabelle FoxCode und die MRU-Listen

Detaillierte Angaben zu diesem Dialog finden Sie in der Referenz von Visual FoxPro.

Zum SeitenanfangZum Seitenanfang

Die Tabelle FoxCode

Diese Tabelle, die als Vorgabewert im Verzeichnis "Dokumente und Einstellungen" des Anwenders auf der lokalen Festplatte installiert wird, ist das Herz der Implementierung von IntelliSense in Visual FoxPro 7.0. Durch die Manipulation der Inhalte dieser Tabelle kann die Funktionalität von IntelliSense angepasst und erweitert werden. Daher ist es unbedingt erforderlich, dass Sie die Struktur und den Einsatz dieser Tabelle mit IntelliSense in Visual FoxPro verstehen.

Feld Definiert als Beschreibung

Type

C (1)

Gibt an, wie der Datensatz verarbeitet werden soll:
C (Command): automatische Vervollständigung, wird durch ein Leerzeichen ausgelöst.
F (Function): QuickInfo, wird durch "(" ausgelöst.
O (COM): Typbibliothek, verwendet für die Typenliste.
P (Property): Aktion, wenn auf eine Eigenschaft zugegriffen wird.
S (Script): das Feld enthält ein Skript, das ausgeführt werden soll.
T (Type): Deklarationen, verwendet für die Typenliste.
U (User): Benutzerdefiniert.
V (Version): reserviert für Vorgabewerte/Versionsangabe.
Z (Special): definiert benutzerdefinierte Verhaltensweisen.

Abbrev

C (24)

Shortcut, der eine Aktion auslöst.

Expanded

C (26)

Wenn erforderlich, die expandierte Version oder die Ersetzung des Shortcut.

Cmd

C (15)

Der Name des auszuführenden Skripts. In "{}" geklammert.

Tip

M ( 4)

Anzeigeinformation des QuickTipp.

Data

M ( 4)

Der Inhalt dieses Datensatzes kann Listenwerte, Code, Skripttext usw. enthalten.

Case

C ( 1)

Gibt an, in welchem Format der Text ersetzt wird.
U = Formatierung mit der Funktion Upper().
L = Formatierung mit der Funktion Lower().
P = Formatierung mit der Funktion Proper().
M = Keine Formatierung (Groß- und Kleinschreibung gemischt).
X = Keine Ersetzung.
Beachten Sie: Der im Datensatz "Version" angegebene Wert definiert den Vorgabewert, der für jeden Datensatz eingesetzt wird, der über keine eigene Einstellung verfügt.

Save

L (1)

Gibt an, ob der Datensatz gespeichert wird, wenn das Feld aktualisiert wird.

TimeStamp

T (8)

Zeitstempel (nur für VFP-Eintragungen)

Source

M (4)

Quelle für den Inhalt des Datensatzes (VFP-Eintragungen nutzen "Reserved")

UniqueID

C (10)

Eindeutige ID (nur für VFP-Eintragungen)

User

M ( 4)

Verfügbar für benutzerdefinierte Informationen.

Die Seite Erweitert (Abbildung 24) des IntelliSense-Managers enthält Optionen, um die Tabelle FoxCode wiederherzustellen und zu bereinigen. Wird die Tabelle beschädigt oder wird ein Eintrag irrtümlich gelöscht oder geändert, kann die Tabelle in ihren Originalzustand zurückgesetzt werden. Die Felder TimeStamp, UniqueID und Save werden geprüft, um festzustellen, ob die Originaldaten geändert oder ob sie überschrieben wurden. Als Vorgabe verfügen die nativen Einträge von Visual FoxPro sowohl über einen Zeitstempel als auch über eine eindeutige ID, das Feld ist aber auf False eingestellt, so dass sie überschrieben werden können. Benutzerdefinierte Einträge haben auf der anderen Seite keine eindeutige ID (und benötigen sie auch nicht) oder einen Zeitstempel. Unter der Voraussetzung, dass das Feld Save auf True steht, werden sie durch Änderungen an der Tabelle nicht überschrieben oder gelöscht.
Wir beschreiben hier detailliert die unterschiedlichen Typen der Datensätze, jeweils mit einem Beispiel:

Versionselementtyp (Typ = V)

Die Tabelle FoxCode enthält einen einzelnen Datensatz dieses Typs. Er wird für die interne Verwaltung durch die IntelliSense-Engine benötigt. Das Feld Expanded enthält die Versionsnummer der aktuellen Tabelle FoxCode. Das Feld Case definiert den Vorgabewert der Formatierung, die für alle Einträge verwendet werden soll, die eine Formatierung benötigen, aber über keine explizite Einstellung verfügen.

Befehlselementtyp (Typ = C)

Dieser Typ definiert einen Eintrag für die automatische Vervollständigung, der durch das Leerzeichen ausgelöst wird und der als Vorgabe durch das "Default Script" (das im Feld Data des Datensatzes mit Typ = S und einem leeren Feld Abbrev definiert ist) aufgerufen wird. Alle grundlegenden Befehle von VFP nutzen diese Methodik, um den Inhalt des Felds Expanded an die abgekürzte Form des Befehls anzuhängen.

Die anderen komplexeren Befehle rufen ein generisches Skript für die Behandlung von Befehlen ({cmdhandler}) auf, das im Feld Cmd angegeben ist. Dieses Skript ersetzt den Inhalt des Feldes Abbrev mit dem Inhalt des Feldes Expanded, statt diesen Inhalt anzuhängen. Diese Methodik kann einfach eingesetzt werden, um "benutzerdefinierte Befehle" zu erstellen, denen explizit ein QuickInfo (vom Feld Tip) oder eine Elementeliste (vom Feld Data) zugeordnet wird. Dies geschieht, indem eine Abkürzung definiert und ein Aufruf an das Skript aufgenommen wird.

Beispiel: Das vorgegebene Verhalten der automatischen Vervollständigung des Befehls ON zeigt eine Liste aller Optionen für diesen Befehl an, auch alle Druck- und Menüoptionen. Allerdings ist in der normalen Programmierung der einzige häufig genutzte ON-Befehl ON KEY LABEL. Um eine automatische Komplettierung von "OKL" zu erstellen, das in "ON KEY LABEL" expandiert wird, sobald nach der Eingabe die Leertaste betätigt wird, fügen Sie der Tabelle FoxCode den folgenden Datensatz hinzu:

Type Abbrev Expanded Cmd Tip Case Save

C

OKL

on key label

{cmdhandler}

ON KEY [LABEL KeyLabelName] [Command]

U

.T.

Funktionselementtyp (Typ = F)

Function definiert einen Eintrag zur automatischen Vervollständigung, der durch eine öffnende runde Klammer ausgelöst wird. Die Inhalte des Feldes Tip werden für die Anzeige des Smarttipps der QuickInfo benötigt, das die Parametereingabe mit der im Datensatz definierten vergleicht.
Beispiel: um einen Eintrag für die automatische Vervollständigung einer benutzerdefinierten Funktion OpenFile() zu erstellen, die durch die Eingabe von "OPF(" ausgelöst werden soll, fügen Sie der Tabelle FoxCode den folgenden Datensatz hinzu:

Type Abbrev Expanded Tip Case Save

F

OPF

OpenFile

cFileName[, cFileDir[, lReadOnly]]

M

.T.

Damit definieren Sie die Funktion mit drei Parametern. Sobald dem eingegebenen Text ein Komma hinzugefügt wird, wird der hervorgehobene Teil des Tips automatisch synchronisiert.

Eigenschaftselementtyp (Type = P)

Ein Eigenschaftselementtyp wird genutzt, um einen Popup-Dialog (oder Wertliste) anzulegen, der angezeigt wird, wenn einer Eigenschaft eines beliebigen Objekts, deren Name dem Wert im Feld Abbrev entspricht, ein Wert zugewiesen wird. Das Feld Cmd zeigt an, ob ein anderweitig in der Tabelle FoxCode definiertes Skript oder der Inhalt des Feldes Data im aktuellen Datensatz für die Generierung des Popup verwändet werden soll. Die Tabelle FoxCode wird mit zwei generischen Skripts ausgeliefert, die mit diesem Datensatztyp eingesetzt werden. Das erste ({color}genannt) zeigt den Dialog für die Farbauswahl an und ist unterschiedlichen Eigenschaften zugeordnet, die Farben definieren (z.B. BackColor, BorderColor und FillColor). Das zweite ({picture} genannt) zeigt den Dialog "Bild öffnen" an, wenn entweder eine Eigenschaft Icon oder Picture gesetzt werden soll.
Beispiel: Um den Dialog Farben einem benutzerdefinierten Eigenschaftsnamen zuzuordnen, fügen Sie der Tabelle FoxCode einfach einen Datensatz hinzu und ersetzen Ihren eigenen Eigenschaftsnamen (beachten Sie, dass der führende "." Im Feld Abbrev erforderlich ist:

Type Abbrev Cmd Case Save

P

.MyColor

{color}

M

.T.

Den Einsatz des Skripts werden wir später in diesem Artikel noch detailliert behandeln. Im Moment genügt die Aussage, dass ein Skript auch direkt in das Feld Data eines Datensatzes geschrieben und ausgeführt werden kann, indem in das Feld Cmd leere geschweifte Klammern ("{}") geschrieben werden. Um ein Skript hinzuzufügen, das den Dialog GetFile() anzeigt und den ausgewählten Dateinamen an eine Eigenschaft mit Namen cSourceFile zurückgibt, fügen Sie der Tabelle FoxCode den folgenden Datensatz hinzu:

Type Abbrev Cmd Data Case Save

P

.cSourceFile

{}

LPARAMETER oFoxCode
LOCAL lc Txt
oFoxcode.valuetype = "V"
lcTxt = ['] + GETFILE() + [']
RETURN lcTxt

M

.T.

Immer, wenn einer Eigenschaft mit Namen cSourceFile ein Wert zugewiesen wird, wird der Dialog GetFile() automatisch angezeigt. Bedenken Sie in diesem Zusammenhang, dass IntelliSense nur in der Entwicklungsumgebung funktioniert, zur Laufzeit passiert nichts.

COM-Komponente-Elementtyp (Typ = O)

Ein COM-Komponente-Elementtyp wird eingesetzt, um für die IntelliSense-Engine zu definieren, wo sich die Typbibliothek für eine COM-Komponente oder ein ActiveX-Steuerelement befindet. Das Feld Data wird eingesetzt, um die GUID und Versionsinformation zu speichern und das Feld Tip enthält den vollständigen Namen des Steuerelements. Was auch immer im Feld Abbrev enthalten ist: es wird als Eintrag für die Typenliste eingesetzt, die mit der Klausel AS zugeordnet wird (DEFINE CLASS...AS..., LOCAL...AS...).
Beispiel: Um Microsofts Steuerelement TreeVies als eine Option in die Typenliste aufzunehmen, fügen Sie der Tabelle FoxCode den folgenden Datensatz hinzu:

Type Abbrev Tip Data Save

O

TreeView

Microsoft TreeView Control 6.0 (SP4)

{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0

.T.

Beachten Sie, dass das Feld Data die korrekte GUID enthalten muss, die aus der Registry ausgelesen werden kann. Die einfachste Möglichkeit, einen Datensatz dieses Typs anzulegen, besteht im Einsatz der Option Typbibliotheken auf der zweiten Seite des IntelliSense-Managers und (wenn erforderlich) dem anschließenden Ändern des vorgegebenen Namens mit dem Editor auf der dritten Seite.

Typangabe-Elementtyp (Typ = T)

Ein Typangabe-Elementtyp wird eingesetzt, um für IntelliSense einen Eintrag zu definieren, der nicht über eine Typbibliothek verfügt, aber trotzdem in die Typenliste aufgenommen wird. Obwohl keine Typbibliothek erforderlich ist, kann dieser Typ genutzt werden, um benutzerdefinierte Klassen in die Liste aufzunehmen. Der Inhalt des Feldes Data wird direkt in der Dropdown-Liste angezeigt. Dies ist auch das einzige Feld, das ausgefüllt werden muss. Allerdings erleichtert eine Beschreibung im Feld Abbrev die Pflege der Tabelle FoxCode.
Für visuelle Klassen kann die Option Klassen auf der zweiten Seite des IntelliSense-Managers eingesetzt werden. Für programmatisch definierte Klassen muss der erforderliche Datensatz allerdings manuell hinzugefügt werden.

Type Abbrev Data Save

T

Container

basecnt OF X:\Projects\Libs\base.vcx"

.T.

T

Header

basehdr OF X:\Projects\Libs onVisClass.prg

.T.

Benutzerelementtyp (Typ = U)

Der Benutzerelementtyp-Datensatz identifiziert die Inhalte als benutzerdefinierter Autotexteintrag, der, wie ein Befehl-Eintrag, durch die Eingabe eines Leerzeichens ausgelöst wird. Der Unterschied liegt darin, dass das vorgegebene Verhalten eines Benutzerelement-Datensatzes darin besteht, den Inhalt des Feldes Abbrev durch den Inhalt des Feldes Expanded auszutauschen. Es ist nicht erforderlich, das Skript für die Befehlsbehandlung aufzurufen und dies ist deshalb die bevorzugte Methode für die Erstellung benutzerdefinierter Shortcuts.
Beispiel: Um den Shortcut "cright" zu expandieren, fügen Sie der Tabelle FoxCode den folgenden Datensatz hinzu:

Type Abbrev Expanded Case Save

U

cright

© 2002 Microsoft Corporation

X

.T.

Diese Datensätze können auch Skripts aufrufen. Das Feld Cmd wird eingesetzt, um anzuzeigen, wo sich das Skript befindet. Ein Paar leerer geschweifter Klammern bedeutet, dass sich das Skript im aktuellen Datensatz befindet, während die Angabe eines Namens bedeutet, dass das Skript in einem Skript-Datensatz an anderer Stelle in der Tabelle definiert ist. Die folgende Variation des Shortcut nutzt ein Skript, um exakt das gleiche Ergebnis zu erzielen:

Type Abbrev Cmd Data Case Save

U

cright

{}

LPARAMETER oFoxCode
LOCAL lcTxt
oFoxcode.valuetype = "V"
lcTxt = "© 2002 Microsoft Corporation"
RETURN lcTxt

X

.T.

Skriptelementtyp (Typ = S)

Skriptelementtypen enthalten Code, der "on the fly" kompiliert und ausgeführt wird. Diese Datensätze werden für die Definition generischer Skripts genutzt, die von anderen Datensätzen in der Tabelle FoxCode genutzt werden. Andere Datensätze stoßen die Ausführung dieser Skripts an, indem sie im Feld Abbrev wie den Inhalt ihres eigenen Feldes Cmd in geschweiften Klammern den Namen des Skripts enthalten. Beachten Sie: Mit Ausnahme von T und O können alle Datensatztypen ein Skript in ihrem eigenen Feld Data enthalten. Um allerdings ein eingebettetes Skript auszuführen, muss sich im Feld Cmd ein leeres Paar geschweifter Klammern befinden.
Beispiel: Das folgende Skript zeigt den Dialog GetFile() an und liefert an die aufrufende Quelle zurück, was es vom Dialog erhält. Alles was erforderlich ist, um der Tabelle FoxCode einen Datensatz hinzuzufügen mit dem Namen des Scripts im Feld Abbrev und dem erforderlichen Code im Feld Data:

Type Abbrev Data Save

S

ChooseFile

LPARAMETER oFoxCode
LOCAL lcTxt
oFoxcode.valuetype = "V"
lcTxt = ['] + GETFILE() + [']
RETURN lcTxt

.T.

Benutzerdefinierte Erweiterung (Typ = Z)

Dieser Typ wird verwendet, um Datensätze zu identifizieren, die IntelliSense nicht automatisch ausführt. Mit Visual FoxPro 7.0 werden nur zwei solche Datensätze ausgeliefert.
Der erste, dessen Feld Abbrev CustomPEMs enthält, speichert die Einstellungen für die erweiterten Eigenschaften für die Konfiguration in seinem Feld Data. Auf diese Eigenschaften kann über die Schaltfläche "Eigenschaften bearbeiten", auf der Seite Erweitert, des IntelliSense-Managers zugegriffen werden.
Der zweite, dessen Feld Abbrev CustomDefaultScripts enthält, speichert die Namen aller vom Anwender definierten Skripte, die über die Hooks im vorgegebenen Skript aufgerufen werden, wenn die erweiterte Eigenschaft lAllowCustomDefScripts auf .T. steht.

Zum SeitenanfangZum Seitenanfang

Erstellen und Einsetzen von Skripts

Alle Skripts bestehen im Grunde aus zwei Teilen. Der erste Teil ist die IntelliSense-spezifische Präambel und der zweite der FoxPro-Code, der das gewünschte Ergebnis generiert. Die IntelliSense-spezifische Komponente besteht in der Regel aus drei Elementen.

Eine Parameter-Anweisung. Skripts müssen in der Lage sein, einen einzelnen Parameter zu akzeptieren, der eine Referenz auf das FoxCode-Objekt darstellt. Die Eigenschaften des FoxCode-Objekts sind in der Hilfedatei vollständig dokumentiert und auch auf MSDN verfügbar.

Eine Definition der Rückgabe, die das Skript generiert. Dies geschieht durch die Einstellung der Eigenschaft ValueType des Objekts FoxCode. Diese Eigenschaft wird benötigt, um zu entscheiden, wie das Ergebnis der Codeausführung im Skript interpretiert werden muss. Drei Werte sind möglich, die in der folgenden Tabelle dargestellt werden:

Value Ergebnis interpretiert als

V

Wert: die Aktion ist vom Skript abhängig - kann eingesetzt werden, um den Text auszuwechseln oder ihm etwas hinzuzufügen.

L

Liste: zeigt die Inhalte des Array FoxCode.Items als Liste an.

T

Tipp: zeigt die Inhalte der Eigenschaft FoxCode.ValueTip als QuickInfo-Tooltipp.

Prüfung des Ortes, von dem das Skript aus aufgerufen wird. Dies geschieht durch die Prüfung der Eigenschaft Location des Objekts FoxCode. Selbstverständlich sind nicht alle Aktionen zu jedem Zeitpunkt angebracht und hier haben wir die Möglichkeit, das Skript zu umgehen, es sei denn, wir befinden uns im richtigen Editor. Die für die unterschiedlichen Editortypen generierten Werte finden Sie in der folgenden Tabelle:

Wert Editor

0

Befehls-Fenster

1

Programm

8

Menü

10

Code Snippet

12

Gespeicherte Prozedur

Beachten Sie bitte: diese Werte erhalten Sie zusammen mit vielen anderen Informationen über das aktive Fenster durch den Aufruf der Funktion _EdGetEnv() der FoxTools. Diese Funktionalität ist nicht für IntelliSense spezifisch.
Der Rest des Skripts besteht im Grunde aus normalem FoxPro-Code, der die Eigenschaften des Objekts FoxCode manipuliert und die erforderlichen Aufgaben ausführt. Die folgenden Beispiele zeigen den Aufbau und den Einsatz von Skripten.

Beispiel 1: Automatisches Einfügen von Text

Vielleicht eine der einfachsten und trotzdem hilfreichsten Anpassungen, die wir mit Hilfe von Skripts an IntelliSense vornehmen können, ist die Ausführung lästiger wiederkehrender Aufgaben wie das Erstellen von Headern für Programme oder Methoden oder auch das Einfügen von Standard-Codeblöcken. Die folgende Abbildung zeigt Ihnen einen Standard-Programmheader, der durch ein Skript erstellt wurde, das durch die Eingabe von "hdr" mit anschließender Leertaste im Editor ausgelöst wurde:

Bild09

Abbildung 9. Durch ein Skript generierter Programm-Header

Um das Skript zu erstellen, das diesen Textblock generiert, müssen wir der Tabelle FoxCode einen Datensatz hinzufügen und es wie in der folgenden Tabelle beschrieben einrichten:

Feld Inhalt

Type

U

Abbrev

hdr

Cmd

{ }

Data

LPARAMETERS toFoxCode
IF toFoxcode.Location <1
   RETURN toFoxCode.UserTyped
ENDIF
toFoxcode.valuetype = "V"
LOCAL lcTxt, lcName, lcComment
STORE "" TO lcTxt, lcName, lcComment
#DEFINE CRLF CHR(13)+CHR(10)
lcName = WONTOP()
lcVersion = "Visual FoxPro" + VERSION(4)
lcComment = INPUTBOX( 'Comment for the header:' )
TEXT TO lcTxt NOSHOW
***********************************************************************
* Program....: <<UPPER(lcName)>>
* Author.....: Andy Kramek
* Date.......: <<DMY(DATE())>>
* Notice.....: Copyright (c) <<TRANSFORM( YEAR(DATE()))>> Tightline Computers Inc
* Compiler...: <<lcVersion>>
* Purpose....: <<lcComment>>
***********************************************************************
~ENDTEXT
RETURN TEXTMERGE(lcTxt)

Obwohl dieses Skript sehr einfach ist, illustriert es doch, wie ein Skript für IntelliSense in zwei Teilen aufgebaut ist. Zunächst sehen wir die für IntelliSense spezifischen Einstellungen, in denen wir einen Parameter einrichten, um eine Referenz auf das Objekt FoxCode erhalten zu können:

LPARAMETERS toFoxCode
*** This script returns a Value
toFoxcode.valuetype = "V"
*** Do nothing unless we are in a program editing window
IF toFoxcode.Location # 1
   RETURN toFoxCode.UserTyped
ENDIF

Anschließend definieren wir, wie die IntelliSense-Engine mit dem Rückgabewert umgeht. Dafür gibt es drei Möglichkeiten:

V (Value): nimmt alles, was von diesem Skript zurückgegeben wurde, als Wert. Als Voreinstellung ersetzt der Wert einfach das Kürzel, dass das Skript ausgelöst hat.

L (List): nutzt die Inhalte der Collection Items als Quelle für eine Liste. Das Skript muss sicherstellen, dass die Collection korrekt dimensioniert und gefüllt ist.

T (Quick Tip): zeigt den Inhalt der Eigenschaft ValueTip als QuickInfo an. Das Skript muss den Inhalt dieser Eigenschaft verwalten.

Zum Schluss prüfen wie die Eigenschaft Location des Objekts FoxCode. Dieser Wert ist als numerischer Wert gespeichert, der von der Funktion EdGetEnv() aus den FoxTools geliefert wird, die ein Array zurückgibt, in dem unterschiedliche Informationen über die aktuelle Session des Editors enthalten sind. Der Fenstertyp (Element 25) wird folgendermaßen angegeben:

0 = Befehls-Fenster
1 = Programm
8 = Menü Snippet
10 = Code Snippet
12 = Gespeicherte Prozedur

Da dieses besondere Skript nur in einer Programmdatei sinnvoll ist, können wir dessen Gültigbereich auf Location = 1 einschränken. Beachten Sie, dass wir, wenn das Skript von anderen Fenstern aufgerufen wird, einfach den Inhalt einer anderen Eigenschaft des Objekts FoxCode zurückgeben. Es handelt sich um die Eigenschaft UserTyped, die, wie der Name bereits aussagt, alles enthält, was der Anwender eingegeben hat, um das Skript auszulösen. Das Ergebnis der Eingabe von "hdr" an anderer Stelle als einem Programm, ergibt also den String "hdr".
Der zweite Teil des Skripts besteht aus normalem Visual FoxPro-Code, der hier den Text des Headers erstellt. Beachten Sie, dass dieses einfache Skript eine Mischung alter und neuer Visual FoxPro-Funktionen enthält.

*** Standard FoxPro Code from here on
*** Define and initialize local variables
LOCAL lcTxt, lcName, lcComment
STORE "" TO lcTxt, lcName, lcComment
*** Get the window name (if one has been defined)
lcName = WONTOP()
*** Get the VFP Version Number 
lcVersion = "Visual FoxPro " + VERSION( 4 )
*** Get the description
lcComment = INPUTBOX( 'Comment for the header:' )
TEXT TO lcTxt NOSHOW
***********************************************************************
* Program....: <<UPPER(lcName)>>
* Author.....: Andy Kramek
* Date.......: <<DMY(DATE())>>
* Notice.....: Copyright (c) <<TRANSFORM( YEAR(DATE()))>> Tightline Computers Inc
* Compiler...: <<lcVersion>>
* Purpose....: <<lcComment>>
***********************************************************************
~
ENDTEXT
RETURN TEXTMERGE(lcTxt)

Nach der Definition und Initialisierung der erforderlichen lokalen Variablen beginnen wir, ihnen Werte zuzuweisen, indem wir mit der alten Funktion WONTOP() den Namen des aktuellen Fensters ermitteln. Anschließend beziehen wir die Versionsnummer von VFP über die Option 4 der Funktion VERSION() und nutzen wir die brandneue Funktion INPUTBOX(), um vom Entwickler einen Kommentar für den Header zu erhalten.
Der Textblock, den wir einfügen wollen, wird mit dem neu erweiterten Konstrukt TEXT...ENDTEXT als String erstellt, was es uns jetzt ermöglicht, den Text direkt in eine Variable zu schreiben, als String erstellt. Beachten Sie den Einsatz der Tilde in der letzten Zeile des Header, wodurch wir sicherstellen, dass der Cursor an der richtigen Stelle positioniert wird. Am Ende nutzt die Anweisung RETURN die andere neue Funktion TEXTMERGE(), um die Variable zu prüfen und den sich ergebenden Text als Austauschtext für die definierte Abkürzung zu verwenden.

Beispiel 2: Erstellen statischer Listen

Eines der offensichtlichsten Features von IntelliSense sind die unterschiedlichen Einsatzmöglichkeiten, die für Listen offen stehen. Viele der nativen Befehle und Funktionen von Visual FoxPro implementieren Listen und Sie können auf einfache Weise Ihre eigenen Listen erstellen. Die einfachste Version ist eine statische Liste, in der Sie die Einträge definieren, die Sie direkt im Datenfeld eines benutzerdefinierten Datensatzes anzeigen und anschließend das native Skript CmdHandler aufrufen, um die Liste zu generieren.
Das folgende Beispiel zeigt, wie wir eine solche einfache Liste definieren können, die es uns ermöglicht, benutzerdefinierte Shortcuts für die nativen Befehle von VFP zu erstellen, die wir häufig einsetzen.

Bild10

Abbildung 10. Eine einfache statische Liste

Hier ein benutzerdefinierter Shortcut (CSPB), der als Liste zwei vordefinierte Optionen anzeigt, die für die Vervollständigung des Befehls CusorSetProp eingesetzt werden kann (in den anderen Modi nutzen wir diesen Befehl normalerweise nicht). Um diesen und ähnliche Shortcuts zu erstellen, müssen wir der Tabelle FoxCode einen Datensatz mit den folgenden Charakteristika hinzufügen:

Feld Inhalt

Type

U

Abbrev

CSPB

Expanded

CURSORSETPROP(

Cmd

{CmdHandler}

Data

"Buffering", 5, ALIAS() ) && Table Buffered
"Buffering", 3, ALIAS() ) && Row Buffered

Das vorgegebene Verhalten des Skripts CmdHandler besteht darin, die Einträge des Feldes Data zu lesen und diese als Liste anzuzeigen. Der Text im Feld abbrev wird durch den Inhalt des Feldes expanded ersetzt.

Allerdings ist dies nicht die einzige Möglichkeit, eine statische Liste zu erstellen. Wie wir bereits bei der Beschreibung des Headerskripts bemerkt haben, bietet das Objekt FoxCode die Collection Items an, die für die Generierung von Listen genutzt wird, wenn die Eigenschaft ValueType auf "L" steht. Wir können daher eine Liste generieren, indem wir ein Skript erstellen, das direkt in die Collection Items schreibt. Dieses Vorgehen hat einen entscheidenden Vorteil gegenüber der Lösung mit CmdHandler, da die Collection Items bereits über zwei Spalten verfügt. Die Inhalte der ersten Spalte werden direkt in der Liste angezeigt und die Inhalte der zweiten werden benötigt, um die Wertliste zu füllen, die auch in den meisten nativen Listen auftaucht.

Das nächste Beispiel füllt die Collection Items mit einer Liste dreier möglicher Referenzen, die eingesetzt werden, um eine lokale Variable zu erstellen, die ein Objekt referenziert. Die folgende Abbildung zeigt die Liste, die durch die Eingabe von "obj", gefolgt von einem Leerzeichen, ausgelöst wird.

Bild11

Abbildung 11. Eine statische Liste, die unter Einsatz der Collection FoxCode.Items erstellt wurde

In diesem Beispiel nutzen wir wieder das Feld expanded, um den Text zu ersetzen, der das Skript und die Liste für die Vervollständigung der Anweisung ausgelöst hat, Der erforderliche Datensatz in FoxCode sieht folgendermaßen aus:

Field Content

Type

U

Abbrev

Obj

Expanded

loRef =

Cmd

{}

Data

LPARAMETER toFoxCode
WITH toFoxCode
  .ValueType = "L"
  DIMENSION 
  .Items[3,2]  
  .Items[1,1] = "This"  
  .Items[1,2] = "Current Object"  
  .Items[2,1] = "ThisForm"  
  .Items[2,2] = "Current Form"  
  .Items[3,1] = "This.Parent"  
  .Items[3,2] = "Immediate Parent Container"  
  RETURN ALLTRIM( .Expanded )   
ENDWITH

Beispiel 3: Erstellen dynamischer Listen

Statische Listen sind manchmal hilfreich. Die Funktionalität, die in IntelliSense für sich allein gesehen die größte Hilfe bei der Steigerung der Produktivität bringt, ist aber wahrscheinlich die Möglichkeit, dynamisch Listen zu generieren. Dieser Prozess ist etwas komplexer als die Beispiele, die wir bislang gesehen haben, aber Sie werden feststellen, dass die Ergebnisse die aufgewendete Zeit rechtfertigen.
Das folgende Beispiel nutzt ein generisches Skript, um eine Liste von Dateien eines bestimmten Typs im aktuellen Verzeichnis und in unmittelbaren Unterverzeichnissen zu erstellen. Der Gedanke dabei ist, dass dieses Skript von anderen Shortcuts aufgerufen wird, die den speziellen Dateityp definieren, der zurzeit benötigt wird. Weshalb sich mühen, wenn wir bereits die MRU-Listen haben? Nun, damit eine Datei in einer MRU-Liste angezeigt wird, müssen Sie diese Datei mindestens einmal benutzt haben. Außerdem muss diese Nutzung innerhalb der letzten n Dateien geschehen sein, wobei n die Zahl repräsentiert, die Sie als Limit der MRU-Listen angegeben haben. Abbildung 28 zeigt das Ergebnis der Eingabe des Shortcut "mop" (für "Modify Program") in der Befehlszeile.

Bild12

Abbildung 12. Eine dynamische Liste von .PRG-Dateien im aktuellen Verzeichnis und den unmittelbaren Unterverzeichnissen

Als erstes müssen wir einen Shortcut-Eintrag in der Tabelle FoxCode anlegen. Dies ist ein einfacher benutzerdefinierter Datensatz, wie wir ihn ja bereits einmal angelegt haben. Der einzige Unterschied besteht hier darin, dass wir kein im Feld Data stehendes Skript aufrufen, sondern das generische Skript ShoFile im Feld Cmd aufrufen. Der Datensatz sieht folgendermaßen aus:

Feld Inhalt

Type

U

Abbrev

Mop

Expanded

MODIFY COMMAND

Cmd

{shofile}

Das aktuelle Skript ist etwas komplexer als diejenigen, die wir bereits gesehen haben, da wir Manipulationen in der Art vornehmen müssen, in der das Objekt FoxCode behandelt wird. Dafür müssen wir von der Klasse FoxCodeScript (definiert in FoxCode.prg) eine Unterklasse ableiten. Hier der erste Teil des Skripts:

LPARAMETER toFoxcode
IF FILE(_CODESENSE)
   LOCAL luRetVal, loFoxCodeLoader
  *** Ensure we have the root class definition
   SET PROCEDURE TO (_CODESENSE) ADDITIVE
  *** Create an instance of our custom sub class
   loFoxCodeLoader = CreateObject("FoxCodeLoader")
  *** Call it's Start() method and pass the FoxCode object
   luRetVal = loFoxCodeLoader.Start( toFoxCode )
  *** Clean up nicely here
   loFoxCodeLoader = NULL
   IF ATC(_CODESENSE,SET("PROC"))#0
      RELEASE PROCEDURE (_CODESENSE)
   ENDIF
  *** Return whatever we got back
   RETURN luRetVal
ENDIF

Beachten Sie, dass dieser Code davon ausgeht, dass die neue Systemvariable _CodeSense auf ein Programm verweist, das die Klassendefinition für das Objekt FoxCodeScript enthält. Der zweite Teil des Skripts (unten) definiert die benutzerdefinierte Unterklasse, die hier instanziiert ist und die Referenz auf das Objekt FoxCode erhält. Der Rest dieses Teils des Skripts stellt lediglich sicher, dass das Objekt sauber freigegeben wird und keine hängenden Referenzen zurückbleiben. Das ist die Standardvoraussetzung für die Erstellung eines benutzerdefinierten Skripts.
Im zweiten Teil des Skripts definieren wir die abgeleitete Klasse, die die erforderlichen Aufgaben ausführt. Die Klasse FoxCodeScript definiert eine benutzerdefinierte Eigenschaft mit Namen oFoxCode, in der die übergebene Referenz auf das Objekt FoxCode festgehalten wird, sowie eine Methoden-Template namens Main(), das von der Methode Start() aufgerufen wird, wenn das Objekt instanziiert ist. Hier platzieren wir unseren speziellen Code:

DEFINE CLASS FoxCodeLoader as FoxCodeScript
  PROCEDURE Main()
    LOCAL lcMenu, lcKey
    lcMenu = THIS.oFoxcode.MenuItem
    IF EMPTY( lcMenu )
      *** Nothing selected, so display list
      lcKey  = UPPER( THIS.oFoxcode.UserTyped )
      *** What sort of files do we want
      DO CASE
        CASE INLIST( lcKey, "MOP","DOP" )
          lcFiles = '*.prg'
        CASE INLIST( lcKey, "MOF", "DOF" )
          lcFiles = '*.scx'
        CASE INLIST( lcKey, "MOR", "DOR" )
          lcFiles = '*.frx'
        OTHERWISE
          lcFiles = ""
      ENDCASE
      *** Populate the Items Array for display
      This.GetItemList( lcFiles )
      *** Return the Expanded item
      RETURN This.AdjustCase()

Es ist wichtig, sich darüber im Klaren zu sein, dass wir dieses Skript zweimal aufrufen. Der erste Aufruf erfolgt, wenn die IntelliSense-Engine auf Ihren definierten Shortcut reagiert (in diesen Falle "Mop"). Das Skript wird explizit vom Datensatz in der Tabelle FoxCode aufgerufen und übergibt wie üblich eine Referenz auf das Objekt FoxCode. Natürlich haben wir zu diesem Zeitpunkt nur "mop" eingegeben, so dass die Eigenschaft MenuItem des Objekts FoxCode leer ist und der Code am Anfang der Methode Main() wird ausgeführt.

Wie Sie sehen können, wird die Eigenschaft UserTyped des Objekts FoxCode überprüft, um zu entscheiden, welcher Shortcut eingegeben wurde, der entsprechende Dateityp wird eingerichtet und die benutzerdefinierte Methode GetItemList() aufgerufen. Diese Methode ist für die Ausführung eines ADIR() verantwortlich, um die Dateinamen zu erhalten und kopiert die Liste in die Collection Items des Objekts FoxCode. Anschließend wird die Eigenschaft ValueType auf "L" gesetzt (um die Liste anzuzeigen). Danach wird die Eigenschaft ItemScript eingestellt, um auf das Skript ShoFile zu verweisen.

Die Eigenschaft ItemScript wird von der IntelliSense-Engine benötigt, um festzustellen, welche Aktion ausgeführt werden soll, wenn ein Anwender einen Eintrag aus der Liste auswählt. Der Rückgabewert dieses Skripts ist in der Regel ein Aufruf eines Datensatzes vom Typ User, um den Shortcut durch den Inhalt des Feldes Expanded (in diesem Fall "Modify Command") zu ersetzen. Zusätzlich wird die durch GetItemList() generierte Liste angezeigt. Obwohl die Eigenschaft ItemScript jetzt auf das Skript ShoFile verweist, wenn in der Liste eine Auswahl getroffen wird, hat die Eigenschaft MenuItem des Objekts FoxCode einen Wert und der zweite Teil der Methode Main() wird ausgeführt:

ELSE
      *** Return the Selected item
      This.oFoxCode.ValueType = "V"
      RETURN lcMenu
    ENDIF
  ENDPROC

Hier geschieht nichts anderes, als dass die Eigenschaft ValueType auf "V" zurückgesetzt und die Auswahl aus der Liste (jetzt in der Variablen lcMenu) als Rückgabewert zurückgegeben wird, um die Operation zu vervollständigen.
Der Code in der Methode GetItemList() besteht mit Ausnahme des Teils, der das Objekt FoxCode für den zweiten Durchgang einstellt, aus Standard-Code von FoxPro, um eine Liste der Dateien im aktuellen Verzeichnis sowie den direkten Unterverzeichnissen zu erhalten:

PROCEDURE GetItemList( tcKey )
  LOCAL ARRAY laFiles[1,2], laDirs[1], laJunk[1]
  LOCAL lcRootDir, lnDirs, lnDCnt, lnFiles, lcNewDir, lnFound, lcCurDir, lnFCnt, lcFile
    *** Save Root Directory
    lcRootDir = FULLPATH( CURDIR())
    *** Get sub-directories
    lnDirs = ADIR( laDirs, '*.' , 'D' )
    lnFiles = 0
    *** And Process them
    FOR lnDCnt = 1 TO lnDirs
      *** Return to root and re-set
      CD ( lcRootDir )
      DIMENSION laJunk[1]
      lcNewDir = UPPER( ALLTRIM( laDirs[ lnDCnt, 1 ] ))
      IF lcNewDir = ".."
        *** Don't go up the tree
        LOOP
      ENDIF
      CD ( lcNewDir )
      lnFound = ADIR( laJunk, lcFiles )
      lcCurDir = FULLPATH( CURDIR())
      *** If we didn't get any just go on
      IF lnFound < 1
        LOOP
      ENDIF
      *** Now process the files
      FOR lnFCnt = 1 TO lnFound
        lcFile = lcCurDir + laJunk[ lnFCnt, 1 ]
        lnFiles = ALEN( laFiles, 1 ) + 1
        IF NOT EMPTY( laFiles[1] )
          DIMENSION laFiles[ lnFiles, 2 ]
        ELSE
          lnFiles = 1
        ENDIF
        laFiles[ lnFiles, 1 ] = lcFile
      NEXT 
    NEXT
    *** Change back to original directory
    CD (lcRootDir)
    *** If we got something, display the list
    IF lnFiles > 0

An diesem Punkt verfügen wir über eine Liste aller Dateien des erforderlichen Typs im Array laJunk. Jetzt müssen wir das Objekt FoxCode einrichten, damit es die Liste anzeigt und dieses Skript neu aufruft:

THIS.oFoxcode.ValueType = "L"
        THIS.oFoxcode.ItemScript = "ShoFile"
        *** Copy items to temporary array
        DIMENSION THIS.oFoxcode.Items[lnFiles ,2]
        ACOPY(laFiles,THIS.oFoxcode.Items)
     ENDIF
  ENDPROC
ENDDEFINE

Das ist gar nicht so komplex wie es aussieht. Hier der gesamte Datensatz ShoFile:

Feld Inhalt

Type

S

Abbrev

Shofile

Cmd

{}

Data

LPARAMETER toFoxcode
IF FILE(_CODESENSE)
   LOCAL luRetVal, loFoxCodeLoader  
   *** Ensure we have the root class definition   
   SET PROCEDURE TO (_CODESENSE) ADDITIVE  
   *** Create an instance of our custom sub class   
   loFoxCodeLoader = CreateObject("FoxCodeLoader")  
   *** Call it's Start() method and pass the FoxCode object   
   luRetVal = loFoxCodeLoader.Start( toFoxCode )  
   *** Clean up nicely here   loFoxCodeLoader = NULL   
   IF ATC(_CODESENSE,SET("PROC"))#0
      RELEASE PROCEDURE (_CODESENSE)   
   ENDIF  
   *** Return whatever we got back   
   RETURN luRetVal
ENDIF
DEFINE CLASS FoxCodeLoader as FoxCodeScript
  PROCEDURE Main()
      LOCAL lcMenu, lcKey    
  lcMenu = THIS.oFoxcode.MenuItem    
  IF EMPTY( lcMenu )
        *** Nothing selected, so display list      
lcKey  = UPPER( THIS.oFoxcode.UserTyped )      
*** What sort of files do we want      
DO CASE
   CASE INLIST( lcKey, "MOP","DOP" )          
 lcFiles = '*.prg'
   CASE INLIST( lcKey, "MOF", "DOF" )
     lcFiles = '*.scx'        
   CASE INLIST( lcKey, "MOR", "DOR" )
     lcFiles = '*.frx'        
   OTHERWISE
     lcFiles = ""      
ENDCASE      
*** Populate the Items Array for display      
This.GetItemList( lcFiles )      
*** Return the Expanded item      
RETURN This.AdjustCase()    
  ELSE
        *** Return the Selected item      
This.oFoxCode.ValueType = "V"      
RETURN lcMenu    
  ENDIF  
  ENDPROC  
  PROCEDURE GetItemList( tcKey )  
  LOCAL ARRAY laFiles[1,2], laDirs[1], laJunk[1]  
  LOCAL lcRootDir, lnDirs, lnDCnt, lnFiles, lcNewDir  
  LOCAL lnFound, lcCurDir, lnFCnt, lcFile
      *** Save Root Directory    
  lcRootDir = FULLPATH( CURDIR())    
  *** Get sub-directories    
  lnDirs = ADIR( laDirs, '*.' , 'D' )    
  lnFiles = 0    
  *** And Process them    
  FOR lnDCnt = 1 TO lnDirs
        *** Return to root and re-set      
CD ( lcRootDir )      
DIMENSION laJunk[1]      
lcNewDir = UPPER( ALLTRIM( laDirs[ lnDCnt, 1 ] ))      
IF lcNewDir = ".."
        *** Don't go up the tree        
LOOP      
ENDIF      
CD ( lcNewDir )      
lnFound = ADIR( laJunk, lcFiles )      
lcCurDir = FULLPATH( CURDIR())      
*** If we didn't get any just go on      
IF lnFound < 1
        LOOP      
ENDIF      
*** Now process the files      
FOR lnFCnt = 1 TO lnFound
        lcFile = lcCurDir + laJunk[ lnFCnt, 1 ]        
lnFiles = ALEN( laFiles, 1 ) + 1        
IF NOT EMPTY( laFiles[1] )
          DIMENSION laFiles[ lnFiles, 2 ]        
ELSE
          lnFiles = 1        
ENDIF        
laFiles[ lnFiles, 1 ] = lcFile      
NEXT     
  NEXT    
  *** Change back to original directory    
  CD (lcRootDir)    
  *** If we got something, display the list    
  IF lnFiles > 0
          THIS.oFoxcode.ValueType = "L"        
  THIS.oFoxcode.ItemScript = "ShoFile"        
  *** Copy items to temporary array        
  DIMENSION THIS.oFoxcode.Items[lnFiles ,2]        
  ACOPY(laFiles,THIS.oFoxcode.Items)     
  ENDIF  
ENDPROC
ENDDEFINE

Das Skript, so wie es hier steht, beinhaltet die Behandlung von Programmen (mop & dop), Formularen (mof und dof) und Berichten (mor und dor). Selbstverständlich ist es eine einfache Aufgabe, diesem Skript zusätzliche Typen hinzuzufügen. Dies überlassen wir dem Leser als Übung.

Zum SeitenanfangZum Seitenanfang